diff options
author | Douglas Gregor <dgregor@apple.com> | 2009-04-17 18:58:21 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2009-04-17 18:58:21 +0000 |
commit | 7d5c2f241c74e5f8d9ec492e8f9f268e5e9ae41f (patch) | |
tree | 7f1fa89837c89cc8eb861fcc9e68b5fe6d7f2383 /lib/Frontend/PCHReader.cpp | |
parent | 00cb00eb8ac9147c397dabf68a13f03914a52aba (diff) |
PCH support for indirect gotos and address-of-label expressions.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@69369 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Frontend/PCHReader.cpp')
-rw-r--r-- | lib/Frontend/PCHReader.cpp | 54 |
1 files changed, 54 insertions, 0 deletions
diff --git a/lib/Frontend/PCHReader.cpp b/lib/Frontend/PCHReader.cpp index 9597b37082..8928b063cf 100644 --- a/lib/Frontend/PCHReader.cpp +++ b/lib/Frontend/PCHReader.cpp @@ -256,6 +256,7 @@ namespace { unsigned VisitDoStmt(DoStmt *S); unsigned VisitForStmt(ForStmt *S); unsigned VisitGotoStmt(GotoStmt *S); + unsigned VisitIndirectGotoStmt(IndirectGotoStmt *S); unsigned VisitContinueStmt(ContinueStmt *S); unsigned VisitBreakStmt(BreakStmt *S); unsigned VisitReturnStmt(ReturnStmt *S); @@ -287,6 +288,7 @@ namespace { unsigned VisitDesignatedInitExpr(DesignatedInitExpr *E); unsigned VisitImplicitValueInitExpr(ImplicitValueInitExpr *E); unsigned VisitVAArgExpr(VAArgExpr *E); + unsigned VisitAddrLabelExpr(AddrLabelExpr *E); unsigned VisitTypesCompatibleExpr(TypesCompatibleExpr *E); unsigned VisitChooseExpr(ChooseExpr *E); unsigned VisitGNUNullExpr(GNUNullExpr *E); @@ -407,6 +409,12 @@ unsigned PCHStmtReader::VisitGotoStmt(GotoStmt *S) { return 0; } +unsigned PCHStmtReader::VisitIndirectGotoStmt(IndirectGotoStmt *S) { + VisitStmt(S); + S->setTarget(cast_or_null<Expr>(StmtStack.back())); + return 1; +} + unsigned PCHStmtReader::VisitContinueStmt(ContinueStmt *S) { VisitStmt(S); S->setContinueLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); @@ -733,6 +741,14 @@ unsigned PCHStmtReader::VisitVAArgExpr(VAArgExpr *E) { return 1; } +unsigned PCHStmtReader::VisitAddrLabelExpr(AddrLabelExpr *E) { + VisitExpr(E); + E->setAmpAmpLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); + E->setLabelLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); + Reader.SetLabelOf(E, Record[Idx++]); + return 0; +} + unsigned PCHStmtReader::VisitTypesCompatibleExpr(TypesCompatibleExpr *E) { VisitExpr(E); E->setArgType1(Reader.GetType(Record[Idx++])); @@ -2218,6 +2234,10 @@ Stmt *PCHReader::ReadStmt() { case pch::STMT_GOTO: S = new (Context) GotoStmt(Empty); break; + + case pch::STMT_INDIRECT_GOTO: + S = new (Context) IndirectGotoStmt(Empty); + break; case pch::STMT_CONTINUE: S = new (Context) ContinueStmt(Empty); @@ -2335,6 +2355,10 @@ Stmt *PCHReader::ReadStmt() { S = new (Context) VAArgExpr(Empty); break; + case pch::EXPR_ADDR_LABEL: + S = new (Context) AddrLabelExpr(Empty); + break; + case pch::EXPR_TYPES_COMPATIBLE: S = new (Context) TypesCompatibleExpr(Empty); break; @@ -2418,6 +2442,16 @@ void PCHReader::RecordLabelStmt(LabelStmt *S, unsigned 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 @@ -2439,3 +2473,23 @@ void PCHReader::SetLabelOf(GotoStmt *S, unsigned ID) { 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 PCHReader::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)); + } +} |