[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