diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2017-05-22 19:43:45 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2017-05-22 19:43:45 +0000 |
commit | aa803409c3bd3930126db630c29f63d42f255153 (patch) | |
tree | 042106605c08352895ba4383ef97eae88b6b31aa /lib/Parse/ParseDecl.cpp | |
parent | 1ce08792766261dcaa25d8215f9d1c2f70d7b7e9 (diff) | |
download | src-aa803409c3bd3930126db630c29f63d42f255153.tar.gz src-aa803409c3bd3930126db630c29f63d42f255153.zip |
Vendor import of clang trunk r303571:vendor/clang/clang-trunk-r303571
Notes
Notes:
svn path=/vendor/clang/dist/; revision=318665
svn path=/vendor/clang/clang-trunk-r303571/; revision=318666; tag=vendor/clang/clang-trunk-r303571
Diffstat (limited to 'lib/Parse/ParseDecl.cpp')
-rw-r--r-- | lib/Parse/ParseDecl.cpp | 46 |
1 files changed, 33 insertions, 13 deletions
diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp index 4ccee74eaa90..b785f5f7d2e6 100644 --- a/lib/Parse/ParseDecl.cpp +++ b/lib/Parse/ParseDecl.cpp @@ -2989,7 +2989,7 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS, } DS.getTypeSpecScope() = SS; - ConsumeToken(); // The C++ scope. + ConsumeAnnotationToken(); // The C++ scope. assert(Tok.is(tok::annot_template_id) && "ParseOptionalCXXScopeSpecifier not working"); AnnotateTemplateIdTokenAsType(); @@ -2998,7 +2998,7 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS, if (Next.is(tok::annot_typename)) { DS.getTypeSpecScope() = SS; - ConsumeToken(); // The C++ scope. + ConsumeAnnotationToken(); // The C++ scope. if (Tok.getAnnotationValue()) { ParsedType T = getTypeAnnotation(Tok); isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typename, @@ -3010,7 +3010,7 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS, else DS.SetTypeSpecError(); DS.SetRangeEnd(Tok.getAnnotationEndLoc()); - ConsumeToken(); // The typename + ConsumeAnnotationToken(); // The typename } if (Next.isNot(tok::identifier)) @@ -3037,7 +3037,8 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS, // C++ doesn't have implicit int. Diagnose it as a typo w.r.t. to the // typename. if (!TypeRep) { - ConsumeToken(); // Eat the scope spec so the identifier is current. + // Eat the scope spec so the identifier is current. + ConsumeAnnotationToken(); ParsedAttributesWithRange Attrs(AttrFactory); if (ParseImplicitInt(DS, &SS, TemplateInfo, AS, DSContext, Attrs)) { if (!Attrs.empty()) { @@ -3050,7 +3051,7 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS, } DS.getTypeSpecScope() = SS; - ConsumeToken(); // The C++ scope. + ConsumeAnnotationToken(); // The C++ scope. isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec, DiagID, TypeRep, Policy); @@ -3080,7 +3081,7 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS, break; DS.SetRangeEnd(Tok.getAnnotationEndLoc()); - ConsumeToken(); // The typename + ConsumeAnnotationToken(); // The typename continue; } @@ -4836,10 +4837,12 @@ bool Parser::isConstructorDeclarator(bool IsUnqualified, bool DeductionGuide) { } // Parse the constructor name. - if (Tok.isOneOf(tok::identifier, tok::annot_template_id)) { + if (Tok.is(tok::identifier)) { // We already know that we have a constructor name; just consume // the token. ConsumeToken(); + } else if (Tok.is(tok::annot_template_id)) { + ConsumeAnnotationToken(); } else { TPA.Revert(); return false; @@ -4895,7 +4898,7 @@ bool Parser::isConstructorDeclarator(bool IsUnqualified, bool DeductionGuide) { // be a constructor declaration with an invalid argument type. Keep // looking. if (Tok.is(tok::annot_cxxscope)) - ConsumeToken(); + ConsumeAnnotationToken(); ConsumeToken(); // If this is not a constructor, we must be parsing a declarator, @@ -5539,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()); |