Add PCH support for PredefinedExpr and FloatingLiteral expressions

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@69084 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Frontend/PCHReader.cpp b/lib/Frontend/PCHReader.cpp
index 909ecdb..bc754cb 100644
--- a/lib/Frontend/PCHReader.cpp
+++ b/lib/Frontend/PCHReader.cpp
@@ -226,8 +226,10 @@
       : Reader(Reader), Record(Record), Idx(Idx) { }
 
     void VisitExpr(Expr *E);
+    void VisitPredefinedExpr(PredefinedExpr *E);
     void VisitDeclRefExpr(DeclRefExpr *E);
     void VisitIntegerLiteral(IntegerLiteral *E);
+    void VisitFloatingLiteral(FloatingLiteral *E);
     void VisitCharacterLiteral(CharacterLiteral *E);
   };
 }
@@ -238,6 +240,12 @@
   E->setValueDependent(Record[Idx++]);
 }
 
+void PCHStmtReader::VisitPredefinedExpr(PredefinedExpr *E) {
+  VisitExpr(E);
+  E->setLocation(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  E->setIdentType((PredefinedExpr::IdentType)Record[Idx++]);
+}
+
 void PCHStmtReader::VisitDeclRefExpr(DeclRefExpr *E) {
   VisitExpr(E);
   E->setDecl(cast<NamedDecl>(Reader.GetDecl(Record[Idx++])));
@@ -250,6 +258,13 @@
   E->setValue(Reader.ReadAPInt(Record, Idx));
 }
 
+void PCHStmtReader::VisitFloatingLiteral(FloatingLiteral *E) {
+  VisitExpr(E);
+  E->setValue(Reader.ReadAPFloat(Record, Idx));
+  E->setExact(Record[Idx++]);
+  E->setLocation(SourceLocation::getFromRawEncoding(Record[Idx++]));
+}
+
 void PCHStmtReader::VisitCharacterLiteral(CharacterLiteral *E) {
   VisitExpr(E);
   E->setValue(Record[Idx++]);
@@ -1484,6 +1499,12 @@
   return llvm::APSInt(ReadAPInt(Record, Idx), isUnsigned);
 }
 
+/// \brief Read a floating-point value
+llvm::APFloat PCHReader::ReadAPFloat(const RecordData &Record, unsigned &Idx) {
+  // FIXME: is this really correct?
+  return llvm::APFloat(ReadAPInt(Record, Idx));
+}
+
 Expr *PCHReader::ReadExpr() {
   RecordData Record;
   unsigned Code = Stream.ReadCode();
@@ -1497,6 +1518,11 @@
     E = 0; 
     break;
 
+  case pch::EXPR_PREDEFINED:
+    // FIXME: untested (until we can serialize function bodies).
+    E = new (Context) PredefinedExpr(Empty);
+    break;
+
   case pch::EXPR_DECL_REF: 
     E = new (Context) DeclRefExpr(Empty); 
     break;
@@ -1505,12 +1531,12 @@
     E = new (Context) IntegerLiteral(Empty);
     break;
 
-  case pch::EXPR_CHARACTER_LITERAL:
-    E = new (Context) CharacterLiteral(Empty);
+  case pch::EXPR_FLOATING_LITERAL:
+    E = new (Context) FloatingLiteral(Empty);
     break;
 
-  default:
-    assert(false && "Unhandled expression kind");
+  case pch::EXPR_CHARACTER_LITERAL:
+    E = new (Context) CharacterLiteral(Empty);
     break;
   }
 
diff --git a/lib/Frontend/PCHWriter.cpp b/lib/Frontend/PCHWriter.cpp
index 1cf98ce..20aee9c 100644
--- a/lib/Frontend/PCHWriter.cpp
+++ b/lib/Frontend/PCHWriter.cpp
@@ -25,6 +25,8 @@
 #include "clang/Basic/SourceManager.h"
 #include "clang/Basic/SourceManagerInternals.h"
 #include "clang/Basic/TargetInfo.h"
+#include "llvm/ADT/APFloat.h"
+#include "llvm/ADT/APInt.h"
 #include "llvm/Bitcode/BitstreamWriter.h"
 #include "llvm/Support/Compiler.h"
 #include "llvm/Support/MemoryBuffer.h"
@@ -442,8 +444,10 @@
       : Writer(Writer), Record(Record) { }
 
     void VisitExpr(Expr *E);
+    void VisitPredefinedExpr(PredefinedExpr *E);
     void VisitDeclRefExpr(DeclRefExpr *E);
     void VisitIntegerLiteral(IntegerLiteral *E);
+    void VisitFloatingLiteral(FloatingLiteral *E);
     void VisitCharacterLiteral(CharacterLiteral *E);
   };
 }
@@ -454,6 +458,13 @@
   Record.push_back(E->isValueDependent());
 }
 
+void PCHStmtWriter::VisitPredefinedExpr(PredefinedExpr *E) {
+  VisitExpr(E);
+  Writer.AddSourceLocation(E->getLocation(), Record);
+  Record.push_back(E->getIdentType()); // FIXME: stable encoding
+  Code = pch::EXPR_PREDEFINED;
+}
+
 void PCHStmtWriter::VisitDeclRefExpr(DeclRefExpr *E) {
   VisitExpr(E);
   Writer.AddDeclRef(E->getDecl(), Record);
@@ -468,6 +479,14 @@
   Code = pch::EXPR_INTEGER_LITERAL;
 }
 
+void PCHStmtWriter::VisitFloatingLiteral(FloatingLiteral *E) {
+  VisitExpr(E);
+  Writer.AddAPFloat(E->getValue(), Record);
+  Record.push_back(E->isExact());
+  Writer.AddSourceLocation(E->getLocation(), Record);
+  Code = pch::EXPR_FLOATING_LITERAL;
+}
+
 void PCHStmtWriter::VisitCharacterLiteral(CharacterLiteral *E) {
   VisitExpr(E);
   Record.push_back(E->getValue());
@@ -1120,6 +1139,10 @@
   AddAPInt(Value, Record);
 }
 
+void PCHWriter::AddAPFloat(const llvm::APFloat &Value, RecordData &Record) {
+  AddAPInt(Value.bitcastToAPInt(), Record);
+}
+
 void PCHWriter::AddIdentifierRef(const IdentifierInfo *II, RecordData &Record) {
   if (II == 0) {
     Record.push_back(0);