31#include "cling/Interpreter/Interpreter.h" 
   32#include "cling/Interpreter/Transaction.h" 
   35#include "clang/AST/ASTContext.h" 
   36#include "clang/AST/Decl.h" 
   37#include "clang/AST/DeclCXX.h" 
   38#include "clang/AST/PrettyPrinter.h" 
   39#include "clang/AST/RecordLayout.h" 
   40#include "clang/AST/Type.h" 
   41#include "clang/AST/CXXInheritance.h" 
   44#include "llvm/Support/Casting.h" 
   45#include "llvm/Support/raw_ostream.h" 
   46#include "llvm/ExecutionEngine/ExecutionEngine.h" 
   47#include "llvm/IR/Module.h" 
   58   : fInterp(interp), fClassInfo(0), fFirstTime(true), fDescend(false),
 
   59     fDecl(0), fIter(0), fBaseInfo(0), fOffset(0L), fClassInfoOwnership(true)
 
   71   const clang::CXXRecordDecl* CRD =
 
   81      cling::Interpreter::PushTransactionRAII RAII(
fInterp);
 
   82      fIter = CRD->bases_begin();
 
   89   : fInterp(interp), fClassInfo(0), fFirstTime(true), fDescend(false),
 
   90     fDecl(0), fIter(0), fBaseInfo(0), fOffset(0L), fClassInfoOwnership(false)
 
   97   const clang::CXXRecordDecl* CRD =
 
   98      llvm::dyn_cast<clang::CXXRecordDecl>(derived->
GetDecl());
 
   99   const clang::CXXRecordDecl* BaseCRD =
 
  100      llvm::dyn_cast<clang::CXXRecordDecl>(base->
GetDecl());
 
  101   if (!CRD || !BaseCRD) {
 
  111   clang::CXXBasePaths Paths;
 
  114   cling::Interpreter::PushTransactionRAII RAII(
fInterp);
 
  116   if (!CRD->isDerivedFrom(BaseCRD, Paths)) {
 
  122   fIter = CRD->bases_end();
 
  126   : fInterp(rhs.fInterp), fClassInfo(0), fFirstTime(rhs.fFirstTime),
 
  127     fDescend(rhs.fDescend), fDecl(rhs.fDecl), fIter(rhs.fIter), fBaseInfo(0),
 
  128     fIterStack(rhs.fIterStack), fOffset(rhs.fOffset), fClassInfoOwnership(true)
 
  167                                                void* address, 
bool isDerivedObject)
 const 
  175   if (
fInterp->isInSyntaxOnlyMode())
 
  179   const clang::RecordDecl* fromDerivedDecl
 
  180      = dyn_cast<clang::RecordDecl>(fromDerivedClass->
GetDecl());
 
  181   if (!fromDerivedDecl) {
 
  182      ::Error(
"TClingBaseClassInfo::GenerateBaseOffsetFunction",
 
  183            "Offset of non-class %s is ill-defined!", fromDerivedClass->
Name());
 
  186   const clang::RecordDecl* toBaseDecl
 
  187      = dyn_cast<clang::RecordDecl>(toBaseClass->
GetDecl());
 
  189      ::Error(
"TClingBaseClassInfo::GenerateBaseOffsetFunction",
 
  190            "Offset of non-class %s is ill-defined!", toBaseClass->
Name());
 
  198      buf << 
"h" << fromDerivedDecl;
 
  200      buf << 
"h" << toBaseDecl;
 
  201      wrapper_name = buf.str();
 
  205   if (!
fInterp->getAddressOfGlobal(wrapper_name)) {
 
  207      string fromDerivedClassName;
 
  208      clang::QualType QTDerived(fromDerivedClass->
GetType(), 0);
 
  211      string toBase_class_name;
 
  212      clang::QualType QTtoBase(toBaseClass->
GetType(), 0);
 
  216      llvm::raw_string_ostream buf(code);
 
  217      buf << 
"extern \"C\" ptrdiff_t " + wrapper_name + 
"(void* address, bool isDerivedObject) {\n" 
  219          << 
"  " << fromDerivedClassName << 
" *fromDerived;" 
  220          << 
"  if (isDerivedObject) {" 
  221          << 
"    fromDerived = (" << fromDerivedClassName << 
"*)address;\n" 
  223          << 
"    fromDerived = dynamic_cast<" << fromDerivedClassName << 
"*>((" << toBase_class_name << 
"*)address);\n" 
  225          << 
"  if (!fromDerived) {\n" 
  228          << 
"  " << toBase_class_name << 
" *toBase = fromDerived;\n" 
  229          << 
"  return ((intptr_t)toBase - (intptr_t)fromDerived);\n}\n";
 
  233   void* 
f = 
fInterp->compileFunction(wrapper_name, code, 
true ,
 
  236      ::Error(
"TClingBaseClassInfo::GenerateBaseOffsetFunction",
 
  237            "Compilation failed!");
 
  261         (
fIter == llvm::dyn_cast<clang::CXXRecordDecl>(
fDecl)->bases_end())) {
 
  277         cling::Interpreter::PushTransactionRAII RAII(
fInterp);
 
  279         const clang::RecordType *Ty = 
fIter->getType()->
 
  280                                       getAs<clang::RecordType>();
 
  283         clang::CXXRecordDecl *Base = llvm::cast<clang::CXXRecordDecl>(
 
  284                                         Ty->getDecl()->getDefinition());
 
  285         clang::ASTContext &Context = Base->getASTContext();
 
  286         const clang::RecordDecl *RD = llvm::dyn_cast<clang::RecordDecl>(
fDecl);
 
  287         const clang::ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
 
  288         int64_t 
offset = Layout.getBaseClassOffset(Base).getQuantity();
 
  291                                             static_cast<ptrdiff_t
>(
offset)));
 
  293         fIter = Base->bases_begin();
 
  301         (
fIter == llvm::dyn_cast<clang::CXXRecordDecl>(
fDecl)->bases_end()) &&
 
  312      if (
fIter == llvm::dyn_cast<clang::CXXRecordDecl>(
fDecl)->bases_end()) {
 
  321      const clang::TagType *Ty = 
fIter->getType()->getAs<clang::TagType>();
 
  327      const clang::CXXRecordDecl *Base =
 
  328         llvm::cast_or_null<clang::CXXRecordDecl>(Ty->getDecl()->
 
  336      if (!onlyDirect && Base->getNumBases()) {
 
  361                                          const clang::CXXRecordDecl *Src,
 
  362                                          const clang::CXXRecordDecl *
Dst,
 
  363                                          cling::Interpreter* interp)
 
  365   clang::CXXBasePaths Paths(
true, 
true,
 
  370   if (!
Dst->isDerivedFrom(Src, Paths))
 
  371     return clang::CharUnits::fromQuantity(-2);
 
  373   unsigned NumPublicPaths = 0;
 
  374   clang::CharUnits Offset;
 
  377   for (clang::CXXBasePaths::paths_iterator 
I = Paths.begin(), E = Paths.end();
 
  382     for (clang::CXXBasePath::iterator J = 
I->begin(), JE = 
I->end(); J != JE; ++J) {
 
  385       if (J->Base->isVirtual())
 
  386         return clang::CharUnits::fromQuantity(-1);
 
  388       if (NumPublicPaths > 1) 
 
  392       cling::Interpreter::PushTransactionRAII RAII(interp);
 
  393       const clang::ASTRecordLayout &L = Context.getASTRecordLayout(J->Class);
 
  394       Offset += L.getBaseClassOffset(J->Base->getType()->getAsCXXRecordDecl());
 
  399   if (NumPublicPaths == 0)
 
  400     return clang::CharUnits::fromQuantity(-2);
 
  403   if (NumPublicPaths > 1)
 
  404     return clang::CharUnits::fromQuantity(-3);
 
  419   const clang::CXXRecordDecl* Base =
 
  427      clang::ASTContext& Context = Base->getASTContext();
 
  428      const clang::CXXRecordDecl* RD = llvm::dyn_cast<clang::CXXRecordDecl>(
fDecl);
 
  434      if (clang_val == -2 || clang_val == -3) {
 
  443                                  getPrintingPolicy());
 
  444            llvm::raw_string_ostream stream(buf);
 
  446               ->getNameForDiagnostic(stream, Policy, 
true);
 
  452               ->getNameForDiagnostic(stream, Policy, 
true);
 
  456         if (clang_val == -2) {
 
  457            ::Error(
"TClingBaseClassInfo::Offset",
 
  458                  "The class %s does not derive from the base %s.",
 
  459                  derivedName.
Data(), baseName.
Data());
 
  462            ::Error(
"TClingBaseClassInfo::Offset",
 
  463                  "There are multiple paths from derived class %s to base class %s.",
 
  464                  derivedName.
Data(), baseName.
Data());
 
  473      ::Error(
"TClingBaseClassInfo::Offset", 
"The address of the object for virtual base offset calculation is not valid.");
 
  479   if (executableFunc) {
 
  481      return (*executableFunc)(address, isDerivedObject);
 
  499   const clang::CXXRecordDecl* CRD
 
  500      = llvm::dyn_cast<CXXRecordDecl>(
fDecl);
 
  501   const clang::CXXRecordDecl* BaseCRD
 
  503   if (!CRD || !BaseCRD) {
 
  504      ::Error(
"TClingBaseClassInfo::Property",
 
  505            "The derived class or the base class do not have a CXXRecordDecl.");
 
  509   clang::CXXBasePaths Paths(
false, 
true,
 
  511   if (!CRD->isDerivedFrom(BaseCRD, Paths)) {
 
  514      ::Error(
"TClingBaseClassInfo", 
"Class not derived from given base.");
 
  516   if (Paths.getDetectedVirtual()) {
 
  520   clang::AccessSpecifier AS = clang::AS_public;
 
  522   for (clang::CXXBasePaths::const_paths_iterator IB = Paths.begin(), EB = Paths.end();
 
  523        AS != clang::AS_private && IB != EB; ++IB) {
 
  524      switch (IB->Access) {
 
  526         case clang::AS_public: 
break;
 
  527         case clang::AS_protected: AS = clang::AS_protected; 
break;
 
  528         case clang::AS_private: AS = clang::AS_private; 
break;
 
  529         case clang::AS_none: 
break;
 
  533      case clang::AS_public:
 
  536      case clang::AS_protected:
 
  539      case clang::AS_private:
 
static clang::CharUnits computeOffsetHint(clang::ASTContext &Context, const clang::CXXRecordDecl *Src, const clang::CXXRecordDecl *Dst, cling::Interpreter *interp)
 
ptrdiff_t(* OffsetPtrFunc_t)(void *, bool)
 
void Error(const char *location, const char *msgfmt,...)
Use this function in case an error occurred.
 
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h offset
 
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t property
 
Emulation of the CINT BaseClassInfo class.
 
const char * TmpltName() const
 
const char * Name() const
 
const clang::Decl * fDecl
 
ptrdiff_t Offset(void *address=0, bool isDerivedObject=true) const
 
TClingClassInfo * fBaseInfo
 
TClingClassInfo * fClassInfo
 
std::vector< std::pair< std::pair< const clang::Decl *, clang::CXXRecordDecl::base_class_const_iterator >, ptrdiff_t > > fIterStack
 
OffsetPtrFunc_t GenerateBaseOffsetFunction(TClingClassInfo *derivedClass, TClingClassInfo *targetClass, void *address, bool isDerivedObject) const
 
TClingBaseClassInfo(cling::Interpreter *, TClingClassInfo *)
 
void FullName(std::string &output, const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) const
 
TClingBaseClassInfo & operator=(const TClingBaseClassInfo &)
 
cling::Interpreter * fInterp
 
int InternalNext(int onlyDirect)
 
clang::CXXRecordDecl::base_class_const_iterator fIter
 
TClingClassInfo * GetBase() const
 
Emulation of the CINT ClassInfo class.
 
void FullName(std::string &output, const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) const
 
const char * TmpltName() const
 
void AddBaseOffsetValue(const clang::Decl *decl, ptrdiff_t offset)
 
const clang::Type * GetType() const
 
void AddBaseOffsetFunction(const clang::Decl *decl, OffsetPtrFunc_t func)
 
virtual const char * Name() const
 
virtual bool IsValid() const
 
virtual const clang::Decl * GetDecl() const
 
const char * Data() const