Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
TClingTypeInfo.cxx
Go to the documentation of this file.
1// @(#)root/core/meta:$Id$
2// Author: Paul Russo 30/07/2012
3
4/*************************************************************************
5 * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. *
6 * All rights reserved. *
7 * *
8 * For the licensing terms see $ROOTSYS/LICENSE. *
9 * For the list of contributors see $ROOTSYS/README/CREDITS. *
10 *************************************************************************/
11
12/** \class TClingTypeInfo
13Emulation of the CINT TypeInfo class.
14
15The CINT C++ interpreter provides an interface to metadata about
16a type through the TypeInfo class. This class provides the same
17functionality, using an interface as close as possible to TypeInfo
18but the type metadata comes from the Clang C++ compiler, not CINT.
19*/
20
21#include "TClingTypeInfo.h"
22
23#include "TDictionary.h"
24#include "Rtypes.h" // for gDebug
25#include "TClassEdit.h"
26#include "TClingUtils.h"
27#include "TInterpreter.h"
28#include "ThreadLocalStorage.h"
29
30#include "cling/Interpreter/Interpreter.h"
31#include "cling/Interpreter/LookupHelper.h"
32#include "cling/Utils/AST.h"
33
34#include "clang/AST/ASTContext.h"
35#include "clang/AST/DeclCXX.h"
36#include "clang/AST/Type.h"
37#include "clang/AST/PrettyPrinter.h"
38#include "clang/Frontend/CompilerInstance.h"
39
40#include <cstdio>
41#include <string>
42
43////////////////////////////////////////////////////////////////////////////////
44
45TClingTypeInfo::TClingTypeInfo(cling::Interpreter *interp, const char *name)
46 : TClingDeclInfo(nullptr), fInterp(interp)
47{
48 Init(name);
49}
50
51////////////////////////////////////////////////////////////////////////////////
52
53void TClingTypeInfo::Init(const char *name)
54{
55 fQualType = clang::QualType();
56 if (gDebug > 0) {
57 fprintf(stderr,
58 "TClingTypeInfo::Init(name): looking up clang type: %s", name);
59 }
60 const cling::LookupHelper& lh = fInterp->getLookupHelper();
61 clang::QualType QT = lh.findType(name,
62 gDebug > 5 ? cling::LookupHelper::WithDiagnostics
63 : cling::LookupHelper::NoDiagnostics);
64 if (QT.isNull()) {
65 if (gDebug > 0) {
66 fprintf(stderr,
67 "TClingTypeInfo::Init(name): clang type not found: %s", name);
68 }
69 std::string buf = TClassEdit::InsertStd(name);
70 QT = lh.findType(buf,
71 gDebug > 5 ? cling::LookupHelper::WithDiagnostics
72 : cling::LookupHelper::NoDiagnostics);
73 if (QT.isNull()) {
74 if (gDebug > 0) {
75 fprintf(stderr,
76 "TClingTypeInfo::Init(name): "
77 "clang type not found name: %s\n", buf.c_str());
78 }
79 }
80 else {
81 fQualType = QT;
82 if (gDebug > 0) {
83 fprintf(stderr,
84 "TClingTypeInfo::Init(name): found clang type name: %s\n",
85 buf.c_str());
86 }
87 }
88 }
89 else {
90 fQualType = QT;
91 if (gDebug > 0) {
92 fprintf(stderr,
93 "TClingTypeInfo::Init(name): clang type found: %s\n", name);
94 }
95 }
96}
97
98////////////////////////////////////////////////////////////////////////////////
99
100const char *TClingTypeInfo::Name() const
101{
102 if (!IsValid()) {
103 return "";
104 }
105 // Note: This *must* be static because we are returning a pointer inside it!
106 TTHREAD_TLS_DECL( std::string, buf);
107 buf.clear();
108
109 // TODO: This needs to be locked, but the lock cannot be placed in TClingUtils.cxx as it cannot depend from
110 // TInterpreter.h for the declaration of gInterpreterMutex. Or can it?
113 return buf.c_str(); // NOLINT
114}
115
116////////////////////////////////////////////////////////////////////////////////
117
119{
120 if (!IsValid()) {
121 return 0L;
122 }
123 long property = 0L;
124 if (llvm::isa<clang::TypedefType>(*fQualType)) {
125 property |= kIsTypedef;
126 }
127 clang::QualType QT = fQualType.getCanonicalType();
128 property = TClingDeclInfo::Property(property, QT);
129 const clang::TagType *tagQT = llvm::dyn_cast<clang::TagType>(QT.getTypePtr());
130 if (tagQT) {
131 // Note: Now we have class, enum, struct, union only.
132 const clang::TagDecl *TD = llvm::dyn_cast<clang::TagDecl>(tagQT->getDecl());
133 if (!TD)
134 return property;
135 if (TD->isEnum()) {
136 property |= kIsEnum;
137 } else {
138 // Note: Now we have class, struct, union only.
139 const clang::CXXRecordDecl *CRD =
140 llvm::dyn_cast<clang::CXXRecordDecl>(TD);
141 if (!CRD)
142 return property;
143 if (CRD->isClass()) {
144 property |= kIsClass;
145 }
146 else if (CRD->isStruct()) {
147 property |= kIsStruct;
148 }
149 else if (CRD->isUnion()) {
150 property |= kIsUnion;
151 }
152 // isAbstract can trigger deserialization
153 cling::Interpreter::PushTransactionRAII RAII(fInterp);
154 if (CRD->isThisDeclarationADefinition() && CRD->isAbstract()) {
155 property |= kIsAbstract;
156 }
157 }
158 }
159 return property;
160}
161
162////////////////////////////////////////////////////////////////////////////////
163
165{
166 if (!IsValid()) {
167 return 0;
168 }
169 int cnt = 0;
170 bool is_ref = false;
171 clang::QualType QT = fQualType.getCanonicalType();
172 while (1) {
173 if (QT->isArrayType()) {
174 QT = llvm::cast<clang::ArrayType>(QT)->getElementType();
175 continue;
176 }
177 else if (QT->isReferenceType()) {
178 is_ref = true;
179 QT = llvm::cast<clang::ReferenceType>(QT)->getPointeeType();
180 continue;
181 }
182 else if (QT->isPointerType()) {
183 ++cnt;
184 QT = llvm::cast<clang::PointerType>(QT)->getPointeeType();
185 continue;
186 }
187 else if (QT->isMemberPointerType()) {
188 QT = llvm::cast<clang::MemberPointerType>(QT)->getPointeeType();
189 continue;
190 }
191 break;
192 }
193 int val = 0;
194 if (cnt > 1) {
195 val = cnt;
196 }
197 if (is_ref) {
198 if (cnt < 2) {
199 val = kParaReference;
200 }
201 else {
202 val |= kParaRef;
203 }
204 }
205 return val;
206}
207
208////////////////////////////////////////////////////////////////////////////////
209
211{
212 if (!IsValid()) {
213 return 1;
214 }
215 if (fQualType->isDependentType()) {
216 // Dependent on a template parameter, we do not know what it is yet.
217 return 0;
218 }
219 if (const clang::RecordType *RT = fQualType->getAs<clang::RecordType>()) {
220 if (!RT->getDecl()->getDefinition()) {
221 // This is a forward-declared class.
222 return 0;
223 }
224 }
225 clang::ASTContext &Context = fInterp->getCI()->getASTContext();
226 // Note: This is an int64_t.
227 clang::CharUnits::QuantityType Quantity =
228 Context.getTypeSizeInChars(fQualType).getQuantity();
229 return static_cast<int>(Quantity);
230}
231
232////////////////////////////////////////////////////////////////////////////////
233/// Return the normalized name of the type (i.e. fully qualified and without
234/// the non-opaque typedefs.
235
237{
238 if (!IsValid()) {
239 return nullptr;
240 }
241 // Note: This *must* be static because we are returning a pointer inside it.
242 TTHREAD_TLS_DECL( std::string, buf);
243 buf.clear();
244
245 // TODO: This needs to be locked, but the lock cannot be placed in TClingUtils.cxx as it cannot depend from
246 // TInterpreter.h for the declaration of gInterpreterMutex. Or can it?
249
250 return buf.c_str(); // NOLINT
251}
252
253////////////////////////////////////////////////////////////////////////////////
254/// Return the normalized name of the type (i.e. fully qualified and without
255/// the non-opaque typedefs.
256
258{
259 if (!IsValid()) {
260 return "";
261 }
262 std::string buf;
263
264 // TODO: This needs to be locked, but the lock cannot be placed in TClingUtils.cxx as it cannot depend from
265 // TInterpreter.h for the declaration of gInterpreterMutex. Or can it?
268
269 // in C++11 this will be efficient thanks to the move constructor.
270 return buf;
271}
272
273////////////////////////////////////////////////////////////////////////////////
274/// Return the QualType as a void pointer
275
277{
278 return fQualType.getAsOpaquePtr();
279}
280
281
@ kIsClass
Definition TDictionary.h:65
@ kIsEnum
Definition TDictionary.h:68
@ kIsAbstract
Definition TDictionary.h:71
@ kIsStruct
Definition TDictionary.h:66
@ kIsUnion
Definition TDictionary.h:67
@ kIsTypedef
Definition TDictionary.h:69
@ kParaRef
@ kParaReference
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
char name[80]
Definition TGX11.cxx:110
R__EXTERN TVirtualMutex * gInterpreterMutex
Int_t gDebug
Definition TROOT.cxx:595
#define R__LOCKGUARD(mutex)
long Property(long property, clang::QualType &qt) const
long Property() const
clang::QualType fQualType
std::string NormalizedName(const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) const
Return the normalized name of the type (i.e.
const char * Name() const override
TClingTypeInfo(cling::Interpreter *interp)
int RefType() const
void * QualTypePtr() const
Return the QualType as a void pointer.
cling::Interpreter * fInterp
bool IsValid() const override
void Init(const char *name)
const char * TrueName(const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) const
Return the normalized name of the type (i.e.
void GetNormalizedName(std::string &norm_name, const clang::QualType &type, const cling::Interpreter &interpreter, const TNormalizedCtxt &normCtxt)
Return the type name normalized for ROOT, keeping only the ROOT opaque typedef (Double32_t,...
void GetFullyQualifiedTypeName(std::string &name, const clang::QualType &type, const cling::Interpreter &interpreter)
std::string InsertStd(const char *tname)