35#include "cling/Interpreter/Interpreter.h"
36#include "cling/Interpreter/LookupHelper.h"
37#include "cling/Utils/AST.h"
39#include "clang/AST/ASTContext.h"
40#include "clang/AST/CXXInheritance.h"
41#include "clang/AST/Decl.h"
42#include "clang/AST/DeclBase.h"
43#include "clang/AST/DeclCXX.h"
44#include "clang/AST/DeclTemplate.h"
45#include "clang/AST/ExprCXX.h"
46#include "clang/AST/GlobalDecl.h"
47#include "clang/AST/Mangle.h"
48#include "clang/AST/PrettyPrinter.h"
49#include "clang/AST/Type.h"
50#include "clang/Basic/IdentifierTable.h"
51#include "clang/Sema/Lookup.h"
52#include "clang/Sema/Sema.h"
53#include "clang/Sema/Template.h"
54#include "clang/Sema/TemplateDeduction.h"
56#include "llvm/Support/Casting.h"
57#include "llvm/Support/raw_ostream.h"
65 llvm::SmallVectorImpl<clang::CXXMethodDecl *> &&specFuncs)
67 auto *CXXRD = llvm::dyn_cast<CXXRecordDecl>(DC);
72 cling::Interpreter::PushTransactionRAII RAII(interp);
74 auto emplaceSpecFunIfNeeded = [&](clang::CXXMethodDecl *D) {
78 if (std::find(CXXRD->decls_begin(), CXXRD->decls_end(), D) == CXXRD->decls_end()) {
83 for (
auto SpecFunc : specFuncs)
84 emplaceSpecFunIfNeeded(SpecFunc);
89 if (
const auto *FD = llvm::dyn_cast<clang::FunctionDecl>(D)) {
92 if (
const auto *RD = llvm::dyn_cast<clang::RecordDecl>(FD->getDeclContext())) {
93 if (
const auto *CXXMD = llvm::dyn_cast<clang::CXXMethodDecl>(FD)) {
94 if (RD->isAnonymousStructOrUnion() &&
95 GetInterpreter()->getSema().getSpecialMember(CXXMD) != clang::CXXSpecialMemberKind::Invalid) {
108 if (
auto *FD = llvm::dyn_cast<clang::FunctionDecl>(USD->getTargetDecl())) {
109 if (
const auto *CXXMD = llvm::dyn_cast<clang::CXXMethodDecl>(FD)) {
110 auto SpecMemKind =
GetInterpreter()->getSema().getSpecialMember(CXXMD);
111 if ((SpecMemKind == clang::CXXSpecialMemberKind::DefaultConstructor && CXXMD->getNumParams() == 0) ||
112 ((SpecMemKind == clang::CXXSpecialMemberKind::CopyConstructor || SpecMemKind == clang::CXXSpecialMemberKind::MoveConstructor) &&
113 CXXMD->getNumParams() == 1)) {
134 using namespace clang;
137 Sema &S = interp->getSema();
138 const cling::LookupHelper &LH = interp->getLookupHelper();
140 if (!isa<FunctionTemplateDecl>(TD))
143 auto templateParms = TD->getTemplateParameters();
144 if (templateParms->containsUnexpandedParameterPack())
147 if (templateParms->getMinRequiredArguments() > 0)
150 const FunctionDecl *templatedDecl = llvm::dyn_cast<FunctionDecl>(TD->getTemplatedDecl());
151 const Decl *declCtxDecl = dyn_cast<Decl>(TD->getDeclContext());
161 llvm::SmallVector<TemplateArgument, 8> defaultTemplateArgs;
162 for (
const NamedDecl *templateParm: *templateParms) {
163 if (templateParm->isTemplateParameterPack()) {
172 }
else if (
auto TTP = dyn_cast<TemplateTypeParmDecl>(templateParm)) {
173 if (!TTP->hasDefaultArgument())
175 defaultTemplateArgs.emplace_back(TTP->getDefaultArgument().getArgument());
176 }
else if (
auto NTTP = dyn_cast<NonTypeTemplateParmDecl>(templateParm)) {
177 if (!NTTP->hasDefaultArgument())
179 defaultTemplateArgs.emplace_back(NTTP->getDefaultArgument().getArgument());
180 }
else if (
auto TTP = dyn_cast<TemplateTemplateParmDecl>(templateParm)) {
181 if (!TTP->hasDefaultArgument())
183 defaultTemplateArgs.emplace_back(TTP->getDefaultArgument().getArgument());
186 assert(0 &&
"unexpected template parameter kind");
191 cling::Interpreter::PushTransactionRAII RAII(interp);
194 llvm::SmallVector<QualType, 8> paramTypes;
197 SmallVector<DeducedTemplateArgument, 4> DeducedArgs;
198 sema::TemplateDeductionInfo
Info{SourceLocation()};
200 auto *FTD =
const_cast<clang::FunctionTemplateDecl *
>(llvm::dyn_cast<clang::FunctionTemplateDecl>(TD));
201 Sema::InstantiatingTemplate Inst(
202 S,
Info.getLocation(), FTD,
203 defaultTemplateArgs, Sema::CodeSynthesisContext::DeducedTemplateArgumentSubstitution, SourceRange());
207 MultiLevelTemplateArgumentList MLTAL{FTD, defaultTemplateArgs,
false};
210 Sema::SFINAETrap Trap(S,
true);
211 for (
const clang::ParmVarDecl *param : templatedDecl->parameters()) {
212 QualType paramType = param->getOriginalType();
216 if (paramType->isDependentType()) {
223 paramType = S.SubstType(paramType, MLTAL, templatedDecl->getLocation(), templatedDecl->getDeclName());
225 if (paramType.isNull() || paramType->isDependentType()) {
231 paramTypes.push_back(paramType);
234 return LH.findFunctionProto(declCtxDecl, TD->getNameAsString(), paramTypes, LH.NoDiagnostics,
235 templatedDecl->getType().isConstQualified());
248 clang::Decl *D =
const_cast<clang::Decl *
>(ci->
GetDecl());
249 auto *DC = llvm::dyn_cast<clang::DeclContext>(D);
251 llvm::SmallVector<clang::CXXMethodDecl*, 8> SpecFuncs;
253 if (
auto *CXXRD = llvm::dyn_cast<CXXRecordDecl>(DC)) {
258 cling::Interpreter::PushTransactionRAII RAII(interp);
260 auto &SemaRef = interp->getSema();
261 SemaRef.ForceDeclarationOfImplicitMembers(CXXRD);
265 for (clang::NamedDecl *ctor : SemaRef.LookupConstructors(CXXRD)) {
267 if (
auto *CXXCD = llvm::dyn_cast<clang::CXXConstructorDecl>(ctor))
268 SpecFuncs.emplace_back(CXXCD);
270 SpecFuncs.emplace_back(SemaRef.LookupCopyingAssignment(CXXRD, 0,
false, 0 ));
271 SpecFuncs.emplace_back(SemaRef.LookupMovingAssignment(CXXRD, 0,
false, 0 ));
272 SpecFuncs.emplace_back(SemaRef.LookupDestructor(CXXRD));
280 const clang::Decl *D)
281 :
TClingDeclInfo(D), fInterp(interp), fFirstTime(true), fTitle(
"")
284 Error(
"TClingMethodInfo",
"nullptr FunctionDecl passed!");
295 return (
const clang::Decl*)(FD->getCanonicalDecl());
301 return dyn_cast<FunctionDecl>(
GetDecl());
306 return dyn_cast<UsingShadowDecl>(
GetDecl());
315 if (
auto FD = dyn_cast<FunctionDecl>(D))
317 }
while ((D = dyn_cast<UsingShadowDecl>(D)->getTargetDecl()));
338 if (arg.
Name() && strlen(arg.
Name())) {
340 signature += arg.
Name();
349 if (decl && decl->isVariadic())
386 unsigned num_params = fd->getNumParams();
388 return static_cast<int>(num_params);
398 unsigned num_params = fd->getNumParams();
399 unsigned min_args = fd->getMinRequiredArguments();
400 unsigned defaulted_params = num_params - min_args;
402 return static_cast<int>(defaulted_params);
421 assert(!
fDecl &&
"This is not an iterator!");
450 const Decl *declAccess =
GetDecl();
451 if (llvm::isa<UsingShadowDecl>(declAccess))
456 clang::AccessSpecifier Access = clang::AS_public;
457 if (!declAccess->getDeclContext()->isNamespace())
458 Access = declAccess->getAccess();
463 Access = clang::AS_public;
464 clang::CXXRecordDecl *typeCXXRD = llvm::cast<RecordType>(
Type()->GetQualType())->getAsCXXRecordDecl();
465 clang::CXXBasePaths basePaths;
466 if (typeCXXRD->isDerivedFrom(llvm::dyn_cast<CXXRecordDecl>(fd->getDeclContext()), basePaths)) {
470 for (
auto el: basePaths) {
471 if (el.Access > Access)
475 Error(
"Property()",
"UsingDecl of ctor not shadowing a base ctor!");
479 if (fd->getAccess() > Access)
480 Access = fd->getAccess();
483 case clang::AS_public:
486 case clang::AS_protected:
489 case clang::AS_private:
493 if (declAccess->getDeclContext()->isNamespace())
498 assert(
false &&
"Unexpected value for the access property value in Clang");
507 if (fd->isConstexpr())
509 if (fd->getStorageClass() == clang::SC_Static) {
512 clang::QualType qt = fd->getReturnType().getCanonicalType();
516 if (
const clang::CXXMethodDecl *md =
517 llvm::dyn_cast<clang::CXXMethodDecl>(fd)) {
518 if (md->getMethodQualifiers().hasConst()) {
521 if (md->isVirtual()) {
524 if (md->isPureVirtual()) {
527 if (
const clang::CXXConstructorDecl *cd =
528 llvm::dyn_cast<clang::CXXConstructorDecl>(md)) {
529 if (cd->isExplicit()) {
533 else if (
const clang::CXXConversionDecl *cd =
534 llvm::dyn_cast<clang::CXXConversionDecl>(md)) {
535 if (cd->isExplicit()) {
553 if (fd->isOverloadedOperator())
555 if (llvm::isa<clang::CXXConversionDecl>(fd))
557 if (llvm::isa<clang::CXXConstructorDecl>(fd))
559 if (llvm::isa<clang::CXXDestructorDecl>(fd))
563 if (fd->getTemplatedKind() != clang::FunctionDecl::TK_NonTemplate)
572 ti.Init(clang::QualType());
581 const clang::TypeDecl* ctorClass = llvm::dyn_cast_or_null<clang::TypeDecl>
584 Error(
"TClingMethodInfo::Type",
"Cannot find DeclContext for constructor!");
586 clang::QualType qt = ctorClass->getASTContext().getTypeDeclType(ctorClass);
601 std::string mangled_name;
602 mangled_name.clear();
607 cling::Interpreter::PushTransactionRAII RAII(
fInterp);
609 if (
const CXXConstructorDecl* Ctor = dyn_cast<CXXConstructorDecl>(D))
610 GD = GlobalDecl(Ctor, Ctor_Complete);
611 else if (
const CXXDestructorDecl* Dtor = dyn_cast<CXXDestructorDecl>(D))
612 GD = GlobalDecl(Dtor, Dtor_Deleting);
616 cling::utils::Analyze::maybeMangleDeclName(GD, mangled_name);
625 TTHREAD_TLS_DECL( std::string, buf );
636 if (
const clang::TypeDecl *td = llvm::dyn_cast<clang::TypeDecl>(
GetDecl()->getDeclContext())) {
638 clang::QualType qualType = td->getASTContext().getTypeDeclType(td);
642 }
else if (
const clang::NamedDecl *nd = llvm::dyn_cast<clang::NamedDecl>(FD->getDeclContext())) {
644 clang::PrintingPolicy policy(FD->getASTContext().getPrintingPolicy());
645 llvm::raw_string_ostream stream(
name);
646 nd->getNameForDiagnostic(stream, policy,
true);
657 if (
const clang::CXXMethodDecl *md =
658 llvm::dyn_cast<clang::CXXMethodDecl>(FD)) {
659 if (md->getMethodQualifiers().hasConst()) {
716 cling::Interpreter::PushTransactionRAII RAII(
fInterp);
717 if (
const FunctionDecl *AnnotFD
719 if (AnnotateAttr *A = AnnotFD->getAttr<AnnotateAttr>()) {
720 fTitle = A->getAnnotation().str();
724 if (!FD->isFromASTFile()) {
void Info(const char *location, const char *msgfmt,...)
Use this function for informational messages.
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 Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t property
R__EXTERN TVirtualMutex * gInterpreterMutex
R__EXTERN TInterpreter * gCling
#define R__LOCKGUARD(mutex)
Iterate over FunctionDecl and UsingShadowDecls of FunctionDecl, within a scope, recursing through "tr...
bool IsValid() const final
const clang::Decl * InstantiateTemplateWithDefaults(const clang::RedeclarableTemplateDecl *TD) const final
bool ShouldSkip(const clang::Decl *FD) const final
Emulation of the CINT CallFunc class.
void SetFunc(const TClingClassInfo *info, const char *method, const char *arglist, Longptr_t *poffset)
Emulation of the CINT ClassInfo class.
const clang::Decl * fDecl
virtual const char * Name() const
virtual bool IsValid() const
long Property(long property, clang::QualType &qt) const
virtual const clang::Decl * GetDecl() const
bool Next()
Advance to next non-skipped; return false if no next decl exists.
cling::Interpreter * fInterp
cling::Interpreter * GetInterpreter() const
Emulation of the CINT MethodInfo class.
const char * DefaultValue() const
const TClingTypeInfo * Type() const
std::string GetMangledName() const
const char * TypeName() const
const clang::FunctionDecl * GetAsFunctionDecl() const
const char * Name() const override
const clang::UsingShadowDecl * GetAsUsingShadowDecl() const
const clang::FunctionDecl * GetTargetFunctionDecl() const
Get the FunctionDecl, or if this represents a UsingShadowDecl, the underlying target FunctionDecl.
const clang::Decl * GetDecl() const override
TClingCXXRecMethIter fIter
const char * GetPrototype()
void Init(const clang::FunctionDecl *)
long ExtraProperty() const
const clang::Decl * GetDeclSlow() const
void * InterfaceMethod() const
TClingMethodInfo(cling::Interpreter *interp)
void CreateSignature(TString &signature) const
TDictionary::DeclId_t GetDeclId() const
cling::Interpreter * fInterp
TClingTypeInfo * Type() const
Emulation of the CINT TypeInfo class.
const char * Name() const override
This class defines an interface to the cling C++ interpreter.