aboutsummaryrefslogtreecommitdiff
path: root/lib/Parse/ParseStmt.cpp
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2011-02-18 02:08:43 +0000
committerChris Lattner <sabre@nondot.org>2011-02-18 02:08:43 +0000
commit4ae493cccbfbf122ec6ebac0e330232c22fa8489 (patch)
tree36dc74511f2ad667433c33a96c1c16bb5a8699ec /lib/Parse/ParseStmt.cpp
parent87152f783602f7548ffa28c56412d0a919cc0415 (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.cpp37
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;