22 #include "llvm/Support/raw_ostream.h" 23 #include "clang/Basic/SourceLocation.h" 24 #include "clang/Basic/SourceManager.h" 25 #include "clang/AST/ASTContext.h" 26 #include "clang/AST/DeclCXX.h" 27 #include "clang/AST/DeclTemplate.h" 29 #include "cling/Interpreter/Interpreter.h" 75 std::cout<<
"Printing Selection Rules:"<<std::endl;
80 std::cout<<
"\tClass sel rule "<<i<<
":"<<std::endl;
85 std::cout<<
"\tNo Class Selection Rules"<<std::endl;
90 std::list<FunctionSelectionRule>::const_iterator it2;
94 std::cout<<
"\tFunction sel rule "<<i<<
":"<<std::endl;
95 std::cout<<
"\t\tSelected: ";
96 switch(it2->GetSelected()){
103 default: std::cout<<
"Unspecified"<<std::endl;
105 it2->PrintAttributes(std::cout,2);
109 std::cout<<
"\tNo function sel rules"<<std::endl;
113 std::list<VariableSelectionRule>::const_iterator it3;
117 std::cout<<
"\tVariable sel rule "<<i<<
":"<<std::endl;
118 std::cout<<
"\t\tSelected: ";
119 switch(it3->GetSelected()){
126 default: std::cout<<
"Unspecified"<<std::endl;
128 it3->PrintAttributes(std::cout,2);
132 std::cout<<
"\tNo variable sel rules"<<std::endl;
136 std::list<EnumSelectionRule>::const_iterator it4;
140 std::cout<<
"\tEnum sel rule "<<i<<
":"<<std::endl;
141 std::cout<<
"\t\tSelected: ";
142 switch(it4->GetSelected()){
149 default: std::cout<<
"Unspecified"<<std::endl;
151 it4->PrintAttributes(std::cout,2);
155 std::cout<<
"\tNo enum sel rules"<<std::endl;
169 std::unordered_map<std::string,RULE*>& storedRules,
170 const std::string& attrName){
171 auto itRetCodePair = storedRules.emplace( attrName, rule );
173 auto storedRule = storedRules[attrName];
175 if (itRetCodePair.second ||
176 storedRule->GetSelected() != rule->GetSelected())
return false;
179 std::stringstream sstr; sstr <<
"Rule:\n";
181 sstr << (
areEqual ?
"Identical " :
"Conflicting ");
182 sstr <<
"rule already stored:\n";
183 storedRule->Print(sstr);
185 "Duplicated rule found.\n%s",sstr.str().c_str());
189 template<
class RULESCOLLECTION,
class RULE =
typename RULESCOLLECTION::value_type>
192 std::unordered_map<std::string, RULE*> patterns,names;
193 for (
auto&& rule : rules){
194 if (rule.HasAttributeName() &&
HasDuplicate(&rule,names,rule.GetAttributeName())) nDuplicates++;
195 if (rule.HasAttributePattern() &&
HasDuplicate(&rule,patterns,rule.GetAttributePattern())) nDuplicates++;
207 if (0 != nDuplicates){
209 "Duplicates in rules were found.\n");
222 if ((nAttrsPattern != 1 || nAttrsName !=1) &&
231 auto implies = 0 == fnmatch(
pattern,
name, FNM_PATHNAME);
234 static const auto msg =
"The pattern rule %s matches the name rule %s. " 235 "Since the name rule has compatible attributes, " 236 "it will be removed: the pattern rule will match the necessary classes if needed.\n";
253 std::list<decltype(ruleIt)> itPositionsToErase;
256 if (ruleIt->HasAttributeName()) {
258 if (intRule.HasAttributePattern() &&
Implies(intRule, *ruleIt)){
259 itPositionsToErase.push_back(ruleIt);
264 itPositionsToErase.unique();
265 for (
auto&& itPositionToErase : itPositionsToErase){
282 std::string patternString;
285 if (classRuleIt->HasAttributeWithName(
"pattern") &&
286 classRuleIt->GetAttributeValue(
"pattern",patternString)){
288 if (patternString.find_last_of(
"*")!=patternString.size()-1){
295 if (classRuleIt->HasAttributeWithName(
"name") &&
296 classRuleIt->GetAttributeValue(
"name",patternString)){
307 std::string qual_name;
314 std::string qual_name;
321 std::string qual_name;
338 #if defined(R__MUST_REVISIT) 339 # if R__MUST_REVISIT(6,4) 340 "Can become no-op once PCMs are available." 344 std::string str_name;
345 std::string qual_name;
368 std::string qual_name;
383 std::string str_name;
384 std::string qual_name;
394 std::string qual_name;
408 clang::Decl::Kind declkind = D->getKind();
411 case clang::Decl::CXXRecord:
412 case clang::Decl::ClassTemplateSpecialization:
413 case clang::Decl::ClassTemplatePartialSpecialization:
416 case clang::Decl::Namespace:
418 case clang::Decl::Enum:
421 case clang::Decl::Var:
423 #if ROOTCLING_NEEDS_FUNCTIONS_SELECTION 424 case clang::Decl::Function:
426 case clang::Decl::CXXMethod:
427 case clang::Decl::CXXConstructor:
428 case clang::Decl::CXXDestructor: {
434 std::string str_name;
435 std::string qual_name;
443 case clang::Decl::Field:
459 const clang::NamedDecl*
N = llvm::dyn_cast<clang::NamedDecl> (D);
465 if (N->getIdentifier()) {
466 name = N->getNameAsString();
468 else if (N->isCXXClassMember()) {
469 name = N->getNameAsString();
471 llvm::raw_string_ostream stream(qual_name);
472 N->getNameForDiagnostic(stream,N->getASTContext().getPrintingPolicy(),
true);
477 const clang::NamedDecl*
N =
static_cast<const clang::NamedDecl*
> (D);
478 llvm::raw_string_ostream stream(qual_name);
479 N->getNameForDiagnostic(stream,N->getASTContext().getPrintingPolicy(),
true);
488 const std::vector<std::string> quals={
"*",
"&"};
493 for (
auto I = F->param_begin(),
E = F->param_end();
I !=
E; ++
I) {
495 clang::ParmVarDecl*
P = *
I;
509 for (
auto& qual : quals){
510 auto pos = type.find(
" "+qual);
511 if (pos != std::string::npos)
512 type.replace( pos, 2, qual );
522 prototype =
"(" + prototype +
")";
531 if (
const clang::TagDecl*
T 532 = llvm::dyn_cast<clang::TagDecl>(D->getDeclContext()))
533 return T->isClass() ||
T->isStruct();
540 if (
const clang::TagDecl* parent
541 = llvm::dyn_cast<clang::TagDecl>(D->getDeclContext())) {
542 if (parent->isClass()|| parent->isStruct()) {
543 GetDeclName(parent, parent_name, parent_qual_name);
552 if (
const clang::RecordDecl* parent
553 = llvm::dyn_cast<clang::RecordDecl>(D->getDeclContext())) {
554 GetDeclName(parent, parent_name, parent_qual_name);
600 const clang::NamespaceDecl*
N = llvm::dyn_cast<clang::NamespaceDecl> (D);
602 std::cout<<
"\n\tCouldn't cast Decl to NamespaceDecl";
615 std::string name_value;
616 std::string pattern_value;
629 explicit_selector = &(*it);
632 if (it->GetAttributeValue(
"pattern", pattern_value) &&
633 pattern_value !=
"*" && pattern_value !=
"*::*") specific_pattern_selector = &(*it);
642 #ifdef SELECTION_DEBUG 643 std::cout<<
"\tNo returned"<<std::endl;
651 if (it->GetAttributeValue(
"pattern", pattern_value) &&
652 (pattern_value ==
"*" || pattern_value ==
"*::*")) ++fImplNo;
661 #ifdef SELECTION_DEBUG 662 std::cout<<
"Empty dontC returned = No"<<std::endl;
672 #ifdef SELECTION_DEBUG 673 std::cout<<
"\n\tfYes = "<<fYes<<
", fImplNo = "<<fImplNo<<std::endl;
676 if (explicit_selector)
return explicit_selector;
677 else if (specific_pattern_selector)
return specific_pattern_selector;
678 else if (fImplNo > 0)
return 0;
679 else return selector;
684 #ifdef SELECTION_DEBUG 685 std::cout<<
"\n\tfYes = "<<fYes<<
", fFileNo = "<<fFileNo<<std::endl;
699 const clang::TagDecl* tagDecl = llvm::dyn_cast<clang::TagDecl> (D);
700 const clang::TypedefNameDecl* typeDefNameDecl = llvm::dyn_cast<clang::TypedefNameDecl> (D);
702 if (!tagDecl && !typeDefNameDecl) {
704 "Cannot cast Decl to TagDecl and Decl is not a typedef.\n");
708 if (!tagDecl && typeDefNameDecl){
712 "Cannot get RecordDecl behind TypedefDecl.\n");
715 tagDecl = recordDecl;
720 if (!( isLinkDefFile || tagDecl->isClass() || tagDecl->isStruct() ))
730 bool earlyReturn=
false;
732 const clang::NamedDecl* nDecl(llvm::dyn_cast<clang::NamedDecl>(D));
737 if (
const clang::ClassTemplateSpecializationDecl* ctsd =
738 llvm::dyn_cast_or_null<clang::ClassTemplateSpecializationDecl>(D))
739 if(
const clang::ClassTemplateDecl* ctd = ctsd->getSpecializedTemplate()){
740 const std::string&
nArgsToKeep = rule.GetAttributeNArgsToKeep();
741 if (!nArgsToKeep.empty()){
743 std::atoi(nArgsToKeep.c_str()));
747 if (earlyReturn)
continue;
756 explicit_selector = &(rule);
760 if (!pattern_value.empty() &&
761 pattern_value !=
"*" &&
762 pattern_value !=
"*::*") specific_pattern_selector = &(rule);
767 if (!isLinkDefFile) {
778 if (!pattern_value.empty() &&
779 (pattern_value ==
"*" || pattern_value ==
"*::*")) ++fImplNo;
792 if (earlyReturn)
return retval;
796 if (explicit_selector)
return explicit_selector;
797 else if (specific_pattern_selector)
return specific_pattern_selector;
798 else if (fImplNo > 0)
return 0;
799 else return selector;
818 for(; it != it_end; ++it) {
836 D->getPrimaryTemplate() !=
nullptr ||
837 llvm::isa<clang::CXXMethodDecl>(D))
return nullptr;
839 std::string prototype;
841 prototype = qual_name + prototype;
890 std::string name_value;
891 std::string pattern_value;
894 = selRule.
Match(llvm::dyn_cast<clang::NamedDecl>(D), qual_name,
"",
false);
900 explicit_selector = &selRule;
902 if (selRule.GetAttributeValue(
"pattern", pattern_value)) {
903 explicit_selector=&selRule;
913 if (selRule.GetAttributeValue(
"pattern", pattern_value)) {
914 if (pattern_value ==
"*" || pattern_value ==
"*::*") ++fImplNo;
927 #ifdef SELECTION_DEBUG 928 std::cout<<
"\n\tfYes = "<<fYes<<
", fImplNo = "<<fImplNo<<std::endl;
931 if (explicit_selector)
return explicit_selector;
932 else if (fImplNo > 0)
return 0;
933 else return selector;
944 D->getPrimaryTemplate() !=
nullptr ||
945 llvm::isa<clang::CXXMethodDecl>(D))
return nullptr;
947 std::string prototype;
950 prototype = qual_name + prototype;
956 std::string pattern_value;
959 = selRule.
Match(llvm::dyn_cast<clang::NamedDecl>(D), qual_name, prototype,
false);
965 explicit_selector = &selRule;
967 if (selRule.GetAttributeValue(
"pattern", pattern_value)) {
968 explicit_selector = &selRule;
978 if (selRule.GetAttributeValue(
"pattern", pattern_value)) {
979 if (pattern_value ==
"*" || pattern_value ==
"*::*") ++fImplNo;
991 if (explicit_selector)
return explicit_selector;
992 else if (fImplNo > 0)
return 0;
993 else return selector;
1002 std::list<VariableSelectionRule>::const_iterator it;
1003 std::list<VariableSelectionRule>::const_iterator it_end;
1012 std::string name_value;
1013 std::string pattern_value;
1014 for(; it != it_end; ++it) {
1016 it->Match(llvm::dyn_cast<clang::NamedDecl>(D), qual_name,
"",
false);
1022 explicit_selector = &(*it);
1024 it->GetAttributeValue(
"pattern", pattern_value)) {
1026 if (pattern_value !=
"*" && pattern_value !=
"*::*") explicit_selector = &(*it);
1033 if (it->GetAttributeValue(
"pattern", pattern_value)) {
1034 if (pattern_value ==
"*" || pattern_value ==
"*::*") ++fImplNo;
1047 #ifdef SELECTION_DEBUG 1048 std::cout<<
"\n\tfYes = "<<fYes<<
", fImplNo = "<<fImplNo<<std::endl;
1051 if (explicit_selector)
return explicit_selector;
1052 else if (fImplNo > 0)
return 0;
1053 else return selector;
1077 std::string prototype;
1079 if (
const clang::FunctionDecl*
F = llvm::dyn_cast<clang::FunctionDecl> (D))
1081 prototype = qual_name + prototype;
1083 #ifdef SELECTION_DEBUG 1084 std::cout<<
"\tFunction prototype = "<<prototype<<std::endl;
1087 int expl_Yes = 0, impl_r_Yes = 0, impl_rr_Yes = 0;
1088 int impl_r_No = 0, impl_rr_No = 0;
1093 if (D->getKind() == clang::Decl::CXXMethod){
1095 std::string pat_value;
1096 for(; it != it_end; ++it) {
1098 = it->Match(llvm::dyn_cast<clang::NamedDecl>(D), qual_name, prototype,
false);
1103 explicit_r = &(*it);
1107 #ifdef SELECTION_DEBUG 1108 std::cout<<
"\tExplicit rule BaseSelectionRule::kNo found"<<std::endl;
1116 if (it->GetAttributeValue(
"pattern", pat_value)) {
1117 if (pat_value ==
"*")
continue;
1119 std::string par_name, par_qual_name;
1121 std::string par_pat = par_qual_name +
"::*";
1123 if (pat_value == par_pat) {
1124 implicit_rr = &(*it);
1127 #ifdef SELECTION_DEBUG 1128 std::cout<<
"Implicit_rr rule ("<<pat_value<<
"), selected = "<<selected<<std::endl;
1135 #ifdef SELECTION_DEBUG 1136 std::cout<<
"Implicit_rr rule ("<<pat_value<<
"), selected = "<<selected<<std::endl;
1143 implicit_r = &(*it);
1146 #ifdef SELECTION_DEBUG 1147 std::cout<<
"Implicit_r rule ("<<pat_value<<
"), selected = "<<selected<<std::endl;
1154 #ifdef SELECTION_DEBUG 1155 std::cout<<
"Implicit_r rule ("<<pat_value<<
"), selected = "<<selected<<std::endl;
1167 #ifdef SELECTION_DEBUG 1168 std::cout<<
"\tExplicit rule BaseSelectionRule::BaseSelectionRule::kYes found"<<std::endl;
1173 else if (implicit_rr) {
1174 if (impl_rr_No > 0) {
1176 #ifdef SELECTION_DEBUG 1177 std::cout<<
"\tImplicit_rr rule BaseSelectionRule::kNo found"<<std::endl;
1184 #ifdef SELECTION_DEBUG 1185 std::cout<<
"\tImplicit_rr rule BaseSelectionRule::kYes found"<<std::endl;
1191 else if (implicit_r) {
1192 if (impl_r_No > 0) {
1194 #ifdef SELECTION_DEBUG 1195 std::cout<<
"\tImplicit_r rule BaseSelectionRule::kNo found"<<std::endl;
1202 #ifdef SELECTION_DEBUG 1203 std::cout<<
"\tImplicit_r rule BaseSelectionRule::kYes found"<<std::endl;
1211 #ifdef SELECTION_DEBUG 1212 std::cout<<
"\tChecking parent class rules"<<std::endl;
1217 std::string parent_name, parent_qual_name;
1218 if (!
GetParentName(D, parent_name, parent_qual_name))
return 0;
1228 std::string name_value;
1229 std::string pattern_value;
1232 = it->Match(llvm::dyn_cast<clang::NamedDecl>(D), parent_qual_name,
"",
true);
1239 explicit_selector = &(*it);
1241 if (it->GetAttributeValue(
"pattern", pattern_value)) {
1243 if (pattern_value !=
"*" && pattern_value !=
"*::*") explicit_selector = &(*it);
1249 if (it->GetAttributeValue(
"pattern", pattern_value)) {
1250 if (pattern_value ==
"*" || pattern_value ==
"*::*") ++fImplNo;
1260 #ifdef SELECTION_DEBUG 1261 std::cout<<
"\n\tfYes = "<<fYes<<
", fImplNo = "<<fImplNo<<std::endl;
1264 if (explicit_selector) {
1266 #ifdef SELECTION_DEBUG 1267 std::cout<<
"\tReturning Yes"<<std::endl;
1270 return explicit_selector;
1272 else if (fImplNo > 0) {
1273 #ifdef SELECTION_DEBUG 1274 std::cout<<
"\tReturning No"<<std::endl;
1281 #ifdef SELECTION_DEBUG 1282 std::cout<<
"\tReturning Yes"<<std::endl;
1295 std::string parent_name;
1296 std::string parent_qual_name;
1300 if (!
GetParentName(D, parent_name, parent_qual_name))
return 0;
1309 std::string name_value;
1310 std::string pattern_value;
1313 = it->Match(llvm::dyn_cast<clang::NamedDecl>(D), parent_qual_name,
"",
false);
1320 explicit_selector = &(*it);
1322 if (it->GetAttributeValue(
"pattern", pattern_value)) {
1324 if (pattern_value !=
"*" && pattern_value !=
"*::*") explicit_selector = &(*it);
1333 #ifdef SELECTION_DEBUG 1334 std::cout<<
"\tNo returned"<<std::endl;
1342 if (pattern_value ==
"*" || pattern_value ==
"*::*") ++fImplNo;
1352 if (!it->HasMethodSelectionRules() && !it->HasFieldSelectionRules()) {
1354 #ifdef SELECTION_DEBUG 1355 std::cout<<
"\tNo fields and methods"<<std::endl;
1361 clang::Decl::Kind kind = D->getKind();
1362 if (kind == clang::Decl::Field || kind == clang::Decl::CXXMethod || kind == clang::Decl::CXXConstructor || kind == clang::Decl::CXXDestructor){
1363 std::list<VariableSelectionRule> members;
1364 std::list<VariableSelectionRule>::iterator mem_it;
1365 std::list<VariableSelectionRule>::iterator mem_it_end;
1366 std::string prototype;
1368 if (kind == clang::Decl::Field) {
1369 members = it->GetFieldSelectionRules();
1372 if (
const clang::FunctionDecl*
F = llvm::dyn_cast<clang::FunctionDecl> (D)){
1374 prototype = str_name + prototype;
1379 members = it->GetMethodSelectionRules();
1381 mem_it = members.begin();
1382 mem_it_end = members.end();
1383 for (; mem_it != mem_it_end; ++mem_it) {
1396 #ifdef SELECTION_DEBUG 1397 std::cout<<
"\n\tfYes = "<<fYes<<
", fImplNo = "<<fImplNo<<std::endl;
1400 if (explicit_selector) {
1401 #ifdef SELECTION_DEBUG 1402 std::cout<<
"\tReturning Yes"<<std::endl;
1405 return explicit_selector;
1407 else if (fImplNo > 0) {
1409 #ifdef SELECTION_DEBUG 1410 std::cout<<
"\tReturning No"<<std::endl;
1417 #ifdef SELECTION_DEBUG 1418 std::cout<<
"\tReturning Yes"<<std::endl;
1438 if (rule.GetAttributeValue(
"pattern", name)) {
1440 }
else if (rule.GetAttributeValue(
"name", name)) {
1445 std::string file_name_value;
1446 if (!rule.GetAttributeValue(
"file_name", file_name_value)) file_name_value.clear();
1448 if (!file_name_value.empty()) {
1453 const char* attrName =
nullptr;
1454 const char* attrVal =
nullptr;
1455 if (!file_name_value.empty()) {
1456 attrName =
"file name";
1457 attrVal = file_name_value.c_str();
1460 if (!name.empty()) attrVal = name.c_str();
1469 if (rule.GetAttributeValue(
"pattern", name)) {
1471 }
else if (rule.GetAttributeValue(
"name", name)) {
1478 rule.PrintAttributes(std::cout,3);
1483 #if defined(R__MUST_REVISIT) 1484 #if R__MUST_REVISIT(6,2) 1486 "Warnings concerning non matching selection rules are suppressed. An action is to be taken.\n");
1520 #if Enums_rules_becomes_useful_for_rootcling 1524 if (rule.GetAttributeValue(
"pattern", name)) {
1526 }
else if (rule.GetAttributeValue(
"name", name)) {
1535 rule.PrintAttributes(std::cout,3);
1550 if (it->HasAttributeWithName(
"name")) {
1551 std::string name_value;
1552 it->GetAttributeValue(
"name", name_value);
1555 const clang::CXXRecordDecl *target
1559 it->SetCXXRecordDecl(target,typeptr);
std::list< ClassSelectionRule > fClassSelectionRules
List of the class selection rules.
bool fIsDeep
if –deep option passed from command line, this should be set to true
ROOT::TMetaUtils::TNormalizedCtxt & fNormCtxt
const BaseSelectionRule * IsVarSelected(const clang::VarDecl *D, const std::string &qual_name) const
EMatchType Match(const clang::NamedDecl *decl, const std::string &name, const std::string &prototype, bool isLinkdef) const
ESelect GetSelected() const
void GetDeclQualName(const clang::Decl *D, std::string &qual_name) const
std::list< VariableSelectionRule > fVariableSelectionRules
List of the global variables selection rules.
const BaseSelectionRule * IsLinkdefMethodSelected(const clang::Decl *D, const std::string &qual_name) const
const BaseSelectionRule * IsLinkdefEnumSelected(const clang::EnumDecl *D, const std::string &qual_name) const
const std::string & GetAttributePattern() const
const ClassSelectionRule * IsClassSelected(const clang::Decl *D, const std::string &qual_name) const
static bool HasDuplicate(RULE *rule, std::unordered_map< std::string, RULE *> &storedRules, const std::string &attrName)
void ClearSelectionRules()
const AttributesMap_t & GetAttributes() const
bool GetParentName(const clang::Decl *D, std::string &parent_name, std::string &parent_qual_name) const
bool IsSelectionXMLFile() const
bool GetHasFileNameRule() const
const BaseSelectionRule * IsLinkdefFunSelected(const clang::FunctionDecl *D, const std::string &qual_name) const
void AddFunctionSelectionRule(const FunctionSelectionRule &funcSel)
bool GetDeclName(const clang::Decl *D, std::string &name, std::string &qual_name) const
const BaseSelectionRule * IsMemberSelected(const clang::Decl *D, const std::string &str_name) const
bool AreAllSelectionRulesUsed() const
bool HasInterpreter() const
bool GetFunctionPrototype(const clang::FunctionDecl *F, std::string &prototype) const
const BaseSelectionRule * IsFunSelected(const clang::FunctionDecl *D, const std::string &qual_name) const
static int CheckDuplicatesImp(RULESCOLLECTION &rules)
const clang::CXXRecordDecl * R__ScopeSearch(const char *name, const clang::Type **resultType=0)
void AddVariableSelectionRule(const VariableSelectionRule &varSel)
const std::string & GetAttributeName() const
Type
enumeration specifying the integration types.
cling::Interpreter & fInterp
const BaseSelectionRule * IsLinkdefVarSelected(const clang::VarDecl *D, const std::string &qual_name) const
const BaseSelectionRule * IsEnumSelected(const clang::EnumDecl *D, const std::string &qual_name) const
static bool Implies(ClassSelectionRule &patternRule, ClassSelectionRule &nameRule)
std::list< EnumSelectionRule > fEnumSelectionRules
List of the enums selection rules.
bool areEqual(const RULE *r1, const RULE *r2, bool moduloNameOrPattern=false)
const ClassSelectionRule * IsNamespaceSelected(const clang::Decl *D, const std::string &qual_name) const
void SetSelected(ESelect sel)
bool IsParentClass(const clang::Decl *D) const
void AddClassSelectionRule(const ClassSelectionRule &classSel)
void AddEnumSelectionRule(const EnumSelectionRule &enumSel)
void SetAttributeValue(const std::string &attributeName, const std::string &attributeValue)
const ClassSelectionRule * IsDeclSelected(const clang::RecordDecl *D) const
std::list< FunctionSelectionRule > fFunctionSelectionRules
List of the global functions selection rules.
void PrintSelectionRules() const
bool IsLinkdefFile() const
bool SearchNames(cling::Interpreter &interp)