Logo ROOT  
Reference Guide
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"
18 using 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 
38 static int fgCount = 0;
39 
41 {
42  // Return the singleton ROOT::Internal::RStl.
43 
45  return instance;
46 
47 }
48 
49 void 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 
93  thisType.getTypePtr(),
94  stlclass,
95  "",
96  false /* for backward compatibility rather than 'true' .. neither really make a difference */,
97  false,
98  false,
99  false,
100  -1,
101  interp,
102  normCtxt) );
103 
104  // fprintf(stderr,"Registered the STL class %s as needing a dictionary\n",R__GetQualifiedName(*stlclass).c_str());
105 
106  for(unsigned int i=0; i < templateCl->getTemplateArgs().size(); ++i) {
107  const clang::TemplateArgument &arg( templateCl->getTemplateArgs().get(i) );
108  if (arg.getKind() == clang::TemplateArgument::Type) {
109  const clang::NamedDecl *decl = arg.getAsType().getTypePtr()->getAsCXXRecordDecl();
110 
111  if (decl && TClassEdit::STLKind( decl->getName().str() ) != 0 )
112  {
113  const clang::CXXRecordDecl *clxx = llvm::dyn_cast<clang::CXXRecordDecl>(decl);
114  if (clxx) {
115  if (!clxx->isCompleteDefinition()) {
116  /* bool result = */ ROOT::TMetaUtils::RequireCompleteType(interp, clxx->getLocation(), arg.getAsType());
117  }
118  // Do we need to strip the qualifier?
119  GenerateTClassFor(arg.getAsType(),interp,normCtxt);
120  }
121  }
122  }
123  }
124 }
125 
126 void ROOT::Internal::RStl::GenerateTClassFor(const char *requestedName, const clang::CXXRecordDecl *stlclass, const cling::Interpreter &interp, const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt)
127 {
128  // Force the generation of the TClass for the given class.
129  const clang::ClassTemplateSpecializationDecl *templateCl = llvm::dyn_cast<clang::ClassTemplateSpecializationDecl>(stlclass);
130 
131  if (!templateCl) {
132  ROOT::TMetaUtils::Error("RStl::GenerateTClassFor","%s not in a template",
133  ROOT::TMetaUtils::GetQualifiedName(*stlclass).c_str());
134  return;
135  }
136 
137 
138  if ( TClassEdit::STLKind( stlclass->getName().str() ) == ROOT::kSTLvector ) {
139  const clang::TemplateArgument &arg( templateCl->getTemplateArgs().get(0) );
140  if (arg.getKind() == clang::TemplateArgument::Type) {
141  const clang::NamedDecl *decl = arg.getAsType().getTypePtr()->getAsCXXRecordDecl();
142  if (decl) {
143  // NOTE: we should just compare the decl to the bool builtin!
144  llvm::StringRef argname = decl->getName();
145  if ( (argname.str() == "bool") || (argname.str() == "Bool_t") ) {
146  ROOT::TMetaUtils::Warning("std::vector<bool>", " is not fully supported yet!\nUse std::vector<char> or std::deque<bool> instead.\n");
147  }
148  }
149  }
150  }
151 
152  fList.insert( ROOT::TMetaUtils::AnnotatedRecordDecl(++fgCount,stlclass,requestedName,true,false,false,false,-1, interp,normCtxt) );
153 
155  for(unsigned int i=0; i < templateCl->getTemplateArgs().size(); ++i) {
156  const clang::TemplateArgument &arg( templateCl->getTemplateArgs().get(i) );
157  if (arg.getKind() == clang::TemplateArgument::Type) {
158  const clang::NamedDecl *decl = arg.getAsType().getTypePtr()->getAsCXXRecordDecl();
159 
160  if (decl && TClassEdit::STLKind( decl->getName().str() ) != 0 )
161  {
162  const clang::CXXRecordDecl *clxx = llvm::dyn_cast<clang::CXXRecordDecl>(decl);
163  if (clxx) {
164  if (!clxx->isCompleteDefinition()) {
165  /* bool result = */ ROOT::TMetaUtils::RequireCompleteType(interp, clxx->getLocation (), arg.getAsType());
166  clxx = arg.getAsType().getTypePtr()->getAsCXXRecordDecl();
167  }
168  if (!splitType.fElements.empty()) {
169  GenerateTClassFor( splitType.fElements[i+1].c_str(), clxx, interp, normCtxt);
170  } else {
171  GenerateTClassFor( "", clxx, interp, normCtxt );
172  }
173  }
174  }
175  }
176  }
177 
178 }
179 
181 {
182  // Print the content of the object
183  fprintf(stderr,"ROOT::Internal::RStl singleton\n");
184  list_t::iterator iter;
185  for(iter = fList.begin(); iter != fList.end(); ++iter) {
186  fprintf(stderr, "need TClass for %s\n", ROOT::TMetaUtils::GetQualifiedName(*(*iter)).c_str());
187  }
188 }
189 
190 void ROOT::Internal::RStl::WriteClassInit(std::ostream &ostr,
191  const cling::Interpreter &interp,
192  const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt,
193  const ROOT::TMetaUtils::RConstructorTypes& ctorTypes,
194  bool &needCollectionProxy,
195  void (*emitStreamerInfo)(const char*) )
196 {
197  // This function writes the TGeneraticClassInfo initialiser
198  // and the auxiliary functions (new and delete wrappers) for
199  // each of the STL containers that have been registered
200 
201  list_t::iterator iter;
202  for(iter = fList.begin(); iter != fList.end(); ++iter) {
203  const clang::CXXRecordDecl* result;
204 
205  if (!iter->GetRecordDecl()->getDefinition()) {
206 
207  // We do not have a complete definition, we need to force the instantiation
208  // and findScope can do that.
209  const cling::LookupHelper& lh = interp.getLookupHelper();
210  result = llvm::dyn_cast_or_null<clang::CXXRecordDecl>(lh.findScope(iter->GetNormalizedName(),
211  cling::LookupHelper::NoDiagnostics,
212  0)
213  );
214 
215  if (!result || !iter->GetRecordDecl()->getDefinition()) {
216  fprintf(stderr,"Error: incomplete definition for %s\n",iter->GetNormalizedName());
217  continue;
218  }
219  }
220  else
221  {
222  result = llvm::dyn_cast<clang::CXXRecordDecl>(iter->GetRecordDecl());
223  }
224 
225  ROOT::TMetaUtils::WriteClassInit(ostr, *iter, result, interp, normCtxt, ctorTypes, needCollectionProxy);
226  ROOT::TMetaUtils::WriteAuxFunctions(ostr, *iter, result, interp, ctorTypes, normCtxt);
227 
228  if (emitStreamerInfo) emitStreamerInfo(iter->GetNormalizedName());
229  }
230 }
ROOT::kSTLvector
@ kSTLvector
Definition: ESTLType.h:30
ROOT::TMetaUtils::Warning
void Warning(const char *location, const char *va_(fmt),...)
Definition: TClingUtils.h:819
RStl.h
ROOT::TMetaUtils::AnnotatedRecordDecl
Definition: TClingUtils.h:191
TClassEdit::kLong64
@ kLong64
Definition: TClassEdit.h:84
TClassEdit
Definition: TClassEdit.h:72
ROOT::TMetaUtils::Error
void Error(const char *location, const char *va_(fmt),...)
Definition: TClingUtils.h:789
RConfig.hxx
fgCount
static int fgCount
Definition: RStl.cxx:38
TClassEdit::TSplitType
Definition: TClassEdit.h:137
Varargs.h
ROOT::Math::IntegrationOneDim::Type
Type
enumeration specifying the integration types.
Definition: AllIntegrationTypes.h:32
ROOT::TMetaUtils::WriteClassInit
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!
Definition: TClingUtils.cxx:1750
ROOT::Internal::RStl
Definition: RStl.h:47
TClassEdit::TSplitType::fElements
std::vector< std::string > fElements
Definition: TClassEdit.h:140
ROOT::TMetaUtils::GetQualifiedName
void GetQualifiedName(std::string &qual_name, const clang::QualType &type, const clang::NamedDecl &forcontext)
Main implementation relying on GetFullyQualifiedTypeName All other GetQualifiedName functions leverag...
Definition: TClingUtils.cxx:1369
ROOT::Internal::RStl::Print
void Print()
Definition: RStl.cxx:180
size
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
ROOT::Internal::RStl::Instance
static RStl & Instance()
Definition: RStl.cxx:40
ROOT::TMetaUtils::WriteAuxFunctions
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()....
Definition: TClingUtils.cxx:2408
ROOT::TMetaUtils::TNormalizedCtxt
Definition: TClingUtils.h:138
ROOT::Internal::RStl::WriteClassInit
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:190
RooFit_internal::instance
static Roo_reg_AGKInteg1D instance
Definition: RooAdaptiveGaussKronrodIntegrator1D.cxx:153
ROOT::TMetaUtils::RequireCompleteType
bool RequireCompleteType(const cling::Interpreter &interp, const clang::CXXRecordDecl *cl)
Definition: TClingUtils.cxx:808
TClassEdit.h
TClassEdit::EModType
EModType
Definition: TClassEdit.h:74
TClassEdit::kDropStd
@ kDropStd
Definition: TClassEdit.h:85
TClingUtils.h
TClassEdit::STLKind
ROOT::ESTLType STLKind(std::string_view type)
Converts STL container name to number.
Definition: TClassEdit.cxx:511
ROOT::TMetaUtils::GetTypeForIO
clang::QualType GetTypeForIO(const clang::QualType &templateInstanceType, const cling::Interpreter &interpreter, const TNormalizedCtxt &normCtxt, TClassEdit::EModType mode=TClassEdit::kNone)
Definition: TClingUtils.cxx:4153
type
int type
Definition: TGX11.cxx:121
ROOT::Internal::RStl::GenerateTClassFor
void GenerateTClassFor(const char *requestedName, const clang::CXXRecordDecl *stlClass, const cling::Interpreter &interp, const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt)
Definition: RStl.cxx:126
ROOT::TMetaUtils::RConstructorTypes
std::list< RConstructorType > RConstructorTypes
Definition: TClingUtils.h:321