From: Abramo Bagnara Date: Sat, 5 Mar 2011 18:21:20 +0000 (+0000) Subject: Fixed LabelDecl source range and cleaned creation code. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=6784304db526cde59046d613c4175ce2caf93e44;p=clang Fixed LabelDecl source range and cleaned creation code. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@127094 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h index f9fe0e9b85..b19eb8c6ef 100644 --- a/include/clang/AST/Decl.h +++ b/include/clang/AST/Decl.h @@ -309,21 +309,32 @@ inline llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, /// location of the statement. For GNU local labels (__label__), the decl /// location is where the __label__ is. class LabelDecl : public NamedDecl { - llvm::PointerIntPair StmtAndGnuLocal; - LabelDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *II, - LabelStmt *S, bool isGnuLocal) - : NamedDecl(Label, DC, L, II), StmtAndGnuLocal(S, isGnuLocal) {} - + LabelStmt *TheStmt; + /// LocStart - For normal labels, this is the same as the main declaration + /// label, i.e., the location of the identifier; for GNU local labels, + /// this is the location of the __label__ keyword. + SourceLocation LocStart; + + LabelDecl(DeclContext *DC, SourceLocation IdentL, IdentifierInfo *II, + LabelStmt *S, SourceLocation StartL) + : NamedDecl(Label, DC, IdentL, II), TheStmt(S), LocStart(StartL) {} + public: static LabelDecl *Create(ASTContext &C, DeclContext *DC, - SourceLocation L, IdentifierInfo *II, - bool isGnuLocal = false); + SourceLocation IdentL, IdentifierInfo *II); + static LabelDecl *Create(ASTContext &C, DeclContext *DC, + SourceLocation IdentL, IdentifierInfo *II, + SourceLocation GnuLabelL); - LabelStmt *getStmt() const { return StmtAndGnuLocal.getPointer(); } - void setStmt(LabelStmt *T) { StmtAndGnuLocal.setPointer(T); } - - bool isGnuLocal() const { return StmtAndGnuLocal.getInt(); } - void setGnuLocal(bool V = true) { StmtAndGnuLocal.setInt(V); } + LabelStmt *getStmt() const { return TheStmt; } + void setStmt(LabelStmt *T) { TheStmt = T; } + + bool isGnuLocal() const { return LocStart != getLocation(); } + void setLocStart(SourceLocation L) { LocStart = L; } + + SourceRange getSourceRange() const { + return SourceRange(LocStart, getLocation()); + } // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h index 1607e6177b..d5444257a6 100644 --- a/include/clang/Sema/Sema.h +++ b/include/clang/Sema/Sema.h @@ -1448,9 +1448,9 @@ public: QualType T1, QualType T2, UnresolvedSetImpl &Functions); - LabelDecl *LookupOrCreateLabel(IdentifierInfo *II, SourceLocation Loc, - bool isLocalLabel = false); - + LabelDecl *LookupOrCreateLabel(IdentifierInfo *II, SourceLocation IdentLoc, + SourceLocation GnuLabelLoc = SourceLocation()); + DeclContextLookupResult LookupConstructors(CXXRecordDecl *Class); CXXDestructorDecl *LookupDestructor(CXXRecordDecl *Class); diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp index cc33d84c94..d72dc22a94 100644 --- a/lib/AST/Decl.cpp +++ b/lib/AST/Decl.cpp @@ -2207,9 +2207,15 @@ TranslationUnitDecl *TranslationUnitDecl::Create(ASTContext &C) { } LabelDecl *LabelDecl::Create(ASTContext &C, DeclContext *DC, - SourceLocation L, IdentifierInfo *II, - bool isGnuLocal) { - return new (C) LabelDecl(DC, L, II, 0, isGnuLocal); + SourceLocation IdentL, IdentifierInfo *II) { + return new (C) LabelDecl(DC, IdentL, II, 0, IdentL); +} + +LabelDecl *LabelDecl::Create(ASTContext &C, DeclContext *DC, + SourceLocation IdentL, IdentifierInfo *II, + SourceLocation GnuLabelL) { + assert(GnuLabelL != IdentL && "Use this only for GNU local labels"); + return new (C) LabelDecl(DC, IdentL, II, 0, GnuLabelL); } diff --git a/lib/Parse/ParseStmt.cpp b/lib/Parse/ParseStmt.cpp index 2d9758333f..d1376accca 100644 --- a/lib/Parse/ParseStmt.cpp +++ b/lib/Parse/ParseStmt.cpp @@ -493,7 +493,7 @@ StmtResult Parser::ParseCompoundStatementBody(bool isStmtExpr) { IdentifierInfo *II = Tok.getIdentifierInfo(); SourceLocation IdLoc = ConsumeToken(); - DeclsInGroup.push_back(Actions.LookupOrCreateLabel(II, IdLoc, true)); + DeclsInGroup.push_back(Actions.LookupOrCreateLabel(II, IdLoc, LabelLoc)); if (!Tok.is(tok::comma)) break; diff --git a/lib/Sema/SemaLookup.cpp b/lib/Sema/SemaLookup.cpp index 31f88554bf..d1b6ef104d 100644 --- a/lib/Sema/SemaLookup.cpp +++ b/lib/Sema/SemaLookup.cpp @@ -2766,30 +2766,35 @@ void Sema::LookupVisibleDecls(DeclContext *Ctx, LookupNameKind Kind, } /// LookupOrCreateLabel - Do a name lookup of a label with the specified name. -/// If isLocalLabel is true, then this is a definition of an __label__ label -/// name, otherwise it is a normal label definition or use. +/// If GnuLabelLoc is a valid source location, then this is a definition +/// of an __label__ label name, otherwise it is a normal label definition +/// or use. LabelDecl *Sema::LookupOrCreateLabel(IdentifierInfo *II, SourceLocation Loc, - bool isLocalLabel) { + SourceLocation GnuLabelLoc) { // Do a lookup to see if we have a label with this name already. NamedDecl *Res = 0; - - // Local label definitions always shadow existing labels. - if (!isLocalLabel) - Res = LookupSingleName(CurScope, II, Loc, LookupLabel, NotForRedeclaration); - - // If we found a label, check to see if it is in the same context as us. When - // in a Block, we don't want to reuse a label in an enclosing function. + + if (GnuLabelLoc.isValid()) { + // Local label definitions always shadow existing labels. + Res = LabelDecl::Create(Context, CurContext, Loc, II, GnuLabelLoc); + Scope *S = CurScope; + PushOnScopeChains(Res, S, true); + return cast(Res); + } + + // Not a GNU local label. + Res = LookupSingleName(CurScope, II, Loc, LookupLabel, NotForRedeclaration); + // If we found a label, check to see if it is in the same context as us. + // When in a Block, we don't want to reuse a label in an enclosing function. if (Res && Res->getDeclContext() != CurContext) Res = 0; - if (Res == 0) { // If not forward referenced or defined already, create the backing decl. - Res = LabelDecl::Create(Context, CurContext, Loc, II, isLocalLabel); - Scope *S = isLocalLabel ? CurScope : CurScope->getFnParent(); + Res = LabelDecl::Create(Context, CurContext, Loc, II); + Scope *S = CurScope->getFnParent(); assert(S && "Not in a function?"); PushOnScopeChains(Res, S, true); } - return cast(Res); } diff --git a/lib/Serialization/ASTReaderDecl.cpp b/lib/Serialization/ASTReaderDecl.cpp index a49f909c6f..d77b146098 100644 --- a/lib/Serialization/ASTReaderDecl.cpp +++ b/lib/Serialization/ASTReaderDecl.cpp @@ -748,8 +748,7 @@ void ASTDeclReader::VisitLinkageSpecDecl(LinkageSpecDecl *D) { void ASTDeclReader::VisitLabelDecl(LabelDecl *D) { VisitNamedDecl(D); - bool IsGnuLocal = Record[Idx++]; - D->setGnuLocal(IsGnuLocal); + D->setLocStart(ReadSourceLocation(Record, Idx)); } diff --git a/lib/Serialization/ASTWriterDecl.cpp b/lib/Serialization/ASTWriterDecl.cpp index 26b325a5d5..0ce3e4fb01 100644 --- a/lib/Serialization/ASTWriterDecl.cpp +++ b/lib/Serialization/ASTWriterDecl.cpp @@ -653,7 +653,7 @@ void ASTDeclWriter::VisitLinkageSpecDecl(LinkageSpecDecl *D) { void ASTDeclWriter::VisitLabelDecl(LabelDecl *D) { VisitNamedDecl(D); - Record.push_back(D->isGnuLocal()); + Writer.AddSourceLocation(D->getLocStart(), Record); Code = serialization::DECL_LABEL; }