Skip to content

Commit c89ea13

Browse files
authored
Merge pull request #9905 from benlangmuir/cache-custom-diags-stable
[cas] Fix caching of diagnostics using getCustomDiagID
2 parents 0c1c6f2 + 58d344d commit c89ea13

32 files changed

+708
-223
lines changed

clang-tools-extra/clangd/Diagnostics.cpp

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -579,7 +579,17 @@ std::vector<Diag> StoreDiags::take(const clang::tidy::ClangTidyContext *Tidy) {
579579
for (auto &Diag : Output) {
580580
if (const char *ClangDiag = getDiagnosticCode(Diag.ID)) {
581581
// Warnings controlled by -Wfoo are better recognized by that name.
582-
StringRef Warning = DiagnosticIDs::getWarningOptionForDiag(Diag.ID);
582+
StringRef Warning = [&] {
583+
if (OrigSrcMgr) {
584+
return OrigSrcMgr->getDiagnostics()
585+
.getDiagnosticIDs()
586+
->getWarningOptionForDiag(Diag.ID);
587+
}
588+
if (!DiagnosticIDs::IsCustomDiag(Diag.ID))
589+
return DiagnosticIDs{}.getWarningOptionForDiag(Diag.ID);
590+
return StringRef{};
591+
}();
592+
583593
if (!Warning.empty()) {
584594
Diag.Name = ("-W" + Warning).str();
585595
} else {
@@ -896,20 +906,23 @@ void StoreDiags::flushLastDiag() {
896906
Output.push_back(std::move(*LastDiag));
897907
}
898908

899-
bool isBuiltinDiagnosticSuppressed(unsigned ID,
900-
const llvm::StringSet<> &Suppress,
901-
const LangOptions &LangOpts) {
909+
bool isDiagnosticSuppressed(const clang::Diagnostic &Diag,
910+
const llvm::StringSet<> &Suppress,
911+
const LangOptions &LangOpts) {
902912
// Don't complain about header-only stuff in mainfiles if it's a header.
903913
// FIXME: would be cleaner to suppress in clang, once we decide whether the
904914
// behavior should be to silently-ignore or respect the pragma.
905-
if (ID == diag::pp_pragma_sysheader_in_main_file && LangOpts.IsHeaderFile)
915+
if (Diag.getID() == diag::pp_pragma_sysheader_in_main_file &&
916+
LangOpts.IsHeaderFile)
906917
return true;
907918

908-
if (const char *CodePtr = getDiagnosticCode(ID)) {
919+
if (const char *CodePtr = getDiagnosticCode(Diag.getID())) {
909920
if (Suppress.contains(normalizeSuppressedCode(CodePtr)))
910921
return true;
911922
}
912-
StringRef Warning = DiagnosticIDs::getWarningOptionForDiag(ID);
923+
StringRef Warning =
924+
Diag.getDiags()->getDiagnosticIDs()->getWarningOptionForDiag(
925+
Diag.getID());
913926
if (!Warning.empty() && Suppress.contains(Warning))
914927
return true;
915928
return false;

clang-tools-extra/clangd/Diagnostics.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -181,11 +181,11 @@ class StoreDiags : public DiagnosticConsumer {
181181
};
182182

183183
/// Determine whether a (non-clang-tidy) diagnostic is suppressed by config.
184-
bool isBuiltinDiagnosticSuppressed(unsigned ID,
185-
const llvm::StringSet<> &Suppressed,
186-
const LangOptions &);
184+
bool isDiagnosticSuppressed(const clang::Diagnostic &Diag,
185+
const llvm::StringSet<> &Suppressed,
186+
const LangOptions &);
187187
/// Take a user-specified diagnostic code, and convert it to a normalized form
188-
/// stored in the config and consumed by isBuiltinDiagnosticsSuppressed.
188+
/// stored in the config and consumed by isDiagnosticsSuppressed.
189189
///
190190
/// (This strips err_ and -W prefix so we can match with or without them.)
191191
llvm::StringRef normalizeSuppressedCode(llvm::StringRef);

clang-tools-extra/clangd/ParsedAST.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -340,7 +340,7 @@ void applyWarningOptions(llvm::ArrayRef<std::string> ExtraArgs,
340340
if (Enable) {
341341
if (Diags.getDiagnosticLevel(ID, SourceLocation()) <
342342
DiagnosticsEngine::Warning) {
343-
auto Group = DiagnosticIDs::getGroupForDiag(ID);
343+
auto Group = Diags.getDiagnosticIDs()->getGroupForDiag(ID);
344344
if (!Group || !EnabledGroups(*Group))
345345
continue;
346346
Diags.setSeverity(ID, diag::Severity::Warning, SourceLocation());
@@ -583,8 +583,8 @@ ParsedAST::build(llvm::StringRef Filename, const ParseInputs &Inputs,
583583
ASTDiags.setLevelAdjuster([&](DiagnosticsEngine::Level DiagLevel,
584584
const clang::Diagnostic &Info) {
585585
if (Cfg.Diagnostics.SuppressAll ||
586-
isBuiltinDiagnosticSuppressed(Info.getID(), Cfg.Diagnostics.Suppress,
587-
Clang->getLangOpts()))
586+
isDiagnosticSuppressed(Info, Cfg.Diagnostics.Suppress,
587+
Clang->getLangOpts()))
588588
return DiagnosticsEngine::Ignored;
589589

590590
auto It = OverriddenSeverity.find(Info.getID());

clang-tools-extra/clangd/Preamble.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -621,8 +621,8 @@ buildPreamble(PathRef FileName, CompilerInvocation CI,
621621
PreambleDiagnostics.setLevelAdjuster([&](DiagnosticsEngine::Level DiagLevel,
622622
const clang::Diagnostic &Info) {
623623
if (Cfg.Diagnostics.SuppressAll ||
624-
isBuiltinDiagnosticSuppressed(Info.getID(), Cfg.Diagnostics.Suppress,
625-
CI.getLangOpts()))
624+
isDiagnosticSuppressed(Info, Cfg.Diagnostics.Suppress,
625+
CI.getLangOpts()))
626626
return DiagnosticsEngine::Ignored;
627627
switch (Info.getID()) {
628628
case diag::warn_no_newline_eof:

clang-tools-extra/clangd/unittests/ConfigCompileTests.cpp

Lines changed: 34 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -298,20 +298,41 @@ TEST_F(ConfigCompileTests, DiagnosticSuppression) {
298298
"unreachable-code", "unused-variable",
299299
"typecheck_bool_condition",
300300
"unexpected_friend", "warn_alloca"));
301-
EXPECT_TRUE(isBuiltinDiagnosticSuppressed(
302-
diag::warn_unreachable, Conf.Diagnostics.Suppress, LangOptions()));
301+
clang::DiagnosticsEngine DiagEngine(new DiagnosticIDs, nullptr,
302+
new clang::IgnoringDiagConsumer);
303+
304+
using Diag = clang::Diagnostic;
305+
{
306+
auto D = DiagEngine.Report(diag::warn_unreachable);
307+
EXPECT_TRUE(isDiagnosticSuppressed(
308+
Diag{&DiagEngine}, Conf.Diagnostics.Suppress, LangOptions()));
309+
}
303310
// Subcategory not respected/suppressed.
304-
EXPECT_FALSE(isBuiltinDiagnosticSuppressed(
305-
diag::warn_unreachable_break, Conf.Diagnostics.Suppress, LangOptions()));
306-
EXPECT_TRUE(isBuiltinDiagnosticSuppressed(
307-
diag::warn_unused_variable, Conf.Diagnostics.Suppress, LangOptions()));
308-
EXPECT_TRUE(isBuiltinDiagnosticSuppressed(diag::err_typecheck_bool_condition,
309-
Conf.Diagnostics.Suppress,
310-
LangOptions()));
311-
EXPECT_TRUE(isBuiltinDiagnosticSuppressed(
312-
diag::err_unexpected_friend, Conf.Diagnostics.Suppress, LangOptions()));
313-
EXPECT_TRUE(isBuiltinDiagnosticSuppressed(
314-
diag::warn_alloca, Conf.Diagnostics.Suppress, LangOptions()));
311+
{
312+
auto D = DiagEngine.Report(diag::warn_unreachable_break);
313+
EXPECT_FALSE(isDiagnosticSuppressed(
314+
Diag{&DiagEngine}, Conf.Diagnostics.Suppress, LangOptions()));
315+
}
316+
{
317+
auto D = DiagEngine.Report(diag::warn_unused_variable);
318+
EXPECT_TRUE(isDiagnosticSuppressed(
319+
Diag{&DiagEngine}, Conf.Diagnostics.Suppress, LangOptions()));
320+
}
321+
{
322+
auto D = DiagEngine.Report(diag::err_typecheck_bool_condition);
323+
EXPECT_TRUE(isDiagnosticSuppressed(
324+
Diag{&DiagEngine}, Conf.Diagnostics.Suppress, LangOptions()));
325+
}
326+
{
327+
auto D = DiagEngine.Report(diag::err_unexpected_friend);
328+
EXPECT_TRUE(isDiagnosticSuppressed(
329+
Diag{&DiagEngine}, Conf.Diagnostics.Suppress, LangOptions()));
330+
}
331+
{
332+
auto D = DiagEngine.Report(diag::warn_alloca);
333+
EXPECT_TRUE(isDiagnosticSuppressed(
334+
Diag{&DiagEngine}, Conf.Diagnostics.Suppress, LangOptions()));
335+
}
315336

316337
Frag.Diagnostics.Suppress.emplace_back("*");
317338
EXPECT_TRUE(compileAndApply());

clang/include/clang/Basic/Attr.td

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3496,18 +3496,16 @@ def DiagnoseIf : InheritableAttr {
34963496
let Spellings = [GNU<"diagnose_if">];
34973497
let Subjects = SubjectList<[Function, ObjCMethod, ObjCProperty]>;
34983498
let Args = [ExprArgument<"Cond">, StringArgument<"Message">,
3499-
EnumArgument<"DiagnosticType", "DiagnosticType",
3499+
EnumArgument<"DefaultSeverity",
3500+
"DefaultSeverity",
35003501
/*is_string=*/true,
3501-
["error", "warning"],
3502-
["DT_Error", "DT_Warning"]>,
3502+
["error", "warning"],
3503+
["DS_error", "DS_warning"]>,
3504+
StringArgument<"WarningGroup", /*optional*/ 1>,
35033505
BoolArgument<"ArgDependent", 0, /*fake*/ 1>,
35043506
DeclArgument<Named, "Parent", 0, /*fake*/ 1>];
35053507
let InheritEvenIfAlreadyPresent = 1;
35063508
let LateParsed = LateAttrParseStandard;
3507-
let AdditionalMembers = [{
3508-
bool isError() const { return diagnosticType == DT_Error; }
3509-
bool isWarning() const { return diagnosticType == DT_Warning; }
3510-
}];
35113509
let TemplateDependent = 1;
35123510
let Documentation = [DiagnoseIfDocs];
35133511
}

clang/include/clang/Basic/Diagnostic.h

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -337,10 +337,12 @@ class DiagnosticsEngine : public RefCountedBase<DiagnosticsEngine> {
337337
// Map extensions to warnings or errors?
338338
diag::Severity ExtBehavior = diag::Severity::Ignored;
339339

340-
DiagState()
340+
DiagnosticIDs &DiagIDs;
341+
342+
DiagState(DiagnosticIDs &DiagIDs)
341343
: IgnoreAllWarnings(false), EnableAllWarnings(false),
342344
WarningsAsErrors(false), ErrorsAsFatal(false),
343-
SuppressSystemWarnings(false) {}
345+
SuppressSystemWarnings(false), DiagIDs(DiagIDs) {}
344346

345347
using iterator = llvm::DenseMap<unsigned, DiagnosticMapping>::iterator;
346348
using const_iterator =
@@ -871,11 +873,25 @@ class DiagnosticsEngine : public RefCountedBase<DiagnosticsEngine> {
871873
/// \param FormatString A fixed diagnostic format string that will be hashed
872874
/// and mapped to a unique DiagID.
873875
template <unsigned N>
876+
// TODO: Deprecate this once all uses are removed from Clang.
877+
// [[deprecated("Use a CustomDiagDesc instead of a Level")]]
874878
unsigned getCustomDiagID(Level L, const char (&FormatString)[N]) {
875879
return Diags->getCustomDiagID((DiagnosticIDs::Level)L,
876880
StringRef(FormatString, N - 1));
877881
}
878882

883+
unsigned getCustomDiagID(DiagnosticIDs::CustomDiagDesc Desc) {
884+
return Diags->getCustomDiagID(std::move(Desc));
885+
}
886+
887+
std::optional<unsigned> getMaxCustomDiagID() const {
888+
return Diags->getMaxCustomDiagID();
889+
}
890+
const DiagnosticIDs::CustomDiagDesc &
891+
getCustomDiagDesc(unsigned DiagID) const {
892+
return Diags->getCustomDiagDesc(DiagID);
893+
}
894+
879895
/// Converts a diagnostic argument (as an intptr_t) into the string
880896
/// that represents it.
881897
void ConvertArgToString(ArgumentKind Kind, intptr_t Val,

clang/include/clang/Basic/DiagnosticCategories.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,12 @@ namespace clang {
2121
};
2222

2323
enum class Group {
24-
#define DIAG_ENTRY(GroupName, FlagNameOffset, Members, SubGroups, Docs) \
25-
GroupName,
24+
#define DIAG_ENTRY(GroupName, FlagNameOffset, Members, SubGroups, Docs) \
25+
GroupName,
2626
#include "clang/Basic/DiagnosticGroups.inc"
2727
#undef CATEGORY
2828
#undef DIAG_ENTRY
29+
NUM_GROUPS
2930
};
3031
} // end namespace diag
3132
} // end namespace clang

0 commit comments

Comments
 (0)