diff --git a/clang/include/clang/Basic/ParsedAttrInfo.h b/clang/include/clang/Basic/ParsedAttrInfo.h --- a/clang/include/clang/Basic/ParsedAttrInfo.h +++ b/clang/include/clang/Basic/ParsedAttrInfo.h @@ -88,6 +88,13 @@ public: virtual ~ParsedAttrInfo() = default; + /// Check if this attribute has specified spelling. + bool hasSpelling(AttributeCommonInfo::Syntax Syntax, StringRef Name) const { + return llvm::any_of(Spellings, [&](const Spelling &S) { + return (S.Syntax == Syntax && S.NormalizedFullName == Name); + }); + } + /// Check if this attribute appertains to D, and issue a diagnostic if not. virtual bool diagAppertainsToDecl(Sema &S, const ParsedAttr &Attr, const Decl *D) const { diff --git a/clang/lib/Sema/ParsedAttr.cpp b/clang/lib/Sema/ParsedAttr.cpp --- a/clang/lib/Sema/ParsedAttr.cpp +++ b/clang/lib/Sema/ParsedAttr.cpp @@ -126,9 +126,8 @@ SyntaxUsed = AttributeCommonInfo::AS_Keyword; for (auto &Ptr : getAttributePluginInstances()) - for (auto &S : Ptr->Spellings) - if (S.Syntax == SyntaxUsed && S.NormalizedFullName == FullName) - return *Ptr; + if (Ptr->hasSpelling(SyntaxUsed, FullName)) + return *Ptr; // If we failed to find a match then return a default ParsedAttrInfo. static const ParsedAttrInfo DefaultParsedAttrInfo(