1515#include " clang/Basic/IdentifierTable.h"
1616#include " clang/Basic/LangOptions.h"
1717#include " clang/Basic/ParsedAttrInfo.h"
18+ #include " clang/Basic/SimpleTypoCorrector.h"
1819#include " clang/Basic/TargetInfo.h"
1920
2021#include " llvm/ADT/StringMap.h"
@@ -32,13 +33,13 @@ static int hasAttributeImpl(AttributeCommonInfo::Syntax Syntax, StringRef Name,
3233}
3334
3435int clang::hasAttribute (AttributeCommonInfo::Syntax Syntax,
35- const IdentifierInfo *Scope, const IdentifierInfo *Attr ,
36+ const IdentifierInfo *Scope, StringRef AttrName ,
3637 const TargetInfo &Target, const LangOptions &LangOpts,
3738 bool CheckPlugins) {
38- StringRef Name = Attr->getName ();
3939 // Normalize the attribute name, __foo__ becomes foo.
40- if (Name.size () >= 4 && Name.starts_with (" __" ) && Name.ends_with (" __" ))
41- Name = Name.substr (2 , Name.size () - 4 );
40+ if (AttrName.size () >= 4 && AttrName.starts_with (" __" ) &&
41+ AttrName.ends_with (" __" ))
42+ AttrName = AttrName.substr (2 , AttrName.size () - 4 );
4243
4344 // Normalize the scope name, but only for gnu and clang attributes.
4445 StringRef ScopeName = Scope ? Scope->getName () : " " ;
@@ -55,23 +56,31 @@ int clang::hasAttribute(AttributeCommonInfo::Syntax Syntax,
5556 // Other OpenMP attributes (e.g. [[omp::assume]]) are handled via the
5657 // regular attribute parsing machinery.
5758 if (LangOpts.OpenMP && ScopeName == " omp" &&
58- (Name == " directive" || Name == " sequence" ))
59+ (AttrName == " directive" || AttrName == " sequence" ))
5960 return 1 ;
6061
61- int res = hasAttributeImpl (Syntax, Name , ScopeName, Target, LangOpts);
62+ int res = hasAttributeImpl (Syntax, AttrName , ScopeName, Target, LangOpts);
6263 if (res)
6364 return res;
6465
6566 if (CheckPlugins) {
6667 // Check if any plugin provides this attribute.
6768 for (auto &Ptr : getAttributePluginInstances ())
68- if (Ptr->hasSpelling (Syntax, Name ))
69+ if (Ptr->hasSpelling (Syntax, AttrName ))
6970 return 1 ;
7071 }
7172
7273 return 0 ;
7374}
7475
76+ int clang::hasAttribute (AttributeCommonInfo::Syntax Syntax,
77+ const IdentifierInfo *Scope, const IdentifierInfo *Attr,
78+ const TargetInfo &Target, const LangOptions &LangOpts,
79+ bool CheckPlugins) {
80+ return hasAttribute (Syntax, Scope, Attr->getName (), Target, LangOpts,
81+ CheckPlugins);
82+ }
83+
7584int clang::hasAttribute (AttributeCommonInfo::Syntax Syntax,
7685 const IdentifierInfo *Scope, const IdentifierInfo *Attr,
7786 const TargetInfo &Target, const LangOptions &LangOpts) {
@@ -191,7 +200,8 @@ getScopeFromNormalizedScopeName(StringRef ScopeName) {
191200 .Case (" hlsl" , AttributeCommonInfo::Scope::HLSL)
192201 .Case (" msvc" , AttributeCommonInfo::Scope::MSVC)
193202 .Case (" omp" , AttributeCommonInfo::Scope::OMP)
194- .Case (" riscv" , AttributeCommonInfo::Scope::RISCV);
203+ .Case (" riscv" , AttributeCommonInfo::Scope::RISCV)
204+ .Default (AttributeCommonInfo::Scope::UNKNOWN);
195205}
196206
197207unsigned AttributeCommonInfo::calculateAttributeSpellingListIndex () const {
@@ -206,3 +216,35 @@ unsigned AttributeCommonInfo::calculateAttributeSpellingListIndex() const {
206216
207217#include " clang/Sema/AttrSpellingListIndex.inc"
208218}
219+
220+ bool AttributeCommonInfo::isUnknownScopeName () const {
221+ return getScopeFromNormalizedScopeName (
222+ normalizeAttrScopeName (getScopeName (), getSyntax ())) ==
223+ AttributeCommonInfo::Scope::UNKNOWN;
224+ }
225+
226+ #include " clang/Basic/AttributeSpellingList.inc"
227+
228+ StringRef AttributeCommonInfo::correctScopeTypo () const {
229+ SimpleTypoCorrector Corrector (getScopeName ()->getName ());
230+
231+ for (const auto &ArrtScopeName : AttrScopeSpellingList)
232+ Corrector.add (ArrtScopeName);
233+
234+ return Corrector.getBestCandidate ();
235+ }
236+
237+ StringRef
238+ AttributeCommonInfo::correctAttributeTypo (const TargetInfo &Target,
239+ const LangOptions &LangOpts) const {
240+ SimpleTypoCorrector Corrector (getAttrName ()->getName ());
241+
242+ for (const auto &ArrtName : AttrSpellingList)
243+ Corrector.add (ArrtName);
244+
245+ if (Corrector.hasCandidate () &&
246+ hasAttribute (getSyntax (), getScopeName (), Corrector.getBestCandidate (),
247+ Target, LangOpts, /* CheckPlugins=*/ false ))
248+ return Corrector.getBestCandidate ();
249+ return StringRef ();
250+ }
0 commit comments