diff options
author | Chris Lattner <sabre@nondot.org> | 2011-02-18 02:08:43 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2011-02-18 02:08:43 +0000 |
commit | 4ae493cccbfbf122ec6ebac0e330232c22fa8489 (patch) | |
tree | 36dc74511f2ad667433c33a96c1c16bb5a8699ec /lib/Parse/ParseStmt.cpp | |
parent | 87152f783602f7548ffa28c56412d0a919cc0415 (diff) |
implement basic support for __label__. I wouldn't be shocked if there are
bugs from other clients that don't expect to see a LabelDecl in a DeclStmt,
but if so they should be easy to fix.
This implements most of PR3429 and rdar://8287027
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@125817 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Parse/ParseStmt.cpp')
-rw-r--r-- | lib/Parse/ParseStmt.cpp | 37 |
1 files changed, 33 insertions, 4 deletions
diff --git a/lib/Parse/ParseStmt.cpp b/lib/Parse/ParseStmt.cpp index 2c4ab655ae..2d9758333f 100644 --- a/lib/Parse/ParseStmt.cpp +++ b/lib/Parse/ParseStmt.cpp @@ -476,12 +476,41 @@ StmtResult Parser::ParseCompoundStatementBody(bool isStmtExpr) { SourceLocation LBraceLoc = ConsumeBrace(); // eat the '{'. - // TODO: "__label__ X, Y, Z;" is the GNU "Local Label" extension. These are - // only allowed at the start of a compound stmt regardless of the language. - StmtVector Stmts(Actions); - while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) { + // "__label__ X, Y, Z;" is the GNU "Local Label" extension. These are + // only allowed at the start of a compound stmt regardless of the language. + while (Tok.is(tok::kw___label__)) { + SourceLocation LabelLoc = ConsumeToken(); + Diag(LabelLoc, diag::ext_gnu_local_label); + + llvm::SmallVector<Decl *, 8> DeclsInGroup; + while (1) { + if (Tok.isNot(tok::identifier)) { + Diag(Tok, diag::err_expected_ident); + break; + } + + IdentifierInfo *II = Tok.getIdentifierInfo(); + SourceLocation IdLoc = ConsumeToken(); + DeclsInGroup.push_back(Actions.LookupOrCreateLabel(II, IdLoc, true)); + + if (!Tok.is(tok::comma)) + break; + ConsumeToken(); + } + + DeclSpec DS; + DeclGroupPtrTy Res = Actions.FinalizeDeclaratorGroup(getCurScope(), DS, + DeclsInGroup.data(), DeclsInGroup.size()); + StmtResult R = Actions.ActOnDeclStmt(Res, LabelLoc, Tok.getLocation()); + + ExpectAndConsume(tok::semi, diag::err_expected_semi_declaration); + if (R.isUsable()) + Stmts.push_back(R.release()); + } + + while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) { if (Tok.is(tok::annot_pragma_unused)) { HandlePragmaUnused(); continue; |