Skip to content

Commit d057811

Browse files
authored
[clang] fix diagnostic printing of expressions ignoring LangOpts (#134693)
Currently when printing a template argument of expression type, the expression is converted immediately into a string to be sent to the diagnostic engine, unsing a fake LangOpts. This makes the expression printing look incorrect for the current language, besides being inneficient, as we don't actually need to print the expression if the diagnostic would be ignored. This fixes a nastiness with the TemplateArgument constructor for expressions being implicit, and all current users just passing an expression to a diagnostic were implicitly going through the template argument path. The expressions are also being printed unquoted. This will be fixed in a subsequent patch, as the test churn is much larger.
1 parent 3a0c95f commit d057811

File tree

16 files changed

+51
-35
lines changed

16 files changed

+51
-35
lines changed

clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "clang/AST/ASTContext.h"
2323
#include "clang/AST/ASTDiagnostic.h"
2424
#include "clang/AST/Attr.h"
25+
#include "clang/AST/Expr.h"
2526
#include "clang/Basic/CharInfo.h"
2627
#include "clang/Basic/Diagnostic.h"
2728
#include "clang/Basic/DiagnosticOptions.h"
@@ -528,6 +529,8 @@ void ClangTidyDiagnosticConsumer::forwardDiagnostic(const Diagnostic &Info) {
528529
case clang::DiagnosticsEngine::ak_addrspace:
529530
Builder << static_cast<LangAS>(Info.getRawArg(Index));
530531
break;
532+
case clang::DiagnosticsEngine::ak_expr:
533+
Builder << reinterpret_cast<const Expr *>(Info.getRawArg(Index));
531534
}
532535
}
533536
}

clang/docs/ReleaseNotes.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,9 @@ Improvements to Clang's diagnostics
280280
- Clang now better preserves the sugared types of pointers to member.
281281
- Clang now better preserves the presence of the template keyword with dependent
282282
prefixes.
283+
- Clang now respects the current language mode when printing expressions in
284+
diagnostics. This fixes a bunch of `bool` being printed as `_Bool`, and also
285+
a bunch of HLSL types being printed as their C++ equivalents.
283286
- When printing types for diagnostics, clang now doesn't suppress the scopes of
284287
template arguments contained within nested names.
285288
- The ``-Wshift-bool`` warning has been added to warn about shifting a boolean. (#GH28334)

clang/include/clang/AST/Expr.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7379,6 +7379,14 @@ class RecoveryExpr final : public Expr,
73797379
friend class ASTStmtWriter;
73807380
};
73817381

7382+
/// Insertion operator for diagnostics. This allows sending
7383+
/// Expr into a diagnostic with <<.
7384+
inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB,
7385+
const Expr *E) {
7386+
DB.AddTaggedVal(reinterpret_cast<uint64_t>(E), DiagnosticsEngine::ak_expr);
7387+
return DB;
7388+
}
7389+
73827390
} // end namespace clang
73837391

73847392
#endif // LLVM_CLANG_AST_EXPR_H

