aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/clang/AST/ExprCXX.h7
-rw-r--r--include/clang/Frontend/PCHBitCodes.h4
-rw-r--r--lib/Frontend/PCHReaderStmt.cpp20
-rw-r--r--lib/Frontend/PCHWriterStmt.cpp16
-rw-r--r--test/PCH/cxx_exprs.h12
5 files changed, 57 insertions, 2 deletions
diff --git a/include/clang/AST/ExprCXX.h b/include/clang/AST/ExprCXX.h
index e6bc39419e..7e47c16f0d 100644
--- a/include/clang/AST/ExprCXX.h
+++ b/include/clang/AST/ExprCXX.h
@@ -387,6 +387,11 @@ public:
Type->isDependentType(), Type->isDependentType()),
Loc(L), Implicit(isImplicit) { }
+ CXXThisExpr(EmptyShell Empty) : Expr(CXXThisExprClass, Empty) {}
+
+ SourceLocation getLocation() const { return Loc; }
+ void setLocation(SourceLocation L) { Loc = L; }
+
virtual SourceRange getSourceRange() const { return SourceRange(Loc); }
bool isImplicit() const { return Implicit; }
@@ -415,6 +420,8 @@ public:
// can by null, if the optional expression to throw isn't present.
CXXThrowExpr(Expr *expr, QualType Ty, SourceLocation l) :
Expr(CXXThrowExprClass, Ty, false, false), Op(expr), ThrowLoc(l) {}
+ CXXThrowExpr(EmptyShell Empty) : Expr(CXXThrowExprClass, Empty) {}
+
const Expr *getSubExpr() const { return cast_or_null<Expr>(Op); }
Expr *getSubExpr() { return cast_or_null<Expr>(Op); }
void setSubExpr(Expr *E) { Op = E; }
diff --git a/include/clang/Frontend/PCHBitCodes.h b/include/clang/Frontend/PCHBitCodes.h
index 575881ad59..21bad01835 100644
--- a/include/clang/Frontend/PCHBitCodes.h
+++ b/include/clang/Frontend/PCHBitCodes.h
@@ -748,7 +748,9 @@ namespace clang {
EXPR_CXX_BOOL_LITERAL,
EXPR_CXX_NULL_PTR_LITERAL, // CXXNullPtrLiteralExpr
EXPR_CXX_TYPEID_EXPR, // CXXTypeidExpr (of expr).
- EXPR_CXX_TYPEID_TYPE // CXXTypeidExpr (of type).
+ EXPR_CXX_TYPEID_TYPE, // CXXTypeidExpr (of type).
+ EXPR_CXX_THIS, // CXXThisExpr
+ EXPR_CXX_THROW // CXXThrowExpr
};
/// \brief The kinds of designators that can occur in a
diff --git a/lib/Frontend/PCHReaderStmt.cpp b/lib/Frontend/PCHReaderStmt.cpp
index cce2e262de..c3cc504a1a 100644
--- a/lib/Frontend/PCHReaderStmt.cpp
+++ b/lib/Frontend/PCHReaderStmt.cpp
@@ -127,6 +127,8 @@ namespace {
unsigned VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *E);
unsigned VisitCXXNullPtrLiteralExpr(CXXNullPtrLiteralExpr *E);
unsigned VisitCXXTypeidExpr(CXXTypeidExpr *E);
+ unsigned VisitCXXThisExpr(CXXThisExpr *E);
+ unsigned VisitCXXThrowExpr(CXXThrowExpr *E);
};
}
@@ -1005,6 +1007,18 @@ unsigned PCHStmtReader::VisitCXXTypeidExpr(CXXTypeidExpr *E) {
return 1;
}
+unsigned PCHStmtReader::VisitCXXThisExpr(CXXThisExpr *E) {
+ VisitExpr(E);
+ E->setLocation(SourceLocation::getFromRawEncoding(Record[Idx++]));
+ E->setImplicit(Record[Idx++]);
+ return 0;
+}
+
+unsigned PCHStmtReader::VisitCXXThrowExpr(CXXThrowExpr *E) {
+ VisitExpr(E);
+ E->setThrowLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+ return 1;
+}
// Within the bitstream, expressions are stored in Reverse Polish
// Notation, with each of the subexpressions preceding the
@@ -1361,6 +1375,12 @@ Stmt *PCHReader::ReadStmt(llvm::BitstreamCursor &Cursor) {
case pch::EXPR_CXX_TYPEID_TYPE:
S = new (Context) CXXTypeidExpr(Empty, false);
break;
+ case pch::EXPR_CXX_THIS:
+ S = new (Context) CXXThisExpr(Empty);
+ break;
+ case pch::EXPR_CXX_THROW:
+ S = new (Context) CXXThrowExpr(Empty);
+ break;
}
// We hit a STMT_STOP, so we're done with this expression.
diff --git a/lib/Frontend/PCHWriterStmt.cpp b/lib/Frontend/PCHWriterStmt.cpp
index 1e272c3c66..e042e77c6b 100644
--- a/lib/Frontend/PCHWriterStmt.cpp
+++ b/lib/Frontend/PCHWriterStmt.cpp
@@ -123,6 +123,8 @@ namespace {
void VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *E);
void VisitCXXNullPtrLiteralExpr(CXXNullPtrLiteralExpr *E);
void VisitCXXTypeidExpr(CXXTypeidExpr *E);
+ void VisitCXXThisExpr(CXXThisExpr *E);
+ void VisitCXXThrowExpr(CXXThrowExpr *E);
};
}
@@ -924,6 +926,20 @@ void PCHStmtWriter::VisitCXXTypeidExpr(CXXTypeidExpr *E) {
}
}
+void PCHStmtWriter::VisitCXXThisExpr(CXXThisExpr *E) {
+ VisitExpr(E);
+ Writer.AddSourceLocation(E->getLocation(), Record);
+ Record.push_back(E->isImplicit());
+ Code = pch::EXPR_CXX_THIS;
+}
+
+void PCHStmtWriter::VisitCXXThrowExpr(CXXThrowExpr *E) {
+ Writer.AddSourceLocation(E->getThrowLoc(), Record);
+ Writer.WriteSubStmt(E->getSubExpr());
+ Code = pch::EXPR_CXX_THROW;
+}
+
+
//===----------------------------------------------------------------------===//
// PCHWriter Implementation
//===----------------------------------------------------------------------===//
diff --git a/test/PCH/cxx_exprs.h b/test/PCH/cxx_exprs.h
index 4f01b3aff6..bda23613ad 100644
--- a/test/PCH/cxx_exprs.h
+++ b/test/PCH/cxx_exprs.h
@@ -6,7 +6,7 @@ typedef __typeof__(static_cast<void *>(0)) static_cast_result;
// CXXDynamicCastExpr
struct Base { virtual void f(); };
-struct Derived : Base { };
+struct Derived : Base { void g(); };
Base *base_ptr;
typedef __typeof__(dynamic_cast<Derived *>(base_ptr)) dynamic_cast_result;
@@ -43,3 +43,13 @@ namespace std {
// CXXTypeidExpr - Both expr and type forms.
typedef __typeof__(typeid(int))* typeid_result1;
typedef __typeof__(typeid(2))* typeid_result2;
+
+void Derived::g() {
+ // CXXThisExpr
+ f(); // Implicit
+ this->f(); // Explicit
+
+ // CXXThrowExpr
+ throw;
+ throw 42;
+} \ No newline at end of file