-
Notifications
You must be signed in to change notification settings - Fork 15.3k
[Clang] add typo correction for unknown attribute names #140629
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Clang] add typo correction for unknown attribute names #140629
Conversation
|
@llvm/pr-subscribers-clang Author: Oleksandr T. (a-tarasyuk) ChangesThis patch enhances Clang's diagnosis for unknown attributes by providing typo correction suggestions for known attributes. [[gmu::deprected]] // expected-warning {{unknown attribute 'gmu::deprected' ignored; did you mean 'gnu::deprecated'?}}
int f1(void) {
return 0;
}
[[deprected]] // expected-warning {{unknown attribute 'deprected' ignored; did you mean 'deprecated'?}}
int f2(void) {
return 0;
}Patch is 30.20 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/140629.diff 20 Files Affected:
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index ac9baf229b489..deee00128c1fa 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -561,6 +561,8 @@ Improvements to Clang's diagnostics
- Fixed a crash when checking a ``__thread``-specified variable declaration
with a dependent type in C++. (#GH140509)
+- Clang now suggests corrections for unknown attribute names.
+
Improvements to Clang's time-trace
----------------------------------
diff --git a/clang/include/clang/Basic/AttributeCommonInfo.h b/clang/include/clang/Basic/AttributeCommonInfo.h
index 6db7b53317e7d..b4b8345b4ed40 100644
--- a/clang/include/clang/Basic/AttributeCommonInfo.h
+++ b/clang/include/clang/Basic/AttributeCommonInfo.h
@@ -21,6 +21,8 @@ namespace clang {
class ASTRecordWriter;
class IdentifierInfo;
+class LangOptions;
+class TargetInfo;
class AttributeCommonInfo {
public:
@@ -196,6 +198,9 @@ class AttributeCommonInfo {
/// with surrounding underscores removed as appropriate (e.g.
/// __gnu__::__attr__ will be normalized to gnu::attr).
std::string getNormalizedFullName() const;
+ std::optional<std::string>
+ getCorrectedFullName(const TargetInfo &Target,
+ const LangOptions &LangOpts) const;
SourceRange getNormalizedRange() const;
bool isDeclspecAttribute() const { return SyntaxUsed == AS_Declspec; }
diff --git a/clang/include/clang/Basic/Attributes.h b/clang/include/clang/Basic/Attributes.h
index 99bb668fe32d0..9cf6fb3d89019 100644
--- a/clang/include/clang/Basic/Attributes.h
+++ b/clang/include/clang/Basic/Attributes.h
@@ -19,6 +19,10 @@ class TargetInfo;
/// Return the version number associated with the attribute if we
/// recognize and implement the attribute specified by the given information.
+int hasAttribute(AttributeCommonInfo::Syntax Syntax, llvm::StringRef ScopeName,
+ llvm::StringRef AttrName, const TargetInfo &Target,
+ const LangOptions &LangOpts, bool CheckPlugins);
+
int hasAttribute(AttributeCommonInfo::Syntax Syntax,
const IdentifierInfo *Scope, const IdentifierInfo *Attr,
const TargetInfo &Target, const LangOptions &LangOpts);
diff --git a/clang/include/clang/Basic/CMakeLists.txt b/clang/include/clang/Basic/CMakeLists.txt
index 265ea1fc06494..1873878e2e46b 100644
--- a/clang/include/clang/Basic/CMakeLists.txt
+++ b/clang/include/clang/Basic/CMakeLists.txt
@@ -79,6 +79,12 @@ clang_tablegen(CXX11AttributeInfo.inc -gen-cxx11-attribute-info
TARGET CXX11AttributeInfo
)
+ clang_tablegen(AttributeSpellingList.inc -gen-attribute-spelling-list
+ -I ${CMAKE_CURRENT_SOURCE_DIR}/../../
+ SOURCE Attr.td
+ TARGET AttributeSpellingList
+ )
+
clang_tablegen(Builtins.inc -gen-clang-builtins
SOURCE Builtins.td
TARGET ClangBuiltins)
diff --git a/clang/include/clang/Basic/DiagnosticCommonKinds.td b/clang/include/clang/Basic/DiagnosticCommonKinds.td
index e4d94fefbbf3d..0bd8a423c393e 100644
--- a/clang/include/clang/Basic/DiagnosticCommonKinds.td
+++ b/clang/include/clang/Basic/DiagnosticCommonKinds.td
@@ -181,6 +181,8 @@ def err_opencl_unknown_type_specifier : Error<
def warn_unknown_attribute_ignored : Warning<
"unknown attribute %0 ignored">, InGroup<UnknownAttributes>;
+def warn_unknown_attribute_ignored_suggestion : Warning<
+ "unknown attribute %0 ignored; did you mean '%1'?">, InGroup<UnknownAttributes>;
def warn_attribute_ignored : Warning<"%0 attribute ignored">,
InGroup<IgnoredAttributes>;
def err_keyword_not_supported_on_target : Error<
diff --git a/clang/include/clang/Basic/SimpleTypoCorrection.h b/clang/include/clang/Basic/SimpleTypoCorrection.h
new file mode 100644
index 0000000000000..4cd104f79aebe
--- /dev/null
+++ b/clang/include/clang/Basic/SimpleTypoCorrection.h
@@ -0,0 +1,35 @@
+#ifndef LLVM_CLANG_BASIC_SIMPLETYPOCORRECTION_H
+#define LLVM_CLANG_BASIC_SIMPLETYPOCORRECTION_H
+
+#include "clang/Basic/LLVM.h"
+#include "llvm/ADT/StringRef.h"
+
+namespace clang {
+
+class IdentifierInfo;
+
+class SimpleTypoCorrection {
+ StringRef BestCandidate;
+ StringRef Typo;
+
+ const unsigned MaxEditDistance;
+ unsigned BestEditDistance;
+ unsigned BestIndex;
+ unsigned NextIndex;
+
+public:
+ explicit SimpleTypoCorrection(StringRef Typo)
+ : BestCandidate(), Typo(Typo), MaxEditDistance((Typo.size() + 2) / 3),
+ BestEditDistance(MaxEditDistance + 1), BestIndex(0), NextIndex(0) {}
+
+ void add(const StringRef Candidate);
+ void add(const char *Candidate);
+ void add(const IdentifierInfo *Candidate);
+
+ std::optional<StringRef> getCorrection() const;
+ bool hasCorrection() const;
+ unsigned getCorrectionIndex() const;
+};
+} // namespace clang
+
+#endif // LLVM_CLANG_BASIC_SIMPLETYPOCORRECTION_H
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 5ec67087aeea4..d7a3a81065d33 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -5033,6 +5033,8 @@ class Sema final : public SemaBase {
/// which might be lying around on it.
void checkUnusedDeclAttributes(Declarator &D);
+ void DiagnoseUnknownAttribute(const ParsedAttr &AL);
+
/// DeclClonePragmaWeak - clone existing decl (maybe definition),
/// \#pragma weak needs a non-definition decl and source may not have one.
NamedDecl *DeclClonePragmaWeak(NamedDecl *ND, const IdentifierInfo *II,
diff --git a/clang/lib/AST/CommentSema.cpp b/clang/lib/AST/CommentSema.cpp
index bd2206bb8a3bc..fb745fc560d2f 100644
--- a/clang/lib/AST/CommentSema.cpp
+++ b/clang/lib/AST/CommentSema.cpp
@@ -13,6 +13,7 @@
#include "clang/AST/DeclTemplate.h"
#include "clang/Basic/DiagnosticComment.h"
#include "clang/Basic/LLVM.h"
+#include "clang/Basic/SimpleTypoCorrection.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Lex/Preprocessor.h"
#include "llvm/ADT/StringSwitch.h"
@@ -975,69 +976,22 @@ unsigned Sema::resolveParmVarReference(StringRef Name,
return ParamCommandComment::InvalidParamIndex;
}
-namespace {
-class SimpleTypoCorrector {
- const NamedDecl *BestDecl;
-
- StringRef Typo;
- const unsigned MaxEditDistance;
-
- unsigned BestEditDistance;
- unsigned BestIndex;
- unsigned NextIndex;
-
-public:
- explicit SimpleTypoCorrector(StringRef Typo)
- : BestDecl(nullptr), Typo(Typo), MaxEditDistance((Typo.size() + 2) / 3),
- BestEditDistance(MaxEditDistance + 1), BestIndex(0), NextIndex(0) {}
-
- void addDecl(const NamedDecl *ND);
-
- const NamedDecl *getBestDecl() const {
- if (BestEditDistance > MaxEditDistance)
- return nullptr;
-
- return BestDecl;
- }
+unsigned
+Sema::correctTypoInParmVarReference(StringRef Typo,
+ ArrayRef<const ParmVarDecl *> ParamVars) {
+ SimpleTypoCorrection STC(Typo);
+ for (unsigned i = 0, e = ParamVars.size(); i != e; ++i) {
+ const ParmVarDecl *Param = ParamVars[i];
+ if (!Param)
+ continue;
- unsigned getBestDeclIndex() const {
- assert(getBestDecl());
- return BestIndex;
+ STC.add(Param->getIdentifier());
}
-};
-
-void SimpleTypoCorrector::addDecl(const NamedDecl *ND) {
- unsigned CurrIndex = NextIndex++;
-
- const IdentifierInfo *II = ND->getIdentifier();
- if (!II)
- return;
- StringRef Name = II->getName();
- unsigned MinPossibleEditDistance = abs((int)Name.size() - (int)Typo.size());
- if (MinPossibleEditDistance > 0 &&
- Typo.size() / MinPossibleEditDistance < 3)
- return;
+ if (STC.hasCorrection())
+ return STC.getCorrectionIndex();
- unsigned EditDistance = Typo.edit_distance(Name, true, MaxEditDistance);
- if (EditDistance < BestEditDistance) {
- BestEditDistance = EditDistance;
- BestDecl = ND;
- BestIndex = CurrIndex;
- }
-}
-} // end anonymous namespace
-
-unsigned Sema::correctTypoInParmVarReference(
- StringRef Typo,
- ArrayRef<const ParmVarDecl *> ParamVars) {
- SimpleTypoCorrector Corrector(Typo);
- for (unsigned i = 0, e = ParamVars.size(); i != e; ++i)
- Corrector.addDecl(ParamVars[i]);
- if (Corrector.getBestDecl())
- return Corrector.getBestDeclIndex();
- else
- return ParamCommandComment::InvalidParamIndex;
+ return ParamCommandComment::InvalidParamIndex;
}
namespace {
@@ -1079,16 +1033,18 @@ bool Sema::resolveTParamReference(
namespace {
void CorrectTypoInTParamReferenceHelper(
- const TemplateParameterList *TemplateParameters,
- SimpleTypoCorrector &Corrector) {
+ const TemplateParameterList *TemplateParameters,
+ SimpleTypoCorrection &STC) {
for (unsigned i = 0, e = TemplateParameters->size(); i != e; ++i) {
const NamedDecl *Param = TemplateParameters->getParam(i);
- Corrector.addDecl(Param);
+ if (!Param)
+ continue;
+
+ STC.add(Param->getIdentifier());
if (const TemplateTemplateParmDecl *TTP =
dyn_cast<TemplateTemplateParmDecl>(Param))
- CorrectTypoInTParamReferenceHelper(TTP->getTemplateParameters(),
- Corrector);
+ CorrectTypoInTParamReferenceHelper(TTP->getTemplateParameters(), STC);
}
}
} // end anonymous namespace
@@ -1096,13 +1052,12 @@ void CorrectTypoInTParamReferenceHelper(
StringRef Sema::correctTypoInTParamReference(
StringRef Typo,
const TemplateParameterList *TemplateParameters) {
- SimpleTypoCorrector Corrector(Typo);
- CorrectTypoInTParamReferenceHelper(TemplateParameters, Corrector);
- if (const NamedDecl *ND = Corrector.getBestDecl()) {
- const IdentifierInfo *II = ND->getIdentifier();
- assert(II && "SimpleTypoCorrector should not return this decl");
- return II->getName();
- }
+ SimpleTypoCorrection STC(Typo);
+ CorrectTypoInTParamReferenceHelper(TemplateParameters, STC);
+
+ if (auto CorrectedTParamReference = STC.getCorrection())
+ return *CorrectedTParamReference;
+
return StringRef();
}
diff --git a/clang/lib/Basic/Attributes.cpp b/clang/lib/Basic/Attributes.cpp
index 8ff5cc54ccc93..0c0a816c78039 100644
--- a/clang/lib/Basic/Attributes.cpp
+++ b/clang/lib/Basic/Attributes.cpp
@@ -15,6 +15,7 @@
#include "clang/Basic/IdentifierTable.h"
#include "clang/Basic/LangOptions.h"
#include "clang/Basic/ParsedAttrInfo.h"
+#include "clang/Basic/SimpleTypoCorrection.h"
#include "clang/Basic/TargetInfo.h"
#include "llvm/ADT/StringMap.h"
@@ -22,30 +23,37 @@
using namespace clang;
-static int hasAttributeImpl(AttributeCommonInfo::Syntax Syntax, StringRef Name,
- StringRef ScopeName, const TargetInfo &Target,
- const LangOptions &LangOpts) {
+static StringRef canonicalizeScopeName(StringRef Name) {
+ // Normalize the scope name, but only for gnu and clang attributes.
+ if (Name == "__gnu__")
+ return "gnu";
-#include "clang/Basic/AttrHasAttributeImpl.inc"
+ if (Name == "_Clang")
+ return "clang";
- return 0;
+ return Name;
}
-int clang::hasAttribute(AttributeCommonInfo::Syntax Syntax,
- const IdentifierInfo *Scope, const IdentifierInfo *Attr,
- const TargetInfo &Target, const LangOptions &LangOpts,
- bool CheckPlugins) {
- StringRef Name = Attr->getName();
+static StringRef canonicalizeAttrName(StringRef Name) {
// Normalize the attribute name, __foo__ becomes foo.
if (Name.size() >= 4 && Name.starts_with("__") && Name.ends_with("__"))
- Name = Name.substr(2, Name.size() - 4);
+ return Name.substr(2, Name.size() - 4);
- // Normalize the scope name, but only for gnu and clang attributes.
- StringRef ScopeName = Scope ? Scope->getName() : "";
- if (ScopeName == "__gnu__")
- ScopeName = "gnu";
- else if (ScopeName == "_Clang")
- ScopeName = "clang";
+ return Name;
+}
+
+static int hasAttributeImpl(AttributeCommonInfo::Syntax Syntax, StringRef Name,
+ StringRef ScopeName, const TargetInfo &Target,
+ const LangOptions &LangOpts) {
+#include "clang/Basic/AttrHasAttributeImpl.inc"
+ return 0;
+}
+
+int clang::hasAttribute(AttributeCommonInfo::Syntax Syntax, StringRef ScopeName,
+ StringRef Name, const TargetInfo &Target,
+ const LangOptions &LangOpts, bool CheckPlugins) {
+ ScopeName = canonicalizeScopeName(ScopeName);
+ Name = canonicalizeAttrName(Name);
// As a special case, look for the omp::sequence and omp::directive
// attributes. We support those, but not through the typical attribute
@@ -72,6 +80,14 @@ int clang::hasAttribute(AttributeCommonInfo::Syntax Syntax,
return 0;
}
+int clang::hasAttribute(AttributeCommonInfo::Syntax Syntax,
+ const IdentifierInfo *Scope, const IdentifierInfo *Attr,
+ const TargetInfo &Target, const LangOptions &LangOpts,
+ bool CheckPlugins) {
+ return hasAttribute(Syntax, Scope ? Scope->getName() : "", Attr->getName(),
+ Target, LangOpts, CheckPlugins);
+}
+
int clang::hasAttribute(AttributeCommonInfo::Syntax Syntax,
const IdentifierInfo *Scope, const IdentifierInfo *Attr,
const TargetInfo &Target, const LangOptions &LangOpts) {
@@ -90,25 +106,25 @@ const char *attr::getSubjectMatchRuleSpelling(attr::SubjectMatchRule Rule) {
}
static StringRef
-normalizeAttrScopeName(const IdentifierInfo *Scope,
+normalizeAttrScopeName(StringRef ScopeName,
AttributeCommonInfo::Syntax SyntaxUsed) {
- if (!Scope)
- return "";
-
- // Normalize the "__gnu__" scope name to be "gnu" and the "_Clang" scope name
- // to be "clang".
- StringRef ScopeName = Scope->getName();
if (SyntaxUsed == AttributeCommonInfo::AS_CXX11 ||
- SyntaxUsed == AttributeCommonInfo::AS_C23) {
- if (ScopeName == "__gnu__")
- ScopeName = "gnu";
- else if (ScopeName == "_Clang")
- ScopeName = "clang";
- }
+ SyntaxUsed == AttributeCommonInfo::AS_C23)
+ return canonicalizeScopeName(ScopeName);
+
return ScopeName;
}
-static StringRef normalizeAttrName(const IdentifierInfo *Name,
+static StringRef
+normalizeAttrScopeName(const IdentifierInfo *ScopeName,
+ AttributeCommonInfo::Syntax SyntaxUsed) {
+ if (ScopeName)
+ return normalizeAttrScopeName(ScopeName->getName(), SyntaxUsed);
+
+ return "";
+}
+
+static StringRef normalizeAttrName(StringRef AttrName,
StringRef NormalizedScopeName,
AttributeCommonInfo::Syntax SyntaxUsed) {
// Normalize the attribute name, __foo__ becomes foo. This is only allowable
@@ -119,10 +135,9 @@ static StringRef normalizeAttrName(const IdentifierInfo *Name,
SyntaxUsed == AttributeCommonInfo::AS_C23) &&
(NormalizedScopeName.empty() || NormalizedScopeName == "gnu" ||
NormalizedScopeName == "clang"));
- StringRef AttrName = Name->getName();
- if (ShouldNormalize && AttrName.size() >= 4 && AttrName.starts_with("__") &&
- AttrName.ends_with("__"))
- AttrName = AttrName.slice(2, AttrName.size() - 2);
+
+ if (ShouldNormalize)
+ return canonicalizeAttrName(AttrName);
return AttrName;
}
@@ -137,16 +152,11 @@ bool AttributeCommonInfo::isClangScope() const {
#include "clang/Sema/AttrParsedAttrKinds.inc"
-static SmallString<64> normalizeName(const IdentifierInfo *Name,
- const IdentifierInfo *Scope,
+static SmallString<64> normalizeName(StringRef AttrName, StringRef ScopeName,
AttributeCommonInfo::Syntax SyntaxUsed) {
- StringRef ScopeName = normalizeAttrScopeName(Scope, SyntaxUsed);
- StringRef AttrName = normalizeAttrName(Name, ScopeName, SyntaxUsed);
-
- std::string StrAttrName = AttrName.str();
- if (SyntaxUsed == AttributeCommonInfo::AS_HLSLAnnotation)
- StrAttrName = AttrName.lower();
-
+ std::string StrAttrName = SyntaxUsed == AttributeCommonInfo::AS_HLSLAnnotation
+ ? AttrName.lower()
+ : AttrName.str();
SmallString<64> FullName = ScopeName;
if (!ScopeName.empty()) {
assert(SyntaxUsed == AttributeCommonInfo::AS_CXX11 ||
@@ -154,10 +164,18 @@ static SmallString<64> normalizeName(const IdentifierInfo *Name,
FullName += "::";
}
FullName += StrAttrName;
-
return FullName;
}
+static SmallString<64> normalizeName(const IdentifierInfo *Name,
+ const IdentifierInfo *Scope,
+ AttributeCommonInfo::Syntax SyntaxUsed) {
+ StringRef ScopeName = normalizeAttrScopeName(Scope, SyntaxUsed);
+ StringRef AttrName =
+ normalizeAttrName(Name->getName(), ScopeName, SyntaxUsed);
+ return normalizeName(AttrName, ScopeName, SyntaxUsed);
+}
+
AttributeCommonInfo::Kind
AttributeCommonInfo::getParsedKind(const IdentifierInfo *Name,
const IdentifierInfo *ScopeName,
@@ -167,8 +185,8 @@ AttributeCommonInfo::getParsedKind(const IdentifierInfo *Name,
AttributeCommonInfo::AttrArgsInfo
AttributeCommonInfo::getCXX11AttrArgsInfo(const IdentifierInfo *Name) {
- StringRef AttrName =
- normalizeAttrName(Name, /*NormalizedScopeName*/ "", Syntax::AS_CXX11);
+ StringRef AttrName = normalizeAttrName(
+ Name->getName(), /*NormalizedScopeName*/ "", Syntax::AS_CXX11);
#define CXX11_ATTR_ARGS_INFO
return llvm::StringSwitch<AttributeCommonInfo::AttrArgsInfo>(AttrName)
#include "clang/Basic/CXX11AttributeInfo.inc"
@@ -203,10 +221,47 @@ unsigned AttributeCommonInfo::calculateAttributeSpellingListIndex() const {
// attribute spell list index matching code.
auto Syntax = static_cast<AttributeCommonInfo::Syntax>(getSyntax());
StringRef ScopeName = normalizeAttrScopeName(getScopeName(), Syntax);
- StringRef Name = normalizeAttrName(getAttrName(), ScopeName, Syntax);
-
+ StringRef Name =
+ normalizeAttrName(getAttrName()->getName(), ScopeName, Syntax);
AttributeCommonInfo::Scope ComputedScope =
getScopeFromNormalizedScopeName(ScopeName);
#include "clang/Sema/AttrSpellingListIndex.inc"
}
+
+#include "clang/Basic/AttributeSpellingList.inc"
+
+std::optional<std::string>
+AttributeCommonInfo::getCorrectedFullName(const TargetInfo &Target,
+ const LangOptions &LangOpts) const {
+ StringRef ScopeName = normalizeAttrScopeName(getScopeName(), getSyntax());
+ if (ScopeName.size() > 0 &&
+ llvm::none_of(AttrScopeSpellingList,
+ [&](const char *S) { return S == ScopeName; })) {
+ SimpleTypoCorrection STC(ScopeName);
+ for (const auto &Scope : AttrScopeSpellingList)
+ STC.add(Scope);
+
+ if (auto CorrectedScopeName = STC.getCorrection())
+ ScopeName = *CorrectedScopeName;
+ }
+
+ StringRef AttrName =
+ normalizeAttrName(getAttrName()->getName(), ScopeName, getSyntax());
+ if (llvm::none_of(AttrSpellingList,
+ [&](const char *A) { return A == AttrName; })) {
+ SimpleTypoCorrection STC(AttrName);
+ for (const auto &Attr : AttrSpellingList)
+ STC.add(Attr);
+
+ if (auto CorrectedAttrName = STC.getCorrection())
+ AttrName = *CorrectedAttrName;
+ }
+
+ if (hasAttribute(getSyntax(), ScopeName, AttrName, Target, LangOpts,
+ /*CheckPlugins=*/true))
+ return static_cast<std::string>(
+ normalizeName(AttrName, ScopeName, getSyntax()));
+
+ return std::nullopt;
+}
diff --git a/clang/lib/Basic/CMakeLists.txt b/clang/lib/Basic/CMakeLists.txt
index 0eacf79f5d478..f8a31c890ac4d 100644
--- a/clang/lib/Basic/CMakeLists.txt
+++ b/clang/lib/Basic/CMakeLists.txt
@@ -86,6 +86,7 @@ add_clang_library(clangBasic
SanitizerSpecialCaseList.cpp
Sanitizers.cpp
Sarif.cpp
+ SimpleTypoCorrection.cpp
SourceLocation.cpp
SourceManager.cpp
SourceMgrAdapter.cpp
diff --git a/clang/lib/Basic/SimpleTypoCorrection.cpp b/clang/lib/Basic/SimpleTypoCorrection.cpp
new file mode 100644
index 0000000000000..c98b89d9f080d
--- /dev/null
+++ b/clang/lib/Basic/SimpleTypoCorrection.cpp
@@ -0,0 +1,52 @@
+#include "clang/Basic/SimpleTypoCorrection.h"
+#include "clang/Basic/IdentifierTable.h"
+#include "clang/Basic/LLVM.h"
+#include "llvm/ADT/StringRef.h"
+
+using namespace clang;
+
+void SimpleTypoCorr...
[truncated]
|
|
✅ With the latest revision this PR passed the C/C++ code formatter. |
AaronBallman
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM but please wait a day before landing in case @erichkeane has comments.
erichkeane
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
1 nit, else lgtm.
…/unknown-attributes-typo-correction
erichkeane
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thought I'd already +1ed! with teh copyright headers, this LGTM.
|
@a-tarasyuk I'm getting the following warnings. Would you mind taking a look? |
|
@kazutakahirata Sure, I'll create PR to fix it |
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/72/builds/11402 Here is the relevant piece of the build log for the reference |
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/168/builds/12358 Here is the relevant piece of the build log for the reference |
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/186/builds/9245 Here is the relevant piece of the build log for the reference |
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/145/builds/7176 Here is the relevant piece of the build log for the reference |
…41090) Fixes #140629 (comment) --- This patch adds `#undef ATTR_NAME` and `#undef ATTR_SCOPE_NAME` to the end of the generated `AttributeSpellingList.inc` file to prevent macro redefinition warnings
…emitter (#141090) Fixes llvm/llvm-project#140629 (comment) --- This patch adds `#undef ATTR_NAME` and `#undef ATTR_SCOPE_NAME` to the end of the generated `AttributeSpellingList.inc` file to prevent macro redefinition warnings
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/64/builds/3739 Here is the relevant piece of the build log for the reference |
This patch enhances Clang's diagnosis for unknown attributes by providing typo correction suggestions for known attributes.