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();
180 fIter = clang::DeclContext::decl_iterator();
210 unsigned num_params = fd->getNumParams();
212 return static_cast<int>(num_params);
221 unsigned num_params = fd->getNumParams();
222 unsigned min_args = fd->getMinRequiredArguments();
223 unsigned defaulted_params = num_params - min_args;
225 return static_cast<int>(defaulted_params);
241static const clang::FunctionDecl *
244 const cling::LookupHelper& LH) {
246 using namespace clang;
248 auto templateParms = FTDecl->getTemplateParameters();
249 if (templateParms->containsUnexpandedParameterPack())
252 if (templateParms->getMinRequiredArguments() > 0)
255 if (templateParms->size() > 0) {
256 NamedDecl *arg0 = *templateParms->begin();
257 if (arg0->isTemplateParameterPack())
259 if (
auto TTP = dyn_cast<TemplateTypeParmDecl>(*templateParms->begin())) {
260 if (!TTP->hasDefaultArgument())
262 }
else if (
auto NTTP = dyn_cast<NonTypeTemplateParmDecl>(
263 *templateParms->begin())) {
264 if (!NTTP->hasDefaultArgument())
272 FunctionDecl *templatedDecl = FTDecl->getTemplatedDecl();
273 Decl *declCtxDecl = dyn_cast<Decl>(FTDecl->getDeclContext());
283 llvm::SmallVector<TemplateArgument, 8> defaultTemplateArgs(templateParms->size());
284 for (
int iParam = 0, nParams = templateParms->size(); iParam < nParams; ++iParam) {
285 const NamedDecl* templateParm = templateParms->getParam(iParam);
286 if (templateParm->isTemplateParameterPack()) {
288 assert(0 &&
"unexpected template parameter pack");
290 }
if (
auto TTP = dyn_cast<TemplateTypeParmDecl>(templateParm)) {
291 defaultTemplateArgs[iParam] = TemplateArgument(TTP->getDefaultArgument());
292 }
else if (
auto NTTP = dyn_cast<NonTypeTemplateParmDecl>(templateParm)) {
293 defaultTemplateArgs[iParam] = TemplateArgument(NTTP->getDefaultArgument());
294 }
else if (
auto TTP = dyn_cast<TemplateTemplateParmDecl>(templateParm)) {
295 defaultTemplateArgs[iParam] = TemplateArgument(TTP->getDefaultArgument().getArgument());
298 assert(0 &&
"unexpected template parameter kind");
304 llvm::SmallVector<QualType, 8> paramTypes;
307 SmallVector<DeducedTemplateArgument, 4> DeducedArgs;
308 sema::TemplateDeductionInfo
Info{SourceLocation()};
310 Sema::InstantiatingTemplate Inst(
S,
Info.getLocation(), FTDecl,
312 Sema::CodeSynthesisContext::DeducedTemplateArgumentSubstitution,
317 TemplateArgumentList templArgList(TemplateArgumentList::OnStack, defaultTemplateArgs);
318 MultiLevelTemplateArgumentList MLTAL{templArgList};
319 for (
const clang::ParmVarDecl *param: templatedDecl->parameters()) {
320 QualType paramType = param->getOriginalType();
324 if (paramType->isDependentType()) {
331 paramType =
S.SubstType(paramType, MLTAL, SourceLocation(),
332 templatedDecl->getDeclName());
334 if (paramType.isNull() || paramType->isDependentType()) {
340 paramTypes.push_back(paramType);
343 return LH.findFunctionProto(declCtxDecl, FTDecl->getNameAsString(),
344 paramTypes, LH.NoDiagnostics,
345 templatedDecl->getType().isConstQualified());
351 assert(!
fDecl &&
"This is not an iterator!");
382 cling::Interpreter::PushTransactionRAII RAII(
fInterp);
383 fIter = dc->decls_begin();
390 if (
const auto templateDecl = llvm::dyn_cast<clang::FunctionTemplateDecl>(*
fIter)) {
392 cling::Interpreter::PushTransactionRAII RAII(
fInterp);
404 if (llvm::isa<clang::FunctionDecl>(*
fIter)) {
430 switch (fd->getAccess()) {
431 case clang::AS_public:
434 case clang::AS_protected:
437 case clang::AS_private:
441 if (fd->getDeclContext()->isNamespace())
448 if (fd->getStorageClass() == clang::SC_Static) {
451 clang::QualType qt = fd->getReturnType().getCanonicalType();
452 if (qt.isConstQualified()) {
456 if (qt->isArrayType()) {
457 qt = llvm::cast<clang::ArrayType>(qt)->getElementType();
460 else if (qt->isReferenceType()) {
462 qt = llvm::cast<clang::ReferenceType>(qt)->getPointeeType();
465 else if (qt->isPointerType()) {
467 if (qt.isConstQualified()) {
470 qt = llvm::cast<clang::PointerType>(qt)->getPointeeType();
473 else if (qt->isMemberPointerType()) {
474 qt = llvm::cast<clang::MemberPointerType>(qt)->getPointeeType();
479 if (qt.isConstQualified()) {
482 if (
const clang::CXXMethodDecl *md =
483 llvm::dyn_cast<clang::CXXMethodDecl>(fd)) {
484 if (md->getTypeQualifiers() & clang::Qualifiers::Const) {
487 if (md->isVirtual()) {
493 if (
const clang::CXXConstructorDecl *cd =
494 llvm::dyn_cast<clang::CXXConstructorDecl>(md)) {
495 if (cd->isExplicit()) {
499 else if (
const clang::CXXConversionDecl *cd =
500 llvm::dyn_cast<clang::CXXConversionDecl>(md)) {
501 if (cd->isExplicit()) {
518 if (fd->isOverloadedOperator()) {
521 else if (llvm::isa<clang::CXXConversionDecl>(fd)) {
523 }
else if (llvm::isa<clang::CXXConstructorDecl>(fd)) {
525 }
else if (llvm::isa<clang::CXXDestructorDecl>(fd)) {
535 ti.Init(clang::QualType());
540 const clang::TypeDecl* ctorClass = llvm::dyn_cast_or_null<clang::TypeDecl>
543 Error(
"TClingMethodInfo::Type",
"Cannot find DeclContext for constructor!");
545 clang::QualType qt(ctorClass->getTypeForDecl(), 0);
560 std::string mangled_name;
561 mangled_name.clear();
565 cling::Interpreter::PushTransactionRAII RAII(
fInterp);
567 if (
const CXXConstructorDecl* Ctor = dyn_cast<CXXConstructorDecl>(D))
568 GD = GlobalDecl(Ctor, Ctor_Complete);
569 else if (
const CXXDestructorDecl* Dtor = dyn_cast<CXXDestructorDecl>(D))
570 GD = GlobalDecl(Dtor, Dtor_Deleting);
574 cling::utils::Analyze::maybeMangleDeclName(GD, mangled_name);
583 TTHREAD_TLS_DECL( std::string, buf );
587 if (
const clang::TypeDecl *td = llvm::dyn_cast<clang::TypeDecl>(
GetMethodDecl()->getDeclContext())) {
589 clang::QualType qualType(td->getTypeForDecl(),0);
590 ROOT::TMetaUtils::GetFullyQualifiedTypeName(
name,qualType,*
fInterp);
593 }
else if (
const clang::NamedDecl *nd = llvm::dyn_cast<clang::NamedDecl>(
GetMethodDecl()->getDeclContext())) {
595 clang::PrintingPolicy policy(
GetMethodDecl()->getASTContext().getPrintingPolicy());
596 llvm::raw_string_ostream stream(
name);
597 nd->getNameForDiagnostic(stream, policy,
true);
611 if (arg.
Name() && strlen(arg.
Name())) {
622 if (
const clang::CXXMethodDecl *md =
624 if (md->getTypeQualifiers() & clang::Qualifiers::Const) {
671 cling::Interpreter::PushTransactionRAII RAII(
fInterp);
672 if (
const FunctionDecl *AnnotFD
673 = ROOT::TMetaUtils::GetAnnotatedRedeclarable(FD)) {
674 if (AnnotateAttr *
A = AnnotFD->getAttr<AnnotateAttr>()) {
675 fTitle =
A->getAnnotation().str();
679 if (!FD->isFromASTFile()) {
683 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