diff options
Diffstat (limited to 'include/clang')
-rw-r--r-- | include/clang/AST/Stmt.h | 73 | ||||
-rw-r--r-- | include/clang/Frontend/PCHBitCodes.h | 14 | ||||
-rw-r--r-- | include/clang/Frontend/PCHReader.h | 13 | ||||
-rw-r--r-- | include/clang/Frontend/PCHWriter.h | 12 |
4 files changed, 102 insertions, 10 deletions
diff --git a/include/clang/AST/Stmt.h b/include/clang/AST/Stmt.h index c20d602a7c..2c88ff4254 100644 --- a/include/clang/AST/Stmt.h +++ b/include/clang/AST/Stmt.h @@ -136,11 +136,22 @@ public: void operator delete(void*, std::size_t) throw() { } void operator delete(void*, void*) throw() { } +public: + /// \brief A placeholder type used to construct an empty shell of a + /// type, that will be filled in later (e.g., by some + /// de-serialization). + struct EmptyShell { }; + protected: /// DestroyChildren - Invoked by destructors of subclasses of Stmt to /// recursively release child AST nodes. void DestroyChildren(ASTContext& Ctx); + /// \brief Construct an empty statement. + explicit Stmt(StmtClass SC, EmptyShell) : sClass(SC) { + if (Stmt::CollectingStats()) Stmt::addStmtClass(SC); + } + public: Stmt(StmtClass SC) : sClass(SC) { if (Stmt::CollectingStats()) Stmt::addStmtClass(SC); @@ -211,11 +222,6 @@ public: return const_child_iterator(const_cast<Stmt*>(this)->child_end()); } - /// \brief A placeholder type used to construct an empty shell of a - /// type, that will be filled in later (e.g., by some - /// de-serialization). - struct EmptyShell { }; - void Emit(llvm::Serializer& S) const; static Stmt* Create(llvm::Deserializer& D, ASTContext& C); @@ -288,7 +294,11 @@ class NullStmt : public Stmt { public: NullStmt(SourceLocation L) : Stmt(NullStmtClass), SemiLoc(L) {} + /// \brief Build an empty null statement. + explicit NullStmt(EmptyShell Empty) : Stmt(NullStmtClass, Empty) { } + SourceLocation getSemiLoc() const { return SemiLoc; } + void setSemiLoc(SourceLocation L) { SemiLoc = L; } virtual SourceRange getSourceRange() const { return SourceRange(SemiLoc); } @@ -323,9 +333,16 @@ public: Body = new (C) Stmt*[NumStmts]; memcpy(Body, StmtStart, numStmts * sizeof(*Body)); } + + // \brief Build an empty compound statement. + explicit CompoundStmt(EmptyShell Empty) + : Stmt(CompoundStmtClass, Empty), Body(0), NumStmts(0) { } + + void setStmts(ASTContext &C, Stmt **Stmts, unsigned NumStmts); bool body_empty() const { return NumStmts == 0; } - + unsigned size() const { return NumStmts; } + typedef Stmt** body_iterator; body_iterator body_begin() { return Body; } body_iterator body_end() { return Body + NumStmts; } @@ -360,7 +377,9 @@ public: } SourceLocation getLBracLoc() const { return LBracLoc; } + void setLBracLoc(SourceLocation L) { LBracLoc = L; } SourceLocation getRBracLoc() const { return RBracLoc; } + void setRBracLoc(SourceLocation L) { RBracLoc = L; } static bool classof(const Stmt *T) { return T->getStmtClass() == CompoundStmtClass; @@ -418,12 +437,17 @@ public: SubExprs[RHS] = reinterpret_cast<Stmt*>(rhs); CaseLoc = caseLoc; } - + + /// \brief Build an empty switch case statement. + explicit CaseStmt(EmptyShell Empty) : SwitchCase(CaseStmtClass) { } + SourceLocation getCaseLoc() const { return CaseLoc; } - + void setCaseLoc(SourceLocation L) { CaseLoc = L; } + Expr *getLHS() { return reinterpret_cast<Expr*>(SubExprs[LHS]); } Expr *getRHS() { return reinterpret_cast<Expr*>(SubExprs[RHS]); } Stmt *getSubStmt() { return SubExprs[SUBSTMT]; } + const Expr *getLHS() const { return reinterpret_cast<const Expr*>(SubExprs[LHS]); } @@ -465,11 +489,16 @@ class DefaultStmt : public SwitchCase { public: DefaultStmt(SourceLocation DL, Stmt *substmt) : SwitchCase(DefaultStmtClass), SubStmt(substmt), DefaultLoc(DL) {} - + + /// \brief Build an empty default statement. + explicit DefaultStmt(EmptyShell) : SwitchCase(DefaultStmtClass) { } + Stmt *getSubStmt() { return SubStmt; } const Stmt *getSubStmt() const { return SubStmt; } - + void setSubStmt(Stmt *S) { SubStmt = S; } + SourceLocation getDefaultLoc() const { return DefaultLoc; } + void setDefaultLoc(SourceLocation L) { DefaultLoc = L; } virtual SourceRange getSourceRange() const { return SourceRange(DefaultLoc, SubStmt->getLocEnd()); @@ -537,14 +566,23 @@ public: IfLoc = IL; } + /// \brief Build an empty if/then/else statement + explicit IfStmt(EmptyShell Empty) : Stmt(IfStmtClass, Empty) { } + const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);} + void setCond(Expr *E) { SubExprs[COND] = reinterpret_cast<Stmt *>(E); } const Stmt *getThen() const { return SubExprs[THEN]; } + void setThen(Stmt *S) { SubExprs[THEN] = S; } const Stmt *getElse() const { return SubExprs[ELSE]; } + void setElse(Stmt *S) { SubExprs[ELSE] = S; } Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); } Stmt *getThen() { return SubExprs[THEN]; } Stmt *getElse() { return SubExprs[ELSE]; } + SourceLocation getIfLoc() const { return IfLoc; } + void setIfLoc(SourceLocation L) { IfLoc = L; } + virtual SourceRange getSourceRange() const { if (SubExprs[ELSE]) return SourceRange(IfLoc, SubExprs[ELSE]->getLocEnd()); @@ -579,13 +617,22 @@ public: SubExprs[BODY] = NULL; } + /// \brief Build a empty switch statement. + explicit SwitchStmt(EmptyShell Empty) : Stmt(SwitchStmtClass, Empty) { } + const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);} const Stmt *getBody() const { return SubExprs[BODY]; } const SwitchCase *getSwitchCaseList() const { return FirstCase; } Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]);} + void setCond(Expr *E) { SubExprs[COND] = reinterpret_cast<Stmt *>(E); } Stmt *getBody() { return SubExprs[BODY]; } + void setBody(Stmt *S) { SubExprs[BODY] = S; } SwitchCase *getSwitchCaseList() { return FirstCase; } + void setSwitchCaseList(SwitchCase *SC) { FirstCase = SC; } + + SourceLocation getSwitchLoc() const { return SwitchLoc; } + void setSwitchLoc(SourceLocation L) { SwitchLoc = L; } void setBody(Stmt *S, SourceLocation SL) { SubExprs[BODY] = S; @@ -814,6 +861,12 @@ class BreakStmt : public Stmt { public: BreakStmt(SourceLocation BL) : Stmt(BreakStmtClass), BreakLoc(BL) {} + /// \brief Build an empty break statement. + explicit BreakStmt(EmptyShell Empty) : Stmt(BreakStmtClass, Empty) { } + + SourceLocation getBreakLoc() const { return BreakLoc; } + void setBreakLoc(SourceLocation L) { BreakLoc = L; } + virtual SourceRange getSourceRange() const { return SourceRange(BreakLoc); } static bool classof(const Stmt *T) { diff --git a/include/clang/Frontend/PCHBitCodes.h b/include/clang/Frontend/PCHBitCodes.h index a218a5fcf6..98d27a0916 100644 --- a/include/clang/Frontend/PCHBitCodes.h +++ b/include/clang/Frontend/PCHBitCodes.h @@ -375,6 +375,20 @@ namespace clang { STMT_STOP, /// \brief A NULL expression. STMT_NULL_PTR, + /// \brief A NullStmt record. + STMT_NULL, + /// \brief A CompoundStmt record. + STMT_COMPOUND, + /// \brief A CaseStmt record. + STMT_CASE, + /// \brief A DefaultStmt record. + STMT_DEFAULT, + /// \brief An IfStmt record. + STMT_IF, + /// \brief A SwitchStmt record. + STMT_SWITCH, + /// \brief A BreakStmt record. + STMT_BREAK, /// \brief A PredefinedExpr record. EXPR_PREDEFINED, /// \brief A DeclRefExpr record. diff --git a/include/clang/Frontend/PCHReader.h b/include/clang/Frontend/PCHReader.h index 995a1d563f..07531df1f3 100644 --- a/include/clang/Frontend/PCHReader.h +++ b/include/clang/Frontend/PCHReader.h @@ -26,6 +26,7 @@ #include "llvm/ADT/SmallVector.h" #include "llvm/Bitcode/BitstreamReader.h" #include "llvm/Support/DataTypes.h" +#include <map> #include <string> #include <utility> #include <vector> @@ -41,6 +42,7 @@ class Attr; class Decl; class DeclContext; class Preprocessor; +class SwitchCase; /// \brief Reads a precompiled head containing the contents of a /// translation unit. @@ -126,6 +128,10 @@ private: /// file. llvm::SmallVector<uint64_t, 16> ExternalDefinitions; + /// \brief Mapping from switch-case IDs in the PCH file to + /// switch-case statements. + std::map<unsigned, SwitchCase *> SwitchCaseStmts; + PCHReadResult ReadPCHBlock(); bool CheckPredefinesBuffer(const char *PCHPredef, unsigned PCHPredefLen, @@ -241,6 +247,13 @@ public: /// \brief Retrieve the AST context that this PCH reader /// supplements. ASTContext &getContext() { return Context; } + + /// \brief Record that the given ID maps to the given switch-case + /// statement. + void RecordSwitchCaseID(SwitchCase *SC, unsigned ID); + + /// \brief Retrieve the switch-case statement with the given ID. + SwitchCase *getSwitchCaseWithID(unsigned ID); }; } // end namespace clang diff --git a/include/clang/Frontend/PCHWriter.h b/include/clang/Frontend/PCHWriter.h index 4af64e6ee1..5828637b04 100644 --- a/include/clang/Frontend/PCHWriter.h +++ b/include/clang/Frontend/PCHWriter.h @@ -20,6 +20,7 @@ #include "clang/Frontend/PCHBitCodes.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallVector.h" +#include <map> #include <queue> namespace llvm { @@ -33,6 +34,7 @@ namespace clang { class ASTContext; class Preprocessor; class SourceManager; +class SwitchCase; class TargetInfo; /// \brief Writes a precompiled header containing the contents of a @@ -108,6 +110,9 @@ private: /// declaration or type. llvm::SmallVector<Stmt *, 8> StmtsToEmit; + /// \brief Mapping from SwitchCase statements to IDs. + std::map<SwitchCase *, unsigned> SwitchCaseIDs; + void WriteTargetTriple(const TargetInfo &Target); void WriteLanguageOptions(const LangOptions &LangOpts); void WriteSourceManagerBlock(SourceManager &SourceMgr); @@ -170,6 +175,13 @@ public: /// \brief Flush all of the statements and expressions that have /// been added to the queue via AddStmt(). void FlushStmts(); + + /// \brief Record an ID for the given switch-case statement. + unsigned RecordSwitchCaseID(SwitchCase *S); + + /// \brief Retrieve the ID for the given switch-case statement. + unsigned getSwitchCaseID(SwitchCase *S); + }; } // end namespace clang |