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"
54using std::string, std::ostringstream;
58 : fInterp(
interp), fClassInfo(nullptr), fFirstTime(
true), fDescend(
false),
59 fDecl(nullptr), fIter(nullptr), fBaseInfo(nullptr), fOffset(0L), fClassInfoOwnership(
true)
71 const clang::CXXRecordDecl*
CRD =
81 cling::Interpreter::PushTransactionRAII
RAII(
fInterp);
89 : fInterp(
interp), fClassInfo(nullptr), fFirstTime(
true), fDescend(
false),
90 fDecl(nullptr), fIter(nullptr), fBaseInfo(nullptr), 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());
111 clang::CXXBasePaths
Paths;
114 cling::Interpreter::PushTransactionRAII
RAII(
fInterp);
126 : fInterp(
rhs.fInterp), fClassInfo(nullptr), fFirstTime(
rhs.fFirstTime),
127 fDescend(
rhs.fDescend), fDecl(
rhs.fDecl), fIter(
rhs.fIter), fBaseInfo(nullptr),
128 fIterStack(
rhs.fIterStack), fOffset(
rhs.fOffset), fClassInfoOwnership(
true)
175 if (
fInterp->isInSyntaxOnlyMode())
182 ::Error(
"TClingBaseClassInfo::GenerateBaseOffsetFunction",
189 ::Error(
"TClingBaseClassInfo::GenerateBaseOffsetFunction",
190 "Offset of non-class %s is ill-defined!",
toBaseClass->Name());
216 llvm::raw_string_ostream buf(code);
217 buf <<
"extern \"C\" ptrdiff_t " +
wrapper_name +
"(void* address, bool isDerivedObject) {\n"
220 <<
" if (isDerivedObject) {"
225 <<
" if (!fromDerived) {\n"
229 <<
" return ((intptr_t)toBase - (intptr_t)fromDerived);\n}\n";
236 ::Error(
"TClingBaseClassInfo::GenerateBaseOffsetFunction",
237 "Compilation failed!");
277 cling::Interpreter::PushTransactionRAII
RAII(
fInterp);
279 const clang::RecordType *
Ty =
fIter->getType()->
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();
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()->
361 const clang::CXXRecordDecl *
Src,
362 const clang::CXXRecordDecl *
Dst,
363 cling::Interpreter*
interp)
365 clang::CXXBasePaths
Paths(
true,
true,
371 return clang::CharUnits::fromQuantity(-2);
374 clang::CharUnits Offset;
385 if (J->Base->isVirtual())
386 return clang::CharUnits::fromQuantity(-1);
392 cling::Interpreter::PushTransactionRAII
RAII(
interp);
393 const clang::ASTRecordLayout &L = Context.getASTRecordLayout(J->Class);
394 Offset += L.getBaseClassOffset(J->Base->getType()->getAsCXXRecordDecl());
400 return clang::CharUnits::fromQuantity(-2);
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);
444 llvm::raw_string_ostream stream(buf);
457 ::Error(
"TClingBaseClassInfo::Offset",
458 "The class %s does not derive from the base %s.",
462 ::Error(
"TClingBaseClassInfo::Offset",
463 "There are multiple paths from derived class %s to base class %s.",
473 ::Error(
"TClingBaseClassInfo::Offset",
"The address of the object for virtual base offset calculation is not valid.");
499 const clang::CXXRecordDecl*
CRD
500 = llvm::dyn_cast<CXXRecordDecl>(
fDecl);
501 const clang::CXXRecordDecl*
BaseCRD
504 ::Error(
"TClingBaseClassInfo::Property",
505 "The derived class or the base class do not have a CXXRecordDecl.");
509 clang::CXXBasePaths
Paths(
false,
true,
514 ::Error(
"TClingBaseClassInfo",
"Class not derived from given base.");
516 if (
Paths.getDetectedVirtual()) {
520 clang::AccessSpecifier
AS = clang::AS_public;
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:
544 assert(
false &&
"Unexpected value for the access property value in Clang");
547 assert(
false &&
"Unexpected value for the access property value in Clang");
static clang::CharUnits computeOffsetHint(clang::ASTContext &Context, const clang::CXXRecordDecl *Src, const clang::CXXRecordDecl *Dst, cling::Interpreter *interp)
ptrdiff_t(* OffsetPtrFunc_t)(void *, bool)
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
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
const_iterator begin() const
const_iterator end() const
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