26 #include "TClingUtils.h"
30 #include "cling/Interpreter/LookupHelper.h"
31 #include "cling/Utils/AST.h"
32 #include "clang/AST/Attr.h"
34 using namespace clang;
40 TClingTypedefInfo::TClingTypedefInfo(cling::Interpreter *interp,
42 : TClingDeclInfo(nullptr), fInterp(interp), fFirstTime(true), fDescend(false), fTitle(
"")
47 TClingTypedefInfo::TClingTypedefInfo(cling::Interpreter *interp,
48 const clang::TypedefNameDecl *TdefD)
49 : TClingDeclInfo(TdefD), fInterp(interp), fFirstTime(true), fDescend(false), fTitle(
"")
58 void TClingTypedefInfo::Init(
const char *name)
65 fIter = clang::DeclContext::decl_iterator();
69 if (!name || !*name)
return;
70 const char lastChar = name[strlen(name) - 1];
71 if (lastChar ==
'*' || lastChar ==
'&' || !strncmp(name,
"const ", 6))
75 const cling::LookupHelper& lh = fInterp->getLookupHelper();
76 clang::QualType QT = lh.findType(name,
77 gDebug > 5 ? cling::LookupHelper::WithDiagnostics
78 : cling::LookupHelper::NoDiagnostics);
80 std::string buf = TClassEdit::InsertStd(name);
83 gDebug > 5 ? cling::LookupHelper::WithDiagnostics
84 : cling::LookupHelper::NoDiagnostics);
90 const clang::TypedefType *td = QT->getAs<clang::TypedefType>();
96 fDecl = td->getDecl();
102 int TClingTypedefInfo::InternalNext()
108 if (fFirstTime && fDecl) {
110 clang::PrintingPolicy Policy(fDecl->getASTContext().getPrintingPolicy());
111 llvm::raw_string_ostream stream(buf);
112 llvm::dyn_cast<clang::NamedDecl>(fDecl)
113 ->getNameForDiagnostic(stream, Policy,
false);
115 Error(
"TClingTypedefInfo::InternalNext",
"Next called but iteration not prepared for %s!",buf.c_str());
120 cling::Interpreter::PushTransactionRAII pushedT(fInterp);
139 fIterStack.push_back(fIter);
140 clang::DeclContext *dc = llvm::cast<clang::DeclContext>(*fIter);
141 fIter = dc->decls_begin();
144 while (!*fIter && fIterStack.size()) {
145 fIter = fIterStack.back();
146 fIterStack.pop_back();
157 if (llvm::isa<clang::TypedefNameDecl>(*fIter)) {
162 clang::Decl::Kind dk = fIter->getKind();
163 if ((dk == clang::Decl::Namespace) || (dk == clang::Decl::CXXRecord) ||
164 (dk == clang::Decl::ClassTemplateSpecialization)) {
173 int TClingTypedefInfo::Next()
175 return InternalNext();
181 long TClingTypedefInfo::Property()
const
187 property |= kIsTypedef;
188 const clang::TypedefNameDecl *td = llvm::dyn_cast<clang::TypedefNameDecl>(fDecl);
189 clang::QualType qt = td->getUnderlyingType().getCanonicalType();
190 if (qt.isConstQualified()) {
191 property |= kIsConstant;
194 if (qt->isArrayType()) {
195 qt = llvm::cast<clang::ArrayType>(qt)->getElementType();
198 else if (qt->isReferenceType()) {
199 property |= kIsReference;
200 qt = llvm::cast<clang::ReferenceType>(qt)->getPointeeType();
203 else if (qt->isPointerType()) {
204 property |= kIsPointer;
205 if (qt.isConstQualified()) {
206 property |= kIsConstPointer;
208 qt = llvm::cast<clang::PointerType>(qt)->getPointeeType();
211 else if (qt->isMemberPointerType()) {
212 qt = llvm::cast<clang::MemberPointerType>(qt)->getPointeeType();
217 if (qt->isBuiltinType()) {
218 property |= kIsFundamental;
220 if (qt.isConstQualified()) {
221 property |= kIsConstant;
229 int TClingTypedefInfo::Size()
const
234 clang::ASTContext &context = fDecl->getASTContext();
235 const clang::TypedefNameDecl *td = llvm::dyn_cast<clang::TypedefNameDecl>(fDecl);
236 clang::QualType qt = td->getUnderlyingType();
237 if (qt->isDependentType()) {
242 if (
const clang::RecordType *rt = qt->getAs<clang::RecordType>()) {
243 if (!rt->getDecl()->getDefinition()) {
250 cling::Interpreter::PushTransactionRAII pushedT(fInterp);
253 clang::CharUnits::QuantityType quantity =
254 context.getTypeSizeInChars(qt).getQuantity();
256 return static_cast<int>(quantity);
262 const char *TClingTypedefInfo::TrueName(
const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt)
const
268 TTHREAD_TLS_DECL( std::string, truename);
270 const clang::TypedefNameDecl *td = llvm::dyn_cast<clang::TypedefNameDecl>(fDecl);
271 clang::QualType underlyingType = td->getUnderlyingType();
272 if (underlyingType->isBooleanType()) {
275 const clang::ASTContext &ctxt = fInterp->getCI()->getASTContext();
276 ROOT::TMetaUtils::GetNormalizedName(truename, ctxt.getTypedefType(td), *fInterp, normCtxt);
278 return truename.c_str();
284 const char *TClingTypedefInfo::Name()
289 if (!fNameCache.empty())
290 return fNameCache.c_str();
292 const clang::TypedefNameDecl *td = llvm::cast<clang::TypedefNameDecl>(fDecl);
293 const clang::ASTContext &ctxt = td->getASTContext();
294 ROOT::TMetaUtils::GetFullyQualifiedTypeName(fNameCache, ctxt.getTypedefType(td), *fInterp);
295 return fNameCache.c_str();
300 const char *TClingTypedefInfo::Title()
313 if (
const TypedefNameDecl *TND = llvm::dyn_cast<TypedefNameDecl>(GetDecl())) {
314 if ( (TND = ROOT::TMetaUtils::GetAnnotatedRedeclarable(TND)) ) {
315 if (AnnotateAttr *A = TND->getAttr<AnnotateAttr>()) {
316 fTitle = A->getAnnotation().str();
317 return fTitle.c_str();
321 else if (!GetDecl()->isFromASTFile()) {
325 fTitle = ROOT::TMetaUtils::GetComment(*GetDecl()).str();
327 return fTitle.c_str();