[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/

Douglas Gregor dgregor at apple.com
Thu Feb 17 12:18:04 PST 2011


On Feb 16, 2011, at 11:39 PM, Chris Lattner wrote:

> 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.

Looks great! Comments inline.

> 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;

This shouldn't still be necessary, since one could use the normal unqualified name lookup mechanism to find label names. That said, there are few enough labels in the world that I don't care if this DenseMap stays.

> 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);
> };

Yay, -'s!

> 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;

This may not be true when __label__ comes along. We'll probably just want to ignore LabelDecls here.

> 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];

This is the place where we could just perform simple, unqualified name lookup with IDNS_Label, rather than keeping another DenseMap on the side.

> 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;


It's right for now. When __label__ comes along, I could imagine that with something like:

  {
    __label__ here;
   goto here;
  here:
   whatever
  }

we would want clang_getCursorReferenced() for the goto statement to refer to the __label__ declaration, then clang_getCursorDefinition() on the __label__ declaration would return the label statement.

	- Doug



More information about the cfe-commits mailing list