diff options
-rw-r--r-- | include/clang/AST/Expr.h | 21 | ||||
-rw-r--r-- | include/clang/Frontend/PCHBitCodes.h | 4 | ||||
-rw-r--r-- | include/clang/Frontend/PCHReader.h | 4 | ||||
-rw-r--r-- | include/clang/Frontend/PCHWriter.h | 4 | ||||
-rw-r--r-- | lib/Frontend/PCHReader.cpp | 34 | ||||
-rw-r--r-- | lib/Frontend/PCHWriter.cpp | 23 | ||||
-rw-r--r-- | test/PCH/exprs.c | 9 | ||||
-rw-r--r-- | test/PCH/exprs.h | 8 | ||||
-rw-r--r-- | test/PCH/external-defs.c | 1 | ||||
-rw-r--r-- | test/PCH/external-defs.h | 1 |
10 files changed, 99 insertions, 10 deletions
diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h index 7001e290fc..f7893d75d7 100644 --- a/include/clang/AST/Expr.h +++ b/include/clang/AST/Expr.h @@ -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) { diff --git a/include/clang/Frontend/PCHBitCodes.h b/include/clang/Frontend/PCHBitCodes.h index 54f686bbb0..0184a7e9b1 100644 --- a/include/clang/Frontend/PCHBitCodes.h +++ b/include/clang/Frontend/PCHBitCodes.h @@ -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 }; diff --git a/include/clang/Frontend/PCHReader.h b/include/clang/Frontend/PCHReader.h index b9596b6de2..e11c2edb10 100644 --- a/include/clang/Frontend/PCHReader.h +++ b/include/clang/Frontend/PCHReader.h @@ -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(); diff --git a/include/clang/Frontend/PCHWriter.h b/include/clang/Frontend/PCHWriter.h index 4713b1e490..edac6bc001 100644 --- a/include/clang/Frontend/PCHWriter.h +++ b/include/clang/Frontend/PCHWriter.h @@ -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); diff --git a/lib/Frontend/PCHReader.cpp b/lib/Frontend/PCHReader.cpp index 909ecdb100..bc754cb845 100644 --- a/lib/Frontend/PCHReader.cpp +++ b/lib/Frontend/PCHReader.cpp @@ -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; } diff --git a/lib/Frontend/PCHWriter.cpp b/lib/Frontend/PCHWriter.cpp index 1cf98cea9c..20aee9c441 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 @@ 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); diff --git a/test/PCH/exprs.c b/test/PCH/exprs.c index d1cd5636b8..faab79dfe3 100644 --- a/test/PCH/exprs.c +++ b/test/PCH/exprs.c @@ -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; diff --git a/test/PCH/exprs.h b/test/PCH/exprs.h index db6513c35b..36660cc0a4 100644 --- a/test/PCH/exprs.h +++ b/test/PCH/exprs.h @@ -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; + diff --git a/test/PCH/external-defs.c b/test/PCH/external-defs.c index 5af21af517..6a46f45cc1 100644 --- a/test/PCH/external-defs.c +++ b/test/PCH/external-defs.c @@ -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 && diff --git a/test/PCH/external-defs.h b/test/PCH/external-defs.h index 06c4601ccb..4d233e2a40 100644 --- a/test/PCH/external-defs.h +++ b/test/PCH/external-defs.h @@ -6,6 +6,7 @@ int x2; // Definitions int y = 17; +double d = 17.42; // Should not show up static int z; |