clang/include/clang/AST/TemplateBase.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -262,7 +262,7 @@ class TemplateArgument {
262262
/// This form of template argument only occurs in template argument
263263
/// lists used for dependent types and for expression; it will not
264264
/// occur in a non-dependent, canonical template argument list.
265-
TemplateArgument(Expr *E, bool IsDefaulted = false) {
265+
explicit TemplateArgument(Expr *E, bool IsDefaulted = false) {
266266
TypeOrValue.Kind = Expression;
267267
TypeOrValue.IsDefaulted = IsDefaulted;
268268
TypeOrValue.V = reinterpret_cast<uintptr_t>(E);

clang/include/clang/Basic/Diagnostic.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -284,7 +284,10 @@ class DiagnosticsEngine : public RefCountedBase<DiagnosticsEngine> {
284284
ak_qualtype_pair,
285285

286286
/// Attr *
287-
ak_attr
287+
ak_attr,
288+
289+
/// Expr *
290+
ak_expr,
288291
};
289292

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

clang/lib/AST/ASTDiagnostic.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -508,6 +508,14 @@ void clang::FormatASTNodeDiagnosticArgument(
508508
NeedQuotes = false;
509509
break;
510510
}
511+
case DiagnosticsEngine::ak_expr: {
512+
const Expr *E = reinterpret_cast<Expr *>(Val);
513+
assert(E && "Received null Expr!");
514+
E->printPretty(OS, /*Helper=*/nullptr, Context.getPrintingPolicy());
515+
// FIXME: Include quotes when printing expressions.
516+
NeedQuotes = false;
517+
break;
518+
}
511519
}
512520

513521
if (NeedQuotes) {

clang/lib/AST/TemplateBase.cpp

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -478,7 +478,7 @@ TemplateArgument TemplateArgument::getPackExpansionPattern() const {
478478
return getAsType()->castAs<PackExpansionType>()->getPattern();
479479

480480
case Expression:
481-
return cast<PackExpansionExpr>(getAsExpr())->getPattern();
481+
return TemplateArgument(cast<PackExpansionExpr>(getAsExpr())->getPattern());
482482

483483
case TemplateExpansion:
484484
return TemplateArgument(getAsTemplateOrTemplatePattern());
@@ -654,18 +654,8 @@ static const T &DiagTemplateArg(const T &DB, const TemplateArgument &Arg) {
654654
case TemplateArgument::TemplateExpansion:
655655
return DB << Arg.getAsTemplateOrTemplatePattern() << "...";
656656

657-
case TemplateArgument::Expression: {
658-
// This shouldn't actually ever happen, so it's okay that we're
659-
// regurgitating an expression here.
660-
// FIXME: We're guessing at LangOptions!
661-
SmallString<32> Str;
662-
llvm::raw_svector_ostream OS(Str);
663-
LangOptions LangOpts;
664-
LangOpts.CPlusPlus = true;
665-
PrintingPolicy Policy(LangOpts);
666-
Arg.getAsExpr()->printPretty(OS, nullptr, Policy);
667-
return DB << OS.str();
668-
}
657+
case TemplateArgument::Expression:
658+
return DB << Arg.getAsExpr();
669659

670660
case TemplateArgument::Pack: {
671661
// FIXME: We're guessing at LangOptions!

clang/lib/Basic/Diagnostic.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1247,6 +1247,7 @@ FormatDiagnostic(const char *DiagStr, const char *DiagEnd,
12471247
case DiagnosticsEngine::ak_nestednamespec:
12481248
case DiagnosticsEngine::ak_declcontext:
12491249
case DiagnosticsEngine::ak_attr:
1250+
case DiagnosticsEngine::ak_expr:
12501251
getDiags()->ConvertArgToString(Kind, getRawArg(ArgNo),
12511252
StringRef(Modifier, ModifierLen),
12521253
StringRef(Argument, ArgumentLen),

clang/lib/Sema/SemaTemplateDeduction.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -493,8 +493,8 @@ DeduceNullPtrTemplateArgument(Sema &S, TemplateParameterList *TemplateParams,
493493
: CK_NullToPointer)
494494
.get();
495495
return DeduceNonTypeTemplateArgument(
496-
S, TemplateParams, NTTP, DeducedTemplateArgument(Value), Value->getType(),
497-
Info, PartialOrdering, Deduced, HasDeducedAnyParam);
496+
S, TemplateParams, NTTP, TemplateArgument(Value), Value->getType(), Info,
497+
PartialOrdering, Deduced, HasDeducedAnyParam);
498498
}
499499

500500
/// Deduce the value of the given non-type template parameter
@@ -508,8 +508,8 @@ DeduceNonTypeTemplateArgument(Sema &S, TemplateParameterList *TemplateParams,
508508
SmallVectorImpl<DeducedTemplateArgument> &Deduced,
509509
bool *HasDeducedAnyParam) {
510510
return DeduceNonTypeTemplateArgument(
511-
S, TemplateParams, NTTP, DeducedTemplateArgument(Value), Value->getType(),
512-
Info, PartialOrdering, Deduced, HasDeducedAnyParam);
511+
S, TemplateParams, NTTP, TemplateArgument(Value), Value->getType(), Info,
512+
PartialOrdering, Deduced, HasDeducedAnyParam);
513513
}
514514

515515
/// Deduce the value of the given non-type template parameter

clang/lib/Sema/SemaTemplateVariadic.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1286,7 +1286,7 @@ TemplateArgumentLoc Sema::getTemplateArgumentPackExpansionPattern(
12861286
Expr *Pattern = Expansion->getPattern();
12871287
Ellipsis = Expansion->getEllipsisLoc();
12881288
NumExpansions = Expansion->getNumExpansions();
1289-
return TemplateArgumentLoc(Pattern, Pattern);
1289+
return TemplateArgumentLoc(TemplateArgument(Pattern), Pattern);
12901290
}
12911291

12921292
case TemplateArgument::TemplateExpansion:

0 commit comments

Comments
 (0)