ROOT  6.06/09
Reference Guide
BaseSelectionRule.cxx
Go to the documentation of this file.
1 // @(#)root/core/utils:$Id: BaseSelectionRule.cxx 41697 2011-11-01 21:03:41Z pcanal $
2 // Author: Velislava Spasova September 2010
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2011, 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 //////////////////////////////////////////////////////////////////////////
13 // //
14 // BaseSelectionRule //
15 // //
16 // Base selection class from which all //
17 // selection classes should be derived //
18 // //
19 //////////////////////////////////////////////////////////////////////////
20 
21 #include "BaseSelectionRule.h"
22 
23 #include <iostream>
24 #include <string.h>
25 #include <cctype>
26 
27 #include "clang/Basic/SourceLocation.h"
28 #include "clang/Basic/SourceManager.h"
29 #include "clang/AST/DeclCXX.h"
30 #include "clang/AST/ASTContext.h"
31 #include "clang/AST/DeclTemplate.h"
32 
33 #ifdef _WIN32
34 #include "process.h"
35 #endif
36 #include <sys/stat.h>
37 
38 static const char *R__GetDeclSourceFileName(const clang::Decl* D)
39 {
40  clang::ASTContext& ctx = D->getASTContext();
41  clang::SourceManager& SM = ctx.getSourceManager();
42  clang::SourceLocation SL = D->getLocation();
43  // If the class decl is the result of a macpo expansion, take the location
44  // where the macro is "invoked" i.e. expanded at (ExpansionLoc), not the
45  // spelling location (where the delc's tokens come from).
46  if (SL.isMacroID())
47  SL = SM.getExpansionLoc(SL);
48 
49  if (SL.isValid() && SL.isFileID()) {
50  clang::PresumedLoc PLoc = SM.getPresumedLoc(SL);
51  return PLoc.getFilename();
52  }
53  else {
54  return "invalid";
55  }
56 }
57 
58 #if MATCH_ON_INSTANTIATION_LOCATION
59 static const char *R__GetDeclSourceFileName(const clang::ClassTemplateSpecializationDecl *tmpltDecl)
60 {
61  clang::SourceLocation SL = tmpltDecl->getPointOfInstantiation();
62  clang::ASTContext& ctx = tmpltDecl->getASTContext();
63  clang::SourceManager& SM = ctx.getSourceManager();
64 
65  if (SL.isValid() && SL.isFileID()) {
66  clang::PresumedLoc PLoc = SM.getPresumedLoc(SL);
67  return PLoc.getFilename();
68  }
69  else {
70  return "invalid";
71  }
72 }
73 #endif
74 
75 static bool R__match_filename(const char *srcname,const char *filename)
76 {
77  if (srcname==0) {
78  return false;
79  }
80  if((strcmp(srcname,filename)==0)) {
81  return true;
82  }
83 
84 #ifdef G__WIN32
85  char i1name[_MAX_PATH];
86  char fullfile[_MAX_PATH];
87  _fullpath( i1name, srcname, _MAX_PATH );
88  _fullpath( fullfile, filename, _MAX_PATH );
89  if((stricmp(i1name, fullfile)==0)) return 1;
90 #else
91  struct stat statBufItem;
92  struct stat statBuf;
93  if ( ( 0 == stat( filename, & statBufItem ) )
94  && ( 0 == stat( srcname, & statBuf ) )
95  && ( statBufItem.st_dev == statBuf.st_dev ) // Files on same device
96  && ( statBufItem.st_ino == statBuf.st_ino ) // Files on same inode (but this is not unique on AFS so we need the next 2 test
97  && ( statBufItem.st_size == statBuf.st_size ) // Files of same size
98  && ( statBufItem.st_mtime == statBuf.st_mtime ) // Files modified at the same time
99  ) {
100  return true;
101  }
102 #endif
103  return false;
104 }
105 
106 const clang::CXXRecordDecl *R__ScopeSearch(const char *name, const cling::Interpreter &gInterp, const clang::Type** resultType = 0);
107 
108 BaseSelectionRule::BaseSelectionRule(long index, BaseSelectionRule::ESelect sel, const std::string& attributeName, const std::string& attributeValue, cling::Interpreter &interp, const char* selFileName, long lineno)
109  : fIndex(index),fLineNumber(lineno),fSelFileName(selFileName),fIsSelected(sel),fMatchFound(false),fCXXRecordDecl(0),fRequestedType(0),fInterp(&interp)
110 {
111  fAttributes.insert(AttributesMap_t::value_type(attributeName, attributeValue));
112 }
113 
115 {
116  fIsSelected = sel;
117 }
118 
120 {
121  return fIsSelected;
122 }
123 
124 bool BaseSelectionRule::HasAttributeWithName(const std::string& attributeName) const
125 {
126  AttributesMap_t::const_iterator iter = fAttributes.find(attributeName);
127 
128  if(iter!=fAttributes.end()) return true;
129  else return false;
130 }
131 
132 bool BaseSelectionRule::GetAttributeValue(const std::string& attributeName, std::string& returnValue) const
133 {
134  AttributesMap_t::const_iterator iter = fAttributes.find(attributeName);
135 
136  bool retVal = iter!=fAttributes.end();
137  returnValue = retVal ? iter->second : "";
138  return retVal;
139 }
140 
141 void BaseSelectionRule::SetAttributeValue(const std::string& attributeName, const std::string& attributeValue)
142 {
143 
144  std::string localAttributeValue(attributeValue);
145 
146  int pos = attributeName.find("pattern");
147  int pos_file = attributeName.find("file_pattern");
148 
149  // Strip trailing spaces from the name or pattern
150  if (attributeName == "name" || pos> -1){
151  while(std::isspace(*localAttributeValue.begin())) localAttributeValue.erase(localAttributeValue.begin());
152  while(std::isspace(*localAttributeValue.rbegin()))localAttributeValue.erase(localAttributeValue.length()-1);
153  }
154  fAttributes.insert(AttributesMap_t::value_type(attributeName, localAttributeValue));
155 
156  if (pos > -1) {
157  if (pos_file > -1) // if we have file_pattern
158  ProcessPattern(localAttributeValue, fFileSubPatterns);
159  else ProcessPattern(localAttributeValue, fSubPatterns); // if we have pattern and proto_pattern
160  }
161 
162 
163 
164 }
165 
167 {
168  return fAttributes;
169 }
170 
172 {
173  Print(std::cout);
174 }
175 
176 void BaseSelectionRule::PrintAttributes(std::ostream &out, int level) const
177 {
178  std::string tabs;
179  for (int i = 0; i < level; ++i) {
180  tabs+='\t';
181  }
182 
183  if (!fAttributes.empty()) {
184  std::map<std::string,std::string> orderedAttributes(fAttributes.begin(),fAttributes.end());
185  for (auto&& attr : orderedAttributes) {
186  out<<tabs<<attr.first<<" = "<<attr.second<<std::endl;
187  }
188  }
189  else {
190  out<<tabs<<"No attributes"<<std::endl;
191  }
192 }
193 
195 {
196  PrintAttributes(std::cout, level);
197 }
198 #ifndef G__WIN32
199 #include <unistd.h>
200 #endif
202  const std::string& name,
203  const std::string& prototype,
204  bool isLinkdef) const
205 {
206  /* This method returns whether and how the declaration is matching the rule.
207  * It returns one of:
208  * kNoMatch : the rule does match the declaration
209  * kName : the rule match the declaration by name
210  * kPattern : the rule match the declaration via a pattern
211  * kFile : the declaration's file name is match by the rule (either by name or pattern).
212  * To check whether the rule is accepting or vetoing the declaration see the result of
213  * GetSelected().
214  (
215  * We pass as arguments of the method:
216  * name - the name of the Decl
217  * prototype - the prototype of the Decl (if it is function or method, otherwise "")
218  * file_name - name of the source file
219  * isLinkdef - if the selection rules were generating from a linkdef.h file
220  */
221 
222 
223  const std::string& name_value = fName;
224  const std::string& pattern_value = fPattern;
225 
226  // Check if we have in hands a typedef to a RecordDecl
227  const clang::CXXRecordDecl *D = llvm::dyn_cast<clang::CXXRecordDecl>(decl);
228  bool isTypedefNametoRecordDecl = false;
229 
230  if (!D){
231  //Either it's a CXXRecordDecl ot a TypedefNameDecl
232  const clang::TypedefNameDecl* typedefNameDecl = llvm::dyn_cast<clang::TypedefNameDecl> (decl);
233  isTypedefNametoRecordDecl = typedefNameDecl &&
234  ROOT::TMetaUtils::GetUnderlyingRecordDecl(typedefNameDecl->getUnderlyingType());
235  }
236 
237  if (! isTypedefNametoRecordDecl && fCXXRecordDecl !=0 && fCXXRecordDecl != (void*)-1) {
238  const clang::CXXRecordDecl *target = fCXXRecordDecl;
239  if ( target && D && target == D ) {
240  // fprintf(stderr,"DECL MATCH: %s %s\n",name_value.c_str(),name.c_str());
241  const_cast<BaseSelectionRule*>(this)->SetMatchFound(true);
242  return kName;
243  }
244  } else if (fHasNameAttribute) {
245  if (name_value == name) {
246  const_cast<BaseSelectionRule*>(this)->SetMatchFound(true);
247  return kName;
248  } else if ( fCXXRecordDecl != (void*)-1 ) {
249  // Try a real match!
250  const clang::CXXRecordDecl *target
251  = fHasFromTypedefAttribute ? nullptr : ROOT::TMetaUtils::ScopeSearch(name_value.c_str(), *fInterp,
252  true /*diagnose*/, 0);
253 
254  if ( target ) {
255  const_cast<BaseSelectionRule*>(this)->fCXXRecordDecl = target;
256  } else {
257  // If the lookup failed, let's not try it again, so mark the value has invalid.
258  const_cast<BaseSelectionRule*>(this)->fCXXRecordDecl = (clang::CXXRecordDecl*)-1;
259  }
260  if ( target && D && target == D ) {
261  const_cast<BaseSelectionRule*>(this)->SetMatchFound(true);
262  return kName;
263  }
264  }
265  }
266 
267  // do we have matching against the file_name (or file_pattern) attribute and if yes - select or veto
268  const std::string& file_name_value = fFileName;
269  const std::string& file_pattern_value = fFilePattern;
270 
272  const char *file_name = R__GetDeclSourceFileName(decl);
273  bool hasFileMatch = ((fHasFileNameAttribute &&
274  //FIXME It would be much better to cache the rule stat result and compare to the clang::FileEntry
275  (R__match_filename(file_name_value.c_str(),file_name))) ||
276  (fHasFilePatternAttribute && CheckPattern(file_name, file_pattern_value, fFileSubPatterns, isLinkdef)));
277 
278 #if MATCH_ON_INSTANTIATION_LOCATION
279  if (!hasFileMatch) {
280  const clang::ClassTemplateSpecializationDecl *tmpltDecl =
281  llvm::dyn_cast<clang::ClassTemplateSpecializationDecl>(decl);
282  // Try the instantiation point.
283  if (tmpltDecl) {
284  file_name = R__GetDeclSourceFileName(tmpltDecl);
285  hasFileMatch = ((HasAttributeFileName() &&
286  //FIXME It would be much better to cache the rule stat result and compare to the clang::FileEntry
287  (R__match_filename(file_name_value.c_str(),file_name)))
288  ||
290  CheckPattern(file_name, file_pattern_value, fFileSubPatterns, isLinkdef)));
291  }
292  }
293 #endif
294  if (hasFileMatch) {
295  // Reject utility classes defined in ClassImp
296  // when using a file based rule
297  if (!strncmp(name.c_str(), "R__Init", 7) ||
298  strstr(name.c_str(), "::R__Init")) {
299  return kNoMatch;
300  }
301  if (!name.compare(0, 24, "ROOT::R__dummyintdefault")) {
302  return kNoMatch;
303  }
304  if (!name.compare(0, 27, "ROOT::R__dummyVersionNumber")) {
305  return kNoMatch;
306  }
307  if (!name.compare(0, 22, "ROOT::R__dummyStreamer")) {
308  return kNoMatch;
309  }
310  if (name.find("(anonymous namespace)") != std::string::npos) {
311  // Reject items declared in anonymous namespace
312  return kNoMatch;
313  }
314  if (fHasPatternAttribute) {
315  if (CheckPattern(name, pattern_value, fSubPatterns, isLinkdef)) {
316  const_cast<BaseSelectionRule*>(this)->SetMatchFound(true);
317  return kPattern;
318  }
319  } else {
320  const_cast<BaseSelectionRule*>(this)->SetMatchFound(true);
321  return kName;
322  }
323  }
324 
325  // We have file_name or file_pattern attribute but the
326  // passed file_name is different than that in the selection rule then return no match
327  return kNoMatch;
328  }
329 
331  {
332  bool patternMatched = CheckPattern(name, pattern_value, fSubPatterns, isLinkdef);
333  if (!patternMatched && !isLinkdef) {
334  std::string auxName(name);
335  std::string &nameNoSpaces = auxName;
336  nameNoSpaces.erase(std::remove_if(nameNoSpaces.begin(), nameNoSpaces.end(), isspace),
337  nameNoSpaces.end());
338  if (name.size() != nameNoSpaces.size()) {
339  patternMatched = CheckPattern(nameNoSpaces, pattern_value, fSubPatterns, isLinkdef);
340  }
341 
342  // For ROOT-6704: use normalised name for matching if the class is in stl
343  // The reason for this check is that we have rules like std::map<*, int>
344  // We do not know how the internal representation of the innocuous "map"
345  // is. We therefore have to act on a nicer name, obtained with TClassEdit
346  // The check ROOT::TMetaUtils::IsStdDropDefaultClass is there to call
347  // TClassEdit only when necessary as it can be expensive, a performance
348  // optimisation.
349  if (!patternMatched &&
350  D &&
351  //ROOT::TMetaUtils::IsStdDropDefaultClass(*D)) {
352  0 != TClassEdit::IsSTLCont(name)) {
353  TClassEdit::GetNormalizedName(auxName, name.c_str());
354  if (name.size() != auxName.size()) {
355  auxName = TClassEdit::InsertStd(auxName.c_str());
356  patternMatched = CheckPattern(auxName, pattern_value, fSubPatterns, isLinkdef);
357  }
358  }
359 
360  }
361  if (patternMatched) {
362  const_cast<BaseSelectionRule *>(this)->SetMatchFound(true);
363  return kPattern;
364  }
365  }
366 
367 
368  // do we have matching against the proto_name (or proto_pattern) attribute and if yes - select or veto
369  // The following selects functions on whether the requested prototype exactly matches the
370  // prototype issued by SelectionRules::GetFunctionPrototype which relies on
371  // ParmVarDecl::getType()->getAsString()
372  // to get the type names. Currently, this does not print the prototype in the usual
373  // human (written) forms. For example:
374  // For Hash have prototype: '(const class TString &)'
375  // For Hash have prototype: '(const class TString*)'
376  // For Hash have prototype: '(const char*)'
377  // In addition, the const can legally be in various place in the type name and thus
378  // a string based match will be hard to work out (it would need to normalize both
379  // the user input string and the clang provided string).
380  // Using lookup form cling would be probably be a better choice.
381  if (!prototype.empty()) {
382  if (fHasProtoNameAttribute && fProtoName==prototype) {
383  const_cast<BaseSelectionRule*>(this)->SetMatchFound(true);
384  return kName;
385  }
386  if (fHasProtoPatternAttribute && CheckPattern(prototype, fProtoPattern, fSubPatterns, isLinkdef)) {
387  const_cast<BaseSelectionRule*>(this)->SetMatchFound(true);
388  return kPattern;
389  }
390  }
391 
392  return kNoMatch;
393 }
394 
395 
396 /*
397  * This method processes the pattern - which means that it splits it in a list of fSubPatterns.
398  * The idea is the following - if we have a pattern = "this*pat*rn", it will be split in the
399  * following list of subpatterns: "this", "pat", "rn". If we have "this*pat\*rn", it will be
400  * split in "this", "pat*rn", i.e. the star could be escaped.
401  */
402 
403 void BaseSelectionRule::ProcessPattern(const std::string& pattern, std::list<std::string>& out)
404 {
405  std::string temp = pattern;
406  std::string split;
407  int pos;
408  bool escape = false;
409 
410  if (pattern.size()==1 && pattern == "*"){
411  out.push_back("");
412  return;
413  }
414 
415  while (!temp.empty()){
416  pos = temp.find("*");
417  if (pos == -1) {
418  if (!escape){ // if we don't find a '*', push_back temp (contains the last sub-pattern)
419  out.push_back(temp);
420  // std::cout<<"1. pushed = "<<temp<<std::endl;
421  }
422  else { // if we don't find a star - add temp to split (in split we keep the previous sub-pattern + the last escaped '*')
423  split += temp;
424  out.push_back(split);
425  // std::cout<<"1. pushed = "<<split<<std::endl;
426  }
427  return;
428  }
429  else if (pos == 0) { // we have '*' at the beginning of the pattern; can't have '\' before the '*'
430  temp = temp.substr(1); // remove the '*'
431  }
432  else if (pos == (int)(temp.length()-1)) { // we have '*' at the end of the pattern
433  if (pos > 0 && temp.at(pos-1) == '\\') { // check if we have '\' before the '*'; if yes, we have to escape it
434  split += temp.substr(0, temp.length()-2); // add evrything from the beginning of temp till the '\' to split (where we keep the last sub-pattern)
435  split += temp.at(pos); // add the '*'
436  out.push_back(split); // push_back() split
437  // std::cout<<"3. pushed = "<<split<<std::endl;
438  temp.clear(); // empty temp (the '*' was at the last position of temp, so we don't have anything else to process)
439  }
440  temp = temp.substr(0, (temp.length()-1));
441  }
442  else { // the '*' is at a random position in the pattern
443  if (pos > 0 && temp.at(pos-1) == '\\') { // check if we have '\' before the '*'; if yes, we have to escape it
444  split += temp.substr(0, pos-1); // remove the '\' and add the star to split
445  split += temp.at(pos);
446  escape = true; // escape = true which means that we will add the next sub-pattern to that one
447 
448  // DEBUG std::cout<<"temp = "<<temp<<std::endl;
449  temp = temp.substr(pos);
450  // DEBUG std::cout<<"temp = "<<temp<<", split = "<<split<<std::endl;
451  }
452  else { // if we don't have '\' before the '*'
453  if (escape) {
454  split += temp.substr(0, pos);
455  }
456  else {
457  split = temp.substr(0, pos);
458  }
459  escape = false;
460  temp = temp.substr(pos);
461  out.push_back(split);
462  // std::cout<<"2. pushed = "<<split<<std::endl;
463  // DEBUG std::cout<<"temp = "<<temp<<std::endl;
464  split = "";
465  }
466  }
467  // DEBUG std::cout<<"temp = "<<temp<<std::endl;
468  }
469 }
470 
471 bool BaseSelectionRule::BeginsWithStar(const std::string& pattern) {
472  return pattern.at(0) == '*';
473 }
474 
475 bool BaseSelectionRule::EndsWithStar(const std::string& pattern) {
476  return pattern.at(pattern.length()-1) == '*';
477 }
478 
479 /*
480  * This method checks if the given test string is matched against the pattern
481  */
482 
483 bool BaseSelectionRule::CheckPattern(const std::string& test, const std::string& pattern, const std::list<std::string>& patterns_list, bool isLinkdef)
484 {
485  if (pattern.size() == 1 && pattern == "*" /* && patterns_list.back().size() == 0 */) {
486  // We have the simple pattern '*', it matches everything by definition!
487  return true;
488  }
489 
490  std::list<std::string>::const_iterator it = patterns_list.begin();
491  size_t pos1, pos2, pos3;
492  pos1= pos2= pos3= std::string::npos;
493  bool begin = BeginsWithStar(pattern);
494  bool end = EndsWithStar(pattern);
495 
496  // we first check if the last sub-pattern is contained in the test string
497  const std::string& last = patterns_list.back();
498  size_t pos_end = test.rfind(last);
499 
500  if (pos_end == std::string::npos) { // the last sub-pattern isn't conatained in the test string
501  return false;
502  }
503  if (!end) { // if the pattern doesn't end with '*', the match has to be complete
504  // i.e. if the last sub-pattern is "sub" the test string should end in "sub" ("1111sub" is OK, "1111sub1" is not OK)
505 
506  int len = last.length(); // length of last sub-pattern
507  if ((pos_end+len) < test.length()) {
508  return false;
509  }
510  }
511 
512  // position of the first sub-pattern
513  pos1 = test.find(*it);
514 
515 
516  if (pos1 == std::string::npos || (!begin && pos1 != 0)) { // if the first sub-pattern isn't found in test or if it is found but the
517  // pattern doesn't start with '*' and the sub-pattern is not at the first position
518  //std::cout<<"\tNo match!"<<std::endl;
519  return false;
520  }
521 
522  if (isLinkdef) { // A* selects all global classes, unions, structs but not the nested, i.e. not A::B
523  // A::* selects the nested classes
524  int len = (*it).length();
525  int pos_colon = test.find("::", pos1+len);
526 
527  if (pos_colon > -1) {
528  return false;
529  }
530 
531  }
532 
533  if (patterns_list.size() > 1) {
534  if (((*it).length())+pos1 > pos_end) {
535  // std::cout<<"\tNo match";
536  return false; // end is contained in begin -> test = "A::B" sub-patterns = "A::", "::" will return false
537  }
538  }
539 
540 
541  ++it;
542 
543  for (; it != patterns_list.end(); ++it) {
544  // std::cout<<"sub-pattern = "<<*it<<std::endl;
545  pos2 = test.find(*it);
546  if (pos2 <= pos1) {
547  return false;
548  }
549  pos1 = pos2;
550  }
551 
552  return true;
553 }
554 
555 
557 {
558  fMatchFound = match;
559 }
560 
562 {
563  return fMatchFound;
564 }
565 
567 {
568  return fRequestedType;
569 }
570 
571 void BaseSelectionRule::SetCXXRecordDecl(const clang::CXXRecordDecl *decl, const clang::Type *typeptr)
572 {
573  fCXXRecordDecl = decl;
574  fRequestedType = typeptr;
575 }
576 
578 {
579  std::string value;
586  fHasFromTypedefAttribute = GetAttributeValue("fromTypedef",value);
587  fIsFromTypedef = (value == "true");
588 
590 
591 
593  if (fSubPatterns.empty()) {
594  std::cout<<"Error - A pattern selection without sub patterns." <<std::endl;
595  }
596  }
597 
598 }
599 
600 
static const std::string nArgsToKeep("nArgsToKeep")
const AttributesMap_t & GetAttributes() const
ROOT::ESTLType IsSTLCont(std::string_view type)
type : type name: vector,allocator> result: 0 : not stl container code of cont...
ClassImp(TAlienJobStatusList) void TAlienJobStatusList TString split(jobstatus->GetKey("split"))
Print information about jobs.
bool GetAttributeValue(const std::string &attributeName, std::string &returnValue) const
cling::Interpreter * gInterp
void PrintAttributes(int level) const
std::string fNArgsToKeep
clang::RecordDecl * GetUnderlyingRecordDecl(clang::QualType type)
std::list< std::string > fSubPatterns
static const char * filename()
std::list< std::string > fFileSubPatterns
std::string InsertStd(const char *tname)
const clang::Type * fRequestedType
bool GetMatchFound() const
std::string fFilePattern
static bool BeginsWithStar(const std::string &pattern)
ClassImp(TIterator) Bool_t TIterator return false
Compare two iterator objects.
Definition: TIterator.cxx:20
static const char * R__GetDeclSourceFileName(const clang::Decl *D)
bool HasAttributeWithName(const std::string &attributeName) const
const clang::CXXRecordDecl * R__ScopeSearch(const char *name, const cling::Interpreter &gInterp, const clang::Type **resultType=0)
std::map< std::string, std::string >::const_iterator iter
Definition: TAlienJob.cxx:54
virtual void DebugPrint() const
virtual void Print(std::ostream &out) const =0
static const std::string pattern("pattern")
static bool CheckPattern(const std::string &test, const std::string &pattern, const std::list< std::string > &patterns_list, bool isLinkdef)
static bool EndsWithStar(const std::string &pattern)
char * out
Definition: TBase64.cxx:29
bool HasAttributeFilePattern() const
const clang::Type * GetRequestedType() const
AttributesMap_t fAttributes
std::string fProtoPattern
void GetNormalizedName(std::string &norm_name, std::string_view name)
Return the normalized name.
Definition: TClassEdit.cxx:787
const clang::CXXRecordDecl * ScopeSearch(const char *name, const cling::Interpreter &gInterp, bool diagnose, const clang::Type **resultType)
Return the scope corresponding to 'name' or std::'name'.
Definition: TMetaUtils.cxx:710
static bool R__match_filename(const char *srcname, const char *filename)
std::unordered_map< std::string, std::string > AttributesMap_t
bool HasAttributeFileName() const
ESelect GetSelected() const
Type
enumeration specifying the integration types.
EMatchType Match(const clang::NamedDecl *decl, const std::string &name, const std::string &prototype, bool isLinkdef) const
cling::Interpreter * fInterp
void SetSelected(ESelect sel)
BaseSelectionRule(ESelect sel)
#define name(a, b)
Definition: linkTestLib0.cpp:5
void SetAttributeValue(const std::string &attributeName, const std::string &attributeValue)
std::string fProtoName
void SetCXXRecordDecl(const clang::CXXRecordDecl *decl, const clang::Type *typeptr)
void SetMatchFound(bool match)
const clang::CXXRecordDecl * fCXXRecordDecl
float value
Definition: math.cpp:443
static void ProcessPattern(const std::string &pattern, std::list< std::string > &out)