Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
RStl.cxx
Go to the documentation of this file.
1// @(#)root/utils:$Id$
2// Author: Philippe Canal 27/08/2003
3
4/*************************************************************************
5 * Copyright (C) 1995-2003, Rene Brun, Fons Rademakers, and al. *
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#include "RConfigure.h"
13#include <ROOT/RConfig.hxx>
14
15#include "RStl.h"
16#include "TClassEdit.h"
17#include "TClingUtils.h"
18using namespace TClassEdit;
19
20#include <stdio.h>
21
22#include "clang/AST/Decl.h"
23#include "clang/AST/DeclTemplate.h"
24
25#include "cling/Interpreter/Interpreter.h"
26#include "cling/Interpreter/LookupHelper.h"
27
28#include "clang/Sema/Sema.h"
29#include "clang/Sema/Template.h"
30#include "clang/Frontend/CompilerInstance.h"
31
32#include "Varargs.h"
33
34//
35// ROOT::Internal::RStl is the rootcint STL handling class.
36//
37
38static int fgCount = 0;
39
41{
42 // Return the singleton ROOT::Internal::RStl.
43
45 return instance;
46
47}
48
49void ROOT::Internal::RStl::GenerateTClassFor(const clang::QualType &type, const cling::Interpreter &interp, const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt)
50{
51 // Force the generation of the TClass for the given class.
52
53 clang::QualType thisType = type;
54
55 auto typePtr = thisType.getTypePtr();
56 const clang::CXXRecordDecl *stlclass = typePtr->getAsCXXRecordDecl();
57 if (!stlclass) {
58 return;
59 }
60
61 // Transform the type to the corresponding one for IO
62 auto typeForIO = ROOT::TMetaUtils::GetTypeForIO(thisType, interp, normCtxt);
63 if (typeForIO.getTypePtr() != typePtr)
64 stlclass = typeForIO->getAsCXXRecordDecl();
65 if (!stlclass) {
66 return;
67 }
68 thisType = typeForIO;
69
70 const clang::ClassTemplateSpecializationDecl *templateCl = llvm::dyn_cast<clang::ClassTemplateSpecializationDecl>(stlclass);
71
72 if (!templateCl) {
73 ROOT::TMetaUtils::Error("RStl::GenerateTClassFor","%s not in a template",
74 ROOT::TMetaUtils::GetQualifiedName(*stlclass).c_str());
75 return;
76 }
77
78 if ( TClassEdit::STLKind( stlclass->getName().str() ) == ROOT::kSTLvector ) {
79 const clang::TemplateArgument &arg( templateCl->getTemplateArgs().get(0) );
80 if (arg.getKind() == clang::TemplateArgument::Type) {
81 const clang::NamedDecl *decl = arg.getAsType().getTypePtr()->getAsCXXRecordDecl();
82 if (decl) {
83 // NOTE: we should just compare the decl to the bool builtin!
84 llvm::StringRef argname = decl->getName();
85 if ( (argname.str() == "bool") || (argname.str() == "Bool_t") ) {
86 ROOT::TMetaUtils::Warning("std::vector<bool>", " is not fully supported yet!\nUse std::vector<char> or std::deque<bool> instead.\n");
87 }
88 }
89 }
90 }
91
92 // clang-format off
94 thisType.getTypePtr(),
95 stlclass,
96 "",
97 false, /* for backward compatibility rather than 'true' ..
98 neither really make a difference */
99 false,
100 false,
101 false,
102 -1,
103 0,
104 interp,
105 normCtxt));
106 // clang-format on
107
108 // fprintf(stderr,"Registered the STL class %s as needing a dictionary\n",R__GetQualifiedName(*stlclass).c_str());
109
110 for(unsigned int i=0; i < templateCl->getTemplateArgs().size(); ++i) {
111 const clang::TemplateArgument &arg( templateCl->getTemplateArgs().get(i) );
112 if (arg.getKind() == clang::TemplateArgument::Type) {
113 const clang::NamedDecl *decl = arg.getAsType().getTypePtr()->getAsCXXRecordDecl();
114
115 if (decl && TClassEdit::STLKind( decl->getName().str() ) != 0 )
116 {
117 const clang::CXXRecordDecl *clxx = llvm::dyn_cast<clang::CXXRecordDecl>(decl);
118 if (clxx) {
119 if (!clxx->isCompleteDefinition()) {
120 /* bool result = */ ROOT::TMetaUtils::RequireCompleteType(interp, clxx->getLocation(), arg.getAsType());
121 }
122 // Do we need to strip the qualifier?
123 GenerateTClassFor(arg.getAsType(),interp,normCtxt);
124 }
125 }
126 }
127 }
128}
129
130void ROOT::Internal::RStl::GenerateTClassFor(const char *requestedName, const clang::CXXRecordDecl *stlclass, const cling::Interpreter &interp, const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt)
131{
132 // Force the generation of the TClass for the given class.
133 const clang::ClassTemplateSpecializationDecl *templateCl = llvm::dyn_cast<clang::ClassTemplateSpecializationDecl>(stlclass);
134
135 if (!templateCl) {
136 ROOT::TMetaUtils::Error("RStl::GenerateTClassFor","%s not in a template",
137 ROOT::TMetaUtils::GetQualifiedName(*stlclass).c_str());
138 return;
139 }
140
141
142 if ( TClassEdit::STLKind( stlclass->getName().str() ) == ROOT::kSTLvector ) {
143 const clang::TemplateArgument &arg( templateCl->getTemplateArgs().get(0) );
144 if (arg.getKind() == clang::TemplateArgument::Type) {
145 const clang::NamedDecl *decl = arg.getAsType().getTypePtr()->getAsCXXRecordDecl();
146 if (decl) {
147 // NOTE: we should just compare the decl to the bool builtin!
148 llvm::StringRef argname = decl->getName();
149 if ( (argname.str() == "bool") || (argname.str() == "Bool_t") ) {
150 ROOT::TMetaUtils::Warning("std::vector<bool>", " is not fully supported yet!\nUse std::vector<char> or std::deque<bool> instead.\n");
151 }
152 }
153 }
154 }
155
156 // clang-format off
158 stlclass,
159 requestedName,
160 true,
161 false,
162 false,
163 false,
164 -1,
165 0,
166 interp,
167 normCtxt));
168 // clang-format on
169
171 for(unsigned int i=0; i < templateCl->getTemplateArgs().size(); ++i) {
172 const clang::TemplateArgument &arg( templateCl->getTemplateArgs().get(i) );
173 if (arg.getKind() == clang::TemplateArgument::Type) {
174 const clang::NamedDecl *decl = arg.getAsType().getTypePtr()->getAsCXXRecordDecl();
175
176 if (decl && TClassEdit::STLKind( decl->getName().str() ) != 0 )
177 {
178 const clang::CXXRecordDecl *clxx = llvm::dyn_cast<clang::CXXRecordDecl>(decl);
179 if (clxx) {
180 if (!clxx->isCompleteDefinition()) {
181 /* bool result = */ ROOT::TMetaUtils::RequireCompleteType(interp, clxx->getLocation (), arg.getAsType());
182 clxx = arg.getAsType().getTypePtr()->getAsCXXRecordDecl();
183 }
184 if (!splitType.fElements.empty()) {
185 GenerateTClassFor( splitType.fElements[i+1].c_str(), clxx, interp, normCtxt);
186 } else {
187 GenerateTClassFor( "", clxx, interp, normCtxt );
188 }
189 }
190 }
191 }
192 }
193
194}
195
197{
198 // Print the content of the object
199 fprintf(stderr,"ROOT::Internal::RStl singleton\n");
200 list_t::iterator iter;
201 for(iter = fList.begin(); iter != fList.end(); ++iter) {
202 fprintf(stderr, "need TClass for %s\n", ROOT::TMetaUtils::GetQualifiedName(*(*iter)).c_str());
203 }
204}
205
207 const cling::Interpreter &interp,
208 const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt,
210 bool &needCollectionProxy,
211 void (*emitStreamerInfo)(const char*) )
212{
213 // This function writes the TGeneraticClassInfo initialiser
214 // and the auxiliary functions (new and delete wrappers) for
215 // each of the STL containers that have been registered
216
217 list_t::iterator iter;
218 for(iter = fList.begin(); iter != fList.end(); ++iter) {
219 const clang::CXXRecordDecl* result;
220
221 if (!iter->GetRecordDecl()->getDefinition()) {
222
223 // We do not have a complete definition, we need to force the instantiation
224 // and findScope can do that.
225 const cling::LookupHelper& lh = interp.getLookupHelper();
226 result = llvm::dyn_cast_or_null<clang::CXXRecordDecl>(lh.findScope(iter->GetNormalizedName(),
227 cling::LookupHelper::NoDiagnostics,
228 nullptr)
229 );
230
231 if (!result || !iter->GetRecordDecl()->getDefinition()) {
232 fprintf(stderr,"Error: incomplete definition for %s\n",iter->GetNormalizedName());
233 continue;
234 }
235 }
236 else
237 {
238 result = llvm::dyn_cast<clang::CXXRecordDecl>(iter->GetRecordDecl());
239 }
240
241 ROOT::TMetaUtils::WriteClassInit(ostr, *iter, result, interp, normCtxt, ctorTypes, needCollectionProxy);
242 ROOT::TMetaUtils::WriteAuxFunctions(ostr, *iter, result, interp, ctorTypes, normCtxt);
243
244 if (emitStreamerInfo) emitStreamerInfo(iter->GetNormalizedName());
245 }
246}
static int fgCount
Definition RStl.cxx:38
static Roo_reg_AGKInteg1D instance
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
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 result
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 type
void GenerateTClassFor(const char *requestedName, const clang::CXXRecordDecl *stlClass, const cling::Interpreter &interp, const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt)
Definition RStl.cxx:130
static RStl & Instance()
Definition RStl.cxx:40
void WriteClassInit(std::ostream &strm, const cling::Interpreter &interp, const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt, const ROOT::TMetaUtils::RConstructorTypes &, bool &needCollectionProxy, void(*emitStreamerInfo)(const char *))
Definition RStl.cxx:206
void Error(const char *location, const char *fmt,...)
void WriteClassInit(std::ostream &finalString, const AnnotatedRecordDecl &cl, const clang::CXXRecordDecl *decl, const cling::Interpreter &interp, const TNormalizedCtxt &normCtxt, const RConstructorTypes &ctorTypes, bool &needCollectionProxy)
FIXME: a function of 450+ lines!
clang::QualType GetTypeForIO(const clang::QualType &templateInstanceType, const cling::Interpreter &interpreter, const TNormalizedCtxt &normCtxt, TClassEdit::EModType mode=TClassEdit::kNone)
std::list< RConstructorType > RConstructorTypes
void WriteAuxFunctions(std::ostream &finalString, const AnnotatedRecordDecl &cl, const clang::CXXRecordDecl *decl, const cling::Interpreter &interp, const RConstructorTypes &ctorTypes, const TNormalizedCtxt &normCtxt)
std::string NormalizedName; GetNormalizedName(NormalizedName, decl->getASTContext()....
void GetQualifiedName(std::string &qual_name, const clang::QualType &type, const clang::NamedDecl &forcontext)
Main implementation relying on GetFullyQualifiedTypeName All other GetQualifiedName functions leverag...
bool RequireCompleteType(const cling::Interpreter &interp, const clang::CXXRecordDecl *cl)
void Warning(const char *location, const char *fmt,...)
@ kSTLvector
Definition ESTLType.h:30
ROOT::ESTLType STLKind(std::string_view type)
Converts STL container name to number.
std::vector< std::string > fElements
Definition TClassEdit.h:141