30#include "TClingUtils.h"
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"
63 fContexts(rhs.fContexts),
64 fFirstTime(rhs.fFirstTime),
65 fContextIdx(rhs.fContextIdx),
68 fTemplateSpec(rhs.fTemplateSpec)
92 :
TClingDeclInfo(nullptr), fInterp(interp), fFirstTime(true), fContextIdx(0U), fTitle(
""),
100 clang::CXXRecordDecl *cxxdecl = llvm::dyn_cast<clang::CXXRecordDecl>(
const_cast<clang::Decl*
>(ci->
GetDecl()));
105 cling::Interpreter::PushTransactionRAII RAII(interp);
107 fInterp->getSema().ForceDeclarationOfImplicitMembers(cxxdecl);
109 clang::DeclContext *dc =
110 llvm::cast<clang::DeclContext>(
const_cast<clang::Decl*
>(ci->
GetDecl()));
113 cling::Interpreter::PushTransactionRAII RAII(interp);
114 fIter = dc->decls_begin();
120 const clang::FunctionDecl *FD)
121 :
TClingDeclInfo(FD), fInterp(interp), fFirstTime(true), fContextIdx(0U), fTitle(
""),
137 return (
const clang::Decl*)(
GetMethodDecl()->getCanonicalDecl());
142 return cast_or_null<FunctionDecl>(
GetDecl());
162 if (arg.
Name() && strlen(arg.
Name())) {
164 signature += arg.
Name();
173 if (decl && decl->isVariadic())
184 fIter = clang::DeclContext::decl_iterator();
214 unsigned num_params = fd->getNumParams();
216 return static_cast<int>(num_params);
225 unsigned num_params = fd->getNumParams();
226 unsigned min_args = fd->getMinRequiredArguments();
227 unsigned defaulted_params = num_params - min_args;
229 return static_cast<int>(defaulted_params);
245static const clang::FunctionDecl *
248 const cling::LookupHelper& LH) {
250 using namespace clang;
252 auto templateParms = FTDecl->getTemplateParameters();
253 if (templateParms->containsUnexpandedParameterPack())
256 if (templateParms->getMinRequiredArguments() > 0)
259 if (templateParms->size() > 0) {
260 NamedDecl *arg0 = *templateParms->begin();
261 if (arg0->isTemplateParameterPack())
263 if (
auto TTP = dyn_cast<TemplateTypeParmDecl>(*templateParms->begin())) {
264 if (!TTP->hasDefaultArgument())
266 }
else if (
auto NTTP = dyn_cast<NonTypeTemplateParmDecl>(
267 *templateParms->begin())) {
268 if (!NTTP->hasDefaultArgument())
276 FunctionDecl *templatedDecl = FTDecl->getTemplatedDecl();
277 Decl *declCtxDecl = dyn_cast<Decl>(FTDecl->getDeclContext());
287 llvm::SmallVector<TemplateArgument, 8> defaultTemplateArgs(templateParms->size());
288 for (
int iParam = 0, nParams = templateParms->size(); iParam < nParams; ++iParam) {
289 const NamedDecl* templateParm = templateParms->getParam(iParam);
290 if (templateParm->isTemplateParameterPack()) {
292 assert(0 &&
"unexpected template parameter pack");
294 }
if (
auto TTP = dyn_cast<TemplateTypeParmDecl>(templateParm)) {
295 if (!TTP->hasDefaultArgument())
297 defaultTemplateArgs[iParam] = TemplateArgument(TTP->getDefaultArgument());
298 }
else if (
auto NTTP = dyn_cast<NonTypeTemplateParmDecl>(templateParm)) {
299 if (!NTTP->hasDefaultArgument())
301 defaultTemplateArgs[iParam] = TemplateArgument(NTTP->getDefaultArgument());
302 }
else if (
auto TTP = dyn_cast<TemplateTemplateParmDecl>(templateParm)) {
303 if (!TTP->hasDefaultArgument())
305 defaultTemplateArgs[iParam] = TemplateArgument(TTP->getDefaultArgument().getArgument());
308 assert(0 &&
"unexpected template parameter kind");
314 llvm::SmallVector<QualType, 8> paramTypes;
317 SmallVector<DeducedTemplateArgument, 4> DeducedArgs;
318 sema::TemplateDeductionInfo
Info{SourceLocation()};
320 Sema::InstantiatingTemplate Inst(
S,
Info.getLocation(), FTDecl,
322 Sema::CodeSynthesisContext::DeducedTemplateArgumentSubstitution,
327 TemplateArgumentList templArgList(TemplateArgumentList::OnStack, defaultTemplateArgs);
328 MultiLevelTemplateArgumentList MLTAL{templArgList};
329 for (
const clang::ParmVarDecl *param: templatedDecl->parameters()) {
330 QualType paramType = param->getOriginalType();
334 if (paramType->isDependentType()) {
341 paramType =
S.SubstType(paramType, MLTAL, SourceLocation(),
342 templatedDecl->getDeclName());
344 if (paramType.isNull() || paramType->isDependentType()) {
350 paramTypes.push_back(paramType);
353 return LH.findFunctionProto(declCtxDecl, FTDecl->getNameAsString(),
354 paramTypes, LH.NoDiagnostics,
355 templatedDecl->getType().isConstQualified());
361 assert(!
fDecl &&
"This is not an iterator!");
392 cling::Interpreter::PushTransactionRAII RAII(
fInterp);
393 fIter = dc->decls_begin();
400 if (
const auto templateDecl = llvm::dyn_cast<clang::FunctionTemplateDecl>(*
fIter)) {
402 cling::Interpreter::PushTransactionRAII RAII(
fInterp);
416 if (
auto *FD = llvm::dyn_cast<clang::FunctionDecl>(*
fIter)) {
417 if (!FD->isDeleted())
423 if (
auto NS = dyn_cast<NamespaceDecl>(*
fIter)) {
424 if (NS->getDeclContext()->isTranslationUnit() && NS->isInlineNamespace())
449 if (fd->isConstexpr())
451 switch (fd->getAccess()) {
452 case clang::AS_public:
455 case clang::AS_protected:
458 case clang::AS_private:
462 if (fd->getDeclContext()->isNamespace())
469 if (fd->getStorageClass() == clang::SC_Static) {
472 clang::QualType qt = fd->getReturnType().getCanonicalType();
473 if (qt.isConstQualified()) {
477 if (qt->isArrayType()) {
478 qt = llvm::cast<clang::ArrayType>(qt)->getElementType();
481 else if (qt->isReferenceType()) {
483 qt = llvm::cast<clang::ReferenceType>(qt)->getPointeeType();
486 else if (qt->isPointerType()) {
488 if (qt.isConstQualified()) {
491 qt = llvm::cast<clang::PointerType>(qt)->getPointeeType();
494 else if (qt->isMemberPointerType()) {
495 qt = llvm::cast<clang::MemberPointerType>(qt)->getPointeeType();
500 if (qt.isConstQualified()) {
503 if (
const clang::CXXMethodDecl *md =
504 llvm::dyn_cast<clang::CXXMethodDecl>(fd)) {
505 if (md->getTypeQualifiers() & clang::Qualifiers::Const) {
508 if (md->isVirtual()) {
514 if (
const clang::CXXConstructorDecl *cd =
515 llvm::dyn_cast<clang::CXXConstructorDecl>(md)) {
516 if (cd->isExplicit()) {
520 else if (
const clang::CXXConversionDecl *cd =
521 llvm::dyn_cast<clang::CXXConversionDecl>(md)) {
522 if (cd->isExplicit()) {
539 if (fd->isOverloadedOperator())
541 if (llvm::isa<clang::CXXConversionDecl>(fd))
543 if (llvm::isa<clang::CXXConstructorDecl>(fd))
545 if (llvm::isa<clang::CXXDestructorDecl>(fd))
556 ti.Init(clang::QualType());
561 const clang::TypeDecl* ctorClass = llvm::dyn_cast_or_null<clang::TypeDecl>
564 Error(
"TClingMethodInfo::Type",
"Cannot find DeclContext for constructor!");
566 clang::QualType qt(ctorClass->getTypeForDecl(), 0);
581 std::string mangled_name;
582 mangled_name.clear();
586 cling::Interpreter::PushTransactionRAII RAII(
fInterp);
588 if (
const CXXConstructorDecl* Ctor = dyn_cast<CXXConstructorDecl>(D))
589 GD = GlobalDecl(Ctor, Ctor_Complete);
590 else if (
const CXXDestructorDecl* Dtor = dyn_cast<CXXDestructorDecl>(D))
591 GD = GlobalDecl(Dtor, Dtor_Deleting);
595 cling::utils::Analyze::maybeMangleDeclName(GD, mangled_name);
604 TTHREAD_TLS_DECL( std::string, buf );
608 if (
const clang::TypeDecl *td = llvm::dyn_cast<clang::TypeDecl>(
GetMethodDecl()->getDeclContext())) {
610 clang::QualType qualType(td->getTypeForDecl(),0);
611 ROOT::TMetaUtils::GetFullyQualifiedTypeName(
name,qualType,*
fInterp);
614 }
else if (
const clang::NamedDecl *nd = llvm::dyn_cast<clang::NamedDecl>(
GetMethodDecl()->getDeclContext())) {
616 clang::PrintingPolicy policy(
GetMethodDecl()->getASTContext().getPrintingPolicy());
617 llvm::raw_string_ostream stream(
name);
618 nd->getNameForDiagnostic(stream, policy,
true);
629 if (
const clang::CXXMethodDecl *md =
631 if (md->getTypeQualifiers() & clang::Qualifiers::Const) {
678 cling::Interpreter::PushTransactionRAII RAII(
fInterp);
679 if (
const FunctionDecl *AnnotFD
680 = ROOT::TMetaUtils::GetAnnotatedRedeclarable(FD)) {
681 if (AnnotateAttr *
A = AnnotFD->getAttr<AnnotateAttr>()) {
682 fTitle =
A->getAnnotation().str();
686 if (!FD->isFromASTFile()) {
690 fTitle = ROOT::TMetaUtils::GetComment(*FD).str();
static const clang::FunctionDecl * GetOrInstantiateFuncTemplateWithDefaults(clang::FunctionTemplateDecl *FTDecl, clang::Sema &S, const cling::LookupHelper &LH)
void Info(const char *location, const char *msgfmt,...)
void Error(const char *location, const char *msgfmt,...)
R__EXTERN TVirtualMutex * gInterpreterMutex
R__EXTERN TInterpreter * gCling
Binding & operator=(OUT(*fun)(void))
#define R__LOCKGUARD(mutex)
Emulation of the CINT CallFunc class.
void SetFunc(const TClingClassInfo *info, const char *method, const char *arglist, long *poffset)
Emulation of the CINT ClassInfo class.
const clang::Decl * fDecl
virtual const char * Name()
virtual bool IsValid() const
virtual const clang::Decl * GetDecl() const
Emulation of the CINT MethodInfo class.
const char * DefaultValue() const
const TClingTypeInfo * Type() const
Emulation of the CINT MethodInfo class.
const char * Name() override
clang::DeclContext::decl_iterator fIter
TClingMethodInfo & operator=(const TClingMethodInfo &in)
std::string GetMangledName() const
const char * TypeName() const
void * InterfaceMethod(const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) const
const clang::Decl * GetDecl() const override
const char * GetPrototype()
void Init(const clang::FunctionDecl *)
const clang::FunctionDecl * GetMethodDecl() const
long ExtraProperty() const
const clang::Decl * GetDeclSlow() const
llvm::SmallVector< clang::DeclContext *, 2 > fContexts
TClingMethodInfo(cling::Interpreter *interp)
void CreateSignature(TString &signature) const
TDictionary::DeclId_t GetDeclId() const
cling::Interpreter * fInterp
TClingTypeInfo * Type() const
const clang::FunctionDecl * fTemplateSpec
Emulation of the CINT TypeInfo class.
const char * Name() const
This class defines an interface to the cling C++ interpreter.
RooArgSet S(const RooAbsArg &v1)
static constexpr double L