34 #include "cling/Interpreter/Interpreter.h" 35 #include "cling/Interpreter/LookupHelper.h" 36 #include "cling/Utils/AST.h" 38 #include "clang/AST/ASTContext.h" 39 #include "clang/AST/Decl.h" 40 #include "clang/AST/DeclCXX.h" 41 #include "clang/AST/DeclTemplate.h" 42 #include "clang/AST/ExprCXX.h" 43 #include "clang/AST/GlobalDecl.h" 44 #include "clang/AST/Mangle.h" 45 #include "clang/AST/PrettyPrinter.h" 46 #include "clang/AST/Type.h" 47 #include "clang/Basic/IdentifierTable.h" 48 #include "clang/Sema/Lookup.h" 49 #include "clang/Sema/Sema.h" 50 #include "clang/Sema/Template.h" 52 #include "llvm/Support/Casting.h" 53 #include "llvm/Support/raw_ostream.h" 57 using namespace clang;
59 class TClingMethodInfo::SpecIterator
62 typedef clang::FunctionTemplateDecl::spec_iterator Iterator;
64 SpecIterator(Iterator begin, Iterator end) : fIter(begin), fEnd(end) {}
65 explicit SpecIterator(clang::FunctionTemplateDecl *decl) : fIter(decl->spec_begin()), fEnd(decl->spec_end()) {}
67 FunctionDecl *
operator* ()
const {
return *fIter; }
68 FunctionDecl *operator-> ()
const {
return *fIter; }
69 SpecIterator & operator++ () { ++fIter;
return *
this; }
70 SpecIterator operator++ (
int) {
71 SpecIterator tmp(fIter,fEnd);
75 bool operator!() {
return fIter == fEnd; }
76 operator bool() {
return fIter != fEnd; }
86 fContexts(rhs.fContexts),
87 fFirstTime(rhs.fFirstTime),
88 fContextIdx(rhs.fContextIdx),
92 fSingleDecl(rhs.fSingleDecl)
112 clang::CXXRecordDecl *cxxdecl = llvm::dyn_cast<clang::CXXRecordDecl>(
const_cast<clang::Decl*
>(ci->
GetDecl()));
117 cling::Interpreter::PushTransactionRAII RAII(interp);
119 fInterp->getSema().ForceDeclarationOfImplicitMembers(cxxdecl);
121 clang::DeclContext *dc =
122 llvm::cast<clang::DeclContext>(
const_cast<clang::Decl*
>(ci->
GetDecl()));
125 cling::Interpreter::PushTransactionRAII RAII(interp);
126 fIter = dc->decls_begin();
132 const clang::FunctionDecl *FD)
149 return (
const clang::Decl*)(
GetMethodDecl()->getCanonicalDecl());
162 return *(*fTemplateSpecIter);
164 return llvm::dyn_cast<clang::FunctionDecl>(*fIter);
184 if (arg.
Name() && strlen(arg.
Name())) {
186 signature += arg.
Name();
202 fIter = clang::DeclContext::decl_iterator();
225 cling::Interpreter::PushTransactionRAII RAII(
fInterp);
226 return *(*fTemplateSpecIter);
237 unsigned num_params = fd->getNumParams();
239 return static_cast<int>(num_params);
248 unsigned num_params = fd->getNumParams();
249 unsigned min_args = fd->getMinRequiredArguments();
250 unsigned defaulted_params = num_params - min_args;
252 return static_cast<int>(defaulted_params);
270 const cling::LookupHelper& LH) {
272 using namespace clang;
274 auto templateParms = FTDecl->getTemplateParameters();
275 if (templateParms->containsUnexpandedParameterPack())
278 if (templateParms->getMinRequiredArguments() > 0)
281 if (templateParms->size() > 0) {
282 NamedDecl *arg0 = *templateParms->begin();
283 if (arg0->isTemplateParameterPack())
285 if (
auto TTP = dyn_cast<TemplateTypeParmDecl>(*templateParms->begin())) {
286 if (!TTP->hasDefaultArgument())
288 }
else if (
auto NTTP = dyn_cast<NonTypeTemplateParmDecl>(
289 *templateParms->begin())) {
290 if (!NTTP->hasDefaultArgument())
298 FunctionDecl *templatedDecl = FTDecl->getTemplatedDecl();
299 Decl *declCtxDecl = dyn_cast<Decl>(FTDecl->getDeclContext());
301 llvm::SmallVector<QualType, 8> paramTypes;
303 const ClassTemplateSpecializationDecl *ctxInstance
304 = dyn_cast<ClassTemplateSpecializationDecl>(declCtxDecl);
307 for (
const clang::ParmVarDecl *param: templatedDecl->parameters()) {
308 QualType paramType = param->getOriginalType();
312 if (ctxInstance && paramType->isDependentType()) {
319 MultiLevelTemplateArgumentList MLTAL(
320 ctxInstance->getTemplateInstantiationArgs());
321 Sema::InstantiatingTemplate Inst(S, SourceLocation(), templatedDecl);
322 paramType = S.SubstType(paramType, MLTAL, SourceLocation(),
323 templatedDecl->getDeclName());
325 if (paramType->isDependentType()) {
332 paramTypes.push_back(paramType);
336 LH.findFunctionProto(declCtxDecl, FTDecl->getNameAsString(),
337 paramTypes, LH.NoDiagnostics,
338 templatedDecl->getType().isConstQualified());
345 assert(!
fSingleDecl &&
"This is not an iterator!");
359 ++(*fTemplateSpecIter);
382 cling::Interpreter::PushTransactionRAII RAII(
fInterp);
383 fIter = dc->decls_begin();
390 clang::FunctionTemplateDecl *templateDecl =
391 llvm::dyn_cast<clang::FunctionTemplateDecl>(*fIter);
393 if ( templateDecl ) {
397 cling::Interpreter::PushTransactionRAII RAII(
fInterp);
407 SpecIterator subiter(templateDecl);
416 if (llvm::isa<clang::FunctionDecl>(*fIter)) {
442 switch (fd->getAccess()) {
443 case clang::AS_public:
446 case clang::AS_protected:
449 case clang::AS_private:
453 if (fd->getDeclContext()->isNamespace())
460 if (fd->getStorageClass() == clang::SC_Static) {
463 clang::QualType qt = fd->getReturnType().getCanonicalType();
464 if (qt.isConstQualified()) {
468 if (qt->isArrayType()) {
469 qt = llvm::cast<clang::ArrayType>(qt)->getElementType();
472 else if (qt->isReferenceType()) {
474 qt = llvm::cast<clang::ReferenceType>(qt)->getPointeeType();
477 else if (qt->isPointerType()) {
479 if (qt.isConstQualified()) {
482 qt = llvm::cast<clang::PointerType>(qt)->getPointeeType();
485 else if (qt->isMemberPointerType()) {
486 qt = llvm::cast<clang::MemberPointerType>(qt)->getPointeeType();
491 if (qt.isConstQualified()) {
494 if (
const clang::CXXMethodDecl *md =
495 llvm::dyn_cast<clang::CXXMethodDecl>(fd)) {
496 if (md->getTypeQualifiers() & clang::Qualifiers::Const) {
499 if (md->isVirtual()) {
505 if (
const clang::CXXConstructorDecl *cd =
506 llvm::dyn_cast<clang::CXXConstructorDecl>(md)) {
507 if (cd->isExplicit()) {
511 else if (
const clang::CXXConversionDecl *cd =
512 llvm::dyn_cast<clang::CXXConversionDecl>(md)) {
513 if (cd->isExplicit()) {
530 if (fd->isOverloadedOperator()) {
533 else if (llvm::isa<clang::CXXConversionDecl>(fd)) {
535 }
else if (llvm::isa<clang::CXXConstructorDecl>(fd)) {
537 }
else if (llvm::isa<clang::CXXDestructorDecl>(fd)) {
547 ti.Init(clang::QualType());
552 const clang::TypeDecl* ctorClass = llvm::dyn_cast_or_null<clang::TypeDecl>
555 Error(
"TClingMethodInfo::Type",
"Cannot find DeclContext for constructor!");
557 clang::QualType qt(ctorClass->getTypeForDecl(), 0);
572 std::string mangled_name;
573 mangled_name.clear();
578 if (
const CXXConstructorDecl* Ctor = dyn_cast<CXXConstructorDecl>(D))
579 GD = GlobalDecl(Ctor, Ctor_Complete);
580 else if (
const CXXDestructorDecl* Dtor = dyn_cast<CXXDestructorDecl>(D))
581 GD = GlobalDecl(Dtor, Dtor_Deleting);
585 cling::utils::Analyze::maybeMangleDeclName(GD, mangled_name);
594 TTHREAD_TLS_DECL( std::string, buf );
598 if (
const clang::TypeDecl *td = llvm::dyn_cast<clang::TypeDecl>(
GetMethodDecl()->getDeclContext())) {
600 clang::QualType qualType(td->getTypeForDecl(),0);
604 }
else if (
const clang::NamedDecl *nd = llvm::dyn_cast<clang::NamedDecl>(
GetMethodDecl()->getDeclContext())) {
606 clang::PrintingPolicy policy(
GetMethodDecl()->getASTContext().getPrintingPolicy());
607 llvm::raw_string_ostream stream(name);
608 nd->getNameForDiagnostic(stream, policy,
true);
613 buf +=
Name(normCtxt);
622 if (arg.
Name() && strlen(arg.
Name())) {
633 if (
const clang::CXXMethodDecl *md =
635 if (md->getTypeQualifiers() & clang::Qualifiers::Const) {
647 TTHREAD_TLS_DECL( std::string, buf );
680 cling::Interpreter::PushTransactionRAII RAII(
fInterp);
681 if (
const FunctionDecl *AnnotFD
683 if (AnnotateAttr *
A = AnnotFD->getAttr<AnnotateAttr>()) {
684 fTitle =
A->getAnnotation().str();
688 if (!FD->isFromASTFile()) {
const char * GetPrototype(const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) const
RooArgList L(const RooAbsArg &v1)
static void InstantiateFuncTemplateWithDefaults(clang::FunctionTemplateDecl *FTDecl, clang::Sema &S, const cling::LookupHelper &LH)
R__EXTERN TVirtualMutex * gInterpreterMutex
const char * Name() const
void SetFunc(const TClingClassInfo *info, const char *method, const char *arglist, long *poffset)
llvm::SmallVector< clang::DeclContext *, 2 > fContexts
Emulation of the CINT MethodInfo class.
const TClingTypeInfo * Type() const
clang::DeclContext::decl_iterator fIter
TClingTypeInfo * Type() const
Emulation of the CINT CallFunc class.
void CreateSignature(TString &signature) const
Emulation of the CINT TypeInfo class.
This class defines an interface to the cling C++ interpreter.
void Error(const char *location, const char *msgfmt,...)
long ExtraProperty() const
SpecIterator * fTemplateSpecIter
const char * Name() const
RooArgSet S(const RooAbsArg &v1)
TCut operator!(const TCut &rhs)
Logical negation.
void Init(const clang::FunctionDecl *)
void * InterfaceMethod(const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) const
const clang::FunctionDecl * GetMethodDecl() const
TTime operator*(const TTime &t1, const TTime &t2)
const char * DefaultValue() const
TDictionary::DeclId_t GetDeclId() const
const char * TypeName() const
std::string GetMangledName() const
const char * Name(const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) const
const clang::Decl * GetDecl() const
const clang::FunctionDecl * fSingleDecl
Emulation of the CINT MethodInfo class.
Emulation of the CINT ClassInfo class.
#define R__LOCKGUARD(mutex)
TClingMethodInfo(cling::Interpreter *interp)
R__EXTERN TInterpreter * gCling
cling::Interpreter * fInterp
static char * skip(char **buf, const char *delimiters)