File tree Expand file tree Collapse file tree 3 files changed +14
-19
lines changed Expand file tree Collapse file tree 3 files changed +14
-19
lines changed Original file line number Diff line number Diff line change @@ -76,23 +76,13 @@ class CXXScopeSpec {
76
76
NestedNameSpecifierLocBuilder Builder;
77
77
ArrayRef<TemplateParameterList *> TemplateParamLists;
78
78
79
- // / Flag indicating whether an incomplete-type diagnostic
80
- // / has already been emitted for this scope specifier.
81
- bool HadIncompleteTypeError = false ;
82
-
83
79
public:
84
80
SourceRange getRange () const { return Range; }
85
81
void setRange (SourceRange R) { Range = R; }
86
82
void setBeginLoc (SourceLocation Loc) { Range.setBegin (Loc); }
87
83
void setEndLoc (SourceLocation Loc) { Range.setEnd (Loc); }
88
84
SourceLocation getBeginLoc () const { return Range.getBegin (); }
89
85
SourceLocation getEndLoc () const { return Range.getEnd (); }
90
-
91
- // / Return true if an incomplete-type diagnostic has already been emitted.
92
- bool hasIncompleteTypeError () const { return HadIncompleteTypeError; }
93
-
94
- // / Mark that an incomplete-type error was emitted for this scope.
95
- void setIncompleteTypeError (bool v = true ) { HadIncompleteTypeError = v; }
96
86
97
87
void setTemplateParamLists (ArrayRef<TemplateParameterList *> L) {
98
88
TemplateParamLists = L;
Original file line number Diff line number Diff line change @@ -1555,6 +1555,12 @@ class Sema final : public SemaBase {
1555
1555
Sema(const Sema &) = delete;
1556
1556
void operator=(const Sema &) = delete;
1557
1557
1558
+ /// Used to suppress duplicate diagnostics for incomplete types
1559
+ /// in nested name specifiers (e.g. `incomplete::type`).
1560
+ /// Without this, Clang may emit the same error multiple times
1561
+ /// in C++20 or later, due to multiple semantic passes over the scope.
1562
+ llvm::DenseSet<const TagDecl *> IncompleteDiagSet;
1563
+
1558
1564
/// The handler for the FileChanged preprocessor events.
1559
1565
///
1560
1566
/// Used for diagnostics that implement custom semantic analysis for #include
Original file line number Diff line number Diff line change @@ -206,22 +206,21 @@ bool Sema::RequireCompleteDeclContext(CXXScopeSpec &SS,
206
206
if (tag->isBeingDefined ())
207
207
return false ;
208
208
209
+ // Avoid emitting duplicate diagnostics for the same tag.
210
+ // This happens in C++20+ due to more aggressive semantic analysis.
211
+ if (IncompleteDiagSet.contains (tag))
212
+ return true ;
213
+
209
214
SourceLocation loc = SS.getLastQualifierNameLoc ();
210
215
if (loc.isInvalid ()) loc = SS.getRange ().getBegin ();
211
216
212
- // If an incomplete-type error has already been emitted for this scope,
213
- // suppress duplicate diagnostics to avoid noisy repeated messages.
214
- if (SS.hasIncompleteTypeError ())
215
- return true ;
216
-
217
217
// The type must be complete.
218
218
if (RequireCompleteType (loc, type, diag::err_incomplete_nested_name_spec,
219
219
SS.getRange ())) {
220
- SS.SetInvalid (SS.getRange ());
220
+ // mark as diagnosed
221
+ IncompleteDiagSet.insert (tag);
221
222
222
- // Remember that we've already diagnosed this incomplete type,
223
- // so later checks won't emit redundant diagnostics.
224
- SS.setIncompleteTypeError ();
223
+ SS.SetInvalid (SS.getRange ());
225
224
226
225
return true ;
227
226
}
You can’t perform that action at this time.
0 commit comments