summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAaron Ballman <aaron@aaronballman.com>2014-01-13 21:42:39 +0000
committerAaron Ballman <aaron@aaronballman.com>2014-01-13 21:42:39 +0000
commit09e98ffa5b5c94f2ea394e0f6f8840eb8d7f1f03 (patch)
tree2218cd94f39226478239e47e64382a24109c3e38
parent3fe6ed5aa0d7d4a99129ed6f4b37592b187b1787 (diff)
downloadbcm5719-llvm-09e98ffa5b5c94f2ea394e0f6f8840eb8d7f1f03.tar.gz
bcm5719-llvm-09e98ffa5b5c94f2ea394e0f6f8840eb8d7f1f03.zip
When determining the attribute's parsed kind, pay attention to the syntax used. This fixes bugs where an attribute has differing GNU and Declspec spellings, but they are treated as the same. Eg) __declspec(aligned) when it should be __attribute__((aligned)), and __attribute__((align)) when it should be __declspec(align).
llvm-svn: 199144
-rw-r--r--clang/lib/Sema/AttributeList.cpp2
-rw-r--r--clang/utils/TableGen/ClangAttrEmitter.cpp63
2 files changed, 43 insertions, 22 deletions
diff --git a/clang/lib/Sema/AttributeList.cpp b/clang/lib/Sema/AttributeList.cpp
index 58a3e23c1b0..dbb31b64904 100644
--- a/clang/lib/Sema/AttributeList.cpp
+++ b/clang/lib/Sema/AttributeList.cpp
@@ -139,7 +139,7 @@ AttributeList::Kind AttributeList::getKind(const IdentifierInfo *Name,
FullName += "::";
FullName += AttrName;
- return ::getAttrKind(FullName);
+ return ::getAttrKind(FullName, SyntaxUsed);
}
unsigned AttributeList::getAttributeSpellingListIndex() const {
diff --git a/clang/utils/TableGen/ClangAttrEmitter.cpp b/clang/utils/TableGen/ClangAttrEmitter.cpp
index ed451d559ff..b3950c20034 100644
--- a/clang/utils/TableGen/ClangAttrEmitter.cpp
+++ b/clang/utils/TableGen/ClangAttrEmitter.cpp
@@ -2250,9 +2250,8 @@ void EmitClangAttrParsedAttrImpl(RecordKeeper &Records, raw_ostream &OS) {
void EmitClangAttrParsedAttrKinds(RecordKeeper &Records, raw_ostream &OS) {
emitSourceFileHeader("Attribute name matcher", OS);
- std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr");
-
- std::vector<StringMatcher::StringPair> Matches;
+ std::vector<Record *> Attrs = Records.getAllDerivedDefinitions("Attr");
+ std::vector<StringMatcher::StringPair> GNU, Declspec, CXX11, Keywords;
std::set<std::string> Seen;
for (std::vector<Record*>::iterator I = Attrs.begin(), E = Attrs.end();
I != E; ++I) {
@@ -2261,8 +2260,16 @@ void EmitClangAttrParsedAttrKinds(RecordKeeper &Records, raw_ostream &OS) {
bool SemaHandler = Attr.getValueAsBit("SemaHandler");
bool Ignored = Attr.getValueAsBit("Ignored");
if (SemaHandler || Ignored) {
- std::vector<Record*> Spellings = Attr.getValueAsListOfDefs("Spellings");
-
+ // Attribute spellings can be shared between target-specific attributes,
+ // and can be shared between syntaxes for the same attribute. For
+ // instance, an attribute can be spelled GNU<"interrupt"> for an ARM-
+ // specific attribute, or MSP430-specific attribute. Additionally, an
+ // attribute can be spelled GNU<"dllexport"> and Declspec<"dllexport">
+ // for the same semantic attribute. Ultimately, we need to map each of
+ // these to a single AttributeList::Kind value, but the StringMatcher
+ // class cannot handle duplicate match strings. So we generate a list of
+ // string to match based on the syntax, and emit multiple string matchers
+ // depending on the syntax used.
std::string AttrName;
if (Attr.isSubClassOf("TargetSpecificAttr") &&
!Attr.isValueUnset("ParseKind")) {
@@ -2273,34 +2280,48 @@ void EmitClangAttrParsedAttrKinds(RecordKeeper &Records, raw_ostream &OS) {
} else
AttrName = NormalizeAttrName(StringRef(Attr.getName())).str();
+ std::vector<Record*> Spellings = Attr.getValueAsListOfDefs("Spellings");
for (std::vector<Record*>::const_iterator I = Spellings.begin(),
E = Spellings.end(); I != E; ++I) {
std::string RawSpelling = (*I)->getValueAsString("Name");
-
- SmallString<64> Spelling;
- if ((*I)->getValueAsString("Variety") == "CXX11") {
+ std::vector<StringMatcher::StringPair> *Matches = 0;
+ std::string Spelling, Variety = (*I)->getValueAsString("Variety");
+ if (Variety == "CXX11") {
+ Matches = &CXX11;
Spelling += (*I)->getValueAsString("Namespace");
Spelling += "::";
- }
- Spelling += NormalizeAttrSpelling(RawSpelling);
+ } else if (Variety == "GNU")
+ Matches = &GNU;
+ else if (Variety == "Declspec")
+ Matches = &Declspec;
+ else if (Variety == "Keyword")
+ Matches = &Keywords;
+ assert(Matches && "Unsupported spelling variety found");
+
+ Spelling += NormalizeAttrSpelling(RawSpelling);
if (SemaHandler)
- Matches.push_back(
- StringMatcher::StringPair(
- StringRef(Spelling),
- "return AttributeList::AT_" + AttrName + ";"));
+ Matches->push_back(StringMatcher::StringPair(Spelling,
+ "return AttributeList::AT_" + AttrName + ";"));
else
- Matches.push_back(
- StringMatcher::StringPair(
- StringRef(Spelling),
- "return AttributeList::IgnoredAttribute;"));
+ Matches->push_back(StringMatcher::StringPair(Spelling,
+ "return AttributeList::IgnoredAttribute;"));
}
}
}
- OS << "static AttributeList::Kind getAttrKind(StringRef Name) {\n";
- StringMatcher("Name", Matches, OS).Emit();
- OS << "return AttributeList::UnknownAttribute;\n"
+ OS << "static AttributeList::Kind getAttrKind(StringRef Name, ";
+ OS << "AttributeList::Syntax Syntax) {\n";
+ OS << " if (AttributeList::AS_GNU == Syntax) {\n";
+ StringMatcher("Name", GNU, OS).Emit();
+ OS << " } else if (AttributeList::AS_Declspec == Syntax) {\n";
+ StringMatcher("Name", Declspec, OS).Emit();
+ OS << " } else if (AttributeList::AS_CXX11 == Syntax) {\n";
+ StringMatcher("Name", CXX11, OS).Emit();
+ OS << " } else if (AttributeList::AS_Keyword == Syntax) {\n";
+ StringMatcher("Name", Keywords, OS).Emit();
+ OS << " }\n";
+ OS << " return AttributeList::UnknownAttribute;\n"
<< "}\n";
}
OpenPOWER on IntegriCloud