Index: clang/include/clang/AST/Attr.h =================================================================== --- clang/include/clang/AST/Attr.h +++ clang/include/clang/AST/Attr.h @@ -329,6 +329,18 @@ static_assert(sizeof(ParamIdx) == sizeof(ParamIdx::SerialType), "ParamIdx does not fit its serialization type"); +/// Contains information gathered from parsing the contents of TargetAttr. +struct ParsedTargetAttr { + std::vector Features; + StringRef Architecture; + StringRef BranchProtection; + bool DuplicateArchitecture = false; + bool operator ==(const ParsedTargetAttr &Other) const { + return DuplicateArchitecture == Other.DuplicateArchitecture && + Architecture == Other.Architecture && Features == Other.Features; + } +}; + #include "clang/AST/Attrs.inc" inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, Index: clang/include/clang/Basic/Attr.td =================================================================== --- clang/include/clang/Basic/Attr.td +++ clang/include/clang/Basic/Attr.td @@ -2162,16 +2162,6 @@ let Subjects = SubjectList<[Function], ErrorDiag>; let Documentation = [TargetDocs]; let AdditionalMembers = [{ - struct ParsedTargetAttr { - std::vector Features; - StringRef Architecture; - StringRef BranchProtection; - bool DuplicateArchitecture = false; - bool operator ==(const ParsedTargetAttr &Other) const { - return DuplicateArchitecture == Other.DuplicateArchitecture && - Architecture == Other.Architecture && Features == Other.Features; - } - }; ParsedTargetAttr parse() const { return parse(getFeaturesStr()); } Index: clang/lib/CodeGen/CodeGenFunction.cpp =================================================================== --- clang/lib/CodeGen/CodeGenFunction.cpp +++ clang/lib/CodeGen/CodeGenFunction.cpp @@ -2286,7 +2286,7 @@ // Get the required features for the callee. const TargetAttr *TD = TargetDecl->getAttr(); - TargetAttr::ParsedTargetAttr ParsedAttr = CGM.filterFunctionTargetAttrs(TD); + ParsedTargetAttr ParsedAttr = CGM.filterFunctionTargetAttrs(TD); SmallVector ReqFeatures; llvm::StringMap CalleeFeatureMap; Index: clang/lib/CodeGen/CodeGenModule.h =================================================================== --- clang/lib/CodeGen/CodeGenModule.h +++ clang/lib/CodeGen/CodeGenModule.h @@ -1152,7 +1152,7 @@ /// Parses the target attributes passed in, and returns only the ones that are /// valid feature names. - TargetAttr::ParsedTargetAttr filterFunctionTargetAttrs(const TargetAttr *TD); + ParsedTargetAttr filterFunctionTargetAttrs(const TargetAttr *TD); // Fills in the supplied string map with the set of target features for the // passed in function. Index: clang/lib/CodeGen/CodeGenModule.cpp =================================================================== --- clang/lib/CodeGen/CodeGenModule.cpp +++ clang/lib/CodeGen/CodeGenModule.cpp @@ -957,7 +957,7 @@ Out << '.'; const TargetInfo &Target = CGM.getTarget(); - TargetAttr::ParsedTargetAttr Info = + ParsedTargetAttr Info = Attr->parse([&Target](StringRef LHS, StringRef RHS) { // Multiversioning doesn't allow "no-${feature}", so we can // only have "+" prefixes here. @@ -1678,7 +1678,7 @@ // get and parse the target attribute so we can get the cpu for // the function. if (TD) { - TargetAttr::ParsedTargetAttr ParsedAttr = TD->parse(); + ParsedTargetAttr ParsedAttr = TD->parse(); if (ParsedAttr.Architecture != "" && getTarget().isValidCPUName(ParsedAttr.Architecture)) TargetCPU = ParsedAttr.Architecture; @@ -5858,9 +5858,9 @@ } } -TargetAttr::ParsedTargetAttr CodeGenModule::filterFunctionTargetAttrs(const TargetAttr *TD) { +ParsedTargetAttr CodeGenModule::filterFunctionTargetAttrs(const TargetAttr *TD) { assert(TD != nullptr); - TargetAttr::ParsedTargetAttr ParsedAttr = TD->parse(); + ParsedTargetAttr ParsedAttr = TD->parse(); ParsedAttr.Features.erase( llvm::remove_if(ParsedAttr.Features, @@ -5880,7 +5880,7 @@ StringRef TargetCPU = Target.getTargetOpts().CPU; const FunctionDecl *FD = GD.getDecl()->getAsFunction(); if (const auto *TD = FD->getAttr()) { - TargetAttr::ParsedTargetAttr ParsedAttr = filterFunctionTargetAttrs(TD); + ParsedTargetAttr ParsedAttr = filterFunctionTargetAttrs(TD); // Make a copy of the features as passed on the command line into the // beginning of the additional features from the function to override. Index: clang/lib/CodeGen/TargetInfo.cpp =================================================================== --- clang/lib/CodeGen/TargetInfo.cpp +++ clang/lib/CodeGen/TargetInfo.cpp @@ -5061,7 +5061,7 @@ CodeGenOptions::SignReturnAddressKeyValue Key = CGM.getCodeGenOpts().getSignReturnAddressKey(); bool BranchTargetEnforcement = CGM.getCodeGenOpts().BranchTargetEnforcement; if (const auto *TA = FD->getAttr()) { - TargetAttr::ParsedTargetAttr Attr = TA->parse(); + ParsedTargetAttr Attr = TA->parse(); if (!Attr.BranchProtection.empty()) { TargetInfo::BranchProtectionInfo BPI; StringRef Error; Index: clang/lib/Sema/SemaDecl.cpp =================================================================== --- clang/lib/Sema/SemaDecl.cpp +++ clang/lib/Sema/SemaDecl.cpp @@ -9741,7 +9741,7 @@ static bool CheckMultiVersionValue(Sema &S, const FunctionDecl *FD) { const auto *TA = FD->getAttr(); assert(TA && "MultiVersion Candidate requires a target attribute"); - TargetAttr::ParsedTargetAttr ParseInfo = TA->parse(); + ParsedTargetAttr ParseInfo = TA->parse(); const TargetInfo &TargetInfo = S.Context.getTargetInfo(); enum ErrType { Feature = 0, Architecture = 1 }; @@ -9992,7 +9992,7 @@ bool &Redeclaration, NamedDecl *&OldDecl, bool &MergeTypeWithPrevious, LookupResult &Previous) { const auto *OldTA = OldFD->getAttr(); - TargetAttr::ParsedTargetAttr NewParsed = NewTA->parse(); + ParsedTargetAttr NewParsed = NewTA->parse(); // Sort order doesn't matter, it just needs to be consistent. llvm::sort(NewParsed.Features); @@ -10036,8 +10036,7 @@ return true; } - TargetAttr::ParsedTargetAttr OldParsed = - OldTA->parse(std::less()); + ParsedTargetAttr OldParsed = OldTA->parse(std::less()); if (OldParsed == NewParsed) { S.Diag(NewFD->getLocation(), diag::err_multiversion_duplicate); @@ -10090,7 +10089,7 @@ return true; } - TargetAttr::ParsedTargetAttr NewParsed; + ParsedTargetAttr NewParsed; if (NewTA) { NewParsed = NewTA->parse(); llvm::sort(NewParsed.Features); @@ -10117,8 +10116,7 @@ return false; } - TargetAttr::ParsedTargetAttr CurParsed = - CurTA->parse(std::less()); + ParsedTargetAttr CurParsed = CurTA->parse(std::less()); if (CurParsed == NewParsed) { S.Diag(NewFD->getLocation(), diag::err_multiversion_duplicate); S.Diag(CurFD->getLocation(), diag::note_previous_declaration); Index: clang/lib/Sema/SemaDeclAttr.cpp =================================================================== --- clang/lib/Sema/SemaDeclAttr.cpp +++ clang/lib/Sema/SemaDeclAttr.cpp @@ -3046,7 +3046,7 @@ return Diag(LiteralLoc, diag::warn_unsupported_target_attribute) << Unsupported << None << Str; - TargetAttr::ParsedTargetAttr ParsedAttrs = TargetAttr::parse(AttrStr); + ParsedTargetAttr ParsedAttrs = TargetAttr::parse(AttrStr); if (!ParsedAttrs.Architecture.empty() && !Context.getTargetInfo().isValidCPUName(ParsedAttrs.Architecture))