summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
Diffstat (limited to 'clang')
-rw-r--r--clang/include/clang/Sema/DeclSpec.h35
-rw-r--r--clang/lib/Parse/ParseDecl.cpp27
-rw-r--r--clang/test/Parser/cxx-template-argument.cpp2
-rw-r--r--clang/test/Parser/cxx0x-decl.cpp3
-rw-r--r--clang/test/Sema/block-args.c2
5 files changed, 27 insertions, 42 deletions
diff --git a/clang/include/clang/Sema/DeclSpec.h b/clang/include/clang/Sema/DeclSpec.h
index df5e1050367..bc817150ab8 100644
--- a/clang/include/clang/Sema/DeclSpec.h
+++ b/clang/include/clang/Sema/DeclSpec.h
@@ -1999,41 +1999,6 @@ public:
llvm_unreachable("unknown context kind!");
}
- /// diagnoseIdentifier - Return true if the identifier is prohibited and
- /// should be diagnosed (because it cannot be anything else).
- bool diagnoseIdentifier() const {
- switch (Context) {
- case FileContext:
- case KNRTypeListContext:
- case MemberContext:
- case BlockContext:
- case ForContext:
- case InitStmtContext:
- case ConditionContext:
- case PrototypeContext:
- case LambdaExprParameterContext:
- case TemplateParamContext:
- case CXXCatchContext:
- case ObjCCatchContext:
- case TypeNameContext:
- case FunctionalCastContext:
- case ConversionIdContext:
- case ObjCParameterContext:
- case ObjCResultContext:
- case BlockLiteralContext:
- case CXXNewContext:
- case LambdaExprContext:
- return false;
-
- case AliasDeclContext:
- case AliasTemplateContext:
- case TemplateTypeArgContext:
- case TrailingReturnContext:
- return true;
- }
- llvm_unreachable("unknown context kind!");
- }
-
/// Return true if the context permits a C++17 decomposition declarator.
bool mayHaveDecompositionDeclarator() const {
switch (Context) {
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp
index 69e1af0ed0b..b785f5f7d2e 100644
--- a/clang/lib/Parse/ParseDecl.cpp
+++ b/clang/lib/Parse/ParseDecl.cpp
@@ -5542,11 +5542,28 @@ void Parser::ParseDirectDeclarator(Declarator &D) {
D.SetRangeEnd(Tok.getLocation());
ConsumeToken();
goto PastIdentifier;
- } else if (Tok.is(tok::identifier) && D.diagnoseIdentifier()) {
- // A virt-specifier isn't treated as an identifier if it appears after a
- // trailing-return-type.
- if (D.getContext() != Declarator::TrailingReturnContext ||
- !isCXX11VirtSpecifier(Tok)) {
+ } else if (Tok.is(tok::identifier) && !D.mayHaveIdentifier()) {
+ // We're not allowed an identifier here, but we got one. Try to figure out
+ // if the user was trying to attach a name to the type, or whether the name
+ // is some unrelated trailing syntax.
+ bool DiagnoseIdentifier = false;
+ if (D.hasGroupingParens())
+ // An identifier within parens is unlikely to be intended to be anything
+ // other than a name being "declared".
+ DiagnoseIdentifier = true;
+ else if (D.getContext() == Declarator::TemplateTypeArgContext)
+ // T<int N> is an accidental identifier; T<int N indicates a missing '>'.
+ DiagnoseIdentifier =
+ NextToken().isOneOf(tok::comma, tok::greater, tok::greatergreater);
+ else if (D.getContext() == Declarator::AliasDeclContext ||
+ D.getContext() == Declarator::AliasTemplateContext)
+ // The most likely error is that the ';' was forgotten.
+ DiagnoseIdentifier = NextToken().isOneOf(tok::comma, tok::semi);
+ else if (D.getContext() == Declarator::TrailingReturnContext &&
+ !isCXX11VirtSpecifier(Tok))
+ DiagnoseIdentifier = NextToken().isOneOf(
+ tok::comma, tok::semi, tok::equal, tok::l_brace, tok::kw_try);
+ if (DiagnoseIdentifier) {
Diag(Tok.getLocation(), diag::err_unexpected_unqualified_id)
<< FixItHint::CreateRemoval(Tok.getLocation());
D.SetIdentifier(nullptr, Tok.getLocation());
diff --git a/clang/test/Parser/cxx-template-argument.cpp b/clang/test/Parser/cxx-template-argument.cpp
index 9b8ca985ddd..963356eaaba 100644
--- a/clang/test/Parser/cxx-template-argument.cpp
+++ b/clang/test/Parser/cxx-template-argument.cpp
@@ -10,7 +10,7 @@ template<typename T> struct A {};
// Check for template argument lists followed by junk
// FIXME: The diagnostics here aren't great...
A<int+> int x; // expected-error {{expected '>'}} expected-error {{expected unqualified-id}}
-A<int x; // expected-error {{type-id cannot have a name}} expected-error {{expected '>'}}
+A<int x; // expected-error {{expected '>'}}
// PR8912
template <bool> struct S {};
diff --git a/clang/test/Parser/cxx0x-decl.cpp b/clang/test/Parser/cxx0x-decl.cpp
index ba322a58948..2b253c019c9 100644
--- a/clang/test/Parser/cxx0x-decl.cpp
+++ b/clang/test/Parser/cxx0x-decl.cpp
@@ -137,6 +137,9 @@ namespace AliasDeclEndLocation {
>\
> // expected-error {{expected ';' after alias declaration}}
;
+ using D = AliasDeclEndLocation::A<int
+ > // expected-error {{expected ';' after alias declaration}}
+ B something_else;
}
struct Base { virtual void f() = 0; virtual void g() = 0; virtual void h() = 0; };
diff --git a/clang/test/Sema/block-args.c b/clang/test/Sema/block-args.c
index c6beead3915..69cf047a9ec 100644
--- a/clang/test/Sema/block-args.c
+++ b/clang/test/Sema/block-args.c
@@ -37,7 +37,7 @@ void f0() {
// rdar://problem/8962770
void test4() {
- int (^f)() = ^((x)) { }; // expected-error {{expected ')'}} expected-warning {{type specifier missing}} expected-note {{to match this}}
+ int (^f)() = ^((x)) { }; // expected-warning {{type specifier missing}} expected-error {{type-id cannot have a name}}
}
// rdar://problem/9170609
OpenPOWER on IntegriCloud