summaryrefslogtreecommitdiff
path: root/utils/TableGen/ClangAttrEmitter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'utils/TableGen/ClangAttrEmitter.cpp')
-rw-r--r--utils/TableGen/ClangAttrEmitter.cpp38
1 files changed, 26 insertions, 12 deletions
diff --git a/utils/TableGen/ClangAttrEmitter.cpp b/utils/TableGen/ClangAttrEmitter.cpp
index a32d80557e..f315262ad0 100644
--- a/utils/TableGen/ClangAttrEmitter.cpp
+++ b/utils/TableGen/ClangAttrEmitter.cpp
@@ -2810,7 +2810,7 @@ void EmitClangAttrPCHWrite(RecordKeeper &Records, raw_ostream &OS) {
// Helper function for GenerateTargetSpecificAttrChecks that alters the 'Test'
// parameter with only a single check type, if applicable.
-static void GenerateTargetSpecificAttrCheck(const Record *R, std::string &Test,
+static bool GenerateTargetSpecificAttrCheck(const Record *R, std::string &Test,
std::string *FnName,
StringRef ListName,
StringRef CheckAgainst,
@@ -2830,7 +2830,9 @@ static void GenerateTargetSpecificAttrCheck(const Record *R, std::string &Test,
*FnName += Part;
}
Test += ")";
+ return true;
}
+ return false;
}
// Generate a conditional expression to check if the current target satisfies
@@ -2838,10 +2840,12 @@ static void GenerateTargetSpecificAttrCheck(const Record *R, std::string &Test,
// those checks to the Test string. If the FnName string pointer is non-null,
// append a unique suffix to distinguish this set of target checks from other
// TargetSpecificAttr records.
-static void GenerateTargetSpecificAttrChecks(const Record *R,
+static bool GenerateTargetSpecificAttrChecks(const Record *R,
std::vector<StringRef> &Arches,
std::string &Test,
std::string *FnName) {
+ bool AnyTargetChecks = false;
+
// It is assumed that there will be an llvm::Triple object
// named "T" and a TargetInfo object named "Target" within
// scope that can be used to determine whether the attribute exists in
@@ -2851,6 +2855,7 @@ static void GenerateTargetSpecificAttrChecks(const Record *R,
// differently because GenerateTargetRequirements needs to combine the list
// with ParseKind.
if (!Arches.empty()) {
+ AnyTargetChecks = true;
Test += " && (";
for (auto I = Arches.begin(), E = Arches.end(); I != E; ++I) {
StringRef Part = *I;
@@ -2865,16 +2870,24 @@ static void GenerateTargetSpecificAttrChecks(const Record *R,
}
// If the attribute is specific to particular OSes, check those.
- GenerateTargetSpecificAttrCheck(R, Test, FnName, "OSes", "T.getOS()",
- "llvm::Triple::");
+ AnyTargetChecks |= GenerateTargetSpecificAttrCheck(
+ R, Test, FnName, "OSes", "T.getOS()", "llvm::Triple::");
- // If one or more CXX ABIs are specified, check those as well.
- GenerateTargetSpecificAttrCheck(R, Test, FnName, "CXXABIs",
- "Target.getCXXABI().getKind()",
- "TargetCXXABI::");
// If one or more object formats is specified, check those.
- GenerateTargetSpecificAttrCheck(R, Test, FnName, "ObjectFormats",
- "T.getObjectFormat()", "llvm::Triple::");
+ AnyTargetChecks |=
+ GenerateTargetSpecificAttrCheck(R, Test, FnName, "ObjectFormats",
+ "T.getObjectFormat()", "llvm::Triple::");
+
+ // If custom code is specified, emit it.
+ StringRef Code = R->getValueAsString("CustomCode");
+ if (!Code.empty()) {
+ AnyTargetChecks = true;
+ Test += " && (";
+ Test += Code;
+ Test += ")";
+ }
+
+ return AnyTargetChecks;
}
static void GenerateHasAttrSpellingStringSwitch(
@@ -3510,7 +3523,7 @@ static std::string GenerateTargetRequirements(const Record &Attr,
std::string FnName = "isTarget";
std::string Test;
- GenerateTargetSpecificAttrChecks(R, Arches, Test, &FnName);
+ bool UsesT = GenerateTargetSpecificAttrChecks(R, Arches, Test, &FnName);
// If this code has already been generated, simply return the previous
// instance of it.
@@ -3520,7 +3533,8 @@ static std::string GenerateTargetRequirements(const Record &Attr,
return *I;
OS << "static bool " << FnName << "(const TargetInfo &Target) {\n";
- OS << " const llvm::Triple &T = Target.getTriple();\n";
+ if (UsesT)
+ OS << " const llvm::Triple &T = Target.getTriple(); (void)T;\n";
OS << " return " << Test << ";\n";
OS << "}\n\n";