aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/clang/AST/StmtCXX.h35
-rw-r--r--include/clang/Frontend/PCHBitCodes.h5
-rw-r--r--lib/AST/Stmt.cpp9
-rw-r--r--lib/Frontend/PCHReaderStmt.cpp31
-rw-r--r--lib/Frontend/PCHWriterStmt.cpp21
-rw-r--r--test/PCH/cxx-templates.h3
6 files changed, 93 insertions, 11 deletions
diff --git a/include/clang/AST/StmtCXX.h b/include/clang/AST/StmtCXX.h
index 4e87c2701c..58d45e801e 100644
--- a/include/clang/AST/StmtCXX.h
+++ b/include/clang/AST/StmtCXX.h
@@ -37,6 +37,9 @@ public:
: Stmt(CXXCatchStmtClass), CatchLoc(catchLoc), ExceptionDecl(exDecl),
HandlerBlock(handlerBlock) {}
+ CXXCatchStmt(EmptyShell Empty)
+ : Stmt(CXXCatchStmtClass), ExceptionDecl(0), HandlerBlock(0) {}
+
virtual SourceRange getSourceRange() const {
return SourceRange(CatchLoc, HandlerBlock->getLocEnd());
}
@@ -53,6 +56,8 @@ public:
virtual child_iterator child_begin();
virtual child_iterator child_end();
+
+ friend class PCHStmtReader;
};
/// CXXTryStmt - A C++ try block, including all handlers.
@@ -64,38 +69,46 @@ class CXXTryStmt : public Stmt {
CXXTryStmt(SourceLocation tryLoc, Stmt *tryBlock, Stmt **handlers,
unsigned numHandlers);
+ CXXTryStmt(EmptyShell Empty, unsigned numHandlers)
+ : Stmt(CXXTryStmtClass), NumHandlers(numHandlers) { }
+
+ Stmt const * const *getStmts() const {
+ return reinterpret_cast<Stmt const * const*>(this + 1);
+ }
+ Stmt **getStmts() {
+ return reinterpret_cast<Stmt **>(this + 1);
+ }
+
public:
static CXXTryStmt *Create(ASTContext &C, SourceLocation tryLoc,
Stmt *tryBlock, Stmt **handlers,
unsigned numHandlers);
+ static CXXTryStmt *Create(ASTContext &C, EmptyShell Empty,
+ unsigned numHandlers);
+
virtual SourceRange getSourceRange() const {
return SourceRange(getTryLoc(), getEndLoc());
}
SourceLocation getTryLoc() const { return TryLoc; }
SourceLocation getEndLoc() const {
- Stmt const * const*Stmts = reinterpret_cast<Stmt const * const*>(this + 1);
- return Stmts[NumHandlers]->getLocEnd();
+ return getStmts()[NumHandlers]->getLocEnd();
}
CompoundStmt *getTryBlock() {
- Stmt **Stmts = reinterpret_cast<Stmt **>(this + 1);
- return llvm::cast<CompoundStmt>(Stmts[0]);
+ return llvm::cast<CompoundStmt>(getStmts()[0]);
}
const CompoundStmt *getTryBlock() const {
- Stmt const * const*Stmts = reinterpret_cast<Stmt const * const*>(this + 1);
- return llvm::cast<CompoundStmt>(Stmts[0]);
+ return llvm::cast<CompoundStmt>(getStmts()[0]);
}
unsigned getNumHandlers() const { return NumHandlers; }
CXXCatchStmt *getHandler(unsigned i) {
- Stmt **Stmts = reinterpret_cast<Stmt **>(this + 1);
- return llvm::cast<CXXCatchStmt>(Stmts[i + 1]);
+ return llvm::cast<CXXCatchStmt>(getStmts()[i + 1]);
}
const CXXCatchStmt *getHandler(unsigned i) const {
- Stmt const * const*Stmts = reinterpret_cast<Stmt const * const*>(this + 1);
- return llvm::cast<CXXCatchStmt>(Stmts[i + 1]);
+ return llvm::cast<CXXCatchStmt>(getStmts()[i + 1]);
}
static bool classof(const Stmt *T) {
@@ -105,6 +118,8 @@ public:
virtual child_iterator child_begin();
virtual child_iterator child_end();
+
+ friend class PCHStmtReader;
};
diff --git a/include/clang/Frontend/PCHBitCodes.h b/include/clang/Frontend/PCHBitCodes.h
index 27a2b7d0b9..eab877aec9 100644
--- a/include/clang/Frontend/PCHBitCodes.h
+++ b/include/clang/Frontend/PCHBitCodes.h
@@ -755,6 +755,11 @@ namespace clang {
STMT_OBJC_AT_THROW,
// C++
+
+ /// \brief A CXXCatchStmt record.
+ STMT_CXX_CATCH,
+ /// \brief A CXXTryStmt record.
+ STMT_CXX_TRY,
/// \brief A CXXOperatorCallExpr record.
EXPR_CXX_OPERATOR_CALL,
diff --git a/lib/AST/Stmt.cpp b/lib/AST/Stmt.cpp
index 6dbe8f4d18..4222ce7edd 100644
--- a/lib/AST/Stmt.cpp
+++ b/lib/AST/Stmt.cpp
@@ -451,6 +451,15 @@ CXXTryStmt *CXXTryStmt::Create(ASTContext &C, SourceLocation tryLoc,
return new (Mem) CXXTryStmt(tryLoc, tryBlock, handlers, numHandlers);
}
+CXXTryStmt *CXXTryStmt::Create(ASTContext &C, EmptyShell Empty,
+ unsigned numHandlers) {
+ std::size_t Size = sizeof(CXXTryStmt);
+ Size += ((numHandlers + 1) * sizeof(Stmt));
+
+ void *Mem = C.Allocate(Size, llvm::alignof<CXXTryStmt>());
+ return new (Mem) CXXTryStmt(Empty, numHandlers);
+}
+
CXXTryStmt::CXXTryStmt(SourceLocation tryLoc, Stmt *tryBlock,
Stmt **handlers, unsigned numHandlers)
: Stmt(CXXTryStmtClass), TryLoc(tryLoc), NumHandlers(numHandlers) {
diff --git a/lib/Frontend/PCHReaderStmt.cpp b/lib/Frontend/PCHReaderStmt.cpp
index 03df4d78d9..65502b8e26 100644
--- a/lib/Frontend/PCHReaderStmt.cpp
+++ b/lib/Frontend/PCHReaderStmt.cpp
@@ -116,6 +116,10 @@ namespace clang {
void VisitObjCAtSynchronizedStmt(ObjCAtSynchronizedStmt *);
void VisitObjCAtThrowStmt(ObjCAtThrowStmt *);
+ // C++ Statements
+ void VisitCXXCatchStmt(CXXCatchStmt *S);
+ void VisitCXXTryStmt(CXXTryStmt *S);
+
void VisitCXXOperatorCallExpr(CXXOperatorCallExpr *E);
void VisitCXXConstructExpr(CXXConstructExpr *E);
void VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *E);
@@ -923,6 +927,24 @@ void PCHStmtReader::VisitObjCAtThrowStmt(ObjCAtThrowStmt *S) {
//===----------------------------------------------------------------------===//
// C++ Expressions and Statements
+//===----------------------------------------------------------------------===//
+
+void PCHStmtReader::VisitCXXCatchStmt(CXXCatchStmt *S) {
+ VisitStmt(S);
+ S->CatchLoc = Reader.ReadSourceLocation(Record, Idx);
+ S->ExceptionDecl = cast_or_null<VarDecl>(Reader.GetDecl(Record[Idx++]));
+ S->HandlerBlock = Reader.ReadSubStmt();
+}
+
+void PCHStmtReader::VisitCXXTryStmt(CXXTryStmt *S) {
+ VisitStmt(S);
+ assert(Record[Idx] == S->getNumHandlers() && "NumStmtFields is wrong ?");
+ ++Idx;
+ S->TryLoc = Reader.ReadSourceLocation(Record, Idx);
+ S->getStmts()[0] = Reader.ReadSubStmt();
+ for (unsigned i = 0, e = S->getNumHandlers(); i != e; ++i)
+ S->getStmts()[i + 1] = Reader.ReadSubStmt();
+}
void PCHStmtReader::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *E) {
VisitCallExpr(E);
@@ -1587,6 +1609,15 @@ Stmt *PCHReader::ReadStmtFromStream(llvm::BitstreamCursor &Cursor) {
S = new (Context) ObjCAtThrowStmt(Empty);
break;
+ case pch::STMT_CXX_CATCH:
+ S = new (Context) CXXCatchStmt(Empty);
+ break;
+
+ case pch::STMT_CXX_TRY:
+ S = CXXTryStmt::Create(*Context, Empty,
+ /*NumHandlers=*/Record[PCHStmtReader::NumStmtFields]);
+ break;
+
case pch::EXPR_CXX_OPERATOR_CALL:
S = new (Context) CXXOperatorCallExpr(*Context, Empty);
break;
diff --git a/lib/Frontend/PCHWriterStmt.cpp b/lib/Frontend/PCHWriterStmt.cpp
index 90e48c457f..e807ddff09 100644
--- a/lib/Frontend/PCHWriterStmt.cpp
+++ b/lib/Frontend/PCHWriterStmt.cpp
@@ -115,6 +115,9 @@ namespace clang {
void VisitObjCAtThrowStmt(ObjCAtThrowStmt *);
// C++ Statements
+ void VisitCXXCatchStmt(CXXCatchStmt *S);
+ void VisitCXXTryStmt(CXXTryStmt *S);
+
void VisitCXXOperatorCallExpr(CXXOperatorCallExpr *E);
void VisitCXXMemberCallExpr(CXXMemberCallExpr *E);
void VisitCXXConstructExpr(CXXConstructExpr *E);
@@ -929,6 +932,24 @@ void PCHStmtWriter::VisitObjCAtThrowStmt(ObjCAtThrowStmt *S) {
// C++ Expressions and Statements.
//===----------------------------------------------------------------------===//
+void PCHStmtWriter::VisitCXXCatchStmt(CXXCatchStmt *S) {
+ VisitStmt(S);
+ Writer.AddSourceLocation(S->getCatchLoc(), Record);
+ Writer.AddDeclRef(S->getExceptionDecl(), Record);
+ Writer.AddStmt(S->getHandlerBlock());
+ Code = pch::STMT_CXX_CATCH;
+}
+
+void PCHStmtWriter::VisitCXXTryStmt(CXXTryStmt *S) {
+ VisitStmt(S);
+ Record.push_back(S->getNumHandlers());
+ Writer.AddSourceLocation(S->getTryLoc(), Record);
+ Writer.AddStmt(S->getTryBlock());
+ for (unsigned i = 0, e = S->getNumHandlers(); i != e; ++i)
+ Writer.AddStmt(S->getHandler(i));
+ Code = pch::STMT_CXX_TRY;
+}
+
void PCHStmtWriter::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *E) {
VisitCallExpr(E);
Record.push_back(E->getOperator());
diff --git a/test/PCH/cxx-templates.h b/test/PCH/cxx-templates.h
index 42c47f0307..47fa11eb08 100644
--- a/test/PCH/cxx-templates.h
+++ b/test/PCH/cxx-templates.h
@@ -88,7 +88,8 @@ template<unsigned N>
bool isInt(int x);
template<> bool isInt<8>(int x) {
- return true;
+ try { ++x; } catch(...) { --x; }
+ return true;
}
template<typename _CharT>