diff options
Diffstat (limited to 'utils/TableGen/ClangAttrEmitter.cpp')
-rw-r--r-- | utils/TableGen/ClangAttrEmitter.cpp | 38 |
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"; |