diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2014-01-08 00:56:48 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2014-01-08 00:56:48 +0000 |
commit | 649c7b069f53596e2c651d6524cf7c6621e3d565 (patch) | |
tree | 843dea1c8f456052afad31c30fa10dcf7f0eb6b1 /clang/lib/Parse/ParseDecl.cpp | |
parent | 1c3996abc7201af3e2041527a3e1fb3d4d4774c1 (diff) | |
download | bcm5719-llvm-649c7b069f53596e2c651d6524cf7c6621e3d565.tar.gz bcm5719-llvm-649c7b069f53596e2c651d6524cf7c6621e3d565.zip |
PR18234: Mark a tag definition as invalid early if it appears in a
type-specifier in C++. Some checks will assert in this case otherwise (in
particular, the access specifier may be missing if this happens inside a class
definition, due to a violation of an AST invariant).
llvm-svn: 198721
Diffstat (limited to 'clang/lib/Parse/ParseDecl.cpp')
-rw-r--r-- | clang/lib/Parse/ParseDecl.cpp | 16 |
1 files changed, 9 insertions, 7 deletions
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp index 277355cd40d..27df0c0795d 100644 --- a/clang/lib/Parse/ParseDecl.cpp +++ b/clang/lib/Parse/ParseDecl.cpp @@ -2056,8 +2056,7 @@ void Parser::ParseSpecifierQualifierList(DeclSpec &DS, AccessSpecifier AS, // Validate declspec for type-name. unsigned Specs = DS.getParsedSpecifiers(); - if ((DSC == DSC_type_specifier || DSC == DSC_trailing) && - !DS.hasTypeSpecifier()) { + if (isTypeSpecifier(DSC) && !DS.hasTypeSpecifier()) { Diag(Tok, diag::err_expected_type); DS.SetTypeSpecError(); } else if (Specs == DeclSpec::PQ_None && !DS.getNumProtocolQualifiers() && @@ -2155,8 +2154,7 @@ bool Parser::ParseImplicitInt(DeclSpec &DS, CXXScopeSpec *SS, // within a type specifier. Outside of C++, we allow this even if the // language doesn't "officially" support implicit int -- we support // implicit int as an extension in C99 and C11. - if (DSC != DSC_type_specifier && DSC != DSC_trailing && - !getLangOpts().CPlusPlus && + if (!isTypeSpecifier(DSC) && !getLangOpts().CPlusPlus && isValidAfterIdentifierInDeclarator(NextToken())) { // If this token is valid for implicit int, e.g. "static x = 4", then // we just avoid eating the identifier, so it will be parsed as the @@ -2226,7 +2224,7 @@ bool Parser::ParseImplicitInt(DeclSpec &DS, CXXScopeSpec *SS, // Determine whether this identifier could plausibly be the name of something // being declared (with a missing type). - if (DSC != DSC_type_specifier && DSC != DSC_trailing && + if (!isTypeSpecifier(DSC) && (!SS || DSC == DSC_top_level || DSC == DSC_class)) { // Look ahead to the next token to try to figure out what this declaration // was supposed to be. @@ -2339,6 +2337,9 @@ Parser::getDeclSpecContextFromDeclaratorContext(unsigned Context) { return DSC_top_level; if (Context == Declarator::TrailingReturnContext) return DSC_trailing; + if (Context == Declarator::AliasDeclContext || + Context == Declarator::AliasTemplateContext) + return DSC_alias_declaration; return DSC_normal; } @@ -3751,7 +3752,7 @@ void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS, } else { TUK = Sema::TUK_Definition; } - } else if (DSC != DSC_type_specifier && + } else if (!isTypeSpecifier(DSC) && (Tok.is(tok::semi) || (Tok.isAtStartOfLine() && !isValidAfterTypeSpecifier(CanBeBitfield)))) { @@ -3813,7 +3814,8 @@ void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS, StartLoc, SS, Name, NameLoc, attrs.getList(), AS, DS.getModulePrivateSpecLoc(), TParams, Owned, IsDependent, ScopedEnumKWLoc, - IsScopedUsingClassTag, BaseType); + IsScopedUsingClassTag, BaseType, + DSC == DSC_type_specifier); if (IsDependent) { // This enum has a dependent nested-name-specifier. Handle it as a |