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" 51 #include "clang/Sema/TemplateDeduction.h" 53 #include "llvm/Support/Casting.h" 54 #include "llvm/Support/raw_ostream.h" 58 using namespace clang;
60 class TClingMethodInfo::SpecIterator
63 typedef clang::FunctionTemplateDecl::spec_iterator Iterator;
65 SpecIterator(Iterator begin, Iterator end) : fIter(begin), fEnd(end) {}
66 explicit SpecIterator(clang::FunctionTemplateDecl *decl) : fIter(decl->spec_begin()), fEnd(decl->spec_end()) {}
68 FunctionDecl *
operator* ()
const {
return *fIter; }
69 FunctionDecl *operator-> ()
const {
return *fIter; }
70 SpecIterator & operator++ () { ++fIter;
return *
this; }
71 SpecIterator operator++ (
int) {
72 SpecIterator tmp(fIter,fEnd);
76 bool operator!() {
return fIter == fEnd; }
77 operator bool() {
return fIter != fEnd; }
87 fContexts(rhs.fContexts),
88 fFirstTime(rhs.fFirstTime),
89 fContextIdx(rhs.fContextIdx),
93 fSingleDecl(rhs.fSingleDecl)
113 clang::CXXRecordDecl *cxxdecl = llvm::dyn_cast<clang::CXXRecordDecl>(
const_cast<clang::Decl*
>(ci->
GetDecl()));
118 cling::Interpreter::PushTransactionRAII RAII(interp);
120 fInterp->getSema().ForceDeclarationOfImplicitMembers(cxxdecl);
122 clang::DeclContext *dc =
123 llvm::cast<clang::DeclContext>(
const_cast<clang::Decl*
>(ci->
GetDecl()));
126 cling::Interpreter::PushTransactionRAII RAII(interp);
127 fIter = dc->decls_begin();
133 const clang::FunctionDecl *FD)
150 return (
const clang::Decl*)(
GetMethodDecl()->getCanonicalDecl());
163 return *(*fTemplateSpecIter);
165 return llvm::dyn_cast<clang::FunctionDecl>(*fIter);
185 if (arg.
Name() && strlen(arg.
Name())) {
187 signature += arg.
Name();
203 fIter = clang::DeclContext::decl_iterator();
226 cling::Interpreter::PushTransactionRAII RAII(
fInterp);
227 return *(*fTemplateSpecIter);
238 unsigned num_params = fd->getNumParams();
240 return static_cast<int>(num_params);
249 unsigned num_params = fd->getNumParams();
250 unsigned min_args = fd->getMinRequiredArguments();
251 unsigned defaulted_params = num_params - min_args;
253 return static_cast<int>(defaulted_params);
271 const cling::LookupHelper& LH) {
273 using namespace clang;
275 auto templateParms = FTDecl->getTemplateParameters();
276 if (templateParms->containsUnexpandedParameterPack())
279 if (templateParms->getMinRequiredArguments() > 0)
282 if (templateParms->size() > 0) {
283 NamedDecl *arg0 = *templateParms->begin();
284 if (arg0->isTemplateParameterPack())
286 if (
auto TTP = dyn_cast<TemplateTypeParmDecl>(*templateParms->begin())) {
287 if (!TTP->hasDefaultArgument())
289 }
else if (
auto NTTP = dyn_cast<NonTypeTemplateParmDecl>(
290 *templateParms->begin())) {
291 if (!NTTP->hasDefaultArgument())
299 FunctionDecl *templatedDecl = FTDecl->getTemplatedDecl();
300 Decl *declCtxDecl = dyn_cast<Decl>(FTDecl->getDeclContext());
302 llvm::SmallVector<QualType, 8> paramTypes;
304 const ClassTemplateSpecializationDecl *ctxInstance
305 = dyn_cast<ClassTemplateSpecializationDecl>(declCtxDecl);
309 SmallVector<DeducedTemplateArgument, 4> DeducedArgs;
310 ArrayRef< TemplateArgument > TemplateArgs;
311 sema::TemplateDeductionInfo
Info{SourceLocation()};
313 Sema::InstantiatingTemplate Inst(S,
Info.getLocation(), FTDecl,
315 Sema::ActiveTemplateInstantiation::DeducedTemplateArgumentSubstitution,
320 for (
const clang::ParmVarDecl *param: templatedDecl->parameters()) {
321 QualType paramType = param->getOriginalType();
325 if (ctxInstance && paramType->isDependentType()) {
332 MultiLevelTemplateArgumentList MLTAL(
333 ctxInstance->getTemplateInstantiationArgs());
334 paramType = S.SubstType(paramType, MLTAL, SourceLocation(),
335 templatedDecl->getDeclName());
337 if (paramType.isNull() || paramType->isDependentType()) {
344 paramTypes.push_back(paramType);
348 LH.findFunctionProto(declCtxDecl, FTDecl->getNameAsString(),
349 paramTypes, LH.NoDiagnostics,
350 templatedDecl->getType().isConstQualified());
357 assert(!
fSingleDecl &&
"This is not an iterator!");
371 ++(*fTemplateSpecIter);
394 cling::Interpreter::PushTransactionRAII RAII(
fInterp);
395 fIter = dc->decls_begin();
402 clang::FunctionTemplateDecl *templateDecl =
403 llvm::dyn_cast<clang::FunctionTemplateDecl>(*fIter);
405 if ( templateDecl ) {
409 cling::Interpreter::PushTransactionRAII RAII(
fInterp);
419 SpecIterator subiter(templateDecl);
428 if (llvm::isa<clang::FunctionDecl>(*fIter)) {
454 switch (fd->getAccess()) {
455 case clang::AS_public:
458 case clang::AS_protected:
461 case clang::AS_private:
465 if (fd->getDeclContext()->isNamespace())
472 if (fd->getStorageClass() == clang::SC_Static) {
475 clang::QualType qt = fd->getReturnType().getCanonicalType();
476 if (qt.isConstQualified()) {
480 if (qt->isArrayType()) {
481 qt = llvm::cast<clang::ArrayType>(qt)->getElementType();
484 else if (qt->isReferenceType()) {
486 qt = llvm::cast<clang::ReferenceType>(qt)->getPointeeType();
489 else if (qt->isPointerType()) {
491 if (qt.isConstQualified()) {
494 qt = llvm::cast<clang::PointerType>(qt)->getPointeeType();
497 else if (qt->isMemberPointerType()) {
498 qt = llvm::cast<clang::MemberPointerType>(qt)->getPointeeType();
503 if (qt.isConstQualified()) {
506 if (
const clang::CXXMethodDecl *md =
507 llvm::dyn_cast<clang::CXXMethodDecl>(fd)) {
508 if (md->getTypeQualifiers() & clang::Qualifiers::Const) {
511 if (md->isVirtual()) {
517 if (
const clang::CXXConstructorDecl *cd =
518 llvm::dyn_cast<clang::CXXConstructorDecl>(md)) {
519 if (cd->isExplicit()) {
523 else if (
const clang::CXXConversionDecl *cd =
524 llvm::dyn_cast<clang::CXXConversionDecl>(md)) {
525 if (cd->isExplicit()) {
542 if (fd->isOverloadedOperator()) {
545 else if (llvm::isa<clang::CXXConversionDecl>(fd)) {
547 }
else if (llvm::isa<clang::CXXConstructorDecl>(fd)) {
549 }
else if (llvm::isa<clang::CXXDestructorDecl>(fd)) {
559 ti.Init(clang::QualType());
564 const clang::TypeDecl* ctorClass = llvm::dyn_cast_or_null<clang::TypeDecl>
567 Error(
"TClingMethodInfo::Type",
"Cannot find DeclContext for constructor!");
569 clang::QualType qt(ctorClass->getTypeForDecl(), 0);
584 std::string mangled_name;
585 mangled_name.clear();
590 if (
const CXXConstructorDecl* Ctor = dyn_cast<CXXConstructorDecl>(D))
591 GD = GlobalDecl(Ctor, Ctor_Complete);
592 else if (
const CXXDestructorDecl* Dtor = dyn_cast<CXXDestructorDecl>(D))
593 GD = GlobalDecl(Dtor, Dtor_Deleting);
597 cling::utils::Analyze::maybeMangleDeclName(GD, mangled_name);
606 TTHREAD_TLS_DECL( std::string, buf );
610 if (
const clang::TypeDecl *td = llvm::dyn_cast<clang::TypeDecl>(
GetMethodDecl()->getDeclContext())) {
612 clang::QualType qualType(td->getTypeForDecl(),0);
616 }
else if (
const clang::NamedDecl *nd = llvm::dyn_cast<clang::NamedDecl>(
GetMethodDecl()->getDeclContext())) {
618 clang::PrintingPolicy policy(
GetMethodDecl()->getASTContext().getPrintingPolicy());
619 llvm::raw_string_ostream stream(name);
620 nd->getNameForDiagnostic(stream, policy,
true);
625 buf +=
Name(normCtxt);
634 if (arg.
Name() && strlen(arg.
Name())) {
645 if (
const clang::CXXMethodDecl *md =
647 if (md->getTypeQualifiers() & clang::Qualifiers::Const) {
659 TTHREAD_TLS_DECL( std::string, buf );
692 cling::Interpreter::PushTransactionRAII RAII(
fInterp);
693 if (
const FunctionDecl *AnnotFD
695 if (AnnotateAttr *
A = AnnotFD->getAttr<AnnotateAttr>()) {
696 fTitle =
A->getAnnotation().str();
700 if (!FD->isFromASTFile()) {
const TClingTypeInfo * Type() const
RooArgList L(const RooAbsArg &v1)
const clang::Decl * GetDecl() const
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 char * DefaultValue() const
clang::DeclContext::decl_iterator fIter
void * InterfaceMethod(const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) const
std::string GetMangledName() const
Emulation of the CINT CallFunc class.
void CreateSignature(TString &signature) const
const char * TypeName() const
void Info(const char *location, const char *msgfmt,...)
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
const clang::FunctionDecl * GetMethodDecl() const
const char * GetPrototype(const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) const
SpecIterator * fTemplateSpecIter
RooArgSet S(const RooAbsArg &v1)
TCut operator!(const TCut &rhs)
Logical negation.
void Init(const clang::FunctionDecl *)
TTime operator*(const TTime &t1, const TTime &t2)
TDictionary::DeclId_t GetDeclId() 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)
TClingTypeInfo * Type() const
R__EXTERN TInterpreter * gCling
const char * Name() const
cling::Interpreter * fInterp
static char * skip(char **buf, const char *delimiters)
const char * Name(const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) const