[cfe-commits] r125817 - in /cfe/trunk: include/clang/Basic/DiagnosticParseKinds.td include/clang/Sema/Sema.h lib/AST/StmtDumper.cpp lib/CodeGen/CGDecl.cpp lib/Parse/ParseStmt.cpp lib/Sema/SemaLookup.cpp test/Parser/goto.c

Chris Lattner sabre at nondot.org
Thu Feb 17 18:08:43 PST 2011


Author: lattner
Date: Thu Feb 17 20:08:43 2011
New Revision: 125817

URL: http://llvm.org/viewvc/llvm-project?rev=125817&view=rev
Log:
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


Modified:
    cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td
    cfe/trunk/include/clang/Sema/Sema.h
    cfe/trunk/lib/AST/StmtDumper.cpp
    cfe/trunk/lib/CodeGen/CGDecl.cpp
    cfe/trunk/lib/Parse/ParseStmt.cpp
    cfe/trunk/lib/Sema/SemaLookup.cpp
    cfe/trunk/test/Parser/goto.c

Modified: cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td?rev=125817&r1=125816&r2=125817&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td Thu Feb 17 20:08:43 2011
@@ -62,6 +62,8 @@
   "use of GNU indirect-goto extension">, InGroup<GNU>;
 def ext_gnu_address_of_label : Extension<
   "use of GNU address-of-label extension">, InGroup<GNU>;
+def ext_gnu_local_label : Extension<
+  "use of GNU locally declared label extension">, InGroup<GNU>;
 def ext_gnu_statement_expr : Extension<
   "use of GNU statement expression extension">, InGroup<GNU>;
 def ext_gnu_conditional_expr : Extension<

Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=125817&r1=125816&r2=125817&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Thu Feb 17 20:08:43 2011
@@ -1414,7 +1414,8 @@
                                     QualType T1, QualType T2,
                                     UnresolvedSetImpl &Functions);
 
-  LabelDecl *LookupOrCreateLabel(IdentifierInfo *II, SourceLocation Loc);
+  LabelDecl *LookupOrCreateLabel(IdentifierInfo *II, SourceLocation Loc,
+                                 bool isLocalLabel = false);
   
   DeclContextLookupResult LookupConstructors(CXXRecordDecl *Class);
   CXXDestructorDecl *LookupDestructor(CXXRecordDecl *Class);

Modified: cfe/trunk/lib/AST/StmtDumper.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/StmtDumper.cpp?rev=125817&r1=125816&r2=125817&view=diff
==============================================================================
--- cfe/trunk/lib/AST/StmtDumper.cpp (original)
+++ cfe/trunk/lib/AST/StmtDumper.cpp Thu Feb 17 20:08:43 2011
@@ -282,6 +282,8 @@
     UD->getTargetNestedNameDecl()->print(OS,
         PrintingPolicy(UD->getASTContext().getLangOptions()));
     OS << ";\"";
+  } else if (LabelDecl *LD = dyn_cast<LabelDecl>(D)) {
+    OS << "label " << LD->getNameAsString();
   } else {
     assert(0 && "Unexpected decl");
   }

Modified: cfe/trunk/lib/CodeGen/CGDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDecl.cpp?rev=125817&r1=125816&r2=125817&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGDecl.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGDecl.cpp Thu Feb 17 20:08:43 2011
@@ -70,7 +70,6 @@
   case Decl::Friend:
   case Decl::FriendTemplate:
   case Decl::Block:
-  case Decl::Label:
     assert(0 && "Declaration not should not be in declstmts!");
   case Decl::Function:  // void X();
   case Decl::Record:    // struct/union/class X;
@@ -82,6 +81,7 @@
   case Decl::UsingDirective: // using namespace X; [C++]
   case Decl::NamespaceAlias:
   case Decl::StaticAssert: // static_assert(X, ""); [C++0x]
+  case Decl::Label:        // __label__ x;
     // None of these decls require codegen support.
     return;
 

Modified: cfe/trunk/lib/Parse/ParseStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseStmt.cpp?rev=125817&r1=125816&r2=125817&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseStmt.cpp (original)
+++ cfe/trunk/lib/Parse/ParseStmt.cpp Thu Feb 17 20:08:43 2011
@@ -476,12 +476,41 @@
   
   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;

Modified: cfe/trunk/lib/Sema/SemaLookup.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaLookup.cpp?rev=125817&r1=125816&r2=125817&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaLookup.cpp (original)
+++ cfe/trunk/lib/Sema/SemaLookup.cpp Thu Feb 17 20:08:43 2011
@@ -2760,10 +2760,18 @@
                        /*InBaseClass=*/false, Consumer, Visited);
 }
 
-LabelDecl *Sema::LookupOrCreateLabel(IdentifierInfo *II, SourceLocation Loc) {
+/// LookupOrCreateLabel - Do a name lookup of a label with the specified name.
+/// If isLocalLabel is true, then this is a definition of an __label__ label
+/// name, otherwise it is a normal label definition or use.
+LabelDecl *Sema::LookupOrCreateLabel(IdentifierInfo *II, SourceLocation Loc,
+                                     bool isLocalLabel) {
   // Do a lookup to see if we have a label with this name already.
-  NamedDecl *Res = LookupSingleName(CurScope, II, Loc, LookupLabel,
-                                    NotForRedeclaration);
+  NamedDecl *Res = 0;
+  
+  // Local label definitions always shadow existing labels.
+  if (!isLocalLabel)
+    Res = LookupSingleName(CurScope, II, Loc, LookupLabel, NotForRedeclaration);
+  
   // If we found a label, check to see if it is in the same context as us.  When
   // in a Block, we don't want to reuse a label in an enclosing function.
   if (Res && Res->getDeclContext() != CurContext)
@@ -2772,7 +2780,8 @@
   if (Res == 0) {
     // If not forward referenced or defined already, create the backing decl.
     Res = LabelDecl::Create(Context, CurContext, Loc, II);
-    PushOnScopeChains(Res, CurScope->getFnParent(), true);
+    PushOnScopeChains(Res, isLocalLabel ? CurScope : CurScope->getFnParent(),
+                      true);
   }
   
   return cast<LabelDecl>(Res);

Modified: cfe/trunk/test/Parser/goto.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/goto.c?rev=125817&r1=125816&r2=125817&view=diff
==============================================================================
--- cfe/trunk/test/Parser/goto.c (original)
+++ cfe/trunk/test/Parser/goto.c Thu Feb 17 20:08:43 2011
@@ -1,6 +1,30 @@
 /* RUN: %clang_cc1 -fsyntax-only -verify %s
 */
 
-void foo() { 
+void test1() { 
   goto ; /* expected-error {{expected identifier}} */
 }
+
+
+void test2() {
+  l:  /* expected-note {{previous definition is here}} */
+  
+  {
+    __label__ l;
+  l: goto l;
+  }
+  
+  {
+    __label__ l;
+    __label__ h;   /* expected-error {{use of undeclared label 'h'}} */
+  l: goto l;
+  }
+
+  /* PR3429 & rdar://8287027
+   */
+  {
+  l:  /* expected-error {{redefinition of label 'l'}} */
+    ;
+  }
+
+}





More information about the cfe-commits mailing list