aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Parse/Parser.cpp
diff options
context:
space:
mode:
authorCorentin Jabot <corentinjabot@gmail.com>2023-03-23 14:26:45 +0100
committerCorentin Jabot <corentinjabot@gmail.com>2023-03-30 16:30:23 +0200
commitabf4a8cb15d4faf04ee0da14e37d7349d3bde9a1 (patch)
tree0e153899e0b010eeac281facbca646a8c54a4d6f /clang/lib/Parse/Parser.cpp
parent5114843983b6d3ec866877308073d3821759a747 (diff)
downloadllvm-abf4a8cb15d4faf04ee0da14e37d7349d3bde9a1.zip
llvm-abf4a8cb15d4faf04ee0da14e37d7349d3bde9a1.tar.gz
llvm-abf4a8cb15d4faf04ee0da14e37d7349d3bde9a1.tar.bz2
[Clang] Improve diagnostics when using a concept as template argument
When using the name of a template variable or concept in places where an expression was expected, Clang would drop the cxxscope token preceeding it, if any. This leads to subpar diagnostics - complaining about the identifier being undeclared as clang would not know to look into a non-global scope. We make sure the scope is preserved. When encountering `ns::Concept foo x;`, Clang would also fail to provide the same quality as it does at global scope. Reviewed By: aaron.ballman, erichkeane Differential Revision: https://reviews.llvm.org/D146719
Diffstat (limited to 'clang/lib/Parse/Parser.cpp')
-rw-r--r--clang/lib/Parse/Parser.cpp26
1 files changed, 10 insertions, 16 deletions
diff --git a/clang/lib/Parse/Parser.cpp b/clang/lib/Parse/Parser.cpp
index e6b1d3f..c0f4556 100644
--- a/clang/lib/Parse/Parser.cpp
+++ b/clang/lib/Parse/Parser.cpp
@@ -1883,31 +1883,25 @@ Parser::TryAnnotateName(CorrectionCandidateCallback *CCC,
return ANK_TemplateName;
}
[[fallthrough]];
+ case Sema::NC_Concept:
case Sema::NC_VarTemplate:
case Sema::NC_FunctionTemplate:
case Sema::NC_UndeclaredTemplate: {
- // We have a type, variable or function template followed by '<'.
- ConsumeToken();
- UnqualifiedId Id;
- Id.setIdentifier(Name, NameLoc);
- if (AnnotateTemplateIdToken(
- TemplateTy::make(Classification.getTemplateName()),
- Classification.getTemplateNameKind(), SS, SourceLocation(), Id))
- return ANK_Error;
- return ANK_Success;
- }
- case Sema::NC_Concept: {
- UnqualifiedId Id;
- Id.setIdentifier(Name, NameLoc);
+ bool IsConceptName = Classification.getKind() == Sema::NC_Concept;
+ // We have a template name followed by '<'. Consume the identifier token so
+ // we reach the '<' and annotate it.
if (Next.is(tok::less))
- // We have a concept name followed by '<'. Consume the identifier token so
- // we reach the '<' and annotate it.
ConsumeToken();
+ UnqualifiedId Id;
+ Id.setIdentifier(Name, NameLoc);
if (AnnotateTemplateIdToken(
TemplateTy::make(Classification.getTemplateName()),
Classification.getTemplateNameKind(), SS, SourceLocation(), Id,
- /*AllowTypeAnnotation=*/false, /*TypeConstraint=*/true))
+ /*AllowTypeAnnotation=*/!IsConceptName,
+ /*TypeConstraint=*/IsConceptName))
return ANK_Error;
+ if (SS.isNotEmpty())
+ AnnotateScopeToken(SS, !WasScopeAnnotation);
return ANK_Success;
}
}