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) {
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) {
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
};
#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"
/// \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();
#include <queue>
namespace llvm {
+ class APFloat;
class APInt;
class BitstreamWriter;
}
/// \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);
: 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);
};
}
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++])));
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++]);
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();
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;
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;
}
#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"
: 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);
};
}
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);
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());
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);
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;
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;
+
// 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 &&
// Definitions
int y = 17;
+double d = 17.42;
// Should not show up
static int z;