diff options
author | Matheus Izvekov <mizvekov@gmail.com> | 2025-02-20 08:50:03 -0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-02-20 08:50:03 -0300 |
commit | 0948fc85aa99a8fd193d2d66a517e31b8b639f20 (patch) | |
tree | 5177a4c7348fd6f0fd5fc81b67fccf883752d709 /clang/lib | |
parent | d7784a649e80d346ba57ccc39f5e2a3e2f7e0a51 (diff) | |
download | llvm-0948fc85aa99a8fd193d2d66a517e31b8b639f20.zip llvm-0948fc85aa99a8fd193d2d66a517e31b8b639f20.tar.gz llvm-0948fc85aa99a8fd193d2d66a517e31b8b639f20.tar.bz2 |
[clang] print correct context for diagnostics suppressed by deduction (#125453)
This patch makes it so the correct instantiation context is printed for
diagnostics suppessed by template argument deduction.
The context is saved along with the suppressed diagnostic, and when the
declaration they were attached to becomes used, we print the correct
context, instead of whatever context was at this point.
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/Sema/Sema.cpp | 13 | ||||
-rw-r--r-- | clang/lib/Sema/SemaAttr.cpp | 7 | ||||
-rw-r--r-- | clang/lib/Sema/SemaExpr.cpp | 7 | ||||
-rw-r--r-- | clang/lib/Sema/SemaTemplateInstantiate.cpp | 271 |
4 files changed, 155 insertions, 143 deletions
diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp index afd1d7a..145cda6 100644 --- a/clang/lib/Sema/Sema.cpp +++ b/clang/lib/Sema/Sema.cpp @@ -1655,11 +1655,20 @@ void Sema::EmitDiagnostic(unsigned DiagID, const DiagnosticBuilder &DB) { } case DiagnosticIDs::SFINAE_Suppress: + if (DiagnosticsEngine::Level Level = getDiagnostics().getDiagnosticLevel( + DiagInfo.getID(), DiagInfo.getLocation()); + Level == DiagnosticsEngine::Ignored) + return; // Make a copy of this suppressed diagnostic and store it with the // template-deduction information; if (*Info) { - (*Info)->addSuppressedDiagnostic(DiagInfo.getLocation(), - PartialDiagnostic(DiagInfo, Context.getDiagAllocator())); + (*Info)->addSuppressedDiagnostic( + DiagInfo.getLocation(), + PartialDiagnostic(DiagInfo, Context.getDiagAllocator())); + if (!Diags.getDiagnosticIDs()->isNote(DiagID)) + PrintContextStack([Info](SourceLocation Loc, PartialDiagnostic PD) { + (*Info)->addSuppressedDiagnostic(Loc, std::move(PD)); + }); } // Suppress this diagnostic. diff --git a/clang/lib/Sema/SemaAttr.cpp b/clang/lib/Sema/SemaAttr.cpp index 37c0546..3c2b63a 100644 --- a/clang/lib/Sema/SemaAttr.cpp +++ b/clang/lib/Sema/SemaAttr.cpp @@ -1221,10 +1221,11 @@ void Sema::AddPragmaAttributes(Scope *S, Decl *D) { } } -void Sema::PrintPragmaAttributeInstantiationPoint() { +void Sema::PrintPragmaAttributeInstantiationPoint( + InstantiationContextDiagFuncRef DiagFunc) { assert(PragmaAttributeCurrentTargetDecl && "Expected an active declaration"); - Diags.Report(PragmaAttributeCurrentTargetDecl->getBeginLoc(), - diag::note_pragma_attribute_applied_decl_here); + DiagFunc(PragmaAttributeCurrentTargetDecl->getBeginLoc(), + PDiag(diag::note_pragma_attribute_applied_decl_here)); } void Sema::DiagnosePrecisionLossInComplexDivision() { diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index fad15bf9..16226f1 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -225,9 +225,10 @@ bool Sema::DiagnoseUseOfDecl(NamedDecl *D, ArrayRef<SourceLocation> Locs, // emit them now. auto Pos = SuppressedDiagnostics.find(D->getCanonicalDecl()); if (Pos != SuppressedDiagnostics.end()) { - for (const PartialDiagnosticAt &Suppressed : Pos->second) - Diag(Suppressed.first, Suppressed.second); - + for (const auto &[DiagLoc, PD] : Pos->second) { + DiagnosticBuilder Builder(Diags.Report(DiagLoc, PD.getDiagID())); + PD.Emit(Builder); + } // Clear out the list of suppressed diagnostics, so that we don't emit // them again for this specialization. However, we don't obsolete this // entry from the table, because we want to avoid ever emitting these diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp index 121da49..fcb7671 100644 --- a/clang/lib/Sema/SemaTemplateInstantiate.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp @@ -903,7 +903,7 @@ bool Sema::InstantiatingTemplate::CheckInstantiationDepth( return true; } -void Sema::PrintInstantiationStack() { +void Sema::PrintInstantiationStack(InstantiationContextDiagFuncRef DiagFunc) { // Determine which template instantiations to skip, if any. unsigned SkipStart = CodeSynthesisContexts.size(), SkipEnd = SkipStart; unsigned Limit = Diags.getTemplateBacktraceLimit(); @@ -923,9 +923,9 @@ void Sema::PrintInstantiationStack() { if (InstantiationIdx >= SkipStart && InstantiationIdx < SkipEnd) { if (InstantiationIdx == SkipStart) { // Note that we're skipping instantiations. - Diags.Report(Active->PointOfInstantiation, - diag::note_instantiation_contexts_suppressed) - << unsigned(CodeSynthesisContexts.size() - Limit); + DiagFunc(Active->PointOfInstantiation, + PDiag(diag::note_instantiation_contexts_suppressed) + << unsigned(CodeSynthesisContexts.size() - Limit)); } continue; } @@ -937,37 +937,34 @@ void Sema::PrintInstantiationStack() { unsigned DiagID = diag::note_template_member_class_here; if (isa<ClassTemplateSpecializationDecl>(Record)) DiagID = diag::note_template_class_instantiation_here; - Diags.Report(Active->PointOfInstantiation, DiagID) - << Record << Active->InstantiationRange; + DiagFunc(Active->PointOfInstantiation, + PDiag(DiagID) << Record << Active->InstantiationRange); } else if (FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) { unsigned DiagID; if (Function->getPrimaryTemplate()) DiagID = diag::note_function_template_spec_here; else DiagID = diag::note_template_member_function_here; - Diags.Report(Active->PointOfInstantiation, DiagID) - << Function - << Active->InstantiationRange; + DiagFunc(Active->PointOfInstantiation, + PDiag(DiagID) << Function << Active->InstantiationRange); } else if (VarDecl *VD = dyn_cast<VarDecl>(D)) { - Diags.Report(Active->PointOfInstantiation, - VD->isStaticDataMember()? - diag::note_template_static_data_member_def_here - : diag::note_template_variable_def_here) - << VD - << Active->InstantiationRange; + DiagFunc(Active->PointOfInstantiation, + PDiag(VD->isStaticDataMember() + ? diag::note_template_static_data_member_def_here + : diag::note_template_variable_def_here) + << VD << Active->InstantiationRange); } else if (EnumDecl *ED = dyn_cast<EnumDecl>(D)) { - Diags.Report(Active->PointOfInstantiation, - diag::note_template_enum_def_here) - << ED - << Active->InstantiationRange; + DiagFunc(Active->PointOfInstantiation, + PDiag(diag::note_template_enum_def_here) + << ED << Active->InstantiationRange); } else if (FieldDecl *FD = dyn_cast<FieldDecl>(D)) { - Diags.Report(Active->PointOfInstantiation, - diag::note_template_nsdmi_here) - << FD << Active->InstantiationRange; + DiagFunc(Active->PointOfInstantiation, + PDiag(diag::note_template_nsdmi_here) + << FD << Active->InstantiationRange); } else if (ClassTemplateDecl *CTD = dyn_cast<ClassTemplateDecl>(D)) { - Diags.Report(Active->PointOfInstantiation, - diag::note_template_class_instantiation_here) - << CTD << Active->InstantiationRange; + DiagFunc(Active->PointOfInstantiation, + PDiag(diag::note_template_class_instantiation_here) + << CTD << Active->InstantiationRange); } break; } @@ -979,35 +976,35 @@ void Sema::PrintInstantiationStack() { Template->printName(OS, getPrintingPolicy()); printTemplateArgumentList(OS, Active->template_arguments(), getPrintingPolicy()); - Diags.Report(Active->PointOfInstantiation, - diag::note_default_arg_instantiation_here) - << OS.str() - << Active->InstantiationRange; + DiagFunc(Active->PointOfInstantiation, + PDiag(diag::note_default_arg_instantiation_here) + << OS.str() << Active->InstantiationRange); break; } case CodeSynthesisContext::ExplicitTemplateArgumentSubstitution: { FunctionTemplateDecl *FnTmpl = cast<FunctionTemplateDecl>(Active->Entity); - Diags.Report(Active->PointOfInstantiation, - diag::note_explicit_template_arg_substitution_here) - << FnTmpl - << getTemplateArgumentBindingsText(FnTmpl->getTemplateParameters(), - Active->TemplateArgs, - Active->NumTemplateArgs) - << Active->InstantiationRange; + DiagFunc(Active->PointOfInstantiation, + PDiag(diag::note_explicit_template_arg_substitution_here) + << FnTmpl + << getTemplateArgumentBindingsText( + FnTmpl->getTemplateParameters(), Active->TemplateArgs, + Active->NumTemplateArgs) + << Active->InstantiationRange); break; } case CodeSynthesisContext::DeducedTemplateArgumentSubstitution: { if (FunctionTemplateDecl *FnTmpl = dyn_cast<FunctionTemplateDecl>(Active->Entity)) { - Diags.Report(Active->PointOfInstantiation, - diag::note_function_template_deduction_instantiation_here) - << FnTmpl - << getTemplateArgumentBindingsText(FnTmpl->getTemplateParameters(), - Active->TemplateArgs, - Active->NumTemplateArgs) - << Active->InstantiationRange; + DiagFunc( + Active->PointOfInstantiation, + PDiag(diag::note_function_template_deduction_instantiation_here) + << FnTmpl + << getTemplateArgumentBindingsText( + FnTmpl->getTemplateParameters(), Active->TemplateArgs, + Active->NumTemplateArgs) + << Active->InstantiationRange); } else { bool IsVar = isa<VarTemplateDecl>(Active->Entity) || isa<VarTemplateSpecializationDecl>(Active->Entity); @@ -1026,12 +1023,13 @@ void Sema::PrintInstantiationStack() { llvm_unreachable("unexpected template kind"); } - Diags.Report(Active->PointOfInstantiation, - diag::note_deduced_template_arg_substitution_here) - << IsVar << IsTemplate << cast<NamedDecl>(Active->Entity) - << getTemplateArgumentBindingsText(Params, Active->TemplateArgs, - Active->NumTemplateArgs) - << Active->InstantiationRange; + DiagFunc(Active->PointOfInstantiation, + PDiag(diag::note_deduced_template_arg_substitution_here) + << IsVar << IsTemplate << cast<NamedDecl>(Active->Entity) + << getTemplateArgumentBindingsText(Params, + Active->TemplateArgs, + Active->NumTemplateArgs) + << Active->InstantiationRange); } break; } @@ -1045,10 +1043,9 @@ void Sema::PrintInstantiationStack() { FD->printName(OS, getPrintingPolicy()); printTemplateArgumentList(OS, Active->template_arguments(), getPrintingPolicy()); - Diags.Report(Active->PointOfInstantiation, - diag::note_default_function_arg_instantiation_here) - << OS.str() - << Active->InstantiationRange; + DiagFunc(Active->PointOfInstantiation, + PDiag(diag::note_default_function_arg_instantiation_here) + << OS.str() << Active->InstantiationRange); break; } @@ -1065,14 +1062,13 @@ void Sema::PrintInstantiationStack() { TemplateParams = cast<ClassTemplatePartialSpecializationDecl>(Active->Template) ->getTemplateParameters(); - Diags.Report(Active->PointOfInstantiation, - diag::note_prior_template_arg_substitution) - << isa<TemplateTemplateParmDecl>(Parm) - << Name - << getTemplateArgumentBindingsText(TemplateParams, - Active->TemplateArgs, - Active->NumTemplateArgs) - << Active->InstantiationRange; + DiagFunc(Active->PointOfInstantiation, + PDiag(diag::note_prior_template_arg_substitution) + << isa<TemplateTemplateParmDecl>(Parm) << Name + << getTemplateArgumentBindingsText(TemplateParams, + Active->TemplateArgs, + Active->NumTemplateArgs) + << Active->InstantiationRange); break; } @@ -1085,55 +1081,56 @@ void Sema::PrintInstantiationStack() { cast<ClassTemplatePartialSpecializationDecl>(Active->Template) ->getTemplateParameters(); - Diags.Report(Active->PointOfInstantiation, - diag::note_template_default_arg_checking) - << getTemplateArgumentBindingsText(TemplateParams, - Active->TemplateArgs, - Active->NumTemplateArgs) - << Active->InstantiationRange; + DiagFunc(Active->PointOfInstantiation, + PDiag(diag::note_template_default_arg_checking) + << getTemplateArgumentBindingsText(TemplateParams, + Active->TemplateArgs, + Active->NumTemplateArgs) + << Active->InstantiationRange); break; } case CodeSynthesisContext::ExceptionSpecEvaluation: - Diags.Report(Active->PointOfInstantiation, - diag::note_evaluating_exception_spec_here) - << cast<FunctionDecl>(Active->Entity); + DiagFunc(Active->PointOfInstantiation, + PDiag(diag::note_evaluating_exception_spec_here) + << cast<FunctionDecl>(Active->Entity)); break; case CodeSynthesisContext::ExceptionSpecInstantiation: - Diags.Report(Active->PointOfInstantiation, - diag::note_template_exception_spec_instantiation_here) - << cast<FunctionDecl>(Active->Entity) - << Active->InstantiationRange; + DiagFunc(Active->PointOfInstantiation, + PDiag(diag::note_template_exception_spec_instantiation_here) + << cast<FunctionDecl>(Active->Entity) + << Active->InstantiationRange); break; case CodeSynthesisContext::RequirementInstantiation: - Diags.Report(Active->PointOfInstantiation, - diag::note_template_requirement_instantiation_here) - << Active->InstantiationRange; + DiagFunc(Active->PointOfInstantiation, + PDiag(diag::note_template_requirement_instantiation_here) + << Active->InstantiationRange); break; case CodeSynthesisContext::RequirementParameterInstantiation: - Diags.Report(Active->PointOfInstantiation, - diag::note_template_requirement_params_instantiation_here) - << Active->InstantiationRange; + DiagFunc(Active->PointOfInstantiation, + PDiag(diag::note_template_requirement_params_instantiation_here) + << Active->InstantiationRange); break; case CodeSynthesisContext::NestedRequirementConstraintsCheck: - Diags.Report(Active->PointOfInstantiation, - diag::note_nested_requirement_here) - << Active->InstantiationRange; + DiagFunc(Active->PointOfInstantiation, + PDiag(diag::note_nested_requirement_here) + << Active->InstantiationRange); break; case CodeSynthesisContext::DeclaringSpecialMember: - Diags.Report(Active->PointOfInstantiation, - diag::note_in_declaration_of_implicit_special_member) - << cast<CXXRecordDecl>(Active->Entity) - << llvm::to_underlying(Active->SpecialMember); + DiagFunc(Active->PointOfInstantiation, + PDiag(diag::note_in_declaration_of_implicit_special_member) + << cast<CXXRecordDecl>(Active->Entity) + << llvm::to_underlying(Active->SpecialMember)); break; case CodeSynthesisContext::DeclaringImplicitEqualityComparison: - Diags.Report(Active->Entity->getLocation(), - diag::note_in_declaration_of_implicit_equality_comparison); + DiagFunc( + Active->Entity->getLocation(), + PDiag(diag::note_in_declaration_of_implicit_equality_comparison)); break; case CodeSynthesisContext::DefiningSynthesizedFunction: { @@ -1144,60 +1141,62 @@ void Sema::PrintInstantiationStack() { FD ? getDefaultedFunctionKind(FD) : DefaultedFunctionKind(); if (DFK.isSpecialMember()) { auto *MD = cast<CXXMethodDecl>(FD); - Diags.Report(Active->PointOfInstantiation, - diag::note_member_synthesized_at) - << MD->isExplicitlyDefaulted() - << llvm::to_underlying(DFK.asSpecialMember()) - << Context.getTagDeclType(MD->getParent()); + DiagFunc(Active->PointOfInstantiation, + PDiag(diag::note_member_synthesized_at) + << MD->isExplicitlyDefaulted() + << llvm::to_underlying(DFK.asSpecialMember()) + << Context.getTagDeclType(MD->getParent())); } else if (DFK.isComparison()) { QualType RecordType = FD->getParamDecl(0) ->getType() .getNonReferenceType() .getUnqualifiedType(); - Diags.Report(Active->PointOfInstantiation, - diag::note_comparison_synthesized_at) - << (int)DFK.asComparison() << RecordType; + DiagFunc(Active->PointOfInstantiation, + PDiag(diag::note_comparison_synthesized_at) + << (int)DFK.asComparison() << RecordType); } break; } case CodeSynthesisContext::RewritingOperatorAsSpaceship: - Diags.Report(Active->Entity->getLocation(), - diag::note_rewriting_operator_as_spaceship); + DiagFunc(Active->Entity->getLocation(), + PDiag(diag::note_rewriting_operator_as_spaceship)); break; case CodeSynthesisContext::InitializingStructuredBinding: - Diags.Report(Active->PointOfInstantiation, - diag::note_in_binding_decl_init) - << cast<BindingDecl>(Active->Entity); + DiagFunc(Active->PointOfInstantiation, + PDiag(diag::note_in_binding_decl_init) + << cast<BindingDecl>(Active->Entity)); break; case CodeSynthesisContext::MarkingClassDllexported: - Diags.Report(Active->PointOfInstantiation, - diag::note_due_to_dllexported_class) - << cast<CXXRecordDecl>(Active->Entity) << !getLangOpts().CPlusPlus11; + DiagFunc(Active->PointOfInstantiation, + PDiag(diag::note_due_to_dllexported_class) + << cast<CXXRecordDecl>(Active->Entity) + << !getLangOpts().CPlusPlus11); break; case CodeSynthesisContext::BuildingBuiltinDumpStructCall: - Diags.Report(Active->PointOfInstantiation, - diag::note_building_builtin_dump_struct_call) - << convertCallArgsToString( - *this, llvm::ArrayRef(Active->CallArgs, Active->NumCallArgs)); + DiagFunc(Active->PointOfInstantiation, + PDiag(diag::note_building_builtin_dump_struct_call) + << convertCallArgsToString( + *this, llvm::ArrayRef(Active->CallArgs, + Active->NumCallArgs))); break; case CodeSynthesisContext::Memoization: break; case CodeSynthesisContext::LambdaExpressionSubstitution: - Diags.Report(Active->PointOfInstantiation, - diag::note_lambda_substitution_here); + DiagFunc(Active->PointOfInstantiation, + PDiag(diag::note_lambda_substitution_here)); break; case CodeSynthesisContext::ConstraintsCheck: { unsigned DiagID = 0; if (!Active->Entity) { - Diags.Report(Active->PointOfInstantiation, - diag::note_nested_requirement_here) - << Active->InstantiationRange; + DiagFunc(Active->PointOfInstantiation, + PDiag(diag::note_nested_requirement_here) + << Active->InstantiationRange); break; } if (isa<ConceptDecl>(Active->Entity)) @@ -1219,42 +1218,44 @@ void Sema::PrintInstantiationStack() { printTemplateArgumentList(OS, Active->template_arguments(), getPrintingPolicy()); } - Diags.Report(Active->PointOfInstantiation, DiagID) << OS.str() - << Active->InstantiationRange; + DiagFunc(Active->PointOfInstantiation, + PDiag(DiagID) << OS.str() << Active->InstantiationRange); break; } case CodeSynthesisContext::ConstraintSubstitution: - Diags.Report(Active->PointOfInstantiation, - diag::note_constraint_substitution_here) - << Active->InstantiationRange; + DiagFunc(Active->PointOfInstantiation, + PDiag(diag::note_constraint_substitution_here) + << Active->InstantiationRange); break; case CodeSynthesisContext::ConstraintNormalization: - Diags.Report(Active->PointOfInstantiation, - diag::note_constraint_normalization_here) - << cast<NamedDecl>(Active->Entity) << Active->InstantiationRange; + DiagFunc(Active->PointOfInstantiation, + PDiag(diag::note_constraint_normalization_here) + << cast<NamedDecl>(Active->Entity) + << Active->InstantiationRange); break; case CodeSynthesisContext::ParameterMappingSubstitution: - Diags.Report(Active->PointOfInstantiation, - diag::note_parameter_mapping_substitution_here) - << Active->InstantiationRange; + DiagFunc(Active->PointOfInstantiation, + PDiag(diag::note_parameter_mapping_substitution_here) + << Active->InstantiationRange); break; case CodeSynthesisContext::BuildingDeductionGuides: - Diags.Report(Active->PointOfInstantiation, - diag::note_building_deduction_guide_here); + DiagFunc(Active->PointOfInstantiation, + PDiag(diag::note_building_deduction_guide_here)); break; case CodeSynthesisContext::TypeAliasTemplateInstantiation: - Diags.Report(Active->PointOfInstantiation, - diag::note_template_type_alias_instantiation_here) - << cast<TypeAliasTemplateDecl>(Active->Entity) - << Active->InstantiationRange; + DiagFunc(Active->PointOfInstantiation, + PDiag(diag::note_template_type_alias_instantiation_here) + << cast<TypeAliasTemplateDecl>(Active->Entity) + << Active->InstantiationRange); break; case CodeSynthesisContext::PartialOrderingTTP: - Diags.Report(Active->PointOfInstantiation, - diag::note_template_arg_template_params_mismatch); + DiagFunc(Active->PointOfInstantiation, + PDiag(diag::note_template_arg_template_params_mismatch)); if (SourceLocation ParamLoc = Active->Entity->getLocation(); ParamLoc.isValid()) - Diags.Report(ParamLoc, diag::note_template_prev_declaration) - << /*isTemplateTemplateParam=*/true << Active->InstantiationRange; + DiagFunc(ParamLoc, PDiag(diag::note_template_prev_declaration) + << /*isTemplateTemplateParam=*/true + << Active->InstantiationRange); break; } } |