@@ -1720,16 +1720,22 @@ void EmitClangAttrPCHWrite(RecordKeeper &Records, raw_ostream &OS) {
1720
1720
OS << " }\n " ;
1721
1721
}
1722
1722
1723
- static void GenerateHasAttrSpellingStringSwitch (
1724
- const std::vector<Record *> &Attrs, raw_ostream &OS,
1725
- const std::string &Variety = " " , const std::string &Scope = " " ) {
1726
- for (const auto *Attr : Attrs) {
1723
+ // Emits the list of spellings for attributes.
1724
+ void EmitClangAttrSpellingList (RecordKeeper &Records, raw_ostream &OS) {
1725
+ emitSourceFileHeader (" llvm::StringSwitch code to match attributes based on "
1726
+ " the target triple, T" , OS);
1727
+
1728
+ std::vector<Record*> Attrs = Records.getAllDerivedDefinitions (" Attr" );
1729
+
1730
+ for (auto I : Attrs) {
1731
+ Record &Attr = *I;
1732
+
1727
1733
// It is assumed that there will be an llvm::Triple object named T within
1728
1734
// scope that can be used to determine whether the attribute exists in
1729
1735
// a given target.
1730
1736
std::string Test;
1731
- if (Attr-> isSubClassOf (" TargetSpecificAttr" )) {
1732
- const Record *R = Attr-> getValueAsDef (" Target" );
1737
+ if (Attr. isSubClassOf (" TargetSpecificAttr" )) {
1738
+ const Record *R = Attr. getValueAsDef (" Target" );
1733
1739
std::vector<std::string> Arches = R->getValueAsListOfStrings (" Arches" );
1734
1740
1735
1741
Test += " (" ;
@@ -1754,79 +1760,13 @@ static void GenerateHasAttrSpellingStringSwitch(
1754
1760
}
1755
1761
Test += " )" ;
1756
1762
}
1757
-
1758
- // If this is the C++11 variety, also add in the LangOpts test.
1759
- if (Variety == " CXX11" )
1760
- Test += " && LangOpts.CPlusPlus11" ;
1761
- } else if (Variety == " CXX11" )
1762
- // C++11 mode should be checked against LangOpts, which is presumed to be
1763
- // present in the caller.
1764
- Test = " LangOpts.CPlusPlus11" ;
1765
- else
1763
+ } else
1766
1764
Test = " true" ;
1767
1765
1768
- std::vector<FlattenedSpelling> Spellings = GetFlattenedSpellings (* Attr);
1766
+ std::vector<FlattenedSpelling> Spellings = GetFlattenedSpellings (Attr);
1769
1767
for (const auto &S : Spellings)
1770
- if (Variety.empty () || (Variety == S.variety () &&
1771
- (Scope.empty () || Scope == S.nameSpace ())))
1772
- OS << " .Case(\" " << S.name () << " \" , " << Test << " )\n " ;
1773
- }
1774
- OS << " .Default(false);\n " ;
1775
- }
1776
-
1777
- // Emits the list of spellings for attributes.
1778
- void EmitClangAttrHasAttrImpl (RecordKeeper &Records, raw_ostream &OS) {
1779
- emitSourceFileHeader (" Code to implement the __has_attribute logic" , OS);
1780
-
1781
- // Separate all of the attributes out into four group: generic, C++11, GNU,
1782
- // and declspecs. Then generate a big switch statement for each of them.
1783
- std::vector<Record *> Attrs = Records.getAllDerivedDefinitions (" Attr" );
1784
- std::vector<Record *> Declspec, GNU;
1785
- std::map<std::string, std::vector<Record *>> CXX;
1786
-
1787
- // Walk over the list of all attributes, and split them out based on the
1788
- // spelling variety.
1789
- for (auto *R : Attrs) {
1790
- std::vector<FlattenedSpelling> Spellings = GetFlattenedSpellings (*R);
1791
- for (const auto &SI : Spellings) {
1792
- std::string Variety = SI.variety ();
1793
- if (Variety == " GNU" )
1794
- GNU.push_back (R);
1795
- else if (Variety == " Declspec" )
1796
- Declspec.push_back (R);
1797
- else if (Variety == " CXX11" ) {
1798
- CXX[SI.nameSpace ()].push_back (R);
1799
- }
1800
- }
1801
- }
1802
-
1803
- OS << " switch (Syntax) {\n " ;
1804
- OS << " case AttrSyntax::Generic:\n " ;
1805
- OS << " return llvm::StringSwitch<bool>(Name)\n " ;
1806
- GenerateHasAttrSpellingStringSwitch (Attrs, OS);
1807
- OS << " case AttrSyntax::GNU:\n " ;
1808
- OS << " return llvm::StringSwitch<bool>(Name)\n " ;
1809
- GenerateHasAttrSpellingStringSwitch (GNU, OS, " GNU" );
1810
- OS << " case AttrSyntax::Declspec:\n " ;
1811
- OS << " return llvm::StringSwitch<bool>(Name)\n " ;
1812
- GenerateHasAttrSpellingStringSwitch (Declspec, OS, " Declspec" );
1813
- OS << " case AttrSyntax::CXX: {\n " ;
1814
- // C++11-style attributes are further split out based on the Scope.
1815
- for (std::map<std::string, std::vector<Record *>>::iterator I = CXX.begin (),
1816
- E = CXX.end ();
1817
- I != E; ++I) {
1818
- if (I != CXX.begin ())
1819
- OS << " else " ;
1820
- if (I->first .empty ())
1821
- OS << " if (!Scope || Scope->getName() == \"\" ) {\n " ;
1822
- else
1823
- OS << " if (Scope->getName() == \" " << I->first << " \" ) {\n " ;
1824
- OS << " return llvm::StringSwitch<bool>(Name)\n " ;
1825
- GenerateHasAttrSpellingStringSwitch (I->second , OS, " CXX11" , I->first );
1826
- OS << " }" ;
1768
+ OS << " .Case(\" " << S.name () << " \" , " << Test << " )\n " ;
1827
1769
}
1828
- OS << " \n }\n " ;
1829
- OS << " }\n " ;
1830
1770
}
1831
1771
1832
1772
void EmitClangAttrSpellingListIndex (RecordKeeper &Records, raw_ostream &OS) {
0 commit comments