34 #include "cling/Interpreter/Interpreter.h"
35 #include "cling/Utils/AST.h"
37 #include "clang/AST/ASTContext.h"
38 #include "clang/AST/Decl.h"
39 #include "clang/AST/DeclCXX.h"
40 #include "clang/AST/DeclTemplate.h"
41 #include "clang/AST/GlobalDecl.h"
42 #include "clang/AST/Mangle.h"
43 #include "clang/AST/PrettyPrinter.h"
44 #include "clang/AST/Type.h"
45 #include "clang/Basic/IdentifierTable.h"
46 #include "clang/Sema/Sema.h"
48 #include "llvm/Support/Casting.h"
49 #include "llvm/Support/raw_ostream.h"
53 using namespace clang;
55 class TClingMethodInfo::SpecIterator
58 typedef clang::FunctionTemplateDecl::spec_iterator Iterator;
60 SpecIterator(Iterator begin, Iterator end) : fIter(begin), fEnd(end) {}
61 explicit SpecIterator(clang::FunctionTemplateDecl *decl) : fIter(decl->spec_begin()), fEnd(decl->spec_end()) {}
63 FunctionDecl *
operator* ()
const {
return *fIter; }
64 FunctionDecl *operator-> ()
const {
return *fIter; }
65 SpecIterator & operator++ () { ++fIter;
return *
this; }
66 SpecIterator operator++ (
int) {
67 SpecIterator tmp(fIter,fEnd);
71 bool operator!() {
return fIter == fEnd; }
72 operator bool() {
return fIter != fEnd; }
82 fContexts(rhs.fContexts),
83 fFirstTime(rhs.fFirstTime),
84 fContextIdx(rhs.fContextIdx),
88 fSingleDecl(rhs.fSingleDecl)
100 : fInterp(interp), fFirstTime(true), fContextIdx(0U), fTitle(
""),
101 fTemplateSpecIter(0), fSingleDecl(0)
108 clang::CXXRecordDecl *cxxdecl = llvm::dyn_cast<clang::CXXRecordDecl>(
const_cast<clang::Decl*
>(ci->
GetDecl()));
113 cling::Interpreter::PushTransactionRAII RAII(interp);
115 fInterp->getSema().ForceDeclarationOfImplicitMembers(cxxdecl);
117 clang::DeclContext *dc =
118 llvm::cast<clang::DeclContext>(
const_cast<clang::Decl*
>(ci->
GetDecl()));
121 cling::Interpreter::PushTransactionRAII RAII(interp);
122 fIter = dc->decls_begin();
128 const clang::FunctionDecl *FD)
129 : fInterp(interp), fFirstTime(true), fContextIdx(0U), fTitle(
""),
130 fTemplateSpecIter(0), fSingleDecl(FD)
145 return (
const clang::Decl*)(
GetMethodDecl()->getCanonicalDecl());
158 return *(*fTemplateSpecIter);
160 return llvm::dyn_cast<clang::FunctionDecl>(*fIter);
180 if (arg.
Name() && strlen(arg.
Name())) {
182 signature += arg.
Name();
198 fIter = clang::DeclContext::decl_iterator();
221 cling::Interpreter::PushTransactionRAII RAII(
fInterp);
222 return *(*fTemplateSpecIter);
233 unsigned num_params = fd->getNumParams();
235 return static_cast<int>(num_params);
244 unsigned num_params = fd->getNumParams();
245 unsigned min_args = fd->getMinRequiredArguments();
246 unsigned defaulted_params = num_params - min_args;
248 return static_cast<int>(defaulted_params);
268 ++(*fTemplateSpecIter);
291 cling::Interpreter::PushTransactionRAII RAII(
fInterp);
292 fIter = dc->decls_begin();
299 clang::FunctionTemplateDecl *templateDecl =
300 llvm::dyn_cast<clang::FunctionTemplateDecl>(*fIter);
301 if ( templateDecl ) {
304 cling::Interpreter::PushTransactionRAII RAII(
fInterp);
305 SpecIterator subiter(templateDecl);
314 if (llvm::isa<clang::FunctionDecl>(*fIter)) {
340 switch (fd->getAccess()) {
341 case clang::AS_public:
344 case clang::AS_protected:
347 case clang::AS_private:
351 if (fd->getDeclContext()->isNamespace())
358 if (fd->getStorageClass() == clang::SC_Static) {
361 clang::QualType qt = fd->getReturnType().getCanonicalType();
362 if (qt.isConstQualified()) {
366 if (qt->isArrayType()) {
367 qt = llvm::cast<clang::ArrayType>(qt)->getElementType();
370 else if (qt->isReferenceType()) {
372 qt = llvm::cast<clang::ReferenceType>(qt)->getPointeeType();
375 else if (qt->isPointerType()) {
377 if (qt.isConstQualified()) {
380 qt = llvm::cast<clang::PointerType>(qt)->getPointeeType();
383 else if (qt->isMemberPointerType()) {
384 qt = llvm::cast<clang::MemberPointerType>(qt)->getPointeeType();
389 if (qt.isConstQualified()) {
392 if (
const clang::CXXMethodDecl *md =
393 llvm::dyn_cast<clang::CXXMethodDecl>(fd)) {
394 if (md->getTypeQualifiers() & clang::Qualifiers::Const) {
397 if (md->isVirtual()) {
403 if (
const clang::CXXConstructorDecl *
cd =
404 llvm::dyn_cast<clang::CXXConstructorDecl>(md)) {
405 if (
cd->isExplicit()) {
409 else if (
const clang::CXXConversionDecl *
cd =
410 llvm::dyn_cast<clang::CXXConversionDecl>(md)) {
411 if (
cd->isExplicit()) {
428 if (fd->isOverloadedOperator()) {
431 else if (llvm::isa<clang::CXXConversionDecl>(fd)) {
433 }
else if (llvm::isa<clang::CXXConstructorDecl>(fd)) {
435 }
else if (llvm::isa<clang::CXXDestructorDecl>(fd)) {
445 ti.Init(clang::QualType());
450 const clang::TypeDecl* ctorClass = llvm::dyn_cast_or_null<clang::TypeDecl>
453 Error(
"TClingMethodInfo::Type",
"Cannot find DeclContext for constructor!");
455 clang::QualType qt(ctorClass->getTypeForDecl(), 0);
470 std::string mangled_name;
471 mangled_name.clear();
476 if (
const CXXConstructorDecl* Ctor = dyn_cast<CXXConstructorDecl>(D))
477 GD = GlobalDecl(Ctor, Ctor_Complete);
478 else if (
const CXXDestructorDecl* Dtor = dyn_cast<CXXDestructorDecl>(D))
479 GD = GlobalDecl(Dtor, Dtor_Deleting);
483 cling::utils::Analyze::maybeMangleDeclName(GD, mangled_name);
492 TTHREAD_TLS_DECL( std::string, buf );
496 if (
const clang::TypeDecl *td = llvm::dyn_cast<clang::TypeDecl>(
GetMethodDecl()->getDeclContext())) {
498 clang::QualType qualType(td->getTypeForDecl(),0);
502 }
else if (
const clang::NamedDecl *nd = llvm::dyn_cast<clang::NamedDecl>(
GetMethodDecl()->getDeclContext())) {
504 clang::PrintingPolicy policy(
GetMethodDecl()->getASTContext().getPrintingPolicy());
505 llvm::raw_string_ostream stream(name);
506 nd->getNameForDiagnostic(stream, policy,
true);
511 buf +=
Name(normCtxt);
520 if (arg.
Name() && strlen(arg.
Name())) {
531 if (
const clang::CXXMethodDecl *md =
533 if (md->getTypeQualifiers() & clang::Qualifiers::Const) {
545 TTHREAD_TLS_DECL( std::string, buf );
578 cling::Interpreter::PushTransactionRAII RAII(
fInterp);
579 if (
const FunctionDecl *AnnotFD
581 if (AnnotateAttr *
A = AnnotFD->getAttr<AnnotateAttr>()) {
582 fTitle =
A->getAnnotation().str();
586 if (!FD->isFromASTFile()) {
const char * GetPrototype(const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) const
RooArgList L(const RooAbsArg &v1)
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
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
const char * cd(char *path=0)