Add PCH support for CXXStaticCastExpr, CXXDynamicCastExpr, CXXReinterpretCastExpr, CXXConstCastExpr and CXXFunctionalCastExpr.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@93658 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/clang/AST/ExprCXX.h b/include/clang/AST/ExprCXX.h
index 699c1f5..ab22ba3 100644
--- a/include/clang/AST/ExprCXX.h
+++ b/include/clang/AST/ExprCXX.h
@@ -121,6 +121,9 @@
                    TypeSourceInfo *writtenTy, SourceLocation l)
     : ExplicitCastExpr(SC, ty, kind, op, writtenTy), Loc(l) {}
 
+  explicit CXXNamedCastExpr(StmtClass SC, EmptyShell Shell)
+    : ExplicitCastExpr(SC, Shell) { }
+
 public:
   const char *getCastName() const;
 
@@ -157,6 +160,9 @@
                     TypeSourceInfo *writtenTy, SourceLocation l)
     : CXXNamedCastExpr(CXXStaticCastExprClass, ty, kind, op, writtenTy, l) {}
 
+  explicit CXXStaticCastExpr(EmptyShell Empty)
+    : CXXNamedCastExpr(CXXStaticCastExprClass, Empty) { }
+
   static bool classof(const Stmt *T) {
     return T->getStmtClass() == CXXStaticCastExprClass;
   }
@@ -175,6 +181,9 @@
                      TypeSourceInfo *writtenTy, SourceLocation l)
     : CXXNamedCastExpr(CXXDynamicCastExprClass, ty, kind, op, writtenTy, l) {}
 
+  explicit CXXDynamicCastExpr(EmptyShell Empty)
+    : CXXNamedCastExpr(CXXDynamicCastExprClass, Empty) { }
+
   static bool classof(const Stmt *T) {
     return T->getStmtClass() == CXXDynamicCastExprClass;
   }
@@ -194,6 +203,9 @@
     : CXXNamedCastExpr(CXXReinterpretCastExprClass, ty, kind, op,
                        writtenTy, l) {}
 
+  explicit CXXReinterpretCastExpr(EmptyShell Empty)
+    : CXXNamedCastExpr(CXXReinterpretCastExprClass, Empty) { }
+
   static bool classof(const Stmt *T) {
     return T->getStmtClass() == CXXReinterpretCastExprClass;
   }
@@ -211,6 +223,9 @@
                    SourceLocation l)
     : CXXNamedCastExpr(CXXConstCastExprClass, ty, CK_NoOp, op, writtenTy, l) {}
 
+  explicit CXXConstCastExpr(EmptyShell Empty)
+    : CXXNamedCastExpr(CXXConstCastExprClass, Empty) { }
+
   static bool classof(const Stmt *T) {
     return T->getStmtClass() == CXXConstCastExprClass;
   }
@@ -632,8 +647,13 @@
                        writtenTy),
       TyBeginLoc(tyBeginLoc), RParenLoc(rParenLoc) {}
 
+  explicit CXXFunctionalCastExpr(EmptyShell Shell)
+    : ExplicitCastExpr(CXXFunctionalCastExprClass, Shell) { }
+
   SourceLocation getTypeBeginLoc() const { return TyBeginLoc; }
+  void setTypeBeginLoc(SourceLocation L) { TyBeginLoc = L; }
   SourceLocation getRParenLoc() const { return RParenLoc; }
+  void setRParenLoc(SourceLocation L) { RParenLoc = L; }
 
   virtual SourceRange getSourceRange() const {
     return SourceRange(TyBeginLoc, RParenLoc);
diff --git a/include/clang/Frontend/PCHBitCodes.h b/include/clang/Frontend/PCHBitCodes.h
index 536bd41..d9d74dc 100644
--- a/include/clang/Frontend/PCHBitCodes.h
+++ b/include/clang/Frontend/PCHBitCodes.h
@@ -676,7 +676,17 @@
       /// \brief A CXXOperatorCallExpr record.
       EXPR_CXX_OPERATOR_CALL,
       /// \brief A CXXConstructExpr record.
-      EXPR_CXX_CONSTRUCT
+      EXPR_CXX_CONSTRUCT,
+      // \brief A CXXStaticCastExpr record.
+      EXPR_CXX_STATIC_CAST,
+      // \brief A CXXDynamicCastExpr record.
+      EXPR_CXX_DYNAMIC_CAST,
+      // \brief A CXXReinterpretCastExpr record.
+      EXPR_CXX_REINTERPRET_CAST,
+      // \brief A CXXConstCastExpr record.
+      EXPR_CXX_CONST_CAST,
+      // \brief A CXXFunctionalCastExpr record.
+      EXPR_CXX_FUNCTIONAL_CAST
     };
 
     /// \brief The kinds of designators that can occur in a
diff --git a/lib/Frontend/PCHReaderStmt.cpp b/lib/Frontend/PCHReaderStmt.cpp
index ff985c3..c49f5e8 100644
--- a/lib/Frontend/PCHReaderStmt.cpp
+++ b/lib/Frontend/PCHReaderStmt.cpp
@@ -117,6 +117,12 @@
 
     unsigned VisitCXXOperatorCallExpr(CXXOperatorCallExpr *E);
     unsigned VisitCXXConstructExpr(CXXConstructExpr *E);
+    unsigned VisitCXXNamedCastExpr(CXXNamedCastExpr *E);
+    unsigned VisitCXXStaticCastExpr(CXXStaticCastExpr *E);
+    unsigned VisitCXXDynamicCastExpr(CXXDynamicCastExpr *E);
+    unsigned VisitCXXReinterpretCastExpr(CXXReinterpretCastExpr *E);
+    unsigned VisitCXXConstCastExpr(CXXConstCastExpr *E);
+    unsigned VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *E);
   };
 }
 
@@ -868,6 +874,35 @@
   return E->getNumArgs();
 }
 
+unsigned PCHStmtReader::VisitCXXNamedCastExpr(CXXNamedCastExpr *E) {
+  unsigned num = VisitExplicitCastExpr(E);
+  E->setOperatorLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  return num;
+}
+
+unsigned PCHStmtReader::VisitCXXStaticCastExpr(CXXStaticCastExpr *E) {
+  return VisitCXXNamedCastExpr(E);
+}
+
+unsigned PCHStmtReader::VisitCXXDynamicCastExpr(CXXDynamicCastExpr *E) {
+  return VisitCXXNamedCastExpr(E);
+}
+
+unsigned PCHStmtReader::VisitCXXReinterpretCastExpr(CXXReinterpretCastExpr *E) {
+  return VisitCXXNamedCastExpr(E);
+}
+
+unsigned PCHStmtReader::VisitCXXConstCastExpr(CXXConstCastExpr *E) {
+  return VisitCXXNamedCastExpr(E);
+}
+
+unsigned PCHStmtReader::VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *E) {
+  unsigned num = VisitExplicitCastExpr(E);
+  E->setTypeBeginLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  E->setRParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  return num;
+}
+
 // Within the bitstream, expressions are stored in Reverse Polish
 // Notation, with each of the subexpressions preceding the
 // expression they are stored in. To evaluate expressions, we
@@ -1176,6 +1211,28 @@
       S = new (Context) CXXConstructExpr(Empty, *Context,
                                       Record[PCHStmtReader::NumExprFields + 2]);
       break;
+
+    case pch::EXPR_CXX_STATIC_CAST:
+      S = new (Context) CXXStaticCastExpr(Empty);
+      break;
+
+    case pch::EXPR_CXX_DYNAMIC_CAST:
+      S = new (Context) CXXDynamicCastExpr(Empty);
+      break;
+
+    case pch::EXPR_CXX_REINTERPRET_CAST:
+      S = new (Context) CXXReinterpretCastExpr(Empty);
+      break;
+
+    case pch::EXPR_CXX_CONST_CAST:
+      S = new (Context) CXXConstCastExpr(Empty);
+      break;
+
+    case pch::EXPR_CXX_FUNCTIONAL_CAST:
+      S = new (Context) CXXFunctionalCastExpr(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 2174aa5..a5ad859 100644
--- a/lib/Frontend/PCHWriterStmt.cpp
+++ b/lib/Frontend/PCHWriterStmt.cpp
@@ -112,6 +112,12 @@
     // C++ Statements
     void VisitCXXOperatorCallExpr(CXXOperatorCallExpr *E);
     void VisitCXXConstructExpr(CXXConstructExpr *E);
+    void VisitCXXNamedCastExpr(CXXNamedCastExpr *E);
+    void VisitCXXStaticCastExpr(CXXStaticCastExpr *E);
+    void VisitCXXDynamicCastExpr(CXXDynamicCastExpr *E);
+    void VisitCXXReinterpretCastExpr(CXXReinterpretCastExpr *E);
+    void VisitCXXConstCastExpr(CXXConstCastExpr *E);
+    void VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *E);
   };
 }
 
@@ -795,6 +801,38 @@
   Code = pch::EXPR_CXX_CONSTRUCT;
 }
 
+void PCHStmtWriter::VisitCXXNamedCastExpr(CXXNamedCastExpr *E) {
+  VisitExplicitCastExpr(E);
+  Writer.AddSourceLocation(E->getOperatorLoc(), Record);
+}
+
+void PCHStmtWriter::VisitCXXStaticCastExpr(CXXStaticCastExpr *E) {
+  VisitCXXNamedCastExpr(E);
+  Code = pch::EXPR_CXX_STATIC_CAST;
+}
+
+void PCHStmtWriter::VisitCXXDynamicCastExpr(CXXDynamicCastExpr *E) {
+  VisitCXXNamedCastExpr(E);
+  Code = pch::EXPR_CXX_DYNAMIC_CAST;
+}
+
+void PCHStmtWriter::VisitCXXReinterpretCastExpr(CXXReinterpretCastExpr *E) {
+  VisitCXXNamedCastExpr(E);
+  Code = pch::EXPR_CXX_REINTERPRET_CAST;
+}
+
+void PCHStmtWriter::VisitCXXConstCastExpr(CXXConstCastExpr *E) {
+  VisitCXXNamedCastExpr(E);
+  Code = pch::EXPR_CXX_CONST_CAST;
+}
+
+void PCHStmtWriter::VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *E) {
+  VisitExplicitCastExpr(E);
+  Writer.AddSourceLocation(E->getTypeBeginLoc(), Record);
+  Writer.AddSourceLocation(E->getRParenLoc(), Record);
+  Code = pch::EXPR_CXX_FUNCTIONAL_CAST;
+}
+
 //===----------------------------------------------------------------------===//
 // PCHWriter Implementation
 //===----------------------------------------------------------------------===//
diff --git a/test/PCH/cxx_exprs.cpp b/test/PCH/cxx_exprs.cpp
new file mode 100644
index 0000000..51269d5
--- /dev/null
+++ b/test/PCH/cxx_exprs.cpp
@@ -0,0 +1,26 @@
+// Test this without pch.
+// RUN: %clang_cc1 -include %S/cxx_exprs.h -fsyntax-only -verify %s
+
+// Test with pch.
+// RUN: %clang_cc1 -x c++-header -emit-pch -o %t %S/cxx_exprs.h
+// RUN: %clang_cc1 -include-pch %t -fsyntax-only -verify %s 
+
+int integer;
+double floating;
+char character;
+
+// CXXStaticCastExpr
+static_cast_result void_ptr = &integer;
+
+// CXXDynamicCastExpr
+Derived *d;
+dynamic_cast_result derived_ptr = d;
+
+// CXXReinterpretCastExpr
+reinterpret_cast_result void_ptr2 = &integer;
+
+// CXXConstCastExpr
+const_cast_result char_ptr = &character;
+
+// CXXFunctionalCastExpr
+functional_cast_result *double_ptr = &floating;
diff --git a/test/PCH/cxx_exprs.h b/test/PCH/cxx_exprs.h
new file mode 100644
index 0000000..b649428
--- /dev/null
+++ b/test/PCH/cxx_exprs.h
@@ -0,0 +1,21 @@
+// Header for PCH test cxx_exprs.cpp
+
+// CXXStaticCastExpr
+typedef typeof(static_cast<void *>(0)) static_cast_result;
+
+// CXXDynamicCastExpr
+struct Base { virtual void f(); };
+struct Derived : Base { };
+Base *base_ptr;
+typedef typeof(dynamic_cast<Derived *>(base_ptr)) dynamic_cast_result;
+
+// CXXReinterpretCastExpr
+typedef typeof(reinterpret_cast<void *>(0)) reinterpret_cast_result;
+
+// CXXConstCastExpr
+const char *const_char_ptr_value;
+typedef typeof(const_cast<char *>(const_char_ptr_value)) const_cast_result;
+
+// CXXFunctionalCastExpr
+int int_value;
+typedef typeof(double(int_value)) functional_cast_result;