aboutsummaryrefslogtreecommitdiff
path: root/include/clang
diff options
context:
space:
mode:
Diffstat (limited to 'include/clang')
-rw-r--r--include/clang/AST/Stmt.h73
-rw-r--r--include/clang/Frontend/PCHBitCodes.h14
-rw-r--r--include/clang/Frontend/PCHReader.h13
-rw-r--r--include/clang/Frontend/PCHWriter.h12
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