29 #include "cling/Interpreter/Interpreter.h"
30 #include "clang/AST/ASTContext.h"
31 #include "clang/AST/Decl.h"
32 #include "clang/AST/Expr.h"
33 #include "clang/AST/ExprCXX.h"
34 #include "clang/AST/PrettyPrinter.h"
35 #include "clang/AST/Type.h"
36 #include "clang/Sema/Sema.h"
38 #include "llvm/Support/Casting.h"
39 #include "llvm/Support/raw_ostream.h"
43 TClingMethodArgInfo::TClingMethodArgInfo(cling::Interpreter *interp,
const TClingMethodInfo* mi) : TClingDeclInfo(mi->GetMethodDecl()), fInterp(interp), fIdx(-1) {}
45 bool TClingMethodArgInfo::IsValid()
const
53 auto FD = llvm::cast_or_null<clang::FunctionDecl>(TClingDeclInfo::GetDecl());
54 int numParams =
static_cast<int>(FD->getNumParams());
55 return (fIdx > -1) && (fIdx < numParams);
58 int TClingMethodArgInfo::Next()
65 long TClingMethodArgInfo::Property()
const
71 const clang::ParmVarDecl *pvd = GetDecl();
72 if (pvd->hasDefaultArg() || pvd->hasInheritedDefaultArg()) {
73 property |= kIsDefault;
75 clang::QualType qt = pvd->getOriginalType().getCanonicalType();
76 if (qt.isConstQualified()) {
77 property |= kIsConstant;
80 if (qt->isArrayType()) {
81 qt = llvm::cast<clang::ArrayType>(qt)->getElementType();
84 else if (qt->isReferenceType()) {
85 property |= kIsReference;
86 qt = llvm::cast<clang::ReferenceType>(qt)->getPointeeType();
89 else if (qt->isPointerType()) {
90 property |= kIsPointer;
91 if (qt.isConstQualified()) {
92 property |= kIsConstPointer;
94 qt = llvm::cast<clang::PointerType>(qt)->getPointeeType();
97 else if (qt->isMemberPointerType()) {
98 qt = llvm::cast<clang::MemberPointerType>(qt)->getPointeeType();
103 if (qt.isConstQualified()) {
104 property |= kIsConstant;
109 const char *TClingMethodArgInfo::DefaultValue()
const
114 const clang::ParmVarDecl *pvd = GetDecl();
116 if (pvd->hasUninstantiatedDefaultArg()) {
118 cling::Interpreter::PushTransactionRAII RAII(fInterp);
119 auto fd = llvm::cast_or_null<clang::FunctionDecl>(TClingDeclInfo::GetDecl());
120 fInterp->getSema().BuildCXXDefaultArgExpr(clang::SourceLocation(),
121 const_cast<clang::FunctionDecl*>(fd),
122 const_cast<clang::ParmVarDecl*>(pvd));
124 const clang::Expr *expr = 0;
125 if (pvd->hasUninstantiatedDefaultArg()) {
127 expr = pvd->getUninstantiatedDefaultArg();
129 expr = pvd->getDefaultArg();
131 clang::ASTContext &context = pvd->getASTContext();
132 clang::PrintingPolicy policy(context.getPrintingPolicy());
133 TTHREAD_TLS_DECL( std::string, buf );
135 llvm::raw_string_ostream out(buf);
140 bool implicitInit =
false;
141 if (
const clang::CXXConstructExpr *construct =
142 llvm::dyn_cast<clang::CXXConstructExpr>(expr)) {
143 implicitInit = (pvd->getInitStyle() == clang::VarDecl::CallInit) &&
144 (construct->getNumArgs() == 0) &&
145 !construct->isListInitialization();
148 if (pvd->getInitStyle() == clang::VarDecl::CallInit) {
151 else if (pvd->getInitStyle() == clang::VarDecl::CInit) {
154 expr->printPretty(out, 0, policy, 0);
155 if (pvd->getInitStyle() == clang::VarDecl::CallInit) {
163 const TClingTypeInfo *TClingMethodArgInfo::Type()
const
165 TTHREAD_TLS_DECL_ARG( TClingTypeInfo, ti, fInterp);
169 const clang::ParmVarDecl *pvd = GetDecl();
170 clang::QualType qt = pvd->getOriginalType();
175 const char *TClingMethodArgInfo::TypeName()
const
180 return Type()->Name();