diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/Parse/ParseStmt.cpp | 3 | ||||
-rw-r--r-- | clang/lib/Sema/SemaStmt.cpp | 27 | ||||
-rw-r--r-- | clang/lib/Sema/TreeTransform.h | 7 | ||||
-rw-r--r-- | clang/lib/Serialization/ASTReaderStmt.cpp | 1 | ||||
-rw-r--r-- | clang/lib/Serialization/ASTWriterStmt.cpp | 1 |
5 files changed, 32 insertions, 7 deletions
diff --git a/clang/lib/Parse/ParseStmt.cpp b/clang/lib/Parse/ParseStmt.cpp index 5ebee67b7a4..d4523d226ad 100644 --- a/clang/lib/Parse/ParseStmt.cpp +++ b/clang/lib/Parse/ParseStmt.cpp @@ -241,10 +241,9 @@ StmtResult Parser::ParseLabeledStatement(AttributeList *Attr) { if (SubStmt.isInvalid()) SubStmt = Actions.ActOnNullStmt(ColonLoc); - // FIXME: use attributes? return Actions.ActOnLabelStmt(IdentTok.getLocation(), IdentTok.getIdentifierInfo(), - ColonLoc, SubStmt.get()); + ColonLoc, SubStmt.get(), AttrList.take()); } /// ParseCaseStatement diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp index 24489544e06..7acadc541c7 100644 --- a/clang/lib/Sema/SemaStmt.cpp +++ b/clang/lib/Sema/SemaStmt.cpp @@ -227,13 +227,35 @@ Sema::ActOnDefaultStmt(SourceLocation DefaultLoc, SourceLocation ColonLoc, StmtResult Sema::ActOnLabelStmt(SourceLocation IdentLoc, IdentifierInfo *II, - SourceLocation ColonLoc, Stmt *SubStmt) { + SourceLocation ColonLoc, Stmt *SubStmt, + const AttributeList *Attr) { + // According to GCC docs, "the only attribute that makes sense after a label + // is 'unused'". + bool HasUnusedAttr = false; + llvm::OwningPtr<const AttributeList> AttrList(Attr); + for (const AttributeList* a = AttrList.get(); a; a = a->getNext()) { + if (a->getKind() == AttributeList::AT_unused) { + HasUnusedAttr = true; + } else { + Diag(a->getLoc(), diag::warn_label_attribute_not_unused); + a->setInvalid(true); + } + } + + return ActOnLabelStmt(IdentLoc, II, ColonLoc, SubStmt, HasUnusedAttr); +} + +StmtResult +Sema::ActOnLabelStmt(SourceLocation IdentLoc, IdentifierInfo *II, + SourceLocation ColonLoc, Stmt *SubStmt, + bool HasUnusedAttr) { // Look up the record for this label identifier. LabelStmt *&LabelDecl = 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)); + return Owned(LabelDecl = new (Context) LabelStmt(IdentLoc, II, SubStmt, + HasUnusedAttr)); assert(LabelDecl->getID() == II && "Label mismatch!"); @@ -249,6 +271,7 @@ Sema::ActOnLabelStmt(SourceLocation IdentLoc, IdentifierInfo *II, // definition. Fill in the forward definition and return it. LabelDecl->setIdentLoc(IdentLoc); LabelDecl->setSubStmt(SubStmt); + LabelDecl->setUnusedAttribute(HasUnusedAttr); return Owned(LabelDecl); } diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index a865348e493..71492254c6e 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -758,8 +758,9 @@ public: StmtResult RebuildLabelStmt(SourceLocation IdentLoc, IdentifierInfo *Id, SourceLocation ColonLoc, - Stmt *SubStmt) { - return SemaRef.ActOnLabelStmt(IdentLoc, Id, ColonLoc, SubStmt); + Stmt *SubStmt, bool HasUnusedAttr) { + return SemaRef.ActOnLabelStmt(IdentLoc, Id, ColonLoc, SubStmt, + HasUnusedAttr); } /// \brief Build a new "if" statement. @@ -3562,7 +3563,7 @@ TreeTransform<Derived>::TransformLabelStmt(LabelStmt *S) { // FIXME: Pass the real colon location in. SourceLocation ColonLoc = SemaRef.PP.getLocForEndOfToken(S->getIdentLoc()); return getDerived().RebuildLabelStmt(S->getIdentLoc(), S->getID(), ColonLoc, - SubStmt.get()); + SubStmt.get(), S->HasUnusedAttribute()); } template<typename Derived> diff --git a/clang/lib/Serialization/ASTReaderStmt.cpp b/clang/lib/Serialization/ASTReaderStmt.cpp index 7b0845d5e7b..ab2bba7283b 100644 --- a/clang/lib/Serialization/ASTReaderStmt.cpp +++ b/clang/lib/Serialization/ASTReaderStmt.cpp @@ -220,6 +220,7 @@ void ASTStmtReader::VisitLabelStmt(LabelStmt *S) { S->setSubStmt(Reader.ReadSubStmt()); S->setIdentLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); S->setUsed(Record[Idx++]); + S->setUnusedAttribute(Record[Idx++]); Reader.RecordLabelStmt(S, Record[Idx++]); } diff --git a/clang/lib/Serialization/ASTWriterStmt.cpp b/clang/lib/Serialization/ASTWriterStmt.cpp index edd8002d47c..3905ad68968 100644 --- a/clang/lib/Serialization/ASTWriterStmt.cpp +++ b/clang/lib/Serialization/ASTWriterStmt.cpp @@ -214,6 +214,7 @@ void ASTStmtWriter::VisitLabelStmt(LabelStmt *S) { 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; } |