summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema/SemaTemplate.cpp
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2018-06-26 23:20:26 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2018-06-26 23:20:26 +0000
commitbf5bcf2c15c50381ad84d1ac9bbb171c91188b56 (patch)
treee101c340b1b367af47e9570d0eefdf5407830ac4 /clang/lib/Sema/SemaTemplate.cpp
parent69b859c2d8d9a0500cf8164c332b378c927f059e (diff)
downloadbcm5719-llvm-bf5bcf2c15c50381ad84d1ac9bbb171c91188b56.tar.gz
bcm5719-llvm-bf5bcf2c15c50381ad84d1ac9bbb171c91188b56.zip
Diagnose missing 'template' keywords in more cases.
We track when we see a name-shaped expression followed by a '<' token and parse the '<' as a comparison. Then: * if we see a token sequence that cannot possibly be an expression but can be a template argument (in particular, a type-id) that follows either a ',' or the '<', diagnose that the '<' was supposed to start a template argument list, and * if we see '>()', diagnose that the '<' was supposed to start a template argument list. This only changes the diagnostic for error cases, and in practice appears to catch the most common cases where a missing 'template' keyword leads to parse errors within a template. Differential Revision: https://reviews.llvm.org/D48571 llvm-svn: 335687
Diffstat (limited to 'clang/lib/Sema/SemaTemplate.cpp')
-rw-r--r--clang/lib/Sema/SemaTemplate.cpp33
1 files changed, 27 insertions, 6 deletions
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index 8f316024cc6..68a5196f6b8 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -508,20 +508,41 @@ void Sema::diagnoseExprIntendedAsTemplateName(Scope *S, ExprResult TemplateName,
DeclContext *LookupCtx = nullptr;
NamedDecl *Found = nullptr;
+ bool MissingTemplateKeyword = false;
// Figure out what name we looked up.
- if (auto *ME = dyn_cast<MemberExpr>(TemplateName.get())) {
+ if (auto *DRE = dyn_cast<DeclRefExpr>(TemplateName.get())) {
+ NameInfo = DRE->getNameInfo();
+ SS.Adopt(DRE->getQualifierLoc());
+ LookupKind = LookupOrdinaryName;
+ Found = DRE->getFoundDecl();
+ } else if (auto *ME = dyn_cast<MemberExpr>(TemplateName.get())) {
NameInfo = ME->getMemberNameInfo();
SS.Adopt(ME->getQualifierLoc());
LookupKind = LookupMemberName;
LookupCtx = ME->getBase()->getType()->getAsCXXRecordDecl();
Found = ME->getMemberDecl();
+ } else if (auto *DSDRE =
+ dyn_cast<DependentScopeDeclRefExpr>(TemplateName.get())) {
+ NameInfo = DSDRE->getNameInfo();
+ SS.Adopt(DSDRE->getQualifierLoc());
+ MissingTemplateKeyword = true;
+ } else if (auto *DSME =
+ dyn_cast<CXXDependentScopeMemberExpr>(TemplateName.get())) {
+ NameInfo = DSME->getMemberNameInfo();
+ SS.Adopt(DSME->getQualifierLoc());
+ MissingTemplateKeyword = true;
} else {
- auto *DRE = cast<DeclRefExpr>(TemplateName.get());
- NameInfo = DRE->getNameInfo();
- SS.Adopt(DRE->getQualifierLoc());
- LookupKind = LookupOrdinaryName;
- Found = DRE->getFoundDecl();
+ llvm_unreachable("unexpected kind of potential template name");
+ }
+
+ // If this is a dependent-scope lookup, diagnose that the 'template' keyword
+ // was missing.
+ if (MissingTemplateKeyword) {
+ Diag(NameInfo.getLocStart(), diag::err_template_kw_missing)
+ << "" << NameInfo.getName().getAsString()
+ << SourceRange(Less, Greater);
+ return;
}
// Try to correct the name by looking for templates and C++ named casts.
OpenPOWER on IntegriCloud