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.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@125733 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp
index fcf09b7..83f8a84 100644
--- a/lib/Serialization/ASTReader.cpp
+++ b/lib/Serialization/ASTReader.cpp
@@ -4814,72 +4814,6 @@
SwitchCaseStmts.clear();
}
-/// \brief Record that the given label statement has been
-/// deserialized and has the given ID.
-void ASTReader::RecordLabelStmt(LabelStmt *S, unsigned ID) {
- assert(LabelStmts.find(ID) == LabelStmts.end() &&
- "Deserialized label twice");
- LabelStmts[ID] = S;
-
- // If we've already seen any goto statements that point to this
- // label, resolve them now.
- typedef std::multimap<unsigned, GotoStmt *>::iterator GotoIter;
- std::pair<GotoIter, GotoIter> Gotos = UnresolvedGotoStmts.equal_range(ID);
- for (GotoIter Goto = Gotos.first; Goto != Gotos.second; ++Goto)
- Goto->second->setLabel(S);
- UnresolvedGotoStmts.erase(Gotos.first, Gotos.second);
-
- // If we've already seen any address-label statements that point to
- // this label, resolve them now.
- typedef std::multimap<unsigned, AddrLabelExpr *>::iterator AddrLabelIter;
- std::pair<AddrLabelIter, AddrLabelIter> AddrLabels
- = UnresolvedAddrLabelExprs.equal_range(ID);
- for (AddrLabelIter AddrLabel = AddrLabels.first;
- AddrLabel != AddrLabels.second; ++AddrLabel)
- AddrLabel->second->setLabel(S);
- UnresolvedAddrLabelExprs.erase(AddrLabels.first, AddrLabels.second);
-}
-
-/// \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 ASTReader::SetLabelOf(GotoStmt *S, unsigned ID) {
- std::map<unsigned, LabelStmt *>::iterator Label = LabelStmts.find(ID);
- if (Label != LabelStmts.end()) {
- // We've already seen this label, so set the label of the goto and
- // we're done.
- S->setLabel(Label->second);
- } else {
- // We haven't seen this label yet, so add this goto to the set of
- // unresolved goto statements.
- UnresolvedGotoStmts.insert(std::make_pair(ID, S));
- }
-}
-
-/// \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 ASTReader::SetLabelOf(AddrLabelExpr *S, unsigned ID) {
- std::map<unsigned, LabelStmt *>::iterator Label = LabelStmts.find(ID);
- if (Label != LabelStmts.end()) {
- // We've already seen this label, so set the label of the
- // label-address expression and we're done.
- S->setLabel(Label->second);
- } else {
- // We haven't seen this label yet, so add this label-address
- // expression to the set of unresolved label-address expressions.
- UnresolvedAddrLabelExprs.insert(std::make_pair(ID, S));
- }
-}
-
void ASTReader::FinishedDeserializing() {
assert(NumCurrentElementsDeserializing &&
"FinishedDeserializing not paired with StartedDeserializing");
diff --git a/lib/Serialization/ASTReaderDecl.cpp b/lib/Serialization/ASTReaderDecl.cpp
index 279d081..27e7718 100644
--- a/lib/Serialization/ASTReaderDecl.cpp
+++ b/lib/Serialization/ASTReaderDecl.cpp
@@ -84,6 +84,7 @@
void VisitDecl(Decl *D);
void VisitTranslationUnitDecl(TranslationUnitDecl *TU);
void VisitNamedDecl(NamedDecl *ND);
+ void VisitLabelDecl(LabelDecl *LD);
void VisitNamespaceDecl(NamespaceDecl *D);
void VisitUsingDirectiveDecl(UsingDirectiveDecl *D);
void VisitNamespaceAliasDecl(NamespaceAliasDecl *D);
@@ -722,6 +723,12 @@
D->setHasBraces(Record[Idx++]);
}
+void ASTDeclReader::VisitLabelDecl(LabelDecl *D) {
+ VisitNamedDecl(D);
+ if (Record[Idx++]) D->setHasUnusedAttribute();
+}
+
+
void ASTDeclReader::VisitNamespaceDecl(NamespaceDecl *D) {
VisitNamedDecl(D);
D->IsInline = Record[Idx++];
@@ -1418,6 +1425,9 @@
(LinkageSpecDecl::LanguageIDs)0,
false);
break;
+ case DECL_LABEL:
+ D = LabelDecl::Create(*Context, 0, SourceLocation(), 0);
+ break;
case DECL_NAMESPACE:
D = NamespaceDecl::Create(*Context, 0, SourceLocation(), 0);
break;
diff --git a/lib/Serialization/ASTReaderStmt.cpp b/lib/Serialization/ASTReaderStmt.cpp
index 864c042..bd59737 100644
--- a/lib/Serialization/ASTReaderStmt.cpp
+++ b/lib/Serialization/ASTReaderStmt.cpp
@@ -245,12 +245,11 @@
void ASTStmtReader::VisitLabelStmt(LabelStmt *S) {
VisitStmt(S);
- S->setID(Reader.GetIdentifierInfo(Record, Idx));
+ LabelDecl *LD = cast<LabelDecl>(Reader.GetDecl(Record[Idx++]));
+ LD->setStmt(S);
+ S->setDecl(LD);
S->setSubStmt(Reader.ReadSubStmt());
S->setIdentLoc(ReadSourceLocation(Record, Idx));
- S->setUsed(Record[Idx++]);
- S->setUnusedAttribute(Record[Idx++]);
- Reader.RecordLabelStmt(S, Record[Idx++]);
}
void ASTStmtReader::VisitIfStmt(IfStmt *S) {
@@ -319,7 +318,7 @@
void ASTStmtReader::VisitGotoStmt(GotoStmt *S) {
VisitStmt(S);
- Reader.SetLabelOf(S, Record[Idx++]);
+ S->setLabel(cast<LabelDecl>(Reader.GetDecl(Record[Idx++])));
S->setGotoLoc(ReadSourceLocation(Record, Idx));
S->setLabelLoc(ReadSourceLocation(Record, Idx));
}
@@ -759,7 +758,7 @@
VisitExpr(E);
E->setAmpAmpLoc(ReadSourceLocation(Record, Idx));
E->setLabelLoc(ReadSourceLocation(Record, Idx));
- Reader.SetLabelOf(E, Record[Idx++]);
+ E->setLabel(cast<LabelDecl>(Reader.GetDecl(Record[Idx++])));
}
void ASTStmtReader::VisitStmtExpr(StmtExpr *E) {
diff --git a/lib/Serialization/ASTWriterDecl.cpp b/lib/Serialization/ASTWriterDecl.cpp
index 17ee85a..dd43e1a 100644
--- a/lib/Serialization/ASTWriterDecl.cpp
+++ b/lib/Serialization/ASTWriterDecl.cpp
@@ -47,6 +47,7 @@
void VisitDecl(Decl *D);
void VisitTranslationUnitDecl(TranslationUnitDecl *D);
void VisitNamedDecl(NamedDecl *D);
+ void VisitLabelDecl(LabelDecl *LD);
void VisitNamespaceDecl(NamespaceDecl *D);
void VisitUsingDirectiveDecl(UsingDirectiveDecl *D);
void VisitNamespaceAliasDecl(NamespaceAliasDecl *D);
@@ -651,6 +652,13 @@
Code = serialization::DECL_LINKAGE_SPEC;
}
+void ASTDeclWriter::VisitLabelDecl(LabelDecl *D) {
+ VisitNamedDecl(D);
+ Record.push_back(D->hasUnusedAttribute());
+ Code = serialization::DECL_LABEL;
+}
+
+
void ASTDeclWriter::VisitNamespaceDecl(NamespaceDecl *D) {
VisitNamedDecl(D);
Record.push_back(D->isInline());
diff --git a/lib/Serialization/ASTWriterStmt.cpp b/lib/Serialization/ASTWriterStmt.cpp
index 8a90ef1..b043f2e 100644
--- a/lib/Serialization/ASTWriterStmt.cpp
+++ b/lib/Serialization/ASTWriterStmt.cpp
@@ -217,12 +217,9 @@
void ASTStmtWriter::VisitLabelStmt(LabelStmt *S) {
VisitStmt(S);
- Writer.AddIdentifierRef(S->getID(), Record);
+ Writer.AddDeclRef(S->getDecl(), Record);
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;
}
@@ -284,7 +281,7 @@
void ASTStmtWriter::VisitGotoStmt(GotoStmt *S) {
VisitStmt(S);
- Record.push_back(Writer.GetLabelID(S->getLabel()));
+ Writer.AddDeclRef(S->getLabel(), Record);
Writer.AddSourceLocation(S->getGotoLoc(), Record);
Writer.AddSourceLocation(S->getLabelLoc(), Record);
Code = serialization::STMT_GOTO;
@@ -722,7 +719,7 @@
VisitExpr(E);
Writer.AddSourceLocation(E->getAmpAmpLoc(), Record);
Writer.AddSourceLocation(E->getLabelLoc(), Record);
- Record.push_back(Writer.GetLabelID(E->getLabel()));
+ Writer.AddDeclRef(E->getLabel(), Record);
Code = serialization::EXPR_ADDR_LABEL;
}
@@ -1359,18 +1356,6 @@
SwitchCaseIDs.clear();
}
-/// \brief Retrieve the ID for the given label statement, which may
-/// or may not have been emitted yet.
-unsigned ASTWriter::GetLabelID(LabelStmt *S) {
- std::map<LabelStmt *, unsigned>::iterator Pos = LabelIDs.find(S);
- if (Pos != LabelIDs.end())
- return Pos->second;
-
- unsigned NextID = LabelIDs.size();
- LabelIDs[S] = NextID;
- return NextID;
-}
-
/// \brief Write the given substatement or subexpression to the
/// bitstream.
void ASTWriter::WriteSubStmt(Stmt *S) {