Skip to content

Commit db4a85b

Browse files
committed
[Clang] add fix-it hints for unknown attributes
1 parent 0adf6e8 commit db4a85b

25 files changed

+417
-248
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -601,6 +601,8 @@ Improvements to Clang's diagnostics
601601
trigger a ``'Blue' is deprecated`` warning, which can be turned off with
602602
``-Wno-deprecated-declarations-switch-case``.
603603

604+
- Clang now suggests fixit hints for unknown attributes.
605+
604606
Improvements to Clang's time-trace
605607
----------------------------------
606608

clang/include/clang/Basic/AttributeCommonInfo.h

Lines changed: 30 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#ifndef LLVM_CLANG_BASIC_ATTRIBUTECOMMONINFO_H
1515
#define LLVM_CLANG_BASIC_ATTRIBUTECOMMONINFO_H
1616

17+
#include "clang/Basic/AttributeScopeInfo.h"
1718
#include "clang/Basic/SourceLocation.h"
1819
#include "clang/Basic/TokenKinds.h"
1920

@@ -61,6 +62,7 @@ class AttributeCommonInfo {
6162
/// implicitly.
6263
AS_Implicit
6364
};
65+
6466
enum Kind {
6567
#define PARSED_ATTR(NAME) AT_##NAME,
6668
#include "clang/Basic/AttrParsedAttrList.inc"
@@ -78,9 +80,9 @@ class AttributeCommonInfo {
7880

7981
private:
8082
const IdentifierInfo *AttrName = nullptr;
81-
const IdentifierInfo *ScopeName = nullptr;
83+
AttributeScopeInfo AttrScope;
8284
SourceRange AttrRange;
83-
const SourceLocation ScopeLoc;
85+
8486
// Corresponds to the Kind enum.
8587
LLVM_PREFERRED_TYPE(Kind)
8688
unsigned AttrKind : 16;
@@ -146,33 +148,31 @@ class AttributeCommonInfo {
146148
};
147149

148150
AttributeCommonInfo(const IdentifierInfo *AttrName,
149-
const IdentifierInfo *ScopeName, SourceRange AttrRange,
150-
SourceLocation ScopeLoc, Kind AttrKind, Form FormUsed)
151-
: AttrName(AttrName), ScopeName(ScopeName), AttrRange(AttrRange),
152-
ScopeLoc(ScopeLoc), AttrKind(AttrKind),
153-
SyntaxUsed(FormUsed.getSyntax()),
151+
AttributeScopeInfo AttrScope, SourceRange AttrRange,
152+
Kind AttrKind, Form FormUsed)
153+
: AttrName(AttrName), AttrScope(AttrScope), AttrRange(AttrRange),
154+
AttrKind(AttrKind), SyntaxUsed(FormUsed.getSyntax()),
154155
SpellingIndex(FormUsed.getSpellingIndex()),
155156
IsAlignas(FormUsed.isAlignas()),
156157
IsRegularKeywordAttribute(FormUsed.isRegularKeywordAttribute()) {
157158
assert(SyntaxUsed >= AS_GNU && SyntaxUsed <= AS_Implicit &&
158159
"Invalid syntax!");
159160
}
160161

161-
AttributeCommonInfo(const IdentifierInfo *AttrName,
162-
const IdentifierInfo *ScopeName, SourceRange AttrRange,
163-
SourceLocation ScopeLoc, Form FormUsed)
162+
AttributeCommonInfo(const IdentifierInfo *AttrName, AttributeScopeInfo Scope,
163+
SourceRange AttrRange, Form FormUsed)
164164
: AttributeCommonInfo(
165-
AttrName, ScopeName, AttrRange, ScopeLoc,
166-
getParsedKind(AttrName, ScopeName, FormUsed.getSyntax()),
165+
AttrName, Scope, AttrRange,
166+
getParsedKind(AttrName, Scope.getName(), FormUsed.getSyntax()),
167167
FormUsed) {}
168168

169169
AttributeCommonInfo(const IdentifierInfo *AttrName, SourceRange AttrRange,
170170
Form FormUsed)
171-
: AttributeCommonInfo(AttrName, nullptr, AttrRange, SourceLocation(),
171+
: AttributeCommonInfo(AttrName, AttributeScopeInfo(), AttrRange,
172172
FormUsed) {}
173173

174174
AttributeCommonInfo(SourceRange AttrRange, Kind K, Form FormUsed)
175-
: AttributeCommonInfo(nullptr, nullptr, AttrRange, SourceLocation(), K,
175+
: AttributeCommonInfo(nullptr, AttributeScopeInfo(), AttrRange, K,
176176
FormUsed) {}
177177

178178
AttributeCommonInfo(AttributeCommonInfo &&) = default;
@@ -190,17 +190,27 @@ class AttributeCommonInfo {
190190
SourceRange getRange() const { return AttrRange; }
191191
void setRange(SourceRange R) { AttrRange = R; }
192192

193-
bool hasScope() const { return ScopeName; }
194-
const IdentifierInfo *getScopeName() const { return ScopeName; }
195-
SourceLocation getScopeLoc() const { return ScopeLoc; }
193+
bool hasScope() const { return AttrScope.isValid(); }
194+
bool isExplicitScope() const { return AttrScope.IsExplicit(); }
195+
196+
const IdentifierInfo *getScopeName() const { return AttrScope.getName(); }
197+
SourceLocation getScopeLoc() const { return AttrScope.getNameLoc(); }
196198

197199
/// Gets the normalized full name, which consists of both scope and name and
198200
/// with surrounding underscores removed as appropriate (e.g.
199201
/// __gnu__::__attr__ will be normalized to gnu::attr).
200202
std::string getNormalizedFullName() const;
201-
std::optional<std::string>
202-
getCorrectedFullName(const TargetInfo &Target,
203-
const LangOptions &LangOpts) const;
203+
std::string getNormalizedFullName(StringRef ScopeName,
204+
StringRef AttrName) const;
205+
StringRef getNormalizedScopeName() const;
206+
StringRef getNormalizedAttrName(StringRef ScopeName) const;
207+
208+
std::optional<StringRef> tryGetCorrectedScopeName(StringRef ScopeName) const;
209+
std::optional<StringRef>
210+
tryGetCorrectedAttrName(StringRef ScopeName, StringRef AttrName,
211+
const TargetInfo &Target,
212+
const LangOptions &LangOpts) const;
213+
204214
SourceRange getNormalizedRange() const;
205215

206216
bool isDeclspecAttribute() const { return SyntaxUsed == AS_Declspec; }
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
#ifndef LLVM_CLANG_BASIC_ATTRIBUTESCOPEINFO_H
2+
#define LLVM_CLANG_BASIC_ATTRIBUTESCOPEINFO_H
3+
4+
#include "clang/Basic/SourceLocation.h"
5+
6+
namespace clang {
7+
8+
class IdentifierInfo;
9+
10+
class AttributeScopeInfo {
11+
public:
12+
AttributeScopeInfo() = default;
13+
14+
AttributeScopeInfo(const IdentifierInfo *Name, SourceLocation NameLoc)
15+
: Name(Name), NameLoc(NameLoc) {}
16+
17+
AttributeScopeInfo(const IdentifierInfo *Name, SourceLocation NameLoc,
18+
SourceLocation UsingPrefixLoc)
19+
: Name(Name), NameLoc(NameLoc), UsingPrefixLoc(UsingPrefixLoc) {}
20+
21+
const IdentifierInfo *getName() const { return Name; }
22+
SourceLocation getNameLoc() const { return NameLoc; }
23+
24+
bool isValid() const { return Name != nullptr; }
25+
bool IsExplicit() const { return UsingPrefixLoc.isInvalid(); }
26+
27+
private:
28+
const IdentifierInfo *Name = nullptr;
29+
SourceLocation NameLoc;
30+
SourceLocation UsingPrefixLoc;
31+
};
32+
33+
} // namespace clang
34+
35+
#endif // LLVM_CLANG_BASIC_ATTRIBUTESCOPEINFO_H

0 commit comments

Comments
 (0)