aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/clang/AST/Decl.h31
-rw-r--r--include/clang/AST/DeclBase.h2
-rw-r--r--include/clang/AST/Expr.h8
-rw-r--r--include/clang/AST/RecursiveASTVisitor.h5
-rw-r--r--include/clang/AST/Stmt.h48
-rw-r--r--include/clang/Basic/DeclNodes.td1
-rw-r--r--include/clang/Basic/DiagnosticSemaKinds.td8
-rw-r--r--include/clang/Sema/ScopeInfo.h15
-rw-r--r--include/clang/Serialization/ASTBitCodes.h4
-rw-r--r--include/clang/Serialization/ASTReader.h39
-rw-r--r--include/clang/Serialization/ASTWriter.h8
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h6
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h2
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h9
-rw-r--r--lib/AST/Decl.cpp6
-rw-r--r--lib/AST/DeclBase.cpp3
-rw-r--r--lib/AST/Stmt.cpp4
-rw-r--r--lib/AST/StmtProfile.cpp6
-rw-r--r--lib/Analysis/CFG.cpp25
-rw-r--r--lib/CodeGen/CGDecl.cpp2
-rw-r--r--lib/CodeGen/CGStmt.cpp18
-rw-r--r--lib/CodeGen/CodeGenFunction.cpp2
-rw-r--r--lib/CodeGen/CodeGenFunction.h11
-rw-r--r--lib/Sema/JumpDiagnostics.cpp42
-rw-r--r--lib/Sema/Sema.cpp48
-rw-r--r--lib/Sema/SemaDecl.cpp41
-rw-r--r--lib/Sema/SemaExpr.cpp34
-rw-r--r--lib/Sema/SemaStmt.cpp50
-rw-r--r--lib/Sema/TreeTransform.h51
-rw-r--r--lib/Serialization/ASTReader.cpp66
-rw-r--r--lib/Serialization/ASTReaderDecl.cpp10
-rw-r--r--lib/Serialization/ASTReaderStmt.cpp11
-rw-r--r--lib/Serialization/ASTWriterDecl.cpp8
-rw-r--r--lib/Serialization/ASTWriterStmt.cpp21
-rw-r--r--lib/StaticAnalyzer/Checkers/ExprEngine.cpp8
-rw-r--r--lib/StaticAnalyzer/Core/SVals.cpp2
-rw-r--r--test/CXX/stmt.stmt/stmt.label/p1.cpp2
-rw-r--r--test/Sema/warn-unused-label.c4
-rw-r--r--tools/libclang/CIndex.cpp17
39 files changed, 294 insertions, 384 deletions
diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h
index cba71ae8cd..e0ffa627ac 100644
--- a/include/clang/AST/Decl.h
+++ b/include/clang/AST/Decl.h
@@ -36,6 +36,7 @@ class FunctionTemplateSpecializationInfo;
class DependentFunctionTemplateSpecializationInfo;
class TypeLoc;
class UnresolvedSetImpl;
+class LabelStmt;
/// \brief A container of type source information.
///
@@ -294,6 +295,36 @@ inline llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
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;
diff --git a/include/clang/AST/DeclBase.h b/include/clang/AST/DeclBase.h
index 3e92c4e651..1407dadd16 100644
--- a/include/clang/AST/DeclBase.h
+++ b/include/clang/AST/DeclBase.h
@@ -324,7 +324,7 @@ public:
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;
diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h
index c09394d9c0..b5724a6475 100644
--- a/include/clang/AST/Expr.h
+++ b/include/clang/AST/Expr.h
@@ -2641,9 +2641,9 @@ public:
/// 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 @@ public:
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;
diff --git a/include/clang/AST/RecursiveASTVisitor.h b/include/clang/AST/RecursiveASTVisitor.h
index 8ddd5875ce..667b840889 100644
--- a/include/clang/AST/RecursiveASTVisitor.h
+++ b/include/clang/AST/RecursiveASTVisitor.h
@@ -1088,6 +1088,11 @@ DEF_TRAVERSE_DECL(NamespaceAliasDecl, {
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
diff --git a/include/clang/AST/Stmt.h b/include/clang/AST/Stmt.h
index 1254926fac..7ede9ce323 100644
--- a/include/clang/AST/Stmt.h
+++ b/include/clang/AST/Stmt.h
@@ -130,14 +130,6 @@ protected:
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 @@ protected:
StmtBitfields StmtBits;
CompoundStmtBitfields CompoundStmtBits;
- LabelStmtBitfields LabelStmtBits;
ExprBitfields ExprBits;
CastExprBitfields CastExprBits;
CallExprBitfields CallExprBits;
@@ -633,40 +624,31 @@ public:
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 @@ public:
/// 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 @@ public:
/// 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();
}
diff --git a/include/clang/Basic/DeclNodes.td b/include/clang/Basic/DeclNodes.td
index f6c31f4877..2ec7427cf7 100644
--- a/include/clang/Basic/DeclNodes.td
+++ b/include/clang/Basic/DeclNodes.td
@@ -15,6 +15,7 @@ def Named : Decl<1>;
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>;
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td
index eb8bf590c3..b815426f6c 100644
--- a/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/include/clang/Basic/DiagnosticSemaKinds.td
@@ -1095,7 +1095,7 @@ def err_regparm_mismatch : Error<"function declared with with regparm(%0) "
"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 @@ def warn_missing_braces : Warning<
"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">;
diff --git a/include/clang/Sema/ScopeInfo.h b/include/clang/Sema/ScopeInfo.h
index edd1432d8e..c9d38715ec 100644
--- a/include/clang/Sema/ScopeInfo.h
+++ b/include/clang/Sema/ScopeInfo.h
@@ -23,7 +23,7 @@ namespace clang {
class BlockDecl;
class IdentifierInfo;
-class LabelStmt;
+class LabelDecl;
class ReturnStmt;
class Scope;
class SwitchStmt;
@@ -52,10 +52,10 @@ public:
/// \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 @@ public:
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();
diff --git a/include/clang/Serialization/ASTBitCodes.h b/include/clang/Serialization/ASTBitCodes.h
index 391438248e..d1998c29a3 100644
--- a/include/clang/Serialization/ASTBitCodes.h
+++ b/include/clang/Serialization/ASTBitCodes.h
@@ -697,7 +697,9 @@ namespace clang {
/// 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,
diff --git a/include/clang/Serialization/ASTReader.h b/include/clang/Serialization/ASTReader.h
index 94bfd16353..002f6be410 100644
--- a/include/clang/Serialization/ASTReader.h
+++ b/include/clang/Serialization/ASTReader.h
@@ -56,7 +56,6 @@ class NestedNameSpecifier;
class CXXBaseSpecifier;
class CXXCtorInitializer;
class GotoStmt;
-class LabelStmt;
class MacroDefinition;
class NamedDecl;
class Preprocessor;
@@ -646,22 +645,6 @@ private:
/// 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 @@ public:
/// \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
diff --git a/include/clang/Serialization/ASTWriter.h b/include/clang/Serialization/ASTWriter.h
index f9a49973e1..d5f622a340 100644
--- a/include/clang/Serialization/ASTWriter.h
+++ b/include/clang/Serialization/ASTWriter.h
@@ -44,7 +44,6 @@ class CXXBaseSpecifier;
class CXXCtorInitializer;
class FPOptions;
class HeaderSearch;
-class LabelStmt;
class MacroDefinition;
class MemorizeStatCalls;
class OpenCLOptions;
@@ -261,9 +260,6 @@ private:
/// \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 @@ public:
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; }
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h b/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h
index d879ea13e7..800e63a4cd 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h
@@ -331,11 +331,11 @@ public:
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;
}
};
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h b/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h
index 9c18711742..e7b39448ac 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h
@@ -238,7 +238,7 @@ public:
return loc::MemRegionVal(R);
}
- Loc makeLoc(const AddrLabelExpr* E) {
+ Loc makeLoc(const AddrLabelExpr *E) {
return loc::GotoLabel(E->getLabel());
}
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h b/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h
index 1d1cd0b8f9..0d430794e7 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h
@@ -432,15 +432,14 @@ enum Kind { GotoLabelKind, MemRegionKind, ConcreteIntKind, ObjCPropRefKind };
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) {
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index fded8ff38c..441444da9e 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -2182,6 +2182,12 @@ TranslationUnitDecl *TranslationUnitDecl::Create(ASTContext &C) {
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);
diff --git a/lib/AST/DeclBase.cpp b/lib/AST/DeclBase.cpp
index 110de64d8c..dfc5a6ae5d 100644
--- a/lib/AST/DeclBase.cpp
+++ b/lib/AST/DeclBase.cpp
@@ -269,7 +269,8 @@ unsigned Decl::getIdentifierNamespaceForKind(Kind DeclKind) {
case ObjCMethod:
case ObjCProperty:
return IDNS_Ordinary;
-
+ case Label:
+ return IDNS_Label;
case IndirectField:
return IDNS_Ordinary | IDNS_Member;
diff --git a/lib/AST/Stmt.cpp b/lib/AST/Stmt.cpp
index 66182957d6..7e73f02e67 100644
--- a/lib/AST/Stmt.cpp
+++ b/lib/AST/Stmt.cpp
@@ -161,7 +161,7 @@ void CompoundStmt::setStmts(ASTContext &C, Stmt **Stmts, unsigned NumStmts) {
}
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 @@ void WhileStmt::setConditionVariable(ASTContext &C, VarDecl *V) {
}
// IndirectGotoStmt
-LabelStmt *IndirectGotoStmt::getConstantTarget() {
+LabelDecl *IndirectGotoStmt::getConstantTarget() {
if (AddrLabelExpr *E =
dyn_cast<AddrLabelExpr>(getTarget()->IgnoreParenImpCasts()))
return E->getLabel();
diff --git a/lib/AST/StmtProfile.cpp b/lib/AST/StmtProfile.cpp
index b96ffe8a48..2ffb807abc 100644
--- a/lib/AST/StmtProfile.cpp
+++ b/lib/AST/StmtProfile.cpp
@@ -101,7 +101,7 @@ void StmtProfiler::VisitDefaultStmt(DefaultStmt *S) {
void StmtProfiler::VisitLabelStmt(LabelStmt *S) {
VisitStmt(S);
- VisitName(S->getID());
+ VisitDecl(S->getDecl());
}
void StmtProfiler::VisitIfStmt(IfStmt *S) {
@@ -129,7 +129,7 @@ void StmtProfiler::VisitForStmt(ForStmt *S) {
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::VisitConditionalOperator(ConditionalOperator *S) {
void StmtProfiler::VisitAddrLabelExpr(AddrLabelExpr *S) {
VisitExpr(S);
- VisitName(S->getLabel()->getID());
+ VisitDecl(S->getLabel());
}
void StmtProfiler::VisitStmtExpr(StmtExpr *S) {
diff --git a/lib/Analysis/CFG.cpp b/lib/Analysis/CFG.cpp
index d46b7e7830..6da4784405 100644
--- a/lib/Analysis/CFG.cpp
+++ b/lib/Analysis/CFG.cpp
@@ -242,7 +242,7 @@ class CFGBuilder {
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 @@ class CFGBuilder {
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 @@ void CFGBuilder::addLocalScopeForStmt(Stmt* S) {
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 @@ void CFGBuilder::addLocalScopeForStmt(Stmt* S) {
// 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 @@ CFGBlock* CFGBuilder::VisitReturnStmt(ReturnStmt* R) {
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* L