Skip to content

Commit 3f9c35a

Browse files
committed
[Clang] include attribute scope in diagnostics
1 parent 362b9d7 commit 3f9c35a

File tree

95 files changed

+527
-488
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

95 files changed

+527
-488
lines changed

clang/include/clang/Basic/AttributeCommonInfo.h

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#define LLVM_CLANG_BASIC_ATTRIBUTECOMMONINFO_H
1616

1717
#include "clang/Basic/AttributeScopeInfo.h"
18+
#include "clang/Basic/Diagnostic.h"
1819
#include "clang/Basic/SourceLocation.h"
1920
#include "clang/Basic/TokenKinds.h"
2021

@@ -175,6 +176,10 @@ class AttributeCommonInfo {
175176
: AttributeCommonInfo(nullptr, AttributeScopeInfo(), AttrRange, K,
176177
FormUsed) {}
177178

179+
AttributeCommonInfo(SourceRange AttrRange, AttributeScopeInfo AttrScope,
180+
Kind K, Form FormUsed)
181+
: AttributeCommonInfo(nullptr, AttrScope, AttrRange, K, FormUsed) {}
182+
178183
AttributeCommonInfo(AttributeCommonInfo &&) = default;
179184
AttributeCommonInfo(const AttributeCommonInfo &) = default;
180185

@@ -292,6 +297,45 @@ inline bool doesKeywordAttributeTakeArgs(tok::TokenKind Kind) {
292297
}
293298
}
294299

300+
inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB,
301+
const AttributeCommonInfo &CI) {
302+
DB.AddTaggedVal(reinterpret_cast<uint64_t>(&CI),
303+
DiagnosticsEngine::ak_attr_info);
304+
return DB;
305+
}
306+
307+
inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB,
308+
const AttributeCommonInfo *CI) {
309+
DB.AddTaggedVal(reinterpret_cast<uint64_t>(CI),
310+
DiagnosticsEngine::ak_attr_info);
311+
return DB;
312+
}
313+
314+
/// AttributeCommonInfo has a non-explicit constructor which takes an
315+
/// SourceRange as its only argument, this constructor has many uses so making
316+
/// it explicit is hard. This constructor causes ambiguity with
317+
/// DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, SourceRange R).
318+
/// We use SFINAE to disable any conversion and remove any ambiguity.
319+
template <
320+
typename ACI,
321+
std::enable_if_t<std::is_same<ACI, AttributeCommonInfo>::value, int> = 0>
322+
inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB,
323+
const ACI &CI) {
324+
DB.AddTaggedVal(reinterpret_cast<uint64_t>(&CI),
325+
DiagnosticsEngine::ak_attr_info);
326+
return DB;
327+
}
328+
329+
template <
330+
typename ACI,
331+
std::enable_if_t<std::is_same<ACI, AttributeCommonInfo>::value, int> = 0>
332+
inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB,
333+
const ACI *CI) {
334+
DB.AddTaggedVal(reinterpret_cast<uint64_t>(CI),
335+
DiagnosticsEngine::ak_attr_info);
336+
return DB;
337+
}
338+
295339
} // namespace clang
296340

297341
#endif // LLVM_CLANG_BASIC_ATTRIBUTECOMMONINFO_H

clang/include/clang/Basic/Diagnostic.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,9 @@ class DiagnosticsEngine : public RefCountedBase<DiagnosticsEngine> {
289289

290290
/// Expr *
291291
ak_expr,
292+
293+
/// AttributeCommonInfo *
294+
ak_attr_info,
292295
};
293296

294297
/// Represents on argument value, which is a union discriminated

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3275,10 +3275,11 @@ def err_attribute_wrong_number_arguments : Error<
32753275
def err_attribute_wrong_number_arguments_for : Error <
32763276
"%0 attribute references function %1, which %plural{0:takes no arguments|1:takes one argument|"
32773277
":takes exactly %2 arguments}2">;
3278-
def err_callback_attribute_wrong_arg_count : Error<
3279-
"'callback' attribute references function of type %0 which expects %1 "
3280-
"%plural{1:argument|:arguments}1 but attribute specifies %2 parameter index "
3281-
"%plural{1:argument|:arguments}2">;
3278+
def err_callback_attribute_wrong_arg_count
3279+
: Error<"%0 attribute references function of type %1 which expects %2 "
3280+
"%plural{1:argument|:arguments}2 but attribute specifies %3 "
3281+
"parameter index "
3282+
"%plural{1:argument|:arguments}3">;
32823283
def err_attribute_bounds_for_function : Error<
32833284
"%0 attribute references parameter %1, but the function %2 has only %3 parameters">;
32843285
def err_attribute_no_member_function : Error<
@@ -4694,9 +4695,9 @@ def note_protocol_decl : Note<
46944695
"protocol is declared here">;
46954696
def note_protocol_decl_undefined : Note<
46964697
"protocol %0 has no definition">;
4697-
def err_attribute_preferred_name_arg_invalid : Error<
4698-
"argument %0 to 'preferred_name' attribute is not a typedef for "
4699-
"a specialization of %1">;
4698+
def err_attribute_preferred_name_arg_invalid
4699+
: Error<"argument %0 to %1 attribute is not a typedef for "
4700+
"a specialization of %2">;
47004701
def err_attribute_builtin_alias : Error<
47014702
"%0 attribute can only be applied to a ARM, HLSL, SPIR-V or RISC-V builtin">;
47024703

clang/include/clang/Sema/ParsedAttr.h

Lines changed: 0 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1094,45 +1094,6 @@ enum AttributeDeclKind {
10941094
ExpectedTypedef,
10951095
};
10961096

1097-
inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB,
1098-
const ParsedAttr &At) {
1099-
DB.AddTaggedVal(reinterpret_cast<uint64_t>(At.getAttrName()),
1100-
DiagnosticsEngine::ak_identifierinfo);
1101-
return DB;
1102-
}
1103-
1104-
inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB,
1105-
const ParsedAttr *At) {
1106-
DB.AddTaggedVal(reinterpret_cast<uint64_t>(At->getAttrName()),
1107-
DiagnosticsEngine::ak_identifierinfo);
1108-
return DB;
1109-
}
1110-
1111-
/// AttributeCommonInfo has a non-explicit constructor which takes an
1112-
/// SourceRange as its only argument, this constructor has many uses so making
1113-
/// it explicit is hard. This constructor causes ambiguity with
1114-
/// DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, SourceRange R).
1115-
/// We use SFINAE to disable any conversion and remove any ambiguity.
1116-
template <
1117-
typename ACI,
1118-
std::enable_if_t<std::is_same<ACI, AttributeCommonInfo>::value, int> = 0>
1119-
inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB,
1120-
const ACI &CI) {
1121-
DB.AddTaggedVal(reinterpret_cast<uint64_t>(CI.getAttrName()),
1122-
DiagnosticsEngine::ak_identifierinfo);
1123-
return DB;
1124-
}
1125-
1126-
template <
1127-
typename ACI,
1128-
std::enable_if_t<std::is_same<ACI, AttributeCommonInfo>::value, int> = 0>
1129-
inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB,
1130-
const ACI *CI) {
1131-
DB.AddTaggedVal(reinterpret_cast<uint64_t>(CI->getAttrName()),
1132-
DiagnosticsEngine::ak_identifierinfo);
1133-
return DB;
1134-
}
1135-
11361097
} // namespace clang
11371098

11381099
#endif // LLVM_CLANG_SEMA_PARSEDATTR_H

clang/lib/AST/ASTDiagnostic.cpp

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -506,7 +506,15 @@ void clang::FormatASTNodeDiagnosticArgument(
506506
case DiagnosticsEngine::ak_attr: {
507507
const Attr *At = reinterpret_cast<Attr *>(Val);
508508
assert(At && "Received null Attr object!");
509-
OS << '\'' << At->getSpelling() << '\'';
509+
510+
OS << '\'';
511+
if (At->hasScope()) {
512+
OS << At->getNormalizedFullName(At->getScopeName()->getName(),
513+
At->getSpelling());
514+
} else {
515+
OS << At->getSpelling();
516+
}
517+
OS << '\'';
510518
NeedQuotes = false;
511519
break;
512520
}
@@ -516,6 +524,20 @@ void clang::FormatASTNodeDiagnosticArgument(
516524
E->printPretty(OS, /*Helper=*/nullptr, Context.getPrintingPolicy());
517525
break;
518526
}
527+
case DiagnosticsEngine::ak_attr_info: {
528+
AttributeCommonInfo *AT = reinterpret_cast<AttributeCommonInfo *>(Val);
529+
assert(AT && "Received null AttributeCommonInfo object!");
530+
531+
OS << '\'';
532+
if (AT->isStandardAttributeSyntax()) {
533+
OS << AT->getNormalizedFullName();
534+
} else {
535+
OS << AT->getAttrName()->getName();
536+
}
537+
OS << '\'';
538+
NeedQuotes = false;
539+
break;
540+
}
519541
}
520542

521543
if (NeedQuotes) {

clang/lib/Basic/Diagnostic.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1349,6 +1349,7 @@ void Diagnostic::FormatDiagnostic(const char *DiagStr, const char *DiagEnd,
13491349
case DiagnosticsEngine::ak_declcontext:
13501350
case DiagnosticsEngine::ak_attr:
13511351
case DiagnosticsEngine::ak_expr:
1352+
case DiagnosticsEngine::ak_attr_info:
13521353
getDiags()->ConvertArgToString(Kind, getRawArg(ArgNo),
13531354
StringRef(Modifier, ModifierLen),
13541355
StringRef(Argument, ArgumentLen),

clang/lib/Sema/SemaDeclAttr.cpp

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1226,7 +1226,7 @@ static void handlePreferredName(Sema &S, Decl *D, const ParsedAttr &AL) {
12261226
}
12271227

12281228
S.Diag(AL.getLoc(), diag::err_attribute_preferred_name_arg_invalid)
1229-
<< T << CTD;
1229+
<< T << AL << CTD;
12301230
if (const auto *TT = T->getAs<TypedefType>())
12311231
S.Diag(TT->getDecl()->getLocation(), diag::note_entity_declared_at)
12321232
<< TT->getDecl();
@@ -4147,7 +4147,8 @@ static void handleCallbackAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
41474147

41484148
if (CalleeFnProtoType->getNumParams() != EncodingIndices.size() - 1) {
41494149
S.Diag(AL.getLoc(), diag::err_callback_attribute_wrong_arg_count)
4150-
<< QualType{CalleeFnProtoType, 0} << CalleeFnProtoType->getNumParams()
4150+
<< AL << QualType{CalleeFnProtoType, 0}
4151+
<< CalleeFnProtoType->getNumParams()
41514152
<< (unsigned)(EncodingIndices.size() - 1);
41524153
return;
41534154
}
@@ -7969,9 +7970,7 @@ void Sema::checkUnusedDeclAttributes(Declarator &D) {
79697970
}
79707971

79717972
void Sema::DiagnoseUnknownAttribute(const ParsedAttr &AL) {
7972-
std::string NormalizedFullName = '\'' + AL.getNormalizedFullName() + '\'';
79737973
SourceRange NR = AL.getNormalizedRange();
7974-
79757974
StringRef ScopeName = AL.getNormalizedScopeName();
79767975
std::optional<StringRef> CorrectedScopeName =
79777976
AL.tryGetCorrectedScopeName(ScopeName);
@@ -7993,7 +7992,7 @@ void Sema::DiagnoseUnknownAttribute(const ParsedAttr &AL) {
79937992
Diag(CorrectedScopeName ? NR.getBegin() : AL.getRange().getBegin(),
79947993
diag::warn_unknown_attribute_ignored_suggestion);
79957994

7996-
D << NormalizedFullName << CorrectedFullName;
7995+
D << AL << CorrectedFullName;
79977996

79987997
if (AL.isExplicitScope()) {
79997998
D << FixItHint::CreateReplacement(NR, CorrectedFullName) << NR;
@@ -8007,8 +8006,7 @@ void Sema::DiagnoseUnknownAttribute(const ParsedAttr &AL) {
80078006
}
80088007
}
80098008
} else {
8010-
Diag(NR.getBegin(), diag::warn_unknown_attribute_ignored)
8011-
<< NormalizedFullName << NR;
8009+
Diag(NR.getBegin(), diag::warn_unknown_attribute_ignored) << AL << NR;
80128010
}
80138011
}
80148012

clang/lib/Sema/SemaHLSL.cpp

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1382,6 +1382,15 @@ bool SemaHLSL::handleResourceTypeAttr(QualType T, const ParsedAttr &AL) {
13821382
return false;
13831383

13841384
Attr *A = nullptr;
1385+
1386+
AttributeCommonInfo ACI(
1387+
AL.getLoc(), AttributeScopeInfo(AL.getScopeName(), AL.getScopeLoc()),
1388+
AttributeCommonInfo::NoSemaHandlerAttribute,
1389+
{
1390+
AttributeCommonInfo::AS_CXX11, 0, false /*IsAlignas*/,
1391+
false /*IsRegularKeywordAttribute*/
1392+
});
1393+
13851394
switch (AL.getKind()) {
13861395
case ParsedAttr::AT_HLSLResourceClass: {
13871396
if (!AL.isArgIdent(0)) {
@@ -1401,16 +1410,16 @@ bool SemaHLSL::handleResourceTypeAttr(QualType T, const ParsedAttr &AL) {
14011410
<< "ResourceClass" << Identifier;
14021411
return false;
14031412
}
1404-
A = HLSLResourceClassAttr::Create(getASTContext(), RC, AL.getLoc());
1413+
A = HLSLResourceClassAttr::Create(getASTContext(), RC, ACI);
14051414
break;
14061415
}
14071416

14081417
case ParsedAttr::AT_HLSLROV:
1409-
A = HLSLROVAttr::Create(getASTContext(), AL.getLoc());
1418+
A = HLSLROVAttr::Create(getASTContext(), ACI);
14101419
break;
14111420

14121421
case ParsedAttr::AT_HLSLRawBuffer:
1413-
A = HLSLRawBufferAttr::Create(getASTContext(), AL.getLoc());
1422+
A = HLSLRawBufferAttr::Create(getASTContext(), ACI);
14141423
break;
14151424

14161425
case ParsedAttr::AT_HLSLContainedType: {
@@ -1425,7 +1434,7 @@ bool SemaHLSL::handleResourceTypeAttr(QualType T, const ParsedAttr &AL) {
14251434
if (SemaRef.RequireCompleteType(TSI->getTypeLoc().getBeginLoc(), QT,
14261435
diag::err_incomplete_type))
14271436
return false;
1428-
A = HLSLContainedTypeAttr::Create(getASTContext(), TSI, AL.getLoc());
1437+
A = HLSLContainedTypeAttr::Create(getASTContext(), TSI, ACI);
14291438
break;
14301439
}
14311440

clang/test/AST/ByteCode/functions.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -637,7 +637,7 @@ namespace {
637637

638638
namespace {
639639
/// The InitListExpr here is of void type.
640-
void bir [[clang::annotate("B", {1, 2, 3, 4})]] (); // both-error {{'annotate' attribute requires parameter 1 to be a constant expression}} \
640+
void bir [[clang::annotate("B", {1, 2, 3, 4})]] (); // both-error {{'clang::annotate' attribute requires parameter 1 to be a constant expression}} \
641641
// both-note {{subexpression not valid in a constant expression}}
642642
}
643643

clang/test/C/C23/n3037.c

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ union purr { float y; int x; }; // c23-error {{type 'union purr' has incompatibl
6060

6161
// The presence of an attribute makes two types not compatible.
6262
struct [[gnu::packed]] attr_test { // c17-note {{previous definition is here}} \
63-
c23-note {{attribute 'packed' here}}
63+
c23-note {{attribute 'gnu::packed' here}}
6464
int x;
6565
};
6666

@@ -75,26 +75,26 @@ struct attr_test_2 { // c17-note {{previous definition is here}}
7575

7676
struct [[gnu::packed]] attr_test_2 { // c17-error {{redefinition of 'attr_test_2'}} \
7777
c23-error {{type 'struct attr_test_2' has an attribute which currently causes the types to be treated as though they are incompatible}} \
78-
c23-note {{attribute 'packed' here}}
78+
c23-note {{attribute 'gnu::packed' here}}
7979
int x;
8080
};
8181

8282
// This includes the same attribute on both types.
8383
struct [[gnu::packed]] attr_test_3 { // c17-note {{previous definition is here}} \
84-
c23-note {{attribute 'packed' here}}
84+
c23-note {{attribute 'gnu::packed' here}}
8585
int x;
8686
};
8787

8888
struct [[gnu::packed]] attr_test_3 { // c17-error {{redefinition of 'attr_test_3'}} \
8989
c23-error {{type 'struct attr_test_3' has an attribute which currently causes the types to be treated as though they are incompatible}} \
90-
c23-note {{attribute 'packed' here}}
90+
c23-note {{attribute 'gnu::packed' here}}
9191
int x;
9292
};
9393

9494
// Everything which applies to the tag itself also applies to fields.
9595
struct field_attr_test_1 { // c17-note {{previous definition is here}}
9696
int x;
97-
[[gnu::packed]] int y; // c23-note {{attribute 'packed' here}}
97+
[[gnu::packed]] int y; // c23-note {{attribute 'gnu::packed' here}}
9898
};
9999

100100
struct field_attr_test_1 { // c17-error {{redefinition of 'field_attr_test_1'}} \
@@ -104,7 +104,7 @@ struct field_attr_test_1 { // c17-error {{redefinition of 'field_attr_test_1'}}
104104
};
105105

106106
struct field_attr_test_2 { // c17-note {{previous definition is here}}
107-
[[gnu::packed]] int x; // c23-note {{attribute 'packed' here}}
107+
[[gnu::packed]] int x; // c23-note {{attribute 'gnu::packed' here}}
108108
int y;
109109
};
110110

@@ -115,13 +115,13 @@ struct field_attr_test_2 { // c17-error {{redefinition of 'field_attr_test_2'}}
115115
};
116116

117117
struct field_attr_test_3 { // c17-note {{previous definition is here}}
118-
[[gnu::packed]] int x; // c23-note {{attribute 'packed' here}}
118+
[[gnu::packed]] int x; // c23-note {{attribute 'gnu::packed' here}}
119119
int y;
120120
};
121121

122122
struct field_attr_test_3 { // c17-error {{redefinition of 'field_attr_test_3'}} \
123123
c23-error {{type 'struct field_attr_test_3' has a member with an attribute which currently causes the types to be treated as though they are incompatible}}
124-
int x [[gnu::packed]]; // c23-note {{attribute 'packed' here}}
124+
int x [[gnu::packed]]; // c23-note {{attribute 'gnu::packed' here}}
125125
int y;
126126
};
127127

0 commit comments

Comments
 (0)