]> granicus.if.org Git - clang/commitdiff
Add PCH support for PredefinedExpr and FloatingLiteral expressions
authorDouglas Gregor <dgregor@apple.com>
Tue, 14 Apr 2009 21:55:33 +0000 (21:55 +0000)
committerDouglas Gregor <dgregor@apple.com>
Tue, 14 Apr 2009 21:55:33 +0000 (21:55 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@69084 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/AST/Expr.h
include/clang/Frontend/PCHBitCodes.h
include/clang/Frontend/PCHReader.h
include/clang/Frontend/PCHWriter.h
lib/Frontend/PCHReader.cpp
lib/Frontend/PCHWriter.cpp
test/PCH/exprs.c
test/PCH/exprs.h
test/PCH/external-defs.c
test/PCH/external-defs.h

index 7001e290fce3c019942bde09b18a69779332859a..f7893d75d7a3b87c936346f35bd02a5241b84130 100644 (file)
@@ -367,8 +367,16 @@ public:
   PredefinedExpr(SourceLocation l, QualType type, IdentType IT) 
     : Expr(PredefinedExprClass, type), Loc(l), Type(IT) {}
   
+  /// \brief Construct an empty predefined expression.
+  explicit PredefinedExpr(EmptyShell Empty) 
+    : Expr(PredefinedExprClass, Empty) { }
+
   IdentType getIdentType() const { return Type; }
-  
+  void setIdentType(IdentType IT) { Type = IT; }
+
+  SourceLocation getLocation() const { return Loc; }
+  void setLocation(SourceLocation L) { Loc = L; }
+
   virtual SourceRange getSourceRange() const { return SourceRange(Loc); }
 
   static bool classof(const Stmt *T) { 
@@ -469,15 +477,24 @@ public:
                   QualType Type, SourceLocation L)
     : Expr(FloatingLiteralClass, Type), Value(V), IsExact(*isexact), Loc(L) {} 
 
+  /// \brief Construct an empty floating-point literal.
+  FloatingLiteral(EmptyShell Empty) 
+    : Expr(FloatingLiteralClass, Empty), Value(0.0) { }
+
   const llvm::APFloat &getValue() const { return Value; }
-  
+  void setValue(const llvm::APFloat &Val) { Value = Val; }
+
   bool isExact() const { return IsExact; }
+  void setExact(bool E) { IsExact = E; }
 
   /// getValueAsApproximateDouble - This returns the value as an inaccurate
   /// double.  Note that this may cause loss of precision, but is useful for
   /// debugging dumps, etc.
   double getValueAsApproximateDouble() const;
  
+  SourceLocation getLocation() const { return Loc; }
+  void setLocation(SourceLocation L) { Loc = L; }
+
   virtual SourceRange getSourceRange() const { return SourceRange(Loc); }
 
   static bool classof(const Stmt *T) { 
index 54f686bbb08a2eb4c389a776bd008b935e48380b..0184a7e9b118f19be595091c04947f914594b0f2 100644 (file)
@@ -370,10 +370,14 @@ namespace clang {
     enum StmtCode {
       /// \brief A NULL expression.
       EXPR_NULL = 100,
+      /// \brief A PredefinedExpr record.
+      EXPR_PREDEFINED,
       /// \brief A DeclRefExpr record.
       EXPR_DECL_REF,
       /// \brief An IntegerLiteral record.
       EXPR_INTEGER_LITERAL,
+      /// \brief A FloatingLiteral record.
+      EXPR_FLOATING_LITERAL,
       /// \brief A CharacterLiteral record.
       EXPR_CHARACTER_LITERAL
     };
index b9596b6de2672e6c6dc8cfd145024f61d5543717..e11c2edb10194d86c83609cd05a68ca35a7c1ca5 100644 (file)
@@ -18,6 +18,7 @@
 #include "clang/AST/ExternalASTSource.h"
 #include "clang/AST/Type.h"
 #include "clang/Basic/Diagnostic.h"
+#include "llvm/ADT/APFloat.h"
 #include "llvm/ADT/APInt.h"
 #include "llvm/ADT/APSInt.h"
 #include "llvm/ADT/DenseMap.h"
@@ -221,6 +222,9 @@ public:
   /// \brief Read a signed integral value
   llvm::APSInt ReadAPSInt(const RecordData &Record, unsigned &Idx);
 
+  /// \brief Read a floating-point value
+  llvm::APFloat ReadAPFloat(const RecordData &Record, unsigned &Idx);
+
   /// \brief Reads an expression from the current stream position.
   Expr *ReadExpr();
 
index 4713b1e4900a6bc0ad5699a46c486306bfd98b65..edac6bc001f13b5573c001601fcfa6e9557eda41 100644 (file)
@@ -23,6 +23,7 @@
 #include <queue>
 
 namespace llvm {
+  class APFloat;
   class APInt;
   class BitstreamWriter;
 }
@@ -138,6 +139,9 @@ public:
   /// \brief Emit a signed integral value.
   void AddAPSInt(const llvm::APSInt &Value, RecordData &Record);
 
+  /// \brief Emit a floating-point value.
+  void AddAPFloat(const llvm::APFloat &Value, RecordData &Record);
+
   /// \brief Emit a reference to an identifier
   void AddIdentifierRef(const IdentifierInfo *II, RecordData &Record);
 
index 909ecdb100c6d21d648bcf8c5034a4966ebb5993..bc754cb845ffaa71762633bc98494bfc26222747 100644 (file)
@@ -226,8 +226,10 @@ namespace {
       : 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 @@ void PCHStmtReader::VisitExpr(Expr *E) {
   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 @@ void PCHStmtReader::VisitIntegerLiteral(IntegerLiteral *E) {
   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 @@ llvm::APSInt PCHReader::ReadAPSInt(const RecordData &Record, unsigned &Idx) {
   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 @@ Expr *PCHReader::ReadExpr() {
     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 @@ Expr *PCHReader::ReadExpr() {
     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;
   }
 
index 1cf98cea9ca89ec0c6e454c30a244ac43ee39e45..20aee9c441960234560a8f77c2e8aaa7dfcb0226 100644 (file)
@@ -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 @@ namespace {
       : 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 @@ void PCHStmtWriter::VisitExpr(Expr *E) {
   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 @@ void PCHStmtWriter::VisitIntegerLiteral(IntegerLiteral *E) {
   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 @@ void PCHWriter::AddAPSInt(const llvm::APSInt &Value, RecordData &Record) {
   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);
index d1cd5636b89a0f510d05a2d1e6b9dbaa2fd9f69c..faab79dfe3ff5970fd416b6371d9129e01ab85b6 100644 (file)
@@ -7,13 +7,18 @@
 
 int integer;
 long long_integer;
+double floating;
 
 // DeclRefExpr
 int_decl_ref *int_ptr1 = &integer;
 enum_decl_ref *enum_ptr1 = &integer;
-// IntegerLiteralExpr
+
+// IntegerLiteral
 integer_literal *int_ptr2 = &integer;
 long_literal *long_ptr1 = &long_integer;
 
-// CharacterLiteralExpr
+// FloatingLiteral
+floating_literal *double_ptr = &floating;
+
+// CharacterLiteral
 char_literal *int_ptr3 = &integer;
index db6513c35bdef76dbb1730e185b941cd0068334e..36660cc0a49edb045ef975f341c6e255f356094b 100644 (file)
@@ -6,9 +6,13 @@ enum Enum { Enumerator = 18 };
 typedef typeof(i) int_decl_ref;
 typedef typeof(Enumerator) enum_decl_ref;
 
-// IntegerLiteralExpr
+// IntegerLiteral
 typedef typeof(17) integer_literal;
 typedef typeof(17l) long_literal;
 
-// CharacterLiteralExpr
+// FloatingLiteral
+typedef typeof(42.5) floating_literal;
+
+// CharacterLiteral
 typedef typeof('a') char_literal;
+
index 5af21af517a21108fd67d3823f1d3fe7437b5ade..6a46f45cc1e57d8694ed4f541d880835a9dcbceb 100644 (file)
@@ -4,6 +4,7 @@
 
 // RUN: grep "@x = common global i32 0" %t | count 1 &&
 // RUN: grep "@y = global i32 17"  %t | count 1 &&
+// RUN: grep "@d = .*1.742"  %t | count 1 &&
 // RUN: grep "@z" %t | count 0 &&
 
 // RUN: grep "@x2 = global i32 19" %t | count 1 &&
index 06c4601ccb32bc8e517763a7212af87ff83bf8f5..4d233e2a4049abeaaf7827856a70d7343000e998 100644 (file)
@@ -6,6 +6,7 @@ int x2;
 
 // Definitions
 int y = 17;
+double d = 17.42;
 
 // Should not show up
 static int z;