24 #define fnmatch(glob, path, dummy) PathMatchSpecA(path, glob);
28 #include "llvm/Support/raw_ostream.h"
29 #include "clang/Basic/SourceLocation.h"
30 #include "clang/Basic/SourceManager.h"
31 #include "clang/AST/ASTContext.h"
32 #include "clang/AST/DeclCXX.h"
33 #include "clang/AST/DeclTemplate.h"
35 #include "cling/Interpreter/Interpreter.h"
37 const clang::CXXRecordDecl *R__ScopeSearch(
const char *name,
const clang::Type** resultType = 0) ;
39 void SelectionRules::AddClassSelectionRule(
const ClassSelectionRule& classSel)
42 fClassSelectionRules.push_front(classSel);
43 if (!classSel.HasInterpreter())
44 fClassSelectionRules.begin()->SetInterpreter(fInterp);
45 if (classSel.GetIndex() < 0)
46 fClassSelectionRules.begin()->SetIndex(fRulesCounter);
49 void SelectionRules::AddFunctionSelectionRule(
const FunctionSelectionRule& funcSel)
52 fFunctionSelectionRules.push_back(funcSel);
53 if (!funcSel.HasInterpreter())
54 fFunctionSelectionRules.begin()->SetInterpreter(fInterp);
55 if (funcSel.GetIndex() < 0)
56 fFunctionSelectionRules.begin()->SetIndex(fRulesCounter);
59 void SelectionRules::AddVariableSelectionRule(
const VariableSelectionRule& varSel)
62 fVariableSelectionRules.push_back(varSel);
63 if (!varSel.HasInterpreter())
64 fVariableSelectionRules.begin()->SetInterpreter(fInterp);
65 if (varSel.GetIndex() < 0)
66 fVariableSelectionRules.begin()->SetIndex(fRulesCounter);
69 void SelectionRules::AddEnumSelectionRule(
const EnumSelectionRule& enumSel)
72 fEnumSelectionRules.push_back(enumSel);
73 if (!enumSel.HasInterpreter())
74 fEnumSelectionRules.begin()->SetInterpreter(fInterp);
75 if (enumSel.GetIndex() < 0)
76 fEnumSelectionRules.begin()->SetIndex( fRulesCounter );
79 void SelectionRules::PrintSelectionRules()
const
81 std::cout<<
"Printing Selection Rules:"<<std::endl;
82 if (!fClassSelectionRules.empty()) {
84 for(std::list<ClassSelectionRule>::const_iterator it = fClassSelectionRules.begin();
85 it != fClassSelectionRules.end(); ++it, ++i) {
86 std::cout<<
"\tClass sel rule "<<i<<
":"<<std::endl;
91 std::cout<<
"\tNo Class Selection Rules"<<std::endl;
94 if (!fFunctionSelectionRules.empty()) {
96 std::list<FunctionSelectionRule>::const_iterator it2;
99 for (it2 = fFunctionSelectionRules.begin(); it2 != fFunctionSelectionRules.end(); ++it2, ++i) {
100 std::cout<<
"\tFunction sel rule "<<i<<
":"<<std::endl;
101 std::cout<<
"\t\tSelected: ";
102 switch(it2->GetSelected()){
103 case BaseSelectionRule::kYes: std::cout<<
"Yes"<<std::endl;
105 case BaseSelectionRule::kNo: std::cout<<
"No"<<std::endl;
107 case BaseSelectionRule::kDontCare: std::cout<<
"Don't Care"<<std::endl;
109 default: std::cout<<
"Unspecified"<<std::endl;
111 it2->PrintAttributes(std::cout,2);
115 std::cout<<
"\tNo function sel rules"<<std::endl;
118 if (!fVariableSelectionRules.empty()) {
119 std::list<VariableSelectionRule>::const_iterator it3;
122 for (it3 = fVariableSelectionRules.begin(); it3 != fVariableSelectionRules.end(); ++it3, ++i) {
123 std::cout<<
"\tVariable sel rule "<<i<<
":"<<std::endl;
124 std::cout<<
"\t\tSelected: ";
125 switch(it3->GetSelected()){
126 case BaseSelectionRule::kYes: std::cout<<
"Yes"<<std::endl;
128 case BaseSelectionRule::kNo: std::cout<<
"No"<<std::endl;
130 case BaseSelectionRule::kDontCare: std::cout<<
"Don't Care"<<std::endl;
132 default: std::cout<<
"Unspecified"<<std::endl;
134 it3->PrintAttributes(std::cout,2);
138 std::cout<<
"\tNo variable sel rules"<<std::endl;
141 if (!fEnumSelectionRules.empty()) {
142 std::list<EnumSelectionRule>::const_iterator it4;
145 for (it4 = fEnumSelectionRules.begin(); it4 != fEnumSelectionRules.end(); ++it4, ++i) {
146 std::cout<<
"\tEnum sel rule "<<i<<
":"<<std::endl;
147 std::cout<<
"\t\tSelected: ";
148 switch(it4->GetSelected()){
149 case BaseSelectionRule::kYes: std::cout<<
"Yes"<<std::endl;
151 case BaseSelectionRule::kNo: std::cout<<
"No"<<std::endl;
153 case BaseSelectionRule::kDontCare: std::cout<<
"Don't Care"<<std::endl;
155 default: std::cout<<
"Unspecified"<<std::endl;
157 it4->PrintAttributes(std::cout,2);
161 std::cout<<
"\tNo enum sel rules"<<std::endl;
165 void SelectionRules::ClearSelectionRules()
167 fClassSelectionRules.clear();
168 fFunctionSelectionRules.clear();
169 fVariableSelectionRules.clear();
170 fEnumSelectionRules.clear();
174 static bool HasDuplicate(RULE* rule,
175 std::unordered_map<std::string,RULE*>& storedRules,
176 const std::string& attrName){
177 auto itRetCodePair = storedRules.emplace( attrName, rule );
179 auto storedRule = storedRules[attrName];
181 if (itRetCodePair.second ||
182 storedRule->GetSelected() != rule->GetSelected())
return false;
183 auto areEqual = SelectionRulesUtils::areEqual(storedRule,rule);
185 std::stringstream sstr; sstr <<
"Rule:\n";
187 sstr << (areEqual ?
"Identical " :
"Conflicting ");
188 sstr <<
"rule already stored:\n";
189 storedRule->Print(sstr);
190 ROOT::TMetaUtils::Warning(
"SelectionRules::CheckDuplicates",
191 "Duplicated rule found.\n%s",sstr.str().c_str());
195 template<
class RULESCOLLECTION,
class RULE =
typename RULESCOLLECTION::value_type>
196 static int CheckDuplicatesImp(RULESCOLLECTION& rules){
198 std::unordered_map<std::string, RULE*> patterns,names;
199 for (
auto&& rule : rules){
200 if (rule.HasAttributeName() && HasDuplicate(&rule,names,rule.GetAttributeName())) nDuplicates++;
201 if (rule.HasAttributePattern() && HasDuplicate(&rule,patterns,rule.GetAttributePattern())) nDuplicates++;
206 int SelectionRules::CheckDuplicates(){
209 nDuplicates += CheckDuplicatesImp(fClassSelectionRules);
210 nDuplicates += CheckDuplicatesImp(fFunctionSelectionRules);
211 nDuplicates += CheckDuplicatesImp(fVariableSelectionRules);
212 nDuplicates += CheckDuplicatesImp(fEnumSelectionRules);
213 if (0 != nDuplicates){
214 ROOT::TMetaUtils::Error(
"SelectionRules::CheckDuplicates",
215 "Duplicates in rules were found.\n");
220 static bool Implies(
const ClassSelectionRule& patternRule,
const ClassSelectionRule& nameRule){
223 if (patternRule.GetSelected() != nameRule.GetSelected())
return false;
226 auto nAttrsPattern = patternRule.GetAttributes().size();
227 auto nAttrsName = nameRule.GetAttributes().size();
228 if ((nAttrsPattern != 1 || nAttrsName !=1) &&
229 !SelectionRulesUtils::areEqual(&patternRule, &nameRule,
true )) {
233 auto pattern = patternRule.GetAttributePattern().c_str();
234 auto name = nameRule.GetAttributeName().c_str();
237 auto implies = 0 == fnmatch(pattern, name, FNM_PATHNAME);
240 static const auto msg =
"The pattern rule %s matches the name rule %s. "
241 "Since the name rule has compatible attributes, "
242 "it will be removed: the pattern rule will match the necessary classes if needed.\n";
244 ROOT::TMetaUtils::Info(
"SelectionRules::Optimize", msg, pattern, name);
252 void SelectionRules::Optimize(){
256 if (!IsSelectionXMLFile())
return;
258 const auto& selectionRules = fClassSelectionRules;
260 auto predicate = [&selectionRules](
const ClassSelectionRule &rule) ->
bool {
261 if (rule.HasAttributeName()) {
262 for (
auto&& intRule : selectionRules){
263 if (intRule.HasAttributePattern() && Implies(intRule, rule)) {
270 fClassSelectionRules.remove_if(predicate);
273 const ClassSelectionRule *SelectionRules::IsDeclSelected(
const clang::RecordDecl *D)
const
275 std::string qual_name;
276 GetDeclQualName(D,qual_name);
277 return IsClassSelected(D, qual_name);
280 const ClassSelectionRule *SelectionRules::IsDeclSelected(
const clang::TypedefNameDecl *D)
const
282 std::string qual_name;
283 GetDeclQualName(D,qual_name);
284 return IsClassSelected(D, qual_name);
287 const ClassSelectionRule *SelectionRules::IsDeclSelected(
const clang::NamespaceDecl *D)
const
289 std::string qual_name;
290 GetDeclQualName(D,qual_name);
291 return IsNamespaceSelected(D, qual_name);
294 const BaseSelectionRule *SelectionRules::IsDeclSelected(
const clang::EnumDecl *D)
const
306 #if defined(R__MUST_REVISIT)
307 # if R__MUST_REVISIT(6,4)
308 "Can become no-op once PCMs are available."
312 std::string str_name;
313 std::string qual_name;
314 GetDeclName(D, str_name, qual_name);
316 if (IsParentClass(D)) {
317 const BaseSelectionRule *selector = IsMemberSelected(D, str_name);
319 return IsEnumSelected(D, qual_name);
327 return IsLinkdefEnumSelected(D, qual_name);
328 return IsEnumSelected(D, qual_name);
334 const BaseSelectionRule *SelectionRules::IsDeclSelected(
const clang::VarDecl* D)
const
336 std::string qual_name;
337 GetDeclQualName(D, qual_name);
340 return IsLinkdefVarSelected(D, qual_name);
342 return IsVarSelected(D, qual_name);
346 const BaseSelectionRule *SelectionRules::IsDeclSelected(
const clang::FieldDecl* )
const
351 std::string str_name;
352 std::string qual_name;
353 GetDeclName(D, str_name, qual_name);
355 return IsMemberSelected(D, str_name);
359 const BaseSelectionRule *SelectionRules::IsDeclSelected(
const clang::FunctionDecl* D)
const
362 std::string qual_name;
363 GetDeclQualName(D, qual_name);
365 return IsLinkdefFunSelected(D, qual_name);
367 return IsFunSelected(D, qual_name);
370 const BaseSelectionRule *SelectionRules::IsDeclSelected(
const clang::Decl *D)
const
376 clang::Decl::Kind declkind = D->getKind();
379 case clang::Decl::CXXRecord:
380 case clang::Decl::ClassTemplateSpecialization:
381 case clang::Decl::ClassTemplatePartialSpecialization:
383 return IsDeclSelected(llvm::dyn_cast<clang::RecordDecl>(D));
384 case clang::Decl::Namespace:
385 return IsDeclSelected(llvm::dyn_cast<clang::NamespaceDecl>(D));
386 case clang::Decl::Enum:
388 return IsDeclSelected(llvm::dyn_cast<clang::EnumDecl>(D));
389 case clang::Decl::Var:
390 return IsDeclSelected(llvm::dyn_cast<clang::VarDecl>(D));
391 #if ROOTCLING_NEEDS_FUNCTIONS_SELECTION
392 case clang::Decl::Function:
393 return IsDeclSelected(llvm::dyn_cast<clang::FunctionDecl>(D));
394 case clang::Decl::CXXMethod:
395 case clang::Decl::CXXConstructor:
396 case clang::Decl::CXXDestructor: {
402 std::string str_name;
403 std::string qual_name;
404 GetDeclName(D, str_name, qual_name);
405 if (IsLinkdefFile()) {
406 return IsLinkdefMethodSelected(D, qual_name);
408 return IsMemberSelected(D, str_name);
411 case clang::Decl::Field:
412 return IsDeclSelected(llvm::dyn_cast<clang::FieldDecl>(D));
425 bool SelectionRules::GetDeclName(
const clang::Decl* D, std::string& name, std::string& qual_name)
const
427 const clang::NamedDecl* N = llvm::dyn_cast<clang::NamedDecl> (D);
433 if (N->getIdentifier()) {
434 name = N->getNameAsString();
436 else if (N->isCXXClassMember()) {
437 name = N->getNameAsString();
439 llvm::raw_string_ostream stream(qual_name);
440 N->getNameForDiagnostic(stream,N->getASTContext().getPrintingPolicy(),
true);
444 void SelectionRules::GetDeclQualName(
const clang::Decl* D, std::string& qual_name)
const{
445 const clang::NamedDecl* N =
static_cast<const clang::NamedDecl*
> (D);
446 llvm::raw_string_ostream stream(qual_name);
447 N->getNameForDiagnostic(stream,N->getASTContext().getPrintingPolicy(),
true);
450 bool SelectionRules::GetFunctionPrototype(
const clang::FunctionDecl* F, std::string& prototype)
const {
456 const std::vector<std::string> quals={
"*",
"&"};
461 for (
auto I = F->param_begin(), E = F->param_end(); I != E; ++I) {
463 clang::ParmVarDecl* P = *I;
468 ROOT::TMetaUtils::GetNormalizedName(type,P->getType(),fInterp,fNormCtxt);
471 ROOT::TMetaUtils::ReplaceAll(type,
"class ",
"");
473 ROOT::TMetaUtils::ReplaceAll(type,
"restrict",
"");
477 for (
auto& qual : quals){
478 auto pos = type.find(
" "+qual);
479 if (pos != std::string::npos)
480 type.replace( pos, 2, qual );
490 prototype =
"(" + prototype +
")";
496 bool SelectionRules::IsParentClass(
const clang::Decl* D)
const
499 if (
const clang::TagDecl* T
500 = llvm::dyn_cast<clang::TagDecl>(D->getDeclContext()))
501 return T->isClass() || T->isStruct();
506 bool SelectionRules::IsParentClass(
const clang::Decl* D, std::string& parent_name, std::string& parent_qual_name)
const
508 if (
const clang::TagDecl* parent
509 = llvm::dyn_cast<clang::TagDecl>(D->getDeclContext())) {
510 if (parent->isClass()|| parent->isStruct()) {
511 GetDeclName(parent, parent_name, parent_qual_name);
518 bool SelectionRules::GetParentName(
const clang::Decl* D, std::string& parent_name, std::string& parent_qual_name)
const
520 if (
const clang::RecordDecl* parent
521 = llvm::dyn_cast<clang::RecordDecl>(D->getDeclContext())) {
522 GetDeclName(parent, parent_name, parent_qual_name);
566 const ClassSelectionRule *SelectionRules::IsNamespaceSelected(
const clang::Decl* D,
const std::string& qual_name)
const
568 const clang::NamespaceDecl* N = llvm::dyn_cast<clang::NamespaceDecl> (D);
570 std::cout<<
"\n\tCouldn't cast Decl to NamespaceDecl";
574 const ClassSelectionRule *selector = 0;
576 const ClassSelectionRule *explicit_selector = 0;
577 const ClassSelectionRule *specific_pattern_selector = 0;
581 std::list<ClassSelectionRule>::const_iterator it = fClassSelectionRules.begin();
583 std::string name_value;
584 std::string pattern_value;
585 BaseSelectionRule::EMatchType match;
586 for(; it != fClassSelectionRules.end(); ++it) {
588 match = it->Match(N,qual_name,
"",IsLinkdefFile());
590 if (match != BaseSelectionRule::kNoMatch) {
592 if (it->GetSelected() == BaseSelectionRule::kYes) {
594 if (IsLinkdefFile()){
596 if (match == BaseSelectionRule::kName) {
597 explicit_selector = &(*it);
598 }
else if (match == BaseSelectionRule::kPattern) {
600 if (it->GetAttributeValue(
"pattern", pattern_value) &&
601 pattern_value !=
"*" && pattern_value !=
"*::*") specific_pattern_selector = &(*it);
604 }
else if (it->GetSelected() == BaseSelectionRule::kNo) {
605 if (!IsLinkdefFile()) {
607 if (match == BaseSelectionRule::kFile) ++fFileNo;
610 #ifdef SELECTION_DEBUG
611 std::cout<<
"\tNo returned"<<std::endl;
617 if (match == BaseSelectionRule::kPattern) {
619 if (it->GetAttributeValue(
"pattern", pattern_value) &&
620 (pattern_value ==
"*" || pattern_value ==
"*::*")) ++fImplNo;
627 else if (it->GetSelected() == BaseSelectionRule::kDontCare && !(it->HasMethodSelectionRules()) && !(it->HasFieldSelectionRules())) {
629 #ifdef SELECTION_DEBUG
630 std::cout<<
"Empty dontC returned = No"<<std::endl;
637 if (IsLinkdefFile()) {
640 #ifdef SELECTION_DEBUG
641 std::cout<<
"\n\tfYes = "<<fYes<<
", fImplNo = "<<fImplNo<<std::endl;
644 if (explicit_selector)
return explicit_selector;
645 else if (specific_pattern_selector)
return specific_pattern_selector;
646 else if (fImplNo > 0)
return 0;
647 else return selector;
652 #ifdef SELECTION_DEBUG
653 std::cout<<
"\n\tfYes = "<<fYes<<
", fFileNo = "<<fFileNo<<std::endl;
665 const ClassSelectionRule *SelectionRules::IsClassSelected(
const clang::Decl* D,
const std::string& qual_name)
const
667 const clang::TagDecl* tagDecl = llvm::dyn_cast<clang::TagDecl> (D);
668 const clang::TypedefNameDecl* typeDefNameDecl = llvm::dyn_cast<clang::TypedefNameDecl> (D);
670 if (!tagDecl && !typeDefNameDecl) {
671 ROOT::TMetaUtils::Error(
"SelectionRules::IsClassSelected",
672 "Cannot cast Decl to TagDecl and Decl is not a typedef.\n");
676 if (!tagDecl && typeDefNameDecl){
677 clang::RecordDecl* recordDecl = ROOT::TMetaUtils::GetUnderlyingRecordDecl(typeDefNameDecl->getUnderlyingType());
679 ROOT::TMetaUtils::Error(
"SelectionRules::IsClassSelected",
680 "Cannot get RecordDecl behind TypedefDecl.\n");
683 tagDecl = recordDecl;
687 const bool isLinkDefFile = IsLinkdefFile();
688 if (!( isLinkDefFile || tagDecl->isClass() || tagDecl->isStruct() ))
691 const ClassSelectionRule *selector = 0;
693 const ClassSelectionRule *explicit_selector = 0;
694 const ClassSelectionRule *specific_pattern_selector = 0;
698 bool earlyReturn=
false;
699 const ClassSelectionRule* retval =
nullptr;
700 const clang::NamedDecl* nDecl(llvm::dyn_cast<clang::NamedDecl>(D));
701 for(
auto& rule : fClassSelectionRules) {
702 BaseSelectionRule::EMatchType match = rule.Match(nDecl, qual_name,
"", isLinkDefFile);
703 if (match != BaseSelectionRule::kNoMatch) {
705 if (
const clang::ClassTemplateSpecializationDecl* ctsd =
706 llvm::dyn_cast_or_null<clang::ClassTemplateSpecializationDecl>(D))
707 if(
const clang::ClassTemplateDecl* ctd = ctsd->getSpecializedTemplate()){
708 const std::string& nArgsToKeep = rule.GetAttributeNArgsToKeep();
709 if (!nArgsToKeep.empty()){
710 fNormCtxt.AddTemplAndNargsToKeep(ctd->getCanonicalDecl(),
711 std::atoi(nArgsToKeep.c_str()));
715 if (earlyReturn)
continue;
719 if (rule.GetSelected() == BaseSelectionRule::kYes) {
723 if (match == BaseSelectionRule::kName) {
724 explicit_selector = &(rule);
725 }
else if (match == BaseSelectionRule::kPattern) {
727 const std::string& pattern_value=rule.GetAttributePattern();
728 if (!pattern_value.empty() &&
729 pattern_value !=
"*" &&
730 pattern_value !=
"*::*") specific_pattern_selector = &(rule);
733 }
else if (rule.GetSelected() == BaseSelectionRule::kNo) {
735 if (!isLinkDefFile) {
737 if (match == BaseSelectionRule::kFile) ++fFileNo;
743 if (match == BaseSelectionRule::kPattern) {
745 const std::string& pattern_value=rule.GetAttributePattern();
746 if (!pattern_value.empty() &&
747 (pattern_value ==
"*" || pattern_value ==
"*::*")) ++fImplNo;
754 else if (rule.GetSelected() == BaseSelectionRule::kDontCare && !(rule.HasMethodSelectionRules()) && !(rule.HasFieldSelectionRules())) {
760 if (earlyReturn)
return retval;
764 if (explicit_selector)
return explicit_selector;
765 else if (specific_pattern_selector)
return specific_pattern_selector;
766 else if (fImplNo > 0)
return 0;
767 else return selector;
776 const BaseSelectionRule *SelectionRules::IsVarSelected(
const clang::VarDecl* D,
const std::string& qual_name)
const
778 std::list<VariableSelectionRule>::const_iterator it = fVariableSelectionRules.begin();
779 std::list<VariableSelectionRule>::const_iterator it_end = fVariableSelectionRules.end();
781 const BaseSelectionRule *selector = 0;
786 for(; it != it_end; ++it) {
787 if (BaseSelectionRule::kNoMatch != it->Match(llvm::dyn_cast<clang::NamedDecl>(D), qual_name,
"",
false)) {
788 if (it->GetSelected() == BaseSelectionRule::kNo) {
800 const BaseSelectionRule *SelectionRules::IsFunSelected(
const clang::FunctionDecl *D,
const std::string &qual_name)
const
803 if (fFunctionSelectionRules.size() == 0 ||
804 D->getPrimaryTemplate() !=
nullptr ||
805 llvm::isa<clang::CXXMethodDecl>(D))
return nullptr;
807 std::string prototype;
808 GetFunctionPrototype(D, prototype);
809 prototype = qual_name + prototype;
811 const BaseSelectionRule *selector =
nullptr;
815 for (
const auto & rule : fFunctionSelectionRules) {
816 if (BaseSelectionRule::kNoMatch != rule.Match(D, qual_name, prototype,
false)) {
817 if (rule.GetSelected() == BaseSelectionRule::kNo) {
829 const BaseSelectionRule *SelectionRules::IsEnumSelected(
const clang::EnumDecl* D,
const std::string& qual_name)
const
831 const BaseSelectionRule *selector = 0;
836 for(
const auto& rule: fEnumSelectionRules) {
837 if (BaseSelectionRule::kNoMatch != rule.Match(llvm::dyn_cast<clang::NamedDecl>(D), qual_name,
"",
false)) {
838 if (rule.GetSelected() == BaseSelectionRule::kNo) {
850 const BaseSelectionRule *SelectionRules::IsLinkdefVarSelected(
const clang::VarDecl* D,
const std::string& qual_name)
const
854 const BaseSelectionRule *selector = 0;
856 const BaseSelectionRule *explicit_selector = 0;
858 std::string name_value;
859 std::string pattern_value;
860 for(
auto& selRule: fVariableSelectionRules) {
861 BaseSelectionRule::EMatchType match
862 = selRule.Match(llvm::dyn_cast<clang::NamedDecl>(D), qual_name,
"",
false);
863 if (match != BaseSelectionRule::kNoMatch) {
864 if (selRule.GetSelected() == BaseSelectionRule::kYes) {
866 if (IsLinkdefFile()){
867 if (match == BaseSelectionRule::kName) {
868 explicit_selector = &selRule;
869 }
else if (match == BaseSelectionRule::kPattern) {
870 if (selRule.GetAttributeValue(
"pattern", pattern_value)) {
871 explicit_selector=&selRule;
879 if (!IsLinkdefFile())
return 0;
881 if (selRule.GetAttributeValue(
"pattern", pattern_value)) {
882 if (pattern_value ==
"*" || pattern_value ==
"*::*") ++fImplNo;
893 if (IsLinkdefFile()) {
895 #ifdef SELECTION_DEBUG
896 std::cout<<
"\n\tfYes = "<<fYes<<
", fImplNo = "<<fImplNo<<std::endl;
899 if (explicit_selector)
return explicit_selector;
900 else if (fImplNo > 0)
return 0;
901 else return selector;
908 const BaseSelectionRule *SelectionRules::IsLinkdefFunSelected(
const clang::FunctionDecl* D,
const std::string& qual_name)
const
911 if (fFunctionSelectionRules.size() == 0 ||
912 D->getPrimaryTemplate() !=
nullptr ||
913 llvm::isa<clang::CXXMethodDecl>(D))
return nullptr;
915 std::string prototype;
917 GetFunctionPrototype(D, prototype);
918 prototype = qual_name + prototype;
920 const BaseSelectionRule *selector = 0;
922 const BaseSelectionRule *explicit_selector = 0;
924 std::string pattern_value;
925 for(
auto& selRule : fFunctionSelectionRules) {
926 BaseSelectionRule::EMatchType match
927 = selRule.Match(llvm::dyn_cast<clang::NamedDecl>(D), qual_name, prototype,
false);
928 if (match != BaseSelectionRule::kNoMatch) {
929 if (selRule.GetSelected() == BaseSelectionRule::kYes) {
931 if (IsLinkdefFile()){
932 if (match == BaseSelectionRule::kName) {
933 explicit_selector = &selRule;
934 }
else if (match == BaseSelectionRule::kPattern) {
935 if (selRule.GetAttributeValue(
"pattern", pattern_value)) {
936 explicit_selector = &selRule;
944 if (!IsLinkdefFile())
return 0;
946 if (selRule.GetAttributeValue(
"pattern", pattern_value)) {
947 if (pattern_value ==
"*" || pattern_value ==
"*::*") ++fImplNo;
958 if (IsLinkdefFile()) {
959 if (explicit_selector)
return explicit_selector;
960 else if (fImplNo > 0)
return 0;
961 else return selector;
968 const BaseSelectionRule *SelectionRules::IsLinkdefEnumSelected(
const clang::EnumDecl* D,
const std::string& qual_name)
const
970 std::list<VariableSelectionRule>::const_iterator it;
971 std::list<VariableSelectionRule>::const_iterator it_end;
973 it = fEnumSelectionRules.begin();
974 it_end = fEnumSelectionRules.end();
976 const BaseSelectionRule *selector = 0;
978 const BaseSelectionRule *explicit_selector = 0;
980 std::string name_value;
981 std::string pattern_value;
982 for(; it != it_end; ++it) {
983 BaseSelectionRule::EMatchType match =
984 it->Match(llvm::dyn_cast<clang::NamedDecl>(D), qual_name,
"",
false);
985 if (match != BaseSelectionRule::kNoMatch) {
986 if (it->GetSelected() == BaseSelectionRule::kYes) {
988 if (IsLinkdefFile()){
989 if (match == BaseSelectionRule::kName){
990 explicit_selector = &(*it);
991 }
else if (match == BaseSelectionRule::kPattern &&
992 it->GetAttributeValue(
"pattern", pattern_value)) {
994 if (pattern_value !=
"*" && pattern_value !=
"*::*") explicit_selector = &(*it);
999 if (!IsLinkdefFile())
return 0;
1001 if (it->GetAttributeValue(
"pattern", pattern_value)) {
1002 if (pattern_value ==
"*" || pattern_value ==
"*::*") ++fImplNo;
1013 if (IsLinkdefFile()) {
1015 #ifdef SELECTION_DEBUG
1016 std::cout<<
"\n\tfYes = "<<fYes<<
", fImplNo = "<<fImplNo<<std::endl;
1019 if (explicit_selector)
return explicit_selector;
1020 else if (fImplNo > 0)
return 0;
1021 else return selector;
1041 const BaseSelectionRule *SelectionRules::IsLinkdefMethodSelected(
const clang::Decl* D,
const std::string& qual_name)
const
1043 std::list<FunctionSelectionRule>::const_iterator it = fFunctionSelectionRules.begin();
1044 std::list<FunctionSelectionRule>::const_iterator it_end = fFunctionSelectionRules.end();
1045 std::string prototype;
1047 if (
const clang::FunctionDecl* F = llvm::dyn_cast<clang::FunctionDecl> (D))
1048 GetFunctionPrototype(F, prototype);
1049 prototype = qual_name + prototype;
1051 #ifdef SELECTION_DEBUG
1052 std::cout<<
"\tFunction prototype = "<<prototype<<std::endl;
1055 int expl_Yes = 0, impl_r_Yes = 0, impl_rr_Yes = 0;
1056 int impl_r_No = 0, impl_rr_No = 0;
1057 const BaseSelectionRule *explicit_r = 0;
1058 const BaseSelectionRule *implicit_r = 0;
1059 const BaseSelectionRule *implicit_rr = 0;
1061 if (D->getKind() == clang::Decl::CXXMethod){
1063 std::string pat_value;
1064 for(; it != it_end; ++it) {
1065 BaseSelectionRule::EMatchType match
1066 = it->Match(llvm::dyn_cast<clang::NamedDecl>(D), qual_name, prototype,
false);
1068 if (match == BaseSelectionRule::kName) {
1071 explicit_r = &(*it);
1072 if (it->GetSelected() == BaseSelectionRule::kYes) ++expl_Yes;
1075 #ifdef SELECTION_DEBUG
1076 std::cout<<
"\tExplicit rule BaseSelectionRule::kNo found"<<std::endl;
1082 }
else if (match == BaseSelectionRule::kPattern) {
1084 if (it->GetAttributeValue(
"pattern", pat_value)) {
1085 if (pat_value ==
"*")
continue;
1087 std::string par_name, par_qual_name;
1088 GetParentName(D, par_name, par_qual_name);
1089 std::string par_pat = par_qual_name +
"::*";
1091 if (pat_value == par_pat) {
1092 implicit_rr = &(*it);
1093 if (it->GetSelected() == BaseSelectionRule::kYes) {
1095 #ifdef SELECTION_DEBUG
1096 std::cout<<
"Implicit_rr rule ("<<pat_value<<
"), selected = "<<selected<<std::endl;
1103 #ifdef SELECTION_DEBUG
1104 std::cout<<
"Implicit_rr rule ("<<pat_value<<
"), selected = "<<selected<<std::endl;
1111 implicit_r = &(*it);
1112 if (it->GetSelected() == BaseSelectionRule::kYes) {
1114 #ifdef SELECTION_DEBUG
1115 std::cout<<
"Implicit_r rule ("<<pat_value<<
"), selected = "<<selected<<std::endl;
1122 #ifdef SELECTION_DEBUG
1123 std::cout<<
"Implicit_r rule ("<<pat_value<<
"), selected = "<<selected<<std::endl;
1135 #ifdef SELECTION_DEBUG
1136 std::cout<<
"\tExplicit rule BaseSelectionRule::BaseSelectionRule::kYes found"<<std::endl;
1141 else if (implicit_rr) {
1142 if (impl_rr_No > 0) {
1144 #ifdef SELECTION_DEBUG
1145 std::cout<<
"\tImplicit_rr rule BaseSelectionRule::kNo found"<<std::endl;
1152 #ifdef SELECTION_DEBUG
1153 std::cout<<
"\tImplicit_rr rule BaseSelectionRule::kYes found"<<std::endl;
1159 else if (implicit_r) {
1160 if (impl_r_No > 0) {
1162 #ifdef SELECTION_DEBUG
1163 std::cout<<
"\tImplicit_r rule BaseSelectionRule::kNo found"<<std::endl;
1170 #ifdef SELECTION_DEBUG
1171 std::cout<<
"\tImplicit_r rule BaseSelectionRule::kYes found"<<std::endl;
1179 #ifdef SELECTION_DEBUG
1180 std::cout<<
"\tChecking parent class rules"<<std::endl;
1185 std::string parent_name, parent_qual_name;
1186 if (!GetParentName(D, parent_name, parent_qual_name))
return 0;
1188 const BaseSelectionRule *selector = 0;
1190 const BaseSelectionRule *explicit_selector = 0;
1195 std::list<ClassSelectionRule>::const_iterator it = fClassSelectionRules.begin();
1196 std::string name_value;
1197 std::string pattern_value;
1198 for(; it != fClassSelectionRules.end(); ++it) {
1199 BaseSelectionRule::EMatchType match
1200 = it->Match(llvm::dyn_cast<clang::NamedDecl>(D), parent_qual_name,
"",
true);
1202 if (match != BaseSelectionRule::kNoMatch) {
1203 if (it->GetSelected() == BaseSelectionRule::kYes) {
1206 if (match == BaseSelectionRule::kName) {
1207 explicit_selector = &(*it);
1208 }
else if (match == BaseSelectionRule::kPattern) {
1209 if (it->GetAttributeValue(
"pattern", pattern_value)) {
1211 if (pattern_value !=
"*" && pattern_value !=
"*::*") explicit_selector = &(*it);
1217 if (it->GetAttributeValue(
"pattern", pattern_value)) {
1218 if (pattern_value ==
"*" || pattern_value ==
"*::*") ++fImplNo;
1228 #ifdef SELECTION_DEBUG
1229 std::cout<<
"\n\tfYes = "<<fYes<<
", fImplNo = "<<fImplNo<<std::endl;
1232 if (explicit_selector) {
1234 #ifdef SELECTION_DEBUG
1235 std::cout<<
"\tReturning Yes"<<std::endl;
1238 return explicit_selector;
1240 else if (fImplNo > 0) {
1241 #ifdef SELECTION_DEBUG
1242 std::cout<<
"\tReturning No"<<std::endl;
1249 #ifdef SELECTION_DEBUG
1250 std::cout<<
"\tReturning Yes"<<std::endl;
1261 const BaseSelectionRule *SelectionRules::IsMemberSelected(
const clang::Decl* D,
const std::string& str_name)
const
1263 std::string parent_name;
1264 std::string parent_qual_name;
1266 if (IsParentClass(D))
1268 if (!GetParentName(D, parent_name, parent_qual_name))
return 0;
1270 const BaseSelectionRule *selector = 0;
1272 const BaseSelectionRule *explicit_selector = 0;
1276 std::list<ClassSelectionRule>::const_iterator it = fClassSelectionRules.begin();
1277 std::string name_value;
1278 std::string pattern_value;
1279 for(; it != fClassSelectionRules.end(); ++it) {
1280 BaseSelectionRule::EMatchType match
1281 = it->Match(llvm::dyn_cast<clang::NamedDecl>(D), parent_qual_name,
"",
false);
1283 if (match != BaseSelectionRule::kNoMatch) {
1284 if (it->GetSelected() == BaseSelectionRule::kYes) {
1286 if (IsLinkdefFile()) {
1287 if (match == BaseSelectionRule::kName) {
1288 explicit_selector = &(*it);
1289 }
else if (match == BaseSelectionRule::kPattern) {
1290 if (it->GetAttributeValue(
"pattern", pattern_value)) {
1292 if (pattern_value !=
"*" && pattern_value !=
"*::*") explicit_selector = &(*it);
1296 }
else if (it->GetSelected() == BaseSelectionRule::kNo) {
1297 if (!IsLinkdefFile()) {
1298 if (match == BaseSelectionRule::kFile) ++fFileNo;
1301 #ifdef SELECTION_DEBUG
1302 std::cout<<
"\tNo returned"<<std::endl;
1309 if (match == BaseSelectionRule::kPattern && it->GetAttributeValue(
"pattern", pattern_value)) {
1310 if (pattern_value ==
"*" || pattern_value ==
"*::*") ++fImplNo;
1318 else if (it->GetSelected() == BaseSelectionRule::kDontCare)
1320 if (!it->HasMethodSelectionRules() && !it->HasFieldSelectionRules()) {
1322 #ifdef SELECTION_DEBUG
1323 std::cout<<
"\tNo fields and methods"<<std::endl;
1329 clang::Decl::Kind kind = D->getKind();
1330 if (kind == clang::Decl::Field || kind == clang::Decl::CXXMethod || kind == clang::Decl::CXXConstructor || kind == clang::Decl::CXXDestructor){
1331 std::list<VariableSelectionRule> members;
1332 std::list<VariableSelectionRule>::iterator mem_it;
1333 std::list<VariableSelectionRule>::iterator mem_it_end;
1334 std::string prototype;
1336 if (kind == clang::Decl::Field) {
1337 members = it->GetFieldSelectionRules();
1340 if (
const clang::FunctionDecl* F = llvm::dyn_cast<clang::FunctionDecl> (D)){
1341 GetFunctionPrototype(F, prototype);
1342 prototype = str_name + prototype;
1345 ROOT::TMetaUtils::Warning(
"",
"Warning: could not cast Decl to FunctionDecl\n");
1347 members = it->GetMethodSelectionRules();
1349 mem_it = members.begin();
1350 mem_it_end = members.end();
1351 for (; mem_it != mem_it_end; ++mem_it) {
1352 if (BaseSelectionRule::kName == mem_it->Match(llvm::dyn_cast<clang::NamedDecl>(D), str_name, prototype,
false)) {
1353 if (mem_it->GetSelected() == BaseSelectionRule::kNo)
return 0;
1362 if (IsLinkdefFile()) {
1364 #ifdef SELECTION_DEBUG
1365 std::cout<<
"\n\tfYes = "<<fYes<<
", fImplNo = "<<fImplNo<<std::endl;
1368 if (explicit_selector) {
1369 #ifdef SELECTION_DEBUG
1370 std::cout<<
"\tReturning Yes"<<std::endl;
1373 return explicit_selector;
1375 else if (fImplNo > 0) {
1377 #ifdef SELECTION_DEBUG
1378 std::cout<<
"\tReturning No"<<std::endl;
1385 #ifdef SELECTION_DEBUG
1386 std::cout<<
"\tReturning Yes"<<std::endl;
1402 bool SelectionRules::AreAllSelectionRulesUsed()
const {
1403 for(
auto&& rule : fClassSelectionRules){
1404 if (BaseSelectionRule::kNo!=rule.GetSelected() && !rule.GetMatchFound() ) {
1406 if (rule.GetAttributeValue(
"pattern", name)) {
1408 }
else if (rule.GetAttributeValue(
"name", name)) {
1413 std::string file_name_value;
1414 if (!rule.GetAttributeValue(
"file_name", file_name_value)) file_name_value.clear();
1416 if (!file_name_value.empty()) {
1421 const char* attrName =
"class";
1422 const char* attrVal =
nullptr;
1423 if (!name.empty()) attrVal = name.c_str();
1425 ROOT::TMetaUtils::Warning(0,
"Unused %s rule: %s\n", attrName, attrVal);
1429 for(
auto&& rule : fVariableSelectionRules){
1430 if (!rule.GetMatchFound() && !GetHasFileNameRule()) {
1432 if (rule.GetAttributeValue(
"pattern", name)) {
1434 }
else if (rule.GetAttributeValue(
"name", name)) {
1439 ROOT::TMetaUtils::Warning(
"",
"Unused variable rule: %s\n",name.c_str());
1441 rule.PrintAttributes(std::cout,3);
1446 #if defined(R__MUST_REVISIT)
1447 #if R__MUST_REVISIT(6,2)
1448 ROOT::TMetaUtils::Warning(
"SelectionRules::AreAllSelectionRulesUsed",
1449 "Warnings concerning non matching selection rules are suppressed. An action is to be taken.\n");
1483 #if Enums_rules_becomes_useful_for_rootcling
1484 for(
auto&& rule : fEnumSelectionRules){
1485 if (!rule.GetMatchFound() && !GetHasFileNameRule()) {
1487 if (rule.GetAttributeValue(
"pattern", name)) {
1489 }
else if (rule.GetAttributeValue(
"name", name)) {
1495 ROOT::TMetaUtils::Warning(
"",
"Unused enum rule: %s\n",name.c_str());
1498 rule.PrintAttributes(std::cout,3);
1506 bool SelectionRules::SearchNames(cling::Interpreter &interp)
1509 for(std::list<ClassSelectionRule>::iterator it = fClassSelectionRules.begin(),
1510 end = fClassSelectionRules.end();
1513 if (it->HasAttributeWithName(
"name")) {
1514 std::string name_value;
1515 it->GetAttributeValue(
"name", name_value);
1517 const clang::Type *typeptr = 0;
1518 const clang::CXXRecordDecl *target
1519 = ROOT::TMetaUtils::ScopeSearch(name_value.c_str(), interp,
1522 it->SetCXXRecordDecl(target,typeptr);
1530 void SelectionRules::FillCache()
1533 for (
auto& rule : fClassSelectionRules) rule.FillCache();
1534 for (
auto& rule : fFunctionSelectionRules) rule.FillCache();
1535 for (
auto& rule : fVariableSelectionRules) rule.FillCache();
1536 for (
auto& rule : fEnumSelectionRules) rule.FillCache();