[cfe-commits] r125733 - in /cfe/trunk: include/clang/AST/ include/clang/Basic/ include/clang/Sema/ include/clang/Serialization/ include/clang/StaticAnalyzer/Core/PathSensitive/ lib/AST/ lib/Analysis/ lib/CodeGen/ lib/Sema/ lib/Serialization/ lib/StaticAnalyzer/Checkers/ lib/StaticAnalyzer/Core/ test/CXX/stmt.stmt/stmt.label/ test/Sema/ tools/libclang/

Chris Lattner sabre at nondot.org
Wed Feb 16 23:39:24 PST 2011


Author: lattner
Date: Thu Feb 17 01:39:24 2011
New Revision: 125733

URL: http://llvm.org/viewvc/llvm-project?rev=125733&view=rev
Log:
Step #1/N of implementing support for __label__: split labels into
LabelDecl and LabelStmt.  There is a 1-1 correspondence between the
two, but this simplifies a bunch of code by itself.  This is because
labels are the only place where we previously had references to random
other statements, causing grief for AST serialization and other stuff.

This does cause one regression (attr(unused) doesn't silence unused
label warnings) which I'll address next.

This does fix some minor bugs:
1. "The only valid attribute " diagnostic was capitalized.
2. Various diagnostics printed as ''labelname'' instead of 'labelname'
3. This reduces duplication of label checking between functions and blocks.

Review appreciated, particularly for the cindex and template bits.


Modified:
    cfe/trunk/include/clang/AST/Decl.h
    cfe/trunk/include/clang/AST/DeclBase.h
    cfe/trunk/include/clang/AST/Expr.h
    cfe/trunk/include/clang/AST/RecursiveASTVisitor.h
    cfe/trunk/include/clang/AST/Stmt.h
    cfe/trunk/include/clang/Basic/DeclNodes.td
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/include/clang/Sema/ScopeInfo.h
    cfe/trunk/include/clang/Serialization/ASTBitCodes.h
    cfe/trunk/include/clang/Serialization/ASTReader.h
    cfe/trunk/include/clang/Serialization/ASTWriter.h
    cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h
    cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h
    cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h
    cfe/trunk/lib/AST/Decl.cpp
    cfe/trunk/lib/AST/DeclBase.cpp
    cfe/trunk/lib/AST/Stmt.cpp
    cfe/trunk/lib/AST/StmtProfile.cpp
    cfe/trunk/lib/Analysis/CFG.cpp
    cfe/trunk/lib/CodeGen/CGDecl.cpp
    cfe/trunk/lib/CodeGen/CGStmt.cpp
    cfe/trunk/lib/CodeGen/CodeGenFunction.cpp
    cfe/trunk/lib/CodeGen/CodeGenFunction.h
    cfe/trunk/lib/Sema/JumpDiagnostics.cpp
    cfe/trunk/lib/Sema/Sema.cpp
    cfe/trunk/lib/Sema/SemaDecl.cpp
    cfe/trunk/lib/Sema/SemaExpr.cpp
    cfe/trunk/lib/Sema/SemaStmt.cpp
    cfe/trunk/lib/Sema/TreeTransform.h
    cfe/trunk/lib/Serialization/ASTReader.cpp
    cfe/trunk/lib/Serialization/ASTReaderDecl.cpp
    cfe/trunk/lib/Serialization/ASTReaderStmt.cpp
    cfe/trunk/lib/Serialization/ASTWriterDecl.cpp
    cfe/trunk/lib/Serialization/ASTWriterStmt.cpp
    cfe/trunk/lib/StaticAnalyzer/Checkers/ExprEngine.cpp
    cfe/trunk/lib/StaticAnalyzer/Core/SVals.cpp
    cfe/trunk/test/CXX/stmt.stmt/stmt.label/p1.cpp
    cfe/trunk/test/Sema/warn-unused-label.c
    cfe/trunk/tools/libclang/CIndex.cpp

Modified: cfe/trunk/include/clang/AST/Decl.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Decl.h?rev=125733&r1=125732&r2=125733&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Decl.h (original)
+++ cfe/trunk/include/clang/AST/Decl.h Thu Feb 17 01:39:24 2011
@@ -36,6 +36,7 @@
 class DependentFunctionTemplateSpecializationInfo;
 class TypeLoc;
 class UnresolvedSetImpl;
+class LabelStmt;
 
 /// \brief A container of type source information.
 ///
@@ -294,6 +295,36 @@
   return OS;
 }
 
+/// LabelDecl - Represents the declaration of a label.  Labels also have a
+/// corresponding LabelStmt, which indicates the position that the label was
+/// defined at.  For normal labels, the location of the decl is the same as the
+/// location of the statement.  For GNU local labels (__label__), the decl
+/// location is where the __label__ is.
+class LabelDecl : public NamedDecl {
+  /// HasUnusedAttr - True if the label has __attribute__((unused)) on it.
+  /// FIXME: Just use attributes!
+  unsigned HasUnusedAttr : 1;
+
+  LabelStmt *TheStmt;
+  LabelDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *II, LabelStmt *S)
+    : NamedDecl(Label, DC, L, II), TheStmt(S) {}
+  
+public:
+  static LabelDecl *Create(ASTContext &C, DeclContext *DC,
+                           SourceLocation L, IdentifierInfo *II);
+
+  LabelStmt *getStmt() const { return TheStmt; }
+  void setStmt(LabelStmt *T) { TheStmt = T; }
+  
+  bool hasUnusedAttribute() const { return HasUnusedAttr; }
+  void setHasUnusedAttribute() { HasUnusedAttr = true; }
+  
+  // Implement isa/cast/dyncast/etc.
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+  static bool classof(const LabelDecl *D) { return true; }
+  static bool classofKind(Kind K) { return K == Label; }
+};
+  
 /// NamespaceDecl - Represent a C++ namespace.
 class NamespaceDecl : public NamedDecl, public DeclContext {
   bool IsInline : 1;

Modified: cfe/trunk/include/clang/AST/DeclBase.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclBase.h?rev=125733&r1=125732&r2=125733&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/DeclBase.h (original)
+++ cfe/trunk/include/clang/AST/DeclBase.h Thu Feb 17 01:39:24 2011
@@ -324,7 +324,7 @@
 
   bool hasAttrs() const { return HasAttrs; }
   void setAttrs(const AttrVec& Attrs);
-  AttrVec& getAttrs() {
+  AttrVec &getAttrs() {
     return const_cast<AttrVec&>(const_cast<const Decl*>(this)->getAttrs());
   }
   const AttrVec &getAttrs() const;

Modified: cfe/trunk/include/clang/AST/Expr.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Expr.h?rev=125733&r1=125732&r2=125733&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Expr.h (original)
+++ cfe/trunk/include/clang/AST/Expr.h Thu Feb 17 01:39:24 2011
@@ -2641,9 +2641,9 @@
 /// AddrLabelExpr - The GNU address of label extension, representing &&label.
 class AddrLabelExpr : public Expr {
   SourceLocation AmpAmpLoc, LabelLoc;
-  LabelStmt *Label;
+  LabelDecl *Label;
 public:
-  AddrLabelExpr(SourceLocation AALoc, SourceLocation LLoc, LabelStmt *L,
+  AddrLabelExpr(SourceLocation AALoc, SourceLocation LLoc, LabelDecl *L,
                 QualType t)
     : Expr(AddrLabelExprClass, t, VK_RValue, OK_Ordinary, false, false, false),
       AmpAmpLoc(AALoc), LabelLoc(LLoc), Label(L) {}
@@ -2661,8 +2661,8 @@
     return SourceRange(AmpAmpLoc, LabelLoc);
   }
 
-  LabelStmt *getLabel() const { return Label; }
-  void setLabel(LabelStmt *S) { Label = S; }
+  LabelDecl *getLabel() const { return Label; }
+  void setLabel(LabelDecl *L) { Label = L; }
 
   static bool classof(const Stmt *T) {
     return T->getStmtClass() == AddrLabelExprClass;

Modified: cfe/trunk/include/clang/AST/RecursiveASTVisitor.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/RecursiveASTVisitor.h?rev=125733&r1=125732&r2=125733&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/RecursiveASTVisitor.h (original)
+++ cfe/trunk/include/clang/AST/RecursiveASTVisitor.h Thu Feb 17 01:39:24 2011
@@ -1088,6 +1088,11 @@
     return true;
   })
 
+DEF_TRAVERSE_DECL(LabelDecl, {
+  // There is no code in a LabelDecl.
+})
+  
+  
 DEF_TRAVERSE_DECL(NamespaceDecl, {
     // Code in an unnamed namespace shows up automatically in
     // decls_begin()/decls_end().  Thus we don't need to recurse on

Modified: cfe/trunk/include/clang/AST/Stmt.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Stmt.h?rev=125733&r1=125732&r2=125733&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Stmt.h (original)
+++ cfe/trunk/include/clang/AST/Stmt.h Thu Feb 17 01:39:24 2011
@@ -130,14 +130,6 @@
     unsigned NumStmts : 32 - NumStmtBits;
   };
 
-  class LabelStmtBitfields {
-    friend class LabelStmt;
-    unsigned : NumStmtBits;
-
-    unsigned Used : 1;
-    unsigned HasUnusedAttr : 1;
-  };
-
   class ExprBitfields {
     friend class Expr;
     friend class DeclRefExpr; // computeDependence
@@ -187,7 +179,6 @@
 
     StmtBitfields StmtBits;
     CompoundStmtBitfields CompoundStmtBits;
-    LabelStmtBitfields LabelStmtBits;
     ExprBitfields ExprBits;
     CastExprBitfields CastExprBits;
     CallExprBitfields CallExprBits;
@@ -633,40 +624,31 @@
   child_range children() { return child_range(&SubStmt, &SubStmt+1); }
 };
 
+  
+/// LabelStmt - Represents a label, which has a substatement.  For example:
+///    foo: return;
+///
 class LabelStmt : public Stmt {
-  IdentifierInfo *Label;
+  LabelDecl *TheDecl;
   Stmt *SubStmt;
   SourceLocation IdentLoc;
 public:
-  LabelStmt(SourceLocation IL, IdentifierInfo *label, Stmt *substmt,
-            bool hasUnusedAttr = false)
-    : Stmt(LabelStmtClass), Label(label), SubStmt(substmt), IdentLoc(IL) {
-    LabelStmtBits.Used = false;
-    LabelStmtBits.HasUnusedAttr = hasUnusedAttr;
+  LabelStmt(SourceLocation IL, LabelDecl *D, Stmt *substmt)
+    : Stmt(LabelStmtClass), TheDecl(D), SubStmt(substmt), IdentLoc(IL) {
   }
 
   // \brief Build an empty label statement.
   explicit LabelStmt(EmptyShell Empty) : Stmt(LabelStmtClass, Empty) { }
 
   SourceLocation getIdentLoc() const { return IdentLoc; }
-  IdentifierInfo *getID() const { return Label; }
-  void setID(IdentifierInfo *II) { Label = II; }
+  LabelDecl *getDecl() const { return TheDecl; }
+  void setDecl(LabelDecl *D) { TheDecl = D; }
   const char *getName() const;
   Stmt *getSubStmt() { return SubStmt; }
   const Stmt *getSubStmt() const { return SubStmt; }
   void setIdentLoc(SourceLocation L) { IdentLoc = L; }
   void setSubStmt(Stmt *SS) { SubStmt = SS; }
 
-  /// \brief Whether this label was used.
-  bool isUsed(bool CheckUnusedAttr = true) const {
-    return LabelStmtBits.Used ||
-           (CheckUnusedAttr && LabelStmtBits.HasUnusedAttr);
-  }
-  void setUsed(bool U = true) { LabelStmtBits.Used = U; }
-
-  bool HasUnusedAttribute() const { return LabelStmtBits.HasUnusedAttr; }
-  void setUnusedAttribute(bool U) { LabelStmtBits.HasUnusedAttr = U; }
-
   SourceRange getSourceRange() const {
     return SourceRange(IdentLoc, SubStmt->getLocEnd());
   }
@@ -995,18 +977,18 @@
 /// GotoStmt - This represents a direct goto.
 ///
 class GotoStmt : public Stmt {
-  LabelStmt *Label;
+  LabelDecl *Label;
   SourceLocation GotoLoc;
   SourceLocation LabelLoc;
 public:
-  GotoStmt(LabelStmt *label, SourceLocation GL, SourceLocation LL)
+  GotoStmt(LabelDecl *label, SourceLocation GL, SourceLocation LL)
     : Stmt(GotoStmtClass), Label(label), GotoLoc(GL), LabelLoc(LL) {}
 
   /// \brief Build an empty goto statement.
   explicit GotoStmt(EmptyShell Empty) : Stmt(GotoStmtClass, Empty) { }
 
-  LabelStmt *getLabel() const { return Label; }
-  void setLabel(LabelStmt *S) { Label = S; }
+  LabelDecl *getLabel() const { return Label; }
+  void setLabel(LabelDecl *D) { Label = D; }
 
   SourceLocation getGotoLoc() const { return GotoLoc; }
   void setGotoLoc(SourceLocation L) { GotoLoc = L; }
@@ -1052,8 +1034,8 @@
 
   /// getConstantTarget - Returns the fixed target of this indirect
   /// goto, if one exists.
-  LabelStmt *getConstantTarget();
-  const LabelStmt *getConstantTarget() const {
+  LabelDecl *getConstantTarget();
+  const LabelDecl *getConstantTarget() const {
     return const_cast<IndirectGotoStmt*>(this)->getConstantTarget();
   }
 

Modified: cfe/trunk/include/clang/Basic/DeclNodes.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DeclNodes.td?rev=125733&r1=125732&r2=125733&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DeclNodes.td (original)
+++ cfe/trunk/include/clang/Basic/DeclNodes.td Thu Feb 17 01:39:24 2011
@@ -15,6 +15,7 @@
   def Namespace : DDecl<Named>, DeclContext;
   def UsingDirective : DDecl<Named>;
   def NamespaceAlias : DDecl<Named>;
+  def Label : DDecl<Named>;
   def Type : DDecl<Named, 1>;
     def Typedef : DDecl<Type>;
     def UnresolvedUsingTypename : DDecl<Type>;

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=125733&r1=125732&r2=125733&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Thu Feb 17 01:39:24 2011
@@ -1095,7 +1095,7 @@
   "attribute was previously declared "
   "%plural{0:without the regparm|:with the regparm(%1)}1 attribute">;
 def warn_label_attribute_not_unused : Warning<
-  "The only valid attribute for labels is 'unused'">;
+  "the only valid attribute for labels is 'unused'">;
 
 def warn_impcast_vector_scalar : Warning<
   "implicit conversion turns vector to scalar: %0 to %1">,
@@ -2157,9 +2157,9 @@
   "suggest braces around initialization of subobject">,
   InGroup<DiagGroup<"missing-braces">>, DefaultIgnore;
 
-def err_redefinition_of_label : Error<"redefinition of label '%0'">;
-def err_undeclared_label_use : Error<"use of undeclared label '%0'">;
-def warn_unused_label : Warning<"unused label '%0'">,
+def err_redefinition_of_label : Error<"redefinition of label %0">;
+def err_undeclared_label_use : Error<"use of undeclared label %0">;
+def warn_unused_label : Warning<"unused label %0">,
   InGroup<UnusedLabel>, DefaultIgnore;
 
 def err_goto_into_protected_scope : Error<"goto into protected scope">;

Modified: cfe/trunk/include/clang/Sema/ScopeInfo.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/ScopeInfo.h?rev=125733&r1=125732&r2=125733&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/ScopeInfo.h (original)
+++ cfe/trunk/include/clang/Sema/ScopeInfo.h Thu Feb 17 01:39:24 2011
@@ -23,7 +23,7 @@
 
 class BlockDecl;
 class IdentifierInfo;
-class LabelStmt;
+class LabelDecl;
 class ReturnStmt;
 class Scope;
 class SwitchStmt;
@@ -52,10 +52,10 @@
   /// \brief Used to determine if errors occurred in this function or block.
   DiagnosticErrorTrap ErrorTrap;
 
-  /// LabelMap - This is a mapping from label identifiers to the LabelStmt for
-  /// it (which acts like the label decl in some ways).  Forward referenced
-  /// labels have a LabelStmt created for them with a null location & SubStmt.
-  llvm::DenseMap<IdentifierInfo*, LabelStmt*> LabelMap;
+  /// LabelMap - This is a mapping from label identifiers to the LabelDecl for
+  /// it.  Forward referenced labels have a LabelDecl created for them with a
+  /// null statement.
+  llvm::DenseMap<IdentifierInfo*, LabelDecl*> LabelMap;
 
   /// SwitchStack - This is the current set of active switch statements in the
   /// block.
@@ -92,6 +92,11 @@
 
   virtual ~FunctionScopeInfo();
 
+  /// checkLabelUse - This checks to see if any labels are used without being
+  /// defined, emiting errors and returning true if any are found.  This also
+  /// warns about unused labels.
+  bool checkLabelUse(Stmt *Body, Sema &S);
+  
   /// \brief Clear out the information in this function scope, making it
   /// suitable for reuse.
   void Clear();

Modified: cfe/trunk/include/clang/Serialization/ASTBitCodes.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTBitCodes.h?rev=125733&r1=125732&r2=125733&view=diff
==============================================================================
--- cfe/trunk/include/clang/Serialization/ASTBitCodes.h (original)
+++ cfe/trunk/include/clang/Serialization/ASTBitCodes.h Thu Feb 17 01:39:24 2011
@@ -697,7 +697,9 @@
       /// IDs. This data is used when performing qualified name lookup
       /// into a DeclContext via DeclContext::lookup.
       DECL_CONTEXT_VISIBLE,
-      /// \brief A NamespaceDecl rcord.
+      /// \brief A LabelDecl record.
+      DECL_LABEL,
+      /// \brief A NamespaceDecl record.
       DECL_NAMESPACE,
       /// \brief A NamespaceAliasDecl record.
       DECL_NAMESPACE_ALIAS,

Modified: cfe/trunk/include/clang/Serialization/ASTReader.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTReader.h?rev=125733&r1=125732&r2=125733&view=diff
==============================================================================
--- cfe/trunk/include/clang/Serialization/ASTReader.h (original)
+++ cfe/trunk/include/clang/Serialization/ASTReader.h Thu Feb 17 01:39:24 2011
@@ -56,7 +56,6 @@
 class CXXBaseSpecifier;
 class CXXCtorInitializer;
 class GotoStmt;
-class LabelStmt;
 class MacroDefinition;
 class NamedDecl;
 class Preprocessor;
@@ -646,22 +645,6 @@
   /// switch statement can refer to them.
   std::map<unsigned, SwitchCase *> SwitchCaseStmts;
 
-  /// \brief Mapping from label statement IDs in the chain to label statements.
-  ///
-  /// Statements usually don't have IDs, but labeled statements need them, so
-  /// that goto statements and address-of-label expressions can refer to them.
-  std::map<unsigned, LabelStmt *> LabelStmts;
-
-  /// \brief Mapping from label IDs to the set of "goto" statements
-  /// that point to that label before the label itself has been
-  /// de-serialized.
-  std::multimap<unsigned, GotoStmt *> UnresolvedGotoStmts;
-
-  /// \brief Mapping from label IDs to the set of address label
-  /// expressions that point to that label before the label itself has
-  /// been de-serialized.
-  std::multimap<unsigned, AddrLabelExpr *> UnresolvedAddrLabelExprs;
-
   /// \brief The number of stat() calls that hit/missed the stat
   /// cache.
   unsigned NumStatHits, NumStatMisses;
@@ -1278,29 +1261,7 @@
   /// \brief Retrieve the switch-case statement with the given ID.
   SwitchCase *getSwitchCaseWithID(unsigned ID);
 
-  /// \brief Record that the given label statement has been
-  /// deserialized and has the given ID.
-  void RecordLabelStmt(LabelStmt *S, unsigned ID);
-
   void ClearSwitchCaseIDs();
-
-  /// \brief Set the label of the given statement to the label
-  /// identified by ID.
-  ///
-  /// Depending on the order in which the label and other statements
-  /// referencing that label occur, this operation may complete
-  /// immediately (updating the statement) or it may queue the
-  /// statement to be back-patched later.
-  void SetLabelOf(GotoStmt *S, unsigned ID);
-
-  /// \brief Set the label of the given expression to the label
-  /// identified by ID.
-  ///
-  /// Depending on the order in which the label and other statements
-  /// referencing that label occur, this operation may complete
-  /// immediately (updating the statement) or it may queue the
-  /// statement to be back-patched later.
-  void SetLabelOf(AddrLabelExpr *S, unsigned ID);
 };
 
 /// \brief Helper class that saves the current stream position and

Modified: cfe/trunk/include/clang/Serialization/ASTWriter.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTWriter.h?rev=125733&r1=125732&r2=125733&view=diff
==============================================================================
--- cfe/trunk/include/clang/Serialization/ASTWriter.h (original)
+++ cfe/trunk/include/clang/Serialization/ASTWriter.h Thu Feb 17 01:39:24 2011
@@ -44,7 +44,6 @@
 class CXXCtorInitializer;
 class FPOptions;
 class HeaderSearch;
-class LabelStmt;
 class MacroDefinition;
 class MemorizeStatCalls;
 class OpenCLOptions;
@@ -261,9 +260,6 @@
   /// \brief Mapping from SwitchCase statements to IDs.
   std::map<SwitchCase *, unsigned> SwitchCaseIDs;
 
-  /// \brief Mapping from LabelStmt statements to IDs.
-  std::map<LabelStmt *, unsigned> LabelIDs;
-
   /// \brief The number of statements written to the AST file.
   unsigned NumStatements;
 
@@ -553,10 +549,6 @@
 
   void ClearSwitchCaseIDs();
 
-  /// \brief Retrieve the ID for the given label statement, which may
-  /// or may not have been emitted yet.
-  unsigned GetLabelID(LabelStmt *S);
-
   unsigned getParmVarDeclAbbrev() const { return ParmVarDeclAbbrev; }
 
   bool hasChain() const { return Chain; }

Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h?rev=125733&r1=125732&r2=125733&view=diff
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h Thu Feb 17 01:39:24 2011
@@ -331,11 +331,11 @@
     iterator& operator++() { ++I; return *this; }
     bool operator!=(const iterator& X) const { return I != X.I; }
 
-    const LabelStmt* getLabel() const {
-      return llvm::cast<LabelStmt>((*I)->getLabel());
+    const LabelDecl *getLabel() const {
+      return llvm::cast<LabelStmt>((*I)->getLabel())->getDecl();
     }
 
-    const CFGBlock*  getBlock() const {
+    const CFGBlock *getBlock() const {
       return *I;
     }
   };

Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h?rev=125733&r1=125732&r2=125733&view=diff
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h Thu Feb 17 01:39:24 2011
@@ -238,7 +238,7 @@
     return loc::MemRegionVal(R);
   }
 
-  Loc makeLoc(const AddrLabelExpr* E) {
+  Loc makeLoc(const AddrLabelExpr *E) {
     return loc::GotoLabel(E->getLabel());
   }
 

Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h?rev=125733&r1=125732&r2=125733&view=diff
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h Thu Feb 17 01:39:24 2011
@@ -432,15 +432,14 @@
 
 class GotoLabel : public Loc {
 public:
-  explicit GotoLabel(LabelStmt* Label) : Loc(GotoLabelKind, Label) {}
+  explicit GotoLabel(LabelDecl *Label) : Loc(GotoLabelKind, Label) {}
 
-  const LabelStmt* getLabel() const {
-    return static_cast<const LabelStmt*>(Data);
+  const LabelDecl *getLabel() const {
+    return static_cast<const LabelDecl*>(Data);
   }
 
   static inline bool classof(const SVal* V) {
-    return V->getBaseKind() == LocKind &&
-           V->getSubKind() == GotoLabelKind;
+    return V->getBaseKind() == LocKind && V->getSubKind() == GotoLabelKind;
   }
 
   static inline bool classof(const Loc* V) {

Modified: cfe/trunk/lib/AST/Decl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Decl.cpp?rev=125733&r1=125732&r2=125733&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Decl.cpp (original)
+++ cfe/trunk/lib/AST/Decl.cpp Thu Feb 17 01:39:24 2011
@@ -2182,6 +2182,12 @@
   return new (C) TranslationUnitDecl(C);
 }
 
+LabelDecl *LabelDecl::Create(ASTContext &C, DeclContext *DC,
+                             SourceLocation L, IdentifierInfo *II) {
+  return new (C) LabelDecl(DC, L, II, 0);
+}
+
+
 NamespaceDecl *NamespaceDecl::Create(ASTContext &C, DeclContext *DC,
                                      SourceLocation L, IdentifierInfo *Id) {
   return new (C) NamespaceDecl(DC, L, Id);

Modified: cfe/trunk/lib/AST/DeclBase.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclBase.cpp?rev=125733&r1=125732&r2=125733&view=diff
==============================================================================
--- cfe/trunk/lib/AST/DeclBase.cpp (original)
+++ cfe/trunk/lib/AST/DeclBase.cpp Thu Feb 17 01:39:24 2011
@@ -269,7 +269,8 @@
     case ObjCMethod:
     case ObjCProperty:
       return IDNS_Ordinary;
-
+    case Label:
+      return IDNS_Label;
     case IndirectField:
       return IDNS_Ordinary | IDNS_Member;
 

Modified: cfe/trunk/lib/AST/Stmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Stmt.cpp?rev=125733&r1=125732&r2=125733&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Stmt.cpp (original)
+++ cfe/trunk/lib/AST/Stmt.cpp Thu Feb 17 01:39:24 2011
@@ -161,7 +161,7 @@
 }
 
 const char *LabelStmt::getName() const {
-  return getID()->getNameStart();
+  return getDecl()->getIdentifier()->getNameStart();
 }
 
 // This is defined here to avoid polluting Stmt.h with importing Expr.h
@@ -658,7 +658,7 @@
 }
 
 // IndirectGotoStmt
-LabelStmt *IndirectGotoStmt::getConstantTarget() {
+LabelDecl *IndirectGotoStmt::getConstantTarget() {
   if (AddrLabelExpr *E =
         dyn_cast<AddrLabelExpr>(getTarget()->IgnoreParenImpCasts()))
     return E->getLabel();

Modified: cfe/trunk/lib/AST/StmtProfile.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/StmtProfile.cpp?rev=125733&r1=125732&r2=125733&view=diff
==============================================================================
--- cfe/trunk/lib/AST/StmtProfile.cpp (original)
+++ cfe/trunk/lib/AST/StmtProfile.cpp Thu Feb 17 01:39:24 2011
@@ -101,7 +101,7 @@
 
 void StmtProfiler::VisitLabelStmt(LabelStmt *S) {
   VisitStmt(S);
-  VisitName(S->getID());
+  VisitDecl(S->getDecl());
 }
 
 void StmtProfiler::VisitIfStmt(IfStmt *S) {
@@ -129,7 +129,7 @@
 
 void StmtProfiler::VisitGotoStmt(GotoStmt *S) {
   VisitStmt(S);
-  VisitName(S->getLabel()->getID());
+  VisitDecl(S->getLabel());
 }
 
 void StmtProfiler::VisitIndirectGotoStmt(IndirectGotoStmt *S) {
@@ -351,7 +351,7 @@
 
 void StmtProfiler::VisitAddrLabelExpr(AddrLabelExpr *S) {
   VisitExpr(S);
-  VisitName(S->getLabel()->getID());
+  VisitDecl(S->getLabel());
 }
 
 void StmtProfiler::VisitStmtExpr(StmtExpr *S) {

Modified: cfe/trunk/lib/Analysis/CFG.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/CFG.cpp?rev=125733&r1=125732&r2=125733&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/CFG.cpp (original)
+++ cfe/trunk/lib/Analysis/CFG.cpp Thu Feb 17 01:39:24 2011
@@ -242,7 +242,7 @@
   LocalScope::const_iterator ScopePos;
 
   // LabelMap records the mapping from Label expressions to their jump targets.
-  typedef llvm::DenseMap<LabelStmt*, JumpTarget> LabelMapTy;
+  typedef llvm::DenseMap<LabelDecl*, JumpTarget> LabelMapTy;
   LabelMapTy LabelMap;
 
   // A list of blocks that end with a "goto" that must be backpatched to their
@@ -251,7 +251,7 @@
   BackpatchBlocksTy BackpatchBlocks;
 
   // A list of labels whose address has been taken (for indirect gotos).
-  typedef llvm::SmallPtrSet<LabelStmt*,5> LabelSetTy;
+  typedef llvm::SmallPtrSet<LabelDecl*, 5> LabelSetTy;
   LabelSetTy AddressTakenLabels;
 
   bool badCFG;
@@ -648,13 +648,13 @@
   LocalScope *Scope = 0;
 
   // For compound statement we will be creating explicit scope.
-  if (CompoundStmt* CS = dyn_cast<CompoundStmt>(S)) {
+  if (CompoundStmt *CS = dyn_cast<CompoundStmt>(S)) {
     for (CompoundStmt::body_iterator BI = CS->body_begin(), BE = CS->body_end()
         ; BI != BE; ++BI) {
-      Stmt* SI = *BI;
-      if (LabelStmt* LS = dyn_cast<LabelStmt>(SI))
+      Stmt *SI = *BI;
+      if (LabelStmt *LS = dyn_cast<LabelStmt>(SI))
         SI = LS->getSubStmt();
-      if (DeclStmt* DS = dyn_cast<DeclStmt>(SI))
+      if (DeclStmt *DS = dyn_cast<DeclStmt>(SI))
         Scope = addLocalScopeForDeclStmt(DS, Scope);
     }
     return;
@@ -662,9 +662,9 @@
 
   // For any other statement scope will be implicit and as such will be
   // interesting only for DeclStmt.
-  if (LabelStmt* LS = dyn_cast<LabelStmt>(S))
+  if (LabelStmt *LS = dyn_cast<LabelStmt>(S))
     S = LS->getSubStmt();
-  if (DeclStmt* DS = dyn_cast<DeclStmt>(S))
+  if (DeclStmt *DS = dyn_cast<DeclStmt>(S))
     addLocalScopeForDeclStmt(DS);
 }
 
@@ -1454,16 +1454,17 @@
   return VisitStmt(R, AddStmtChoice::AlwaysAdd);
 }
 
-CFGBlock* CFGBuilder::VisitLabelStmt(LabelStmt* L) {
+CFGBlock* CFGBuilder::VisitLabelStmt(LabelStmt *L) {
   // Get the block of the labeled statement.  Add it to our map.
   addStmt(L->getSubStmt());
-  CFGBlock* LabelBlock = Block;
+  CFGBlock *LabelBlock = Block;
 
   if (!LabelBlock)              // This can happen when the body is empty, i.e.
     LabelBlock = createBlock(); // scopes that only contains NullStmts.
 
-  assert(LabelMap.find(L) == LabelMap.end() && "label already in map");
-  LabelMap[ L ] = JumpTarget(LabelBlock, ScopePos);
+  assert(LabelMap.find(L->getDecl()) == LabelMap.end() &&
+         "label already in map");
+  LabelMap[L->getDecl()] = JumpTarget(LabelBlock, ScopePos);
 
   // Labels partition blocks, so this is the end of the basic block we were
   // processing (L is the block's label).  Because this is label (and we have

Modified: cfe/trunk/lib/CodeGen/CGDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDecl.cpp?rev=125733&r1=125732&r2=125733&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGDecl.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGDecl.cpp Thu Feb 17 01:39:24 2011
@@ -70,7 +70,7 @@
   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;

Modified: cfe/trunk/lib/CodeGen/CGStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGStmt.cpp?rev=125733&r1=125732&r2=125733&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGStmt.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGStmt.cpp Thu Feb 17 01:39:24 2011
@@ -208,7 +208,7 @@
     // emitting them before we evaluate the subexpr.
     const Stmt *LastStmt = S.body_back();
     while (const LabelStmt *LS = dyn_cast<LabelStmt>(LastStmt)) {
-      EmitLabel(*LS);
+      EmitLabel(LS->getDecl());
       LastStmt = LS->getSubStmt();
     }
 
@@ -276,24 +276,24 @@
 }
 
 CodeGenFunction::JumpDest
-CodeGenFunction::getJumpDestForLabel(const LabelStmt *S) {
-  JumpDest &Dest = LabelMap[S];
+CodeGenFunction::getJumpDestForLabel(const LabelDecl *D) {
+  JumpDest &Dest = LabelMap[D];
   if (Dest.isValid()) return Dest;
 
   // Create, but don't insert, the new block.
-  Dest = JumpDest(createBasicBlock(S->getName()),
+  Dest = JumpDest(createBasicBlock(D->getName()),
                   EHScopeStack::stable_iterator::invalid(),
                   NextCleanupDestIndex++);
   return Dest;
 }
 
-void CodeGenFunction::EmitLabel(const LabelStmt &S) {
-  JumpDest &Dest = LabelMap[&S];
+void CodeGenFunction::EmitLabel(const LabelDecl *D) {
+  JumpDest &Dest = LabelMap[D];
 
   // If we didn't need a forward reference to this label, just go
   // ahead and create a destination at the current scope.
   if (!Dest.isValid()) {
-    Dest = getJumpDestInCurrentScope(S.getName());
+    Dest = getJumpDestInCurrentScope(D->getName());
 
   // Otherwise, we need to give this label a target depth and remove
   // it from the branch-fixups list.
@@ -311,7 +311,7 @@
 
 
 void CodeGenFunction::EmitLabelStmt(const LabelStmt &S) {
-  EmitLabel(S);
+  EmitLabel(S.getDecl());
   EmitStmt(S.getSubStmt());
 }
 
@@ -327,7 +327,7 @@
 
 
 void CodeGenFunction::EmitIndirectGotoStmt(const IndirectGotoStmt &S) {
-  if (const LabelStmt *Target = S.getConstantTarget()) {
+  if (const LabelDecl *Target = S.getConstantTarget()) {
     EmitBranchThroughCleanup(getJumpDestForLabel(Target));
     return;
   }

Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.cpp?rev=125733&r1=125732&r2=125733&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenFunction.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenFunction.cpp Thu Feb 17 01:39:24 2011
@@ -668,7 +668,7 @@
   Builder.CreateMemSet(DestPtr, Builder.getInt8(0), SizeVal, Align, false);
 }
 
-llvm::BlockAddress *CodeGenFunction::GetAddrOfLabel(const LabelStmt *L) {
+llvm::BlockAddress *CodeGenFunction::GetAddrOfLabel(const LabelDecl *L) {
   // Make sure that there is a block for the indirect goto.
   if (IndirectBranch == 0)
     GetIndirectGotoBlock();

Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.h?rev=125733&r1=125732&r2=125733&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenFunction.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenFunction.h Thu Feb 17 01:39:24 2011
@@ -45,6 +45,7 @@
   class CXXDestructorDecl;
   class CXXTryStmt;
   class Decl;
+  class LabelDecl;
   class EnumConstantDecl;
   class FunctionDecl;
   class FunctionProtoType;
@@ -768,7 +769,7 @@
   /// The given basic block lies in the current EH scope, but may be a
   /// target of a potentially scope-crossing jump; get a stable handle
   /// to which we can perform this jump later.
-  JumpDest getJumpDestInCurrentScope(const char *Name = 0) {
+  JumpDest getJumpDestInCurrentScope(llvm::StringRef Name = llvm::StringRef()) {
     return getJumpDestInCurrentScope(createBasicBlock(Name));
   }
 
@@ -887,7 +888,7 @@
   DeclMapTy LocalDeclMap;
 
   /// LabelMap - This keeps track of the LLVM basic block for each C label.
-  llvm::DenseMap<const LabelStmt*, JumpDest> LabelMap;
+  llvm::DenseMap<const LabelDecl*, JumpDest> LabelMap;
 
   // BreakContinueStack - This keeps track of where break and continue
   // statements should jump to.
@@ -1168,7 +1169,7 @@
 
   /// getBasicBlockForLabel - Return the LLVM basicblock that the specified
   /// label maps to.
-  JumpDest getJumpDestForLabel(const LabelStmt *S);
+  JumpDest getJumpDestForLabel(const LabelDecl *S);
 
   /// SimplifyForwardingBlocks - If the given basic block is only a branch to
   /// another basic block, simplify it. This assumes that no other code could
@@ -1321,7 +1322,7 @@
   /// the input field number being accessed.
   static unsigned getAccessedFieldNo(unsigned Idx, const llvm::Constant *Elts);
 
-  llvm::BlockAddress *GetAddrOfLabel(const LabelStmt *L);
+  llvm::BlockAddress *GetAddrOfLabel(const LabelDecl *L);
   llvm::BasicBlock *GetIndirectGotoBlock();
 
   /// EmitNullInitialization - Generate code to set a value of the given type to
@@ -1504,7 +1505,7 @@
 
   /// EmitLabel - Emit the block for the given label. It is legal to call this
   /// function even if there is no current insertion point.
-  void EmitLabel(const LabelStmt &S); // helper for EmitLabelStmt.
+  void EmitLabel(const LabelDecl *D); // helper for EmitLabelStmt.
 
   void EmitLabelStmt(const LabelStmt &S);
   void EmitGotoStmt(const GotoStmt &S);

Modified: cfe/trunk/lib/Sema/JumpDiagnostics.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/JumpDiagnostics.cpp?rev=125733&r1=125732&r2=125733&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/JumpDiagnostics.cpp (original)
+++ cfe/trunk/lib/Sema/JumpDiagnostics.cpp Thu Feb 17 01:39:24 2011
@@ -62,7 +62,7 @@
   llvm::SmallVector<Stmt*, 16> Jumps;
 
   llvm::SmallVector<IndirectGotoStmt*, 4> IndirectJumps;
-  llvm::SmallVector<LabelStmt*, 4> IndirectJumpTargets;
+  llvm::SmallVector<LabelDecl*, 4> IndirectJumpTargets;
 public:
   JumpScopeChecker(Stmt *Body, Sema &S);
 private:
@@ -71,7 +71,7 @@
   void VerifyJumps();
   void VerifyIndirectJumps();
   void DiagnoseIndirectJump(IndirectGotoStmt *IG, unsigned IGScope,
-                            LabelStmt *Target, unsigned TargetScope);
+                            LabelDecl *Target, unsigned TargetScope);
   void CheckJump(Stmt *From, Stmt *To,
                  SourceLocation DiagLoc, unsigned JumpDiag);
 
@@ -235,12 +235,12 @@
     // order to avoid blowing out the stack.
     while (true) {
       Stmt *Next;
-      if (isa<CaseStmt>(SubStmt))
-        Next = cast<CaseStmt>(SubStmt)->getSubStmt();
-      else if (isa<DefaultStmt>(SubStmt))
-        Next = cast<DefaultStmt>(SubStmt)->getSubStmt();
-      else if (isa<LabelStmt>(SubStmt))
-        Next = cast<LabelStmt>(SubStmt)->getSubStmt();
+      if (CaseStmt *CS = dyn_cast<CaseStmt>(SubStmt))
+        Next = CS->getSubStmt();
+      else if (DefaultStmt *DS = dyn_cast<DefaultStmt>(SubStmt))
+        Next = DS->getSubStmt();
+      else if (LabelStmt *LS = dyn_cast<LabelStmt>(SubStmt))
+        Next = LS->getSubStmt();
       else
         break;
 
@@ -346,15 +346,15 @@
 
     // With a goto,
     if (GotoStmt *GS = dyn_cast<GotoStmt>(Jump)) {
-      CheckJump(GS, GS->getLabel(), GS->getGotoLoc(),
+      CheckJump(GS, GS->getLabel()->getStmt(), GS->getGotoLoc(),
                 diag::err_goto_into_protected_scope);
       continue;
     }
 
     // We only get indirect gotos here when they have a constant target.
     if (IndirectGotoStmt *IGS = dyn_cast<IndirectGotoStmt>(Jump)) {
-      LabelStmt *Target = IGS->getConstantTarget();
-      CheckJump(IGS, Target, IGS->getGotoLoc(),
+      LabelDecl *Target = IGS->getConstantTarget();
+      CheckJump(IGS, Target->getStmt(), IGS->getGotoLoc(),
                 diag::err_goto_into_protected_scope);
       continue;
     }
@@ -424,15 +424,15 @@
   // Collect a single representative of every scope containing a
   // label whose address was taken somewhere in the function.
   // For most code bases, there will be only one such scope.
-  llvm::DenseMap<unsigned, LabelStmt*> TargetScopes;
-  for (llvm::SmallVectorImpl<LabelStmt*>::iterator
+  llvm::DenseMap<unsigned, LabelDecl*> TargetScopes;
+  for (llvm::SmallVectorImpl<LabelDecl*>::iterator
          I = IndirectJumpTargets.begin(), E = IndirectJumpTargets.end();
        I != E; ++I) {
-    LabelStmt *TheLabel = *I;
-    assert(LabelAndGotoScopes.count(TheLabel) &&
+    LabelDecl *TheLabel = *I;
+    assert(LabelAndGotoScopes.count(TheLabel->getStmt()) &&
            "Referenced label didn't get added to scopes?");
-    unsigned LabelScope = LabelAndGotoScopes[TheLabel];
-    LabelStmt *&Target = TargetScopes[LabelScope];
+    unsigned LabelScope = LabelAndGotoScopes[TheLabel->getStmt()];
+    LabelDecl *&Target = TargetScopes[LabelScope];
     if (!Target) Target = TheLabel;
   }
 
@@ -445,10 +445,10 @@
   // entered, then verify that every jump scope can be trivially
   // exitted to reach a scope in S.
   llvm::BitVector Reachable(Scopes.size(), false);
-  for (llvm::DenseMap<unsigned,LabelStmt*>::iterator
+  for (llvm::DenseMap<unsigned,LabelDecl*>::iterator
          TI = TargetScopes.begin(), TE = TargetScopes.end(); TI != TE; ++TI) {
     unsigned TargetScope = TI->first;
-    LabelStmt *TargetLabel = TI->second;
+    LabelDecl *TargetLabel = TI->second;
 
     Reachable.reset();
 
@@ -511,12 +511,12 @@
 /// Diagnose an indirect jump which is known to cross scopes.
 void JumpScopeChecker::DiagnoseIndirectJump(IndirectGotoStmt *Jump,
                                             unsigned JumpScope,
-                                            LabelStmt *Target,
+                                            LabelDecl *Target,
                                             unsigned TargetScope) {
   assert(JumpScope != TargetScope);
 
   S.Diag(Jump->getGotoLoc(), diag::err_indirect_goto_in_protected_scope);
-  S.Diag(Target->getIdentLoc(), diag::note_indirect_goto_target);
+  S.Diag(Target->getStmt()->getIdentLoc(), diag::note_indirect_goto_target);
 
   unsigned Common = GetDeepestCommonScope(JumpScope, TargetScope);
 

Modified: cfe/trunk/lib/Sema/Sema.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.cpp?rev=125733&r1=125732&r2=125733&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/Sema.cpp (original)
+++ cfe/trunk/lib/Sema/Sema.cpp Thu Feb 17 01:39:24 2011
@@ -31,6 +31,7 @@
 #include "clang/AST/DeclCXX.h"
 #include "clang/AST/DeclObjC.h"
 #include "clang/AST/Expr.h"
+#include "clang/AST/StmtCXX.h"
 #include "clang/Lex/Preprocessor.h"
 #include "clang/Basic/PartialDiagnostic.h"
 #include "clang/Basic/TargetInfo.h"
@@ -50,6 +51,53 @@
   ErrorTrap.reset();
 }
 
+bool FunctionScopeInfo::checkLabelUse(Stmt *Body, Sema &S) {
+  bool AnyErrors = false;
+  for (llvm::DenseMap<IdentifierInfo*, LabelDecl*>::iterator
+       I = LabelMap.begin(), E = LabelMap.end(); I != E; ++I) {
+    LabelDecl *L = I->second;
+    
+    // Verify that we have no forward references left.  If so, there was a goto
+    // or address of a label taken, but no definition of it.  Label fwd
+    // definitions are indicated with a null substmt.
+    if (L->getStmt() != 0) {
+      if (!L->isUsed())
+        S.Diag(L->getLocation(), diag::warn_unused_label) << L->getDeclName();
+      continue;
+    }
+    
+    AnyErrors = true;
+    
+    // Emit error.
+    S.Diag(L->getLocation(), diag::err_undeclared_label_use) << L->getDeclName();
+    
+    // At this point, we have gotos that use the bogus label.  Stitch it into
+    // the function body so that the AST is well formed.
+    if (Body == 0) {
+      // The whole function wasn't parsed correctly.
+      continue;
+    }
+    
+    // Otherwise, the body is valid: we want to stitch the label decl into the
+    // function somewhere so that it is properly owned and so that the goto
+    // has a valid target.  Do this by creating LabelStmt and adding it to the
+    // end of the outer CompoundStmt.
+    LabelStmt *LS = new (S.Context) LabelStmt(L->getLocation(), L, 
+                                    new (S.Context) NullStmt(L->getLocation()));
+    
+    CompoundStmt *Compound = isa<CXXTryStmt>(Body) ?
+    cast<CXXTryStmt>(Body)->getTryBlock() :
+    cast<CompoundStmt>(Body);
+    llvm::SmallVector<Stmt*, 64> Elements(Compound->body_begin(),
+                                          Compound->body_end());
+    Elements.push_back(LS);
+    Compound->setStmts(S.Context, Elements.data(), Elements.size());
+  }
+  return AnyErrors;
+}
+
+
+
 BlockScopeInfo::~BlockScopeInfo() { }
 
 void Sema::ActOnTranslationUnitScope(Scope *S) {

Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=125733&r1=125732&r2=125733&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Thu Feb 17 01:39:24 2011
@@ -5477,46 +5477,7 @@
 
   // Check goto/label use.
   FunctionScopeInfo *CurFn = getCurFunction();
-  for (llvm::DenseMap<IdentifierInfo*, LabelStmt*>::iterator
-         I = CurFn->LabelMap.begin(), E = CurFn->LabelMap.end(); I != E; ++I) {
-    LabelStmt *L = I->second;
-
-    // Verify that we have no forward references left.  If so, there was a goto
-    // or address of a label taken, but no definition of it.  Label fwd
-    // definitions are indicated with a null substmt.
-    if (L->getSubStmt() != 0) {
-      if (!L->isUsed())
-        Diag(L->getIdentLoc(), diag::warn_unused_label) << L->getName();
-      continue;
-    }
-
-    // Emit error.
-    Diag(L->getIdentLoc(), diag::err_undeclared_label_use) << L->getName();
-
-    // At this point, we have gotos that use the bogus label.  Stitch it into
-    // the function body so that they aren't leaked and that the AST is well
-    // formed.
-    if (Body == 0) {
-      // The whole function wasn't parsed correctly.
-      continue;
-    }
-
-    // Otherwise, the body is valid: we want to stitch the label decl into the
-    // function somewhere so that it is properly owned and so that the goto
-    // has a valid target.  Do this by creating a new compound stmt with the
-    // label in it.
-
-    // Give the label a sub-statement.
-    L->setSubStmt(new (Context) NullStmt(L->getIdentLoc()));
-
-    CompoundStmt *Compound = isa<CXXTryStmt>(Body) ?
-                               cast<CXXTryStmt>(Body)->getTryBlock() :
-                               cast<CompoundStmt>(Body);
-    llvm::SmallVector<Stmt*, 64> Elements(Compound->body_begin(),
-                                          Compound->body_end());
-    Elements.push_back(L);
-    Compound->setStmts(Context, Elements.data(), Elements.size());
-  }
+  CurFn->checkLabelUse(Body, *this);
 
   if (Body) {
     // C++ constructors that have function-try-blocks can't have return

Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=125733&r1=125732&r2=125733&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Thu Feb 17 01:39:24 2011
@@ -8321,20 +8321,19 @@
 }
 
 /// ActOnAddrLabel - Parse the GNU address of label extension: "&&foo".
-ExprResult Sema::ActOnAddrLabel(SourceLocation OpLoc,
-                                            SourceLocation LabLoc,
-                                            IdentifierInfo *LabelII) {
+ExprResult Sema::ActOnAddrLabel(SourceLocation OpLoc, SourceLocation LabLoc,
+                                IdentifierInfo *LabelII) {
   // Look up the record for this label identifier.
-  LabelStmt *&LabelDecl = getCurFunction()->LabelMap[LabelII];
+  LabelDecl *&TheDecl = getCurFunction()->LabelMap[LabelII];
 
   // If we haven't seen this label yet, create a forward reference. It
   // will be validated and/or cleaned up in ActOnFinishFunctionBody.
-  if (LabelDecl == 0)
-    LabelDecl = new (Context) LabelStmt(LabLoc, LabelII, 0);
+  if (TheDecl == 0)
+    TheDecl = LabelDecl::Create(Context, CurContext, LabLoc, LabelII);
 
-  LabelDecl->setUsed();
+  TheDecl->setUsed();
   // Create the AST node.  The address of a label always has type 'void*'.
-  return Owned(new (Context) AddrLabelExpr(OpLoc, LabLoc, LabelDecl,
+  return Owned(new (Context) AddrLabelExpr(OpLoc, LabLoc, TheDecl,
                                        Context.getPointerType(Context.VoidTy)));
 }
 
@@ -8833,25 +8832,8 @@
 
   BSI->TheDecl->setBody(cast<CompoundStmt>(Body));
 
-  bool Good = true;
   // Check goto/label use.
-  for (llvm::DenseMap<IdentifierInfo*, LabelStmt*>::iterator
-         I = BSI->LabelMap.begin(), E = BSI->LabelMap.end(); I != E; ++I) {
-    LabelStmt *L = I->second;
-
-    // Verify that we have no forward references left.  If so, there was a goto
-    // or address of a label taken, but no definition of it.
-    if (L->getSubStmt() != 0) {
-      if (!L->isUsed())
-        Diag(L->getIdentLoc(), diag::warn_unused_label) << L->getName();
-      continue;
-    }
-
-    // Emit error.
-    Diag(L->getIdentLoc(), diag::err_undeclared_label_use) << L->getName();
-    Good = false;
-  }
-  if (!Good) {
+  if (BSI->checkLabelUse(0, *this)) {
     PopFunctionOrBlockScope();
     return ExprError();
   }

Modified: cfe/trunk/lib/Sema/SemaStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaStmt.cpp?rev=125733&r1=125732&r2=125733&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaStmt.cpp (original)
+++ cfe/trunk/lib/Sema/SemaStmt.cpp Thu Feb 17 01:39:24 2011
@@ -255,29 +255,31 @@
                      SourceLocation ColonLoc, Stmt *SubStmt,
                      bool HasUnusedAttr) {
   // Look up the record for this label identifier.
-  LabelStmt *&LabelDecl = getCurFunction()->LabelMap[II];
+  LabelDecl *&TheDecl = getCurFunction()->LabelMap[II];
 
-  // If not forward referenced or defined already, just create a new LabelStmt.
-  if (LabelDecl == 0)
-    return Owned(LabelDecl = new (Context) LabelStmt(IdentLoc, II, SubStmt,
-                                                     HasUnusedAttr));
-
-  assert(LabelDecl->getID() == II && "Label mismatch!");
-
-  // Otherwise, this label was either forward reference or multiply defined.  If
-  // multiply defined, reject it now.
-  if (LabelDecl->getSubStmt()) {
-    Diag(IdentLoc, diag::err_redefinition_of_label) << LabelDecl->getID();
-    Diag(LabelDecl->getIdentLoc(), diag::note_previous_definition);
+  // If not forward referenced or defined already, create the backing decl.
+  if (TheDecl == 0)
+    TheDecl = LabelDecl::Create(Context, CurContext, IdentLoc, II);
+
+  assert(TheDecl->getIdentifier() == II && "Label mismatch!");
+
+  // If the label was multiply defined, reject it now.
+  if (TheDecl->getStmt()) {
+    Diag(IdentLoc, diag::err_redefinition_of_label) << TheDecl->getDeclName();
+    Diag(TheDecl->getLocation(), diag::note_previous_definition);
     return Owned(SubStmt);
   }
 
-  // Otherwise, this label was forward declared, and we just found its real
-  // definition.  Fill in the forward definition and return it.
-  LabelDecl->setIdentLoc(IdentLoc);
-  LabelDecl->setSubStmt(SubStmt);
-  LabelDecl->setUnusedAttribute(HasUnusedAttr);
-  return Owned(LabelDecl);
+  // Otherwise, things are good.  Fill in the declaration and return it.
+  TheDecl->setLocation(IdentLoc);
+  
+  // FIXME: Just use Decl ATTRIBUTES!
+  if (HasUnusedAttr)
+    TheDecl->setHasUnusedAttribute();
+  LabelStmt *LS = new (Context) LabelStmt(IdentLoc, TheDecl, SubStmt);
+  TheDecl->setStmt(LS);
+  TheDecl->setLocation(IdentLoc);
+  return Owned(LS);
 }
 
 StmtResult
@@ -1036,17 +1038,17 @@
 StmtResult
 Sema::ActOnGotoStmt(SourceLocation GotoLoc, SourceLocation LabelLoc,
                     IdentifierInfo *LabelII) {
-  // Look up the record for this label identifier.
-  LabelStmt *&LabelDecl = getCurFunction()->LabelMap[LabelII];
-
   getCurFunction()->setHasBranchIntoScope();
+  
+  // Look up the record for this label identifier.
+  LabelDecl *&TheDecl = getCurFunction()->LabelMap[LabelII];
 
   // If we haven't seen this label yet, create a forward reference.
-  if (LabelDecl == 0)
-    LabelDecl = new (Context) LabelStmt(LabelLoc, LabelII, 0);
+  if (TheDecl == 0)
+    TheDecl = LabelDecl::Create(Context, CurContext, LabelLoc, LabelII);
 
-  LabelDecl->setUsed();
-  return Owned(new (Context) GotoStmt(LabelDecl, GotoLoc, LabelLoc));
+  TheDecl->setUsed();
+  return Owned(new (Context) GotoStmt(TheDecl, GotoLoc, LabelLoc));
 }
 
 StmtResult

Modified: cfe/trunk/lib/Sema/TreeTransform.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/TreeTransform.h?rev=125733&r1=125732&r2=125733&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/TreeTransform.h (original)
+++ cfe/trunk/lib/Sema/TreeTransform.h Thu Feb 17 01:39:24 2011
@@ -975,10 +975,9 @@
   ///
   /// By default, performs semantic analysis to build the new statement.
   /// Subclasses may override this routine to provide different behavior.
-  StmtResult RebuildLabelStmt(SourceLocation IdentLoc,
-                                    IdentifierInfo *Id,
-                                    SourceLocation ColonLoc,
-                                    Stmt *SubStmt, bool HasUnusedAttr) {
+  StmtResult RebuildLabelStmt(SourceLocation IdentLoc, IdentifierInfo *Id,
+                              SourceLocation ColonLoc, Stmt *SubStmt,
+                              bool HasUnusedAttr) {
     return SemaRef.ActOnLabelStmt(IdentLoc, Id, ColonLoc, SubStmt,
                                   HasUnusedAttr);
   }
@@ -1028,10 +1027,8 @@
   /// By default, performs semantic analysis to build the new statement.
   /// Subclasses may override this routine to provide different behavior.
   StmtResult RebuildDoStmt(SourceLocation DoLoc, Stmt *Body,
-                                 SourceLocation WhileLoc,
-                                 SourceLocation LParenLoc,
-                                 Expr *Cond,
-                                 SourceLocation RParenLoc) {
+                           SourceLocation WhileLoc, SourceLocation LParenLoc,
+                           Expr *Cond, SourceLocation RParenLoc) {
     return getSema().ActOnDoStmt(DoLoc, Body, WhileLoc, LParenLoc,
                                  Cond, RParenLoc);
   }
@@ -1040,24 +1037,21 @@
   ///
   /// By default, performs semantic analysis to build the new statement.
   /// Subclasses may override this routine to provide different behavior.
-  StmtResult RebuildForStmt(SourceLocation ForLoc,
-                                  SourceLocation LParenLoc,
-                                  Stmt *Init, Sema::FullExprArg Cond, 
-                                  VarDecl *CondVar, Sema::FullExprArg Inc,
-                                  SourceLocation RParenLoc, Stmt *Body) {
+  StmtResult RebuildForStmt(SourceLocation ForLoc, SourceLocation LParenLoc,
+                            Stmt *Init, Sema::FullExprArg Cond, 
+                            VarDecl *CondVar, Sema::FullExprArg Inc,
+                            SourceLocation RParenLoc, Stmt *Body) {
     return getSema().ActOnForStmt(ForLoc, LParenLoc, Init, Cond, 
-                                  CondVar,
-                                  Inc, RParenLoc, Body);
+                                  CondVar, Inc, RParenLoc, Body);
   }
 
   /// \brief Build a new goto statement.
   ///
   /// By default, performs semantic analysis to build the new statement.
   /// Subclasses may override this routine to provide different behavior.
-  StmtResult RebuildGotoStmt(SourceLocation GotoLoc,
-                                   SourceLocation LabelLoc,
-                                   LabelStmt *Label) {
-    return getSema().ActOnGotoStmt(GotoLoc, LabelLoc, Label->getID());
+  StmtResult RebuildGotoStmt(SourceLocation GotoLoc, SourceLocation LabelLoc,
+                             LabelDecl *Label) {
+    return getSema().ActOnGotoStmt(GotoLoc, LabelLoc, Label->getIdentifier());
   }
 
   /// \brief Build a new indirect goto statement.
@@ -1065,8 +1059,8 @@
   /// By default, performs semantic analysis to build the new statement.
   /// Subclasses may override this routine to provide different behavior.
   StmtResult RebuildIndirectGotoStmt(SourceLocation GotoLoc,
-                                           SourceLocation StarLoc,
-                                           Expr *Target) {
+                                     SourceLocation StarLoc,
+                                     Expr *Target) {
     return getSema().ActOnIndirectGotoStmt(GotoLoc, StarLoc, Target);
   }
 
@@ -1074,9 +1068,7 @@
   ///
   /// By default, performs semantic analysis to build the new statement.
   /// Subclasses may override this routine to provide different behavior.
-  StmtResult RebuildReturnStmt(SourceLocation ReturnLoc,
-                                     Expr *Result) {
-
+  StmtResult RebuildReturnStmt(SourceLocation ReturnLoc, Expr *Result) {
     return getSema().ActOnReturnStmt(ReturnLoc, Result);
   }
 
@@ -1550,9 +1542,8 @@
   /// rather than attempting to map the label statement itself.
   /// Subclasses may override this routine to provide different behavior.
   ExprResult RebuildAddrLabelExpr(SourceLocation AmpAmpLoc,
-                                        SourceLocation LabelLoc,
-                                        LabelStmt *Label) {
-    return getSema().ActOnAddrLabel(AmpAmpLoc, LabelLoc, Label->getID());
+                                  SourceLocation LabelLoc, LabelDecl *Label) {
+    return getSema().ActOnAddrLabel(AmpAmpLoc, LabelLoc,Label->getIdentifier());
   }
 
   /// \brief Build a new GNU statement expression.
@@ -4522,8 +4513,10 @@
 
   // FIXME: Pass the real colon location in.
   SourceLocation ColonLoc = SemaRef.PP.getLocForEndOfToken(S->getIdentLoc());
-  return getDerived().RebuildLabelStmt(S->getIdentLoc(), S->getID(), ColonLoc,
-                                       SubStmt.get(), S->HasUnusedAttribute());
+  return getDerived().RebuildLabelStmt(S->getIdentLoc(),
+                                       S->getDecl()->getIdentifier(), ColonLoc,
+                                       SubStmt.get(),
+                                       S->getDecl()->hasUnusedAttribute());
 }
 
 template<typename Derived>

Modified: cfe/trunk/lib/Serialization/ASTReader.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReader.cpp?rev=125733&r1=125732&r2=125733&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReader.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReader.cpp Thu Feb 17 01:39:24 2011
@@ -4814,72 +4814,6 @@
   SwitchCaseStmts.clear();
 }
 
-/// \brief Record that the given label statement has been
-/// deserialized and has the given ID.
-void ASTReader::RecordLabelStmt(LabelStmt *S, unsigned ID) {
-  assert(LabelStmts.find(ID) == LabelStmts.end() &&
-         "Deserialized label twice");
-  LabelStmts[ID] = S;
-
-  // If we've already seen any goto statements that point to this
-  // label, resolve them now.
-  typedef std::multimap<unsigned, GotoStmt *>::iterator GotoIter;
-  std::pair<GotoIter, GotoIter> Gotos = UnresolvedGotoStmts.equal_range(ID);
-  for (GotoIter Goto = Gotos.first; Goto != Gotos.second; ++Goto)
-    Goto->second->setLabel(S);
-  UnresolvedGotoStmts.erase(Gotos.first, Gotos.second);
-
-  // If we've already seen any address-label statements that point to
-  // this label, resolve them now.
-  typedef std::multimap<unsigned, AddrLabelExpr *>::iterator AddrLabelIter;
-  std::pair<AddrLabelIter, AddrLabelIter> AddrLabels
-    = UnresolvedAddrLabelExprs.equal_range(ID);
-  for (AddrLabelIter AddrLabel = AddrLabels.first;
-       AddrLabel != AddrLabels.second; ++AddrLabel)
-    AddrLabel->second->setLabel(S);
-  UnresolvedAddrLabelExprs.erase(AddrLabels.first, AddrLabels.second);
-}
-
-/// \brief Set the label of the given statement to the label
-/// identified by ID.
-///
-/// Depending on the order in which the label and other statements
-/// referencing that label occur, this operation may complete
-/// immediately (updating the statement) or it may queue the
-/// statement to be back-patched later.
-void ASTReader::SetLabelOf(GotoStmt *S, unsigned ID) {
-  std::map<unsigned, LabelStmt *>::iterator Label = LabelStmts.find(ID);
-  if (Label != LabelStmts.end()) {
-    // We've already seen this label, so set the label of the goto and
-    // we're done.
-    S->setLabel(Label->second);
-  } else {
-    // We haven't seen this label yet, so add this goto to the set of
-    // unresolved goto statements.
-    UnresolvedGotoStmts.insert(std::make_pair(ID, S));
-  }
-}
-
-/// \brief Set the label of the given expression to the label
-/// identified by ID.
-///
-/// Depending on the order in which the label and other statements
-/// referencing that label occur, this operation may complete
-/// immediately (updating the statement) or it may queue the
-/// statement to be back-patched later.
-void ASTReader::SetLabelOf(AddrLabelExpr *S, unsigned ID) {
-  std::map<unsigned, LabelStmt *>::iterator Label = LabelStmts.find(ID);
-  if (Label != LabelStmts.end()) {
-    // We've already seen this label, so set the label of the
-    // label-address expression and we're done.
-    S->setLabel(Label->second);
-  } else {
-    // We haven't seen this label yet, so add this label-address
-    // expression to the set of unresolved label-address expressions.
-    UnresolvedAddrLabelExprs.insert(std::make_pair(ID, S));
-  }
-}
-
 void ASTReader::FinishedDeserializing() {
   assert(NumCurrentElementsDeserializing &&
          "FinishedDeserializing not paired with StartedDeserializing");

Modified: cfe/trunk/lib/Serialization/ASTReaderDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderDecl.cpp?rev=125733&r1=125732&r2=125733&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReaderDecl.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReaderDecl.cpp Thu Feb 17 01:39:24 2011
@@ -84,6 +84,7 @@
     void VisitDecl(Decl *D);
     void VisitTranslationUnitDecl(TranslationUnitDecl *TU);
     void VisitNamedDecl(NamedDecl *ND);
+    void VisitLabelDecl(LabelDecl *LD);
     void VisitNamespaceDecl(NamespaceDecl *D);
     void VisitUsingDirectiveDecl(UsingDirectiveDecl *D);
     void VisitNamespaceAliasDecl(NamespaceAliasDecl *D);
@@ -722,6 +723,12 @@
   D->setHasBraces(Record[Idx++]);
 }
 
+void ASTDeclReader::VisitLabelDecl(LabelDecl *D) {
+  VisitNamedDecl(D);
+  if (Record[Idx++]) D->setHasUnusedAttribute();
+}
+
+
 void ASTDeclReader::VisitNamespaceDecl(NamespaceDecl *D) {
   VisitNamedDecl(D);
   D->IsInline = Record[Idx++];
@@ -1418,6 +1425,9 @@
                                 (LinkageSpecDecl::LanguageIDs)0,
                                 false);
     break;
+  case DECL_LABEL:
+    D = LabelDecl::Create(*Context, 0, SourceLocation(), 0);
+    break;
   case DECL_NAMESPACE:
     D = NamespaceDecl::Create(*Context, 0, SourceLocation(), 0);
     break;

Modified: cfe/trunk/lib/Serialization/ASTReaderStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderStmt.cpp?rev=125733&r1=125732&r2=125733&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReaderStmt.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReaderStmt.cpp Thu Feb 17 01:39:24 2011
@@ -245,12 +245,11 @@
 
 void ASTStmtReader::VisitLabelStmt(LabelStmt *S) {
   VisitStmt(S);
-  S->setID(Reader.GetIdentifierInfo(Record, Idx));
+  LabelDecl *LD = cast<LabelDecl>(Reader.GetDecl(Record[Idx++]));
+  LD->setStmt(S);
+  S->setDecl(LD);
   S->setSubStmt(Reader.ReadSubStmt());
   S->setIdentLoc(ReadSourceLocation(Record, Idx));
-  S->setUsed(Record[Idx++]);
-  S->setUnusedAttribute(Record[Idx++]);
-  Reader.RecordLabelStmt(S, Record[Idx++]);
 }
 
 void ASTStmtReader::VisitIfStmt(IfStmt *S) {
@@ -319,7 +318,7 @@
 
 void ASTStmtReader::VisitGotoStmt(GotoStmt *S) {
   VisitStmt(S);
-  Reader.SetLabelOf(S, Record[Idx++]);
+  S->setLabel(cast<LabelDecl>(Reader.GetDecl(Record[Idx++])));
   S->setGotoLoc(ReadSourceLocation(Record, Idx));
   S->setLabelLoc(ReadSourceLocation(Record, Idx));
 }
@@ -759,7 +758,7 @@
   VisitExpr(E);
   E->setAmpAmpLoc(ReadSourceLocation(Record, Idx));
   E->setLabelLoc(ReadSourceLocation(Record, Idx));
-  Reader.SetLabelOf(E, Record[Idx++]);
+  E->setLabel(cast<LabelDecl>(Reader.GetDecl(Record[Idx++])));
 }
 
 void ASTStmtReader::VisitStmtExpr(StmtExpr *E) {

Modified: cfe/trunk/lib/Serialization/ASTWriterDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriterDecl.cpp?rev=125733&r1=125732&r2=125733&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTWriterDecl.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTWriterDecl.cpp Thu Feb 17 01:39:24 2011
@@ -47,6 +47,7 @@
     void VisitDecl(Decl *D);
     void VisitTranslationUnitDecl(TranslationUnitDecl *D);
     void VisitNamedDecl(NamedDecl *D);
+    void VisitLabelDecl(LabelDecl *LD);
     void VisitNamespaceDecl(NamespaceDecl *D);
     void VisitUsingDirectiveDecl(UsingDirectiveDecl *D);
     void VisitNamespaceAliasDecl(NamespaceAliasDecl *D);
@@ -651,6 +652,13 @@
   Code = serialization::DECL_LINKAGE_SPEC;
 }
 
+void ASTDeclWriter::VisitLabelDecl(LabelDecl *D) {
+  VisitNamedDecl(D);
+  Record.push_back(D->hasUnusedAttribute());
+  Code = serialization::DECL_LABEL;
+}
+
+
 void ASTDeclWriter::VisitNamespaceDecl(NamespaceDecl *D) {
   VisitNamedDecl(D);
   Record.push_back(D->isInline());

Modified: cfe/trunk/lib/Serialization/ASTWriterStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriterStmt.cpp?rev=125733&r1=125732&r2=125733&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTWriterStmt.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTWriterStmt.cpp Thu Feb 17 01:39:24 2011
@@ -217,12 +217,9 @@
 
 void ASTStmtWriter::VisitLabelStmt(LabelStmt *S) {
   VisitStmt(S);
-  Writer.AddIdentifierRef(S->getID(), Record);
+  Writer.AddDeclRef(S->getDecl(), Record);
   Writer.AddStmt(S->getSubStmt());
   Writer.AddSourceLocation(S->getIdentLoc(), Record);
-  Record.push_back(S->isUsed());
-  Record.push_back(S->HasUnusedAttribute());
-  Record.push_back(Writer.GetLabelID(S));
   Code = serialization::STMT_LABEL;
 }
 
@@ -284,7 +281,7 @@
 
 void ASTStmtWriter::VisitGotoStmt(GotoStmt *S) {
   VisitStmt(S);
-  Record.push_back(Writer.GetLabelID(S->getLabel()));
+  Writer.AddDeclRef(S->getLabel(), Record);
   Writer.AddSourceLocation(S->getGotoLoc(), Record);
   Writer.AddSourceLocation(S->getLabelLoc(), Record);
   Code = serialization::STMT_GOTO;
@@ -722,7 +719,7 @@
   VisitExpr(E);
   Writer.AddSourceLocation(E->getAmpAmpLoc(), Record);
   Writer.AddSourceLocation(E->getLabelLoc(), Record);
-  Record.push_back(Writer.GetLabelID(E->getLabel()));
+  Writer.AddDeclRef(E->getLabel(), Record);
   Code = serialization::EXPR_ADDR_LABEL;
 }
 
@@ -1359,18 +1356,6 @@
   SwitchCaseIDs.clear();
 }
 
-/// \brief Retrieve the ID for the given label statement, which may
-/// or may not have been emitted yet.
-unsigned ASTWriter::GetLabelID(LabelStmt *S) {
-  std::map<LabelStmt *, unsigned>::iterator Pos = LabelIDs.find(S);
-  if (Pos != LabelIDs.end())
-    return Pos->second;
-
-  unsigned NextID = LabelIDs.size();
-  LabelIDs[S] = NextID;
-  return NextID;
-}
-
 /// \brief Write the given substatement or subexpression to the
 /// bitstream.
 void ASTWriter::WriteSubStmt(Stmt *S) {

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/ExprEngine.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/ExprEngine.cpp?rev=125733&r1=125732&r2=125733&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/ExprEngine.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/ExprEngine.cpp Thu Feb 17 01:39:24 2011
@@ -1344,7 +1344,7 @@
 
 /// processIndirectGoto - Called by CoreEngine.  Used to generate successor
 ///  nodes by processing the 'effects' of a computed goto jump.
-void ExprEngine::processIndirectGoto(IndirectGotoNodeBuilder& builder) {
+void ExprEngine::processIndirectGoto(IndirectGotoNodeBuilder &builder) {
 
   const GRState *state = builder.getState();
   SVal V = state->getSVal(builder.getTarget());
@@ -1359,16 +1359,16 @@
   typedef IndirectGotoNodeBuilder::iterator iterator;
 
   if (isa<loc::GotoLabel>(V)) {
-    const LabelStmt* L = cast<loc::GotoLabel>(V).getLabel();
+    const LabelDecl *L = cast<loc::GotoLabel>(V).getLabel();
 
-    for (iterator I=builder.begin(), E=builder.end(); I != E; ++I) {
+    for (iterator I = builder.begin(), E = builder.end(); I != E; ++I) {
       if (I.getLabel() == L) {
         builder.generateNode(I, state);
         return;
       }
     }
 
-    assert (false && "No block with label.");
+    assert(false && "No block with label.");
     return;
   }
 

Modified: cfe/trunk/lib/StaticAnalyzer/Core/SVals.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/SVals.cpp?rev=125733&r1=125732&r2=125733&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/SVals.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/SVals.cpp Thu Feb 17 01:39:24 2011
@@ -350,7 +350,7 @@
       os << cast<loc::ConcreteInt>(this)->getValue().getZExtValue() << " (Loc)";
       break;
     case loc::GotoLabelKind:
-      os << "&&" << cast<loc::GotoLabel>(this)->getLabel()->getID()->getName();
+      os << "&&" << cast<loc::GotoLabel>(this)->getLabel()->getName();
       break;
     case loc::MemRegionKind:
       os << '&' << cast<loc::MemRegionVal>(this)->getRegion()->getString();

Modified: cfe/trunk/test/CXX/stmt.stmt/stmt.label/p1.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/stmt.stmt/stmt.label/p1.cpp?rev=125733&r1=125732&r2=125733&view=diff
==============================================================================
--- cfe/trunk/test/CXX/stmt.stmt/stmt.label/p1.cpp (original)
+++ cfe/trunk/test/CXX/stmt.stmt/stmt.label/p1.cpp Thu Feb 17 01:39:24 2011
@@ -9,7 +9,7 @@
   x = 1;
   goto label2; // expected-error{{use of undeclared label 'label2'}}
 
-label1: // expected-error{{redefinition of label ''label1''}}
+label1: // expected-error{{redefinition of label 'label1'}}
   x = 2;
 }
 

Modified: cfe/trunk/test/Sema/warn-unused-label.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/warn-unused-label.c?rev=125733&r1=125732&r2=125733&view=diff
==============================================================================
--- cfe/trunk/test/Sema/warn-unused-label.c (original)
+++ cfe/trunk/test/Sema/warn-unused-label.c Thu Feb 17 01:39:24 2011
@@ -4,8 +4,8 @@
   a:
   goto a;
   b: // expected-warning{{unused}}
-  c: __attribute__((unused));
-  d: __attribute__((noreturn)); // expected-warning {{The only valid attribute for labels is 'unused'}}
+  c: __attribute__((unused));    // expected-warning {{unused label 'c'}}
+  d: __attribute__((noreturn)); // expected-warning {{the only valid attribute for labels is 'unused'}}
   goto d;
   return;
 }

Modified: cfe/trunk/tools/libclang/CIndex.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CIndex.cpp?rev=125733&r1=125732&r2=125733&view=diff
==============================================================================
--- cfe/trunk/tools/libclang/CIndex.cpp (original)
+++ cfe/trunk/tools/libclang/CIndex.cpp Thu Feb 17 01:39:24 2011
@@ -1529,14 +1529,14 @@
 
 class LabelRefVisit : public VisitorJob {
 public:
-  LabelRefVisit(LabelStmt *LS, SourceLocation labelLoc, CXCursor parent)
-    : VisitorJob(parent, VisitorJob::LabelRefVisitKind, LS,
+  LabelRefVisit(LabelDecl *LD, SourceLocation labelLoc, CXCursor parent)
+    : VisitorJob(parent, VisitorJob::LabelRefVisitKind, LD,
                  labelLoc.getPtrEncoding()) {}
   
   static bool classof(const VisitorJob *VJ) {
     return VJ->getKind() == VisitorJob::LabelRefVisitKind;
   }
-  LabelStmt *get() const { return static_cast<LabelStmt*>(data[0]); }
+  LabelDecl *get() const { return static_cast<LabelDecl*>(data[0]); }
   SourceLocation getLoc() const { 
     return SourceLocation::getFromPtrEncoding(data[1]); }
 };
@@ -1985,8 +1985,8 @@
         continue;
       }
       case VisitorJob::LabelRefVisitKind: {
-        LabelStmt *LS = cast<LabelRefVisit>(&LI)->get();
-        if (Visit(MakeCursorLabelRef(LS,
+        LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
+        if (Visit(MakeCursorLabelRef(LS->getStmt(),
                                      cast<LabelRefVisit>(&LI)->getLoc(),
                                      TU)))
           return true;
@@ -2851,7 +2851,7 @@
       LabelStmt *Label = getCursorLabelRef(C).first;
       assert(Label && "Missing label");
       
-      return createCXString(Label->getID()->getName());
+      return createCXString(Label->getName());
     }
 
     case CXCursor_OverloadedDeclRef: {
@@ -2885,7 +2885,7 @@
   if (clang_isStatement(C.kind)) {
     Stmt *S = getCursorStmt(C);
     if (LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
-      return createCXString(Label->getID()->getName());
+      return createCXString(Label->getName());
 
     return createCXString("");
   }
@@ -3569,7 +3569,7 @@
   if (clang_isStatement(C.kind)) {
     Stmt *S = getCursorStmt(C);
     if (GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
-      return MakeCXCursor(Goto->getLabel(), getCursorDecl(C), tu);
+      return MakeCXCursor(Goto->getLabel()->getStmt(), getCursorDecl(C), tu);
 
     return clang_getNullCursor();
   }
@@ -3676,6 +3676,7 @@
   case Decl::FileScopeAsm:
   case Decl::StaticAssert:
   case Decl::Block:
+  case Decl::Label:  // FIXME: Is this right??
     return C;
 
   // Declaration kinds that don't make any sense here, but are





More information about the cfe-commits mailing list