Author: aaronballman
Date: Thu Jan 9 16:57:44 2014
New Revision: 198897
URL: http://llvm.org/viewvc/llvm-project?rev=198897&view=rev
Log:
__has_attribute now understands target-specific attributes. So when you ask
whether an ARM target has the "interrupt" attribute, it will return true for
ARM and MSP430 targets, and false for others.
Modified:
cfe/trunk/lib/Lex/PPMacroExpansion.cpp
cfe/trunk/test/Preprocessor/has_attribute.c
cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp
Modified: cfe/trunk/lib/Lex/PPMacroExpansion.cpp
URL:
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/PPMacroExpansion.cpp?rev=198897&r1=198896&r2=198897&view=diff
==============================================================================
--- cfe/trunk/lib/Lex/PPMacroExpansion.cpp (original)
+++ cfe/trunk/lib/Lex/PPMacroExpansion.cpp Thu Jan 9 16:57:44 2014
@@ -1045,7 +1045,7 @@ static bool HasExtension(const Preproces
/// HasAttribute - Return true if we recognize and implement the attribute
/// specified by the given identifier.
-static bool HasAttribute(const IdentifierInfo *II) {
+static bool HasAttribute(const IdentifierInfo *II, const llvm::Triple &T) {
StringRef Name = II->getName();
// Normalize the attribute name, __foo__ becomes foo.
if (Name.size() >= 4 && Name.startswith("__") && Name.endswith("__"))
@@ -1395,7 +1395,7 @@ void Preprocessor::ExpandBuiltinMacro(To
// Check for a builtin is trivial.
Value = FeatureII->getBuiltinID() != 0;
} else if (II == Ident__has_attribute)
- Value = HasAttribute(FeatureII);
+ Value = HasAttribute(FeatureII, getTargetInfo().getTriple());
else if (II == Ident__has_extension)
Value = HasExtension(*this, FeatureII);
else {
Modified: cfe/trunk/test/Preprocessor/has_attribute.c
URL:
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Preprocessor/has_attribute.c?rev=198897&r1=198896&r2=198897&view=diff
==============================================================================
--- cfe/trunk/test/Preprocessor/has_attribute.c (original)
+++ cfe/trunk/test/Preprocessor/has_attribute.c Thu Jan 9 16:57:44 2014
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -E %s -o - | FileCheck %s
+// RUN: %clang_cc1 -triple arm-unknown-linux -E %s -o - | FileCheck %s
// CHECK: always_inline
#if __has_attribute(always_inline)
@@ -38,3 +38,13 @@ int has_something_we_dont_have();
#if !__has_attribute(volatile)
int has_no_volatile_attribute();
#endif
+
+// CHECK: has_arm_interrupt
+#if __has_attribute(interrupt)
+ int has_arm_interrupt();
+#endif
+
+// CHECK: does_not_have_dllexport
+#if !__has_attribute(dllexport)
+ int does_not_have_dllexport();
+#endif
Modified: cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp
URL:
http://llvm.org/viewvc/llvm-project/cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp?rev=198897&r1=198896&r2=198897&view=diff
==============================================================================
--- cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp (original)
+++ cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp Thu Jan 9 16:57:44 2014
@@ -1537,18 +1537,55 @@ void EmitClangAttrPCHWrite(RecordKeeper
// Emits the list of spellings for attributes.
void EmitClangAttrSpellingList(RecordKeeper &Records, raw_ostream &OS) {
- emitSourceFileHeader("llvm::StringSwitch code to match all known attributes",
- OS);
+ emitSourceFileHeader("llvm::StringSwitch code to match attributes based on "
+ "the target triple, T", OS);
std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr");
- for (std::vector<Record*>::iterator I = Attrs.begin(), E = Attrs.end(); I !=
E; ++I) {
+ for (std::vector<Record*>::iterator I = Attrs.begin(), E = Attrs.end();
+ I != E; ++I) {
Record &Attr = **I;
- std::vector<Record*> Spellings = Attr.getValueAsListOfDefs("Spellings");
+ // It is assumed that there will be an llvm::Triple object named T within
+ // scope that can be used to determine whether the attribute exists in
+ // a given target.
+ std::string Test;
+ if (Attr.isSubClassOf("TargetSpecificAttr")) {
+ const Record *R = Attr.getValueAsDef("Target");
+ std::vector<std::string> Arches = R->getValueAsListOfStrings("Arches");
+
+ Test += "(";
+ for (std::vector<std::string>::const_iterator AI = Arches.begin(),
+ AE = Arches.end(); AI != AE; ++AI) {
+ std::string Part = *AI;
+ Test += "T.getArch() == llvm::Triple::" + Part;
+ if (AI + 1 != AE)
+ Test += " || ";
+ }
+ Test += ")";
+
+ std::vector<std::string> OSes;
+ if (!R->isValueUnset("OSes")) {
+ Test += " && (";
+ std::vector<std::string> OSes = R->getValueAsListOfStrings("OSes");
+ for (std::vector<std::string>::const_iterator AI = OSes.begin(),
+ AE = OSes.end(); AI != AE; ++AI) {
+ std::string Part = *AI;
- for (std::vector<Record*>::const_iterator I = Spellings.begin(), E =
Spellings.end(); I != E; ++I) {
- OS << ".Case(\"" << (*I)->getValueAsString("Name") << "\", true)\n";
+ Test += "T.getOS() == llvm::Triple::" + Part;
+ if (AI + 1 != AE)
+ Test += " || ";
+ }
+ Test += ")";
+ }
+ } else
+ Test = "true";
+
+ std::vector<Record*> Spellings = Attr.getValueAsListOfDefs("Spellings");
+ for (std::vector<Record*>::const_iterator I = Spellings.begin(),
+ E = Spellings.end(); I != E; ++I) {
+ OS << ".Case(\"" << (*I)->getValueAsString("Name") << "\", " << Test;
+ OS << ")\n";
}
}
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits