diff options
author | Chris Lattner <sabre@nondot.org> | 2009-03-29 16:50:03 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2009-03-29 16:50:03 +0000 |
commit | 682bf92db408a6cbc3d37b5496a99b6ef85041ec (patch) | |
tree | e804127e1ead3b5b43c405f01f0a00c1eaf1734b /lib/Parse/Parser.cpp | |
parent | 827ecb0db9225c98f08cfc991598210bcf0045dd (diff) |
Push DeclGroup much farther throughout the compiler. Now the various
productions (except the already broken ObjC cases like @class X,Y;) in
the parser that can produce more than one Decl return a DeclGroup instead
of a Decl, etc.
This allows elimination of the Decl::NextDeclarator field, and exposes
various clients that should look at all decls in a group, but which were
only looking at one (such as the dumper, printer, etc). These have been
fixed.
Still TODO:
1) there are some FIXME's in the code about potentially using
DeclGroup for better location info.
2) ParseObjCAtDirectives should return a DeclGroup due to @class etc.
3) I'm not sure what is going on with StmtIterator.cpp, or if it can
be radically simplified now.
4) I put a truly horrible hack in ParseTemplate.cpp.
I plan to bring up #3/4 on the mailing list, but don't plan to tackle
#1/2 in the short term.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@68002 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Parse/Parser.cpp')
-rw-r--r-- | lib/Parse/Parser.cpp | 98 |
1 files changed, 59 insertions, 39 deletions
diff --git a/lib/Parse/Parser.cpp b/lib/Parse/Parser.cpp index 00a3349c21..56f922d400 100644 --- a/lib/Parse/Parser.cpp +++ b/lib/Parse/Parser.cpp @@ -324,8 +324,8 @@ void Parser::Initialize() { /// ParseTopLevelDecl - Parse one top-level declaration, return whatever the /// action tells us to. This returns true if the EOF was encountered. -bool Parser::ParseTopLevelDecl(DeclPtrTy &Result) { - Result = DeclPtrTy(); +bool Parser::ParseTopLevelDecl(DeclGroupPtrTy &Result) { + Result = DeclGroupPtrTy(); if (Tok.is(tok::eof)) { Actions.ActOnEndOfTranslationUnit(); return true; @@ -342,7 +342,7 @@ bool Parser::ParseTopLevelDecl(DeclPtrTy &Result) { void Parser::ParseTranslationUnit() { Initialize(); - DeclPtrTy Res; + DeclGroupPtrTy Res; while (!ParseTopLevelDecl(Res)) /*parse them all*/; @@ -368,20 +368,21 @@ void Parser::ParseTranslationUnit() { /// [GNU] asm-definition: /// simple-asm-expr ';' /// -Parser::DeclPtrTy Parser::ParseExternalDeclaration() { +Parser::DeclGroupPtrTy Parser::ParseExternalDeclaration() { + DeclPtrTy SingleDecl; switch (Tok.getKind()) { case tok::semi: Diag(Tok, diag::ext_top_level_semi); ConsumeToken(); // TODO: Invoke action for top-level semicolon. - return DeclPtrTy(); + return DeclGroupPtrTy(); case tok::r_brace: Diag(Tok, diag::err_expected_external_declaration); ConsumeBrace(); - return DeclPtrTy(); + return DeclGroupPtrTy(); case tok::eof: Diag(Tok, diag::err_expected_external_declaration); - return DeclPtrTy(); + return DeclGroupPtrTy(); case tok::kw___extension__: { // __extension__ silences extension warnings in the subexpression. ExtensionRAIIObject O(Diags); // Use RAII to do this. @@ -394,20 +395,26 @@ Parser::DeclPtrTy Parser::ParseExternalDeclaration() { ExpectAndConsume(tok::semi, diag::err_expected_semi_after, "top-level asm block"); - if (!Result.isInvalid()) - return Actions.ActOnFileScopeAsmDecl(Tok.getLocation(), move(Result)); - return DeclPtrTy(); + if (Result.isInvalid()) + return DeclGroupPtrTy(); + SingleDecl = Actions.ActOnFileScopeAsmDecl(Tok.getLocation(), move(Result)); + break; } case tok::at: - // @ is not a legal token unless objc is enabled, no need to check. - return ParseObjCAtDirectives(); + // @ is not a legal token unless objc is enabled, no need to check for ObjC. + /// FIXME: ParseObjCAtDirectives should return a DeclGroup for things like + /// @class foo, bar; + SingleDecl = ParseObjCAtDirectives(); + break; case tok::minus: case tok::plus: - if (getLang().ObjC1) - return ParseObjCMethodDefinition(); - Diag(Tok, diag::err_expected_external_declaration); - ConsumeToken(); - return DeclPtrTy(); + if (!getLang().ObjC1) { + Diag(Tok, diag::err_expected_external_declaration); + ConsumeToken(); + return DeclGroupPtrTy(); + } + SingleDecl = ParseObjCMethodDefinition(); + break; case tok::kw_using: case tok::kw_namespace: case tok::kw_typedef: @@ -420,6 +427,10 @@ Parser::DeclPtrTy Parser::ParseExternalDeclaration() { // We can't tell whether this is a function-definition or declaration yet. return ParseDeclarationOrFunctionDefinition(); } + + // This routine returns a DeclGroup, if the thing we parsed only contains a + // single decl, convert it now. + return Actions.ConvertDeclToDeclGroup(SingleDecl); } /// ParseDeclarationOrFunctionDefinition - Parse either a function-definition or @@ -438,7 +449,7 @@ Parser::DeclPtrTy Parser::ParseExternalDeclaration() { /// [!C99] init-declarator-list ';' [TODO: warn in c99 mode] /// [OMP] threadprivate-directive [TODO] /// -Parser::DeclPtrTy +Parser::DeclGroupPtrTy Parser::ParseDeclarationOrFunctionDefinition( TemplateParameterLists *TemplateParams, AccessSpecifier AS) { @@ -450,7 +461,8 @@ Parser::ParseDeclarationOrFunctionDefinition( // declaration-specifiers init-declarator-list[opt] ';' if (Tok.is(tok::semi)) { ConsumeToken(); - return Actions.ParsedFreeStandingDeclSpec(CurScope, DS); + DeclPtrTy TheDecl = Actions.ParsedFreeStandingDeclSpec(CurScope, DS); + return Actions.ConvertDeclToDeclGroup(TheDecl); } // ObjC2 allows prefix attributes on class interfaces and protocols. @@ -462,14 +474,18 @@ Parser::ParseDeclarationOrFunctionDefinition( !Tok.isObjCAtKeyword(tok::objc_protocol)) { Diag(Tok, diag::err_objc_unexpected_attr); SkipUntil(tok::semi); // FIXME: better skip? - return DeclPtrTy(); + return DeclGroupPtrTy(); } const char *PrevSpec = 0; if (DS.SetTypeSpecType(DeclSpec::TST_unspecified, AtLoc, PrevSpec)) Diag(AtLoc, diag::err_invalid_decl_spec_combination) << PrevSpec; + + DeclPtrTy TheDecl; if (Tok.isObjCAtKeyword(tok::objc_protocol)) - return ParseObjCAtProtocolDeclaration(AtLoc, DS.getAttributes()); - return ParseObjCAtInterfaceDeclaration(AtLoc, DS.getAttributes()); + TheDecl = ParseObjCAtProtocolDeclaration(AtLoc, DS.getAttributes()); + else + TheDecl = ParseObjCAtInterfaceDeclaration(AtLoc, DS.getAttributes()); + return Actions.ConvertDeclToDeclGroup(TheDecl); } // If the declspec consisted only of 'extern' and we have a string @@ -477,8 +493,10 @@ Parser::ParseDeclarationOrFunctionDefinition( // 'extern "C"'. if (Tok.is(tok::string_literal) && getLang().CPlusPlus && DS.getStorageClassSpec() == DeclSpec::SCS_extern && - DS.getParsedSpecifiers() == DeclSpec::PQ_StorageClassSpecifier) - return ParseLinkage(Declarator::FileContext); + DS.getParsedSpecifiers() == DeclSpec::PQ_StorageClassSpecifier) { + DeclPtrTy TheDecl = ParseLinkage(Declarator::FileContext); + return Actions.ConvertDeclToDeclGroup(TheDecl); + } // Parse the first declarator. Declarator DeclaratorInfo(DS, Declarator::FileContext); @@ -489,7 +507,7 @@ Parser::ParseDeclarationOrFunctionDefinition( SkipUntil(tok::r_brace, true, true); if (Tok.is(tok::semi)) ConsumeToken(); - return DeclPtrTy(); + return DeclGroupPtrTy(); } // If the declarator is the start of a function definition, handle it. @@ -500,8 +518,12 @@ Parser::ParseDeclarationOrFunctionDefinition( Tok.is(tok::kw___attribute) || // int X() __attr__ -> not a function def (getLang().CPlusPlus && Tok.is(tok::l_paren)) ) { // int X(0) -> not a function def [C++] - // FALL THROUGH. - } else if (DeclaratorInfo.isFunctionDeclarator() && + // Parse the init-declarator-list for a normal declaration. + return ParseInitDeclaratorListAfterFirstDeclarator(DeclaratorInfo); + } + + + if (DeclaratorInfo.isFunctionDeclarator() && (Tok.is(tok::l_brace) || // int X() {} (!getLang().CPlusPlus && isDeclarationSpecifier()) || // int X(f) int f; {} @@ -519,20 +541,18 @@ Parser::ParseDeclarationOrFunctionDefinition( } else { SkipUntil(tok::semi); } - return DeclPtrTy(); + return DeclGroupPtrTy(); } - return ParseFunctionDefinition(DeclaratorInfo); - } else { - if (DeclaratorInfo.isFunctionDeclarator()) - Diag(Tok, diag::err_expected_fn_body); - else - Diag(Tok, diag::err_invalid_token_after_toplevel_declarator); - SkipUntil(tok::semi); - return DeclPtrTy(); + DeclPtrTy TheDecl = ParseFunctionDefinition(DeclaratorInfo); + return Actions.ConvertDeclToDeclGroup(TheDecl); } - - // Parse the init-declarator-list for a normal declaration. - return ParseInitDeclaratorListAfterFirstDeclarator(DeclaratorInfo); + + if (DeclaratorInfo.isFunctionDeclarator()) + Diag(Tok, diag::err_expected_fn_body); + else + Diag(Tok, diag::err_invalid_token_after_toplevel_declarator); + SkipUntil(tok::semi); + return DeclGroupPtrTy(); } /// ParseFunctionDefinition - We parsed and verified that the specified |