r363493 - [clang] Add storage for APValue in ConstantExpr
Gauthier Harnisch via cfe-commits
cfe-commits at lists.llvm.org
Sat Jun 15 03:24:48 PDT 2019
Author: tyker
Date: Sat Jun 15 03:24:47 2019
New Revision: 363493
URL: http://llvm.org/viewvc/llvm-project?rev=363493&view=rev
Log:
[clang] Add storage for APValue in ConstantExpr
Summary:
When using ConstantExpr we often need the result of the expression to be kept in the AST. Currently this is done on a by the node that needs the result and has been done multiple times for enumerator, for constexpr variables... . This patch adds to ConstantExpr the ability to store the result of evaluating the expression. no functional changes expected.
Changes:
- Add trailling object to ConstantExpr that can hold an APValue or an uint64_t. the uint64_t is here because most ConstantExpr yield integral values so there is an optimized layout for integral values.
- Add basic* serialization support for the trailing result.
- Move conversion functions from an enum to a fltSemantics from clang::FloatingLiteral to llvm::APFloatBase. this change is to make it usable for serializing APValues.
- Add basic* Import support for the trailing result.
- ConstantExpr created in CheckConvertedConstantExpression now stores the result in the ConstantExpr Node.
- Adapt AST dump to print the result when present.
basic* : None, Indeterminate, Int, Float, FixedPoint, ComplexInt, ComplexFloat,
the result is not yet used anywhere but for -ast-dump.
Reviewers: rsmith, martong, shafik
Reviewed By: rsmith
Subscribers: rnkovacs, hiraditya, dexonsmith, cfe-commits, llvm-commits
Tags: #clang, #llvm
Differential Revision: https://reviews.llvm.org/D62399
Modified:
cfe/trunk/include/clang/AST/APValue.h
cfe/trunk/include/clang/AST/ASTContext.h
cfe/trunk/include/clang/AST/Expr.h
cfe/trunk/include/clang/AST/Stmt.h
cfe/trunk/include/clang/AST/TextNodeDumper.h
cfe/trunk/include/clang/Serialization/ASTReader.h
cfe/trunk/include/clang/Serialization/ASTWriter.h
cfe/trunk/lib/AST/APValue.cpp
cfe/trunk/lib/AST/ASTContext.cpp
cfe/trunk/lib/AST/ASTImporter.cpp
cfe/trunk/lib/AST/Expr.cpp
cfe/trunk/lib/AST/TextNodeDumper.cpp
cfe/trunk/lib/Sema/SemaOverload.cpp
cfe/trunk/lib/Serialization/ASTReader.cpp
cfe/trunk/lib/Serialization/ASTReaderStmt.cpp
cfe/trunk/lib/Serialization/ASTWriter.cpp
cfe/trunk/lib/Serialization/ASTWriterStmt.cpp
cfe/trunk/test/AST/ast-dump-color.cpp
Modified: cfe/trunk/include/clang/AST/APValue.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/APValue.h?rev=363493&r1=363492&r2=363493&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/APValue.h (original)
+++ cfe/trunk/include/clang/AST/APValue.h Sat Jun 15 03:24:47 2019
@@ -182,6 +182,10 @@ public:
struct NoLValuePath {};
struct UninitArray {};
struct UninitStruct {};
+
+ friend class ASTReader;
+ friend class ASTWriter;
+
private:
ValueKind Kind;
@@ -326,8 +330,8 @@ public:
void dump() const;
void dump(raw_ostream &OS) const;
- void printPretty(raw_ostream &OS, ASTContext &Ctx, QualType Ty) const;
- std::string getAsString(ASTContext &Ctx, QualType Ty) const;
+ void printPretty(raw_ostream &OS, const ASTContext &Ctx, QualType Ty) const;
+ std::string getAsString(const ASTContext &Ctx, QualType Ty) const;
APSInt &getInt() {
assert(isInt() && "Invalid accessor");
Modified: cfe/trunk/include/clang/AST/ASTContext.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTContext.h?rev=363493&r1=363492&r2=363493&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/ASTContext.h (original)
+++ cfe/trunk/include/clang/AST/ASTContext.h Sat Jun 15 03:24:47 2019
@@ -271,6 +271,9 @@ private:
llvm::DenseMap<const MaterializeTemporaryExpr *, APValue *>
MaterializedTemporaryValues;
+ /// Used to cleanups APValues stored in the AST.
+ mutable llvm::SmallVector<APValue *, 0> APValueCleanups;
+
/// A cache mapping a string value to a StringLiteral object with the same
/// value.
///
@@ -2816,6 +2819,10 @@ public:
APValue *getMaterializedTemporaryValue(const MaterializeTemporaryExpr *E,
bool MayCreate);
+ /// Adds an APValue that will be destructed during the destruction of the
+ /// ASTContext.
+ void AddAPValueCleanup(APValue *Ptr) const { APValueCleanups.push_back(Ptr); }
+
/// Return a string representing the human readable name for the specified
/// function declaration or file name. Used by SourceLocExpr and
/// PredefinedExpr to cache evaluated results.
Modified: cfe/trunk/include/clang/AST/Expr.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Expr.h?rev=363493&r1=363492&r2=363493&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Expr.h (original)
+++ cfe/trunk/include/clang/AST/Expr.h Sat Jun 15 03:24:47 2019
@@ -943,21 +943,61 @@ public:
}
};
-/// ConstantExpr - An expression that occurs in a constant context.
-class ConstantExpr : public FullExpr {
- ConstantExpr(Expr *subexpr)
- : FullExpr(ConstantExprClass, subexpr) {}
+/// ConstantExpr - An expression that occurs in a constant context and
+/// optionally the result of evaluating the expression.
+class ConstantExpr final
+ : public FullExpr,
+ private llvm::TrailingObjects<ConstantExpr, APValue, uint64_t> {
+ static_assert(std::is_same<uint64_t, llvm::APInt::WordType>::value,
+ "this class assumes llvm::APInt::WordType is uint64_t for "
+ "trail-allocated storage");
public:
- static ConstantExpr *Create(const ASTContext &Context, Expr *E) {
- assert(!isa<ConstantExpr>(E));
- return new (Context) ConstantExpr(E);
+ /// Describes the kind of result that can be trail-allocated.
+ enum ResultStorageKind { RSK_None, RSK_Int64, RSK_APValue };
+
+private:
+ size_t numTrailingObjects(OverloadToken<APValue>) const {
+ return ConstantExprBits.ResultKind == ConstantExpr::RSK_APValue;
+ }
+ size_t numTrailingObjects(OverloadToken<uint64_t>) const {
+ return ConstantExprBits.ResultKind == ConstantExpr::RSK_Int64;
+ }
+
+ void DefaultInit(ResultStorageKind StorageKind);
+ uint64_t &Int64Result() {
+ assert(ConstantExprBits.ResultKind == ConstantExpr::RSK_Int64 &&
+ "invalid accessor");
+ return *getTrailingObjects<uint64_t>();
+ }
+ const uint64_t &Int64Result() const {
+ return const_cast<ConstantExpr *>(this)->Int64Result();
+ }
+ APValue &APValueResult() {
+ assert(ConstantExprBits.ResultKind == ConstantExpr::RSK_APValue &&
+ "invalid accessor");
+ return *getTrailingObjects<APValue>();
+ }
+ const APValue &APValueResult() const {
+ return const_cast<ConstantExpr *>(this)->APValueResult();
}
- /// Build an empty constant expression wrapper.
- explicit ConstantExpr(EmptyShell Empty)
- : FullExpr(ConstantExprClass, Empty) {}
+ ConstantExpr(Expr *subexpr, ResultStorageKind StorageKind);
+ ConstantExpr(ResultStorageKind StorageKind, EmptyShell Empty);
+public:
+ friend TrailingObjects;
+ friend class ASTStmtReader;
+ friend class ASTStmtWriter;
+ static ConstantExpr *Create(const ASTContext &Context, Expr *E,
+ const APValue &Result);
+ static ConstantExpr *Create(const ASTContext &Context, Expr *E,
+ ResultStorageKind Storage = RSK_None);
+ static ConstantExpr *CreateEmpty(const ASTContext &Context,
+ ResultStorageKind StorageKind,
+ EmptyShell Empty);
+
+ static ResultStorageKind getStorageKind(const APValue &Value);
SourceLocation getBeginLoc() const LLVM_READONLY {
return SubExpr->getBeginLoc();
}
@@ -969,6 +1009,25 @@ public:
return T->getStmtClass() == ConstantExprClass;
}
+ void SetResult(APValue Value) { MoveIntoResult(Value); }
+ void MoveIntoResult(APValue &Value);
+
+ APValue::ValueKind getResultAPValueKind() const {
+ switch (ConstantExprBits.ResultKind) {
+ case ConstantExpr::RSK_APValue:
+ return APValueResult().getKind();
+ case ConstantExpr::RSK_Int64:
+ return APValue::Int;
+ case ConstantExpr::RSK_None:
+ return APValue::None;
+ }
+ llvm_unreachable("invalid ResultKind");
+ }
+ ResultStorageKind getResultStorageKind() const {
+ return static_cast<const ResultStorageKind>(ConstantExprBits.ResultKind);
+ }
+ APValue getAPValueResult() const;
+
// Iterators
child_range children() { return child_range(&SubExpr, &SubExpr+1); }
const_child_range children() const {
@@ -1517,21 +1576,28 @@ public:
/// Get a raw enumeration value representing the floating-point semantics of
/// this literal (32-bit IEEE, x87, ...), suitable for serialisation.
- APFloatSemantics getRawSemantics() const {
- return static_cast<APFloatSemantics>(FloatingLiteralBits.Semantics);
+ llvm::APFloatBase::Semantics getRawSemantics() const {
+ return static_cast<llvm::APFloatBase::Semantics>(
+ FloatingLiteralBits.Semantics);
}
/// Set the raw enumeration value representing the floating-point semantics of
/// this literal (32-bit IEEE, x87, ...), suitable for serialisation.
- void setRawSemantics(APFloatSemantics Sem) {
+ void setRawSemantics(llvm::APFloatBase::Semantics Sem) {
FloatingLiteralBits.Semantics = Sem;
}
/// Return the APFloat semantics this literal uses.
- const llvm::fltSemantics &getSemantics() const;
+ const llvm::fltSemantics &getSemantics() const {
+ return llvm::APFloatBase::EnumToSemantics(
+ static_cast<llvm::APFloatBase::Semantics>(
+ FloatingLiteralBits.Semantics));
+ }
/// Set the APFloat semantics this literal uses.
- void setSemantics(const llvm::fltSemantics &Sem);
+ void setSemantics(const llvm::fltSemantics &Sem) {
+ FloatingLiteralBits.Semantics = llvm::APFloatBase::SemanticsToEnum(Sem);
+ }
bool isExact() const { return FloatingLiteralBits.IsExact; }
void setExact(bool E) { FloatingLiteralBits.IsExact = E; }
Modified: cfe/trunk/include/clang/AST/Stmt.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Stmt.h?rev=363493&r1=363492&r2=363493&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Stmt.h (original)
+++ cfe/trunk/include/clang/AST/Stmt.h Sat Jun 15 03:24:47 2019
@@ -322,6 +322,26 @@ protected:
};
enum { NumExprBits = NumStmtBits + 9 };
+ class ConstantExprBitfields {
+ friend class ASTStmtReader;
+ friend class ASTStmtWriter;
+ friend class ConstantExpr;
+
+ unsigned : NumExprBits;
+
+ /// The kind of result that is trail-allocated.
+ unsigned ResultKind : 2;
+
+ /// When ResultKind == RSK_Int64. whether the trail-allocated integer is
+ /// signed.
+ unsigned IsUnsigned : 1;
+
+ /// When ResultKind == RSK_Int64. the BitWidth of the trail-allocated
+ /// integer. 7 bits because it is the minimal number of bit to represent a
+ /// value from 0 to 64 (the size of the trail-allocated number).
+ unsigned BitWidth : 7;
+ };
+
class PredefinedExprBitfields {
friend class ASTStmtReader;
friend class PredefinedExpr;
@@ -357,14 +377,6 @@ protected:
SourceLocation Loc;
};
- enum APFloatSemantics {
- IEEEhalf,
- IEEEsingle,
- IEEEdouble,
- x87DoubleExtended,
- IEEEquad,
- PPCDoubleDouble
- };
class FloatingLiteralBitfields {
friend class FloatingLiteral;
@@ -938,6 +950,7 @@ protected:
// Expressions
ExprBitfields ExprBits;
+ ConstantExprBitfields ConstantExprBits;
PredefinedExprBitfields PredefinedExprBits;
DeclRefExprBitfields DeclRefExprBits;
FloatingLiteralBitfields FloatingLiteralBits;
Modified: cfe/trunk/include/clang/AST/TextNodeDumper.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/TextNodeDumper.h?rev=363493&r1=363492&r2=363493&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/TextNodeDumper.h (original)
+++ cfe/trunk/include/clang/AST/TextNodeDumper.h Sat Jun 15 03:24:47 2019
@@ -146,6 +146,8 @@ class TextNodeDumper
const comments::CommandTraits *Traits;
+ const ASTContext *Context;
+
const char *getCommandName(unsigned CommandID);
public:
@@ -228,6 +230,7 @@ public:
void VisitLabelStmt(const LabelStmt *Node);
void VisitGotoStmt(const GotoStmt *Node);
void VisitCaseStmt(const CaseStmt *Node);
+ void VisitConstantExpr(const ConstantExpr *Node);
void VisitCallExpr(const CallExpr *Node);
void VisitCastExpr(const CastExpr *Node);
void VisitImplicitCastExpr(const ImplicitCastExpr *Node);
Modified: cfe/trunk/include/clang/Serialization/ASTReader.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTReader.h?rev=363493&r1=363492&r2=363493&view=diff
==============================================================================
--- cfe/trunk/include/clang/Serialization/ASTReader.h (original)
+++ cfe/trunk/include/clang/Serialization/ASTReader.h Sat Jun 15 03:24:47 2019
@@ -2220,6 +2220,9 @@ public:
llvm::APFloat ReadAPFloat(const RecordData &Record,
const llvm::fltSemantics &Sem, unsigned &Idx);
+ /// Read an APValue
+ APValue ReadAPValue(const RecordData &Record, unsigned &Idx);
+
// Read a string
static std::string ReadString(const RecordData &Record, unsigned &Idx);
@@ -2612,6 +2615,8 @@ public:
return Reader->ReadSourceRange(*F, Record, Idx);
}
+ APValue readAPValue() { return Reader->ReadAPValue(Record, Idx); }
+
/// Read an integral value, advancing Idx.
llvm::APInt readAPInt() {
return Reader->ReadAPInt(Record, Idx);
Modified: cfe/trunk/include/clang/Serialization/ASTWriter.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTWriter.h?rev=363493&r1=363492&r2=363493&view=diff
==============================================================================
--- cfe/trunk/include/clang/Serialization/ASTWriter.h (original)
+++ cfe/trunk/include/clang/Serialization/ASTWriter.h Sat Jun 15 03:24:47 2019
@@ -863,6 +863,9 @@ public:
/// Emit a floating-point value.
void AddAPFloat(const llvm::APFloat &Value);
+ /// Emit an APvalue.
+ void AddAPValue(const APValue &Value);
+
/// Emit a reference to an identifier.
void AddIdentifierRef(const IdentifierInfo *II) {
return Writer->AddIdentifierRef(II, *Record);
Modified: cfe/trunk/lib/AST/APValue.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/APValue.cpp?rev=363493&r1=363492&r2=363493&view=diff
==============================================================================
--- cfe/trunk/lib/AST/APValue.cpp (original)
+++ cfe/trunk/lib/AST/APValue.cpp Sat Jun 15 03:24:47 2019
@@ -456,7 +456,8 @@ void APValue::dump(raw_ostream &OS) cons
llvm_unreachable("Unknown APValue kind!");
}
-void APValue::printPretty(raw_ostream &Out, ASTContext &Ctx, QualType Ty) const{
+void APValue::printPretty(raw_ostream &Out, const ASTContext &Ctx,
+ QualType Ty) const {
switch (getKind()) {
case APValue::None:
Out << "<out of lifetime>";
@@ -675,7 +676,7 @@ void APValue::printPretty(raw_ostream &O
llvm_unreachable("Unknown APValue kind!");
}
-std::string APValue::getAsString(ASTContext &Ctx, QualType Ty) const {
+std::string APValue::getAsString(const ASTContext &Ctx, QualType Ty) const {
std::string Result;
llvm::raw_string_ostream Out(Result);
printPretty(Out, Ctx, Ty);
Modified: cfe/trunk/lib/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=363493&r1=363492&r2=363493&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTContext.cpp (original)
+++ cfe/trunk/lib/AST/ASTContext.cpp Sat Jun 15 03:24:47 2019
@@ -827,6 +827,9 @@ ASTContext::~ASTContext() {
for (const auto &Value : ModuleInitializers)
Value.second->~PerModuleInitializers();
+
+ for (APValue *Value : APValueCleanups)
+ Value->~APValue();
}
class ASTContext::ParentMap {
Modified: cfe/trunk/lib/AST/ASTImporter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTImporter.cpp?rev=363493&r1=363492&r2=363493&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTImporter.cpp (original)
+++ cfe/trunk/lib/AST/ASTImporter.cpp Sat Jun 15 03:24:47 2019
@@ -6376,6 +6376,13 @@ ExpectedStmt ASTNodeImporter::VisitConst
Expr *ToSubExpr;
std::tie(ToSubExpr) = *Imp;
+ // TODO : Handle APValue::ValueKind that require importing.
+ APValue::ValueKind Kind = E->getResultAPValueKind();
+ if (Kind == APValue::Int || Kind == APValue::Float ||
+ Kind == APValue::FixedPoint || Kind == APValue::ComplexFloat ||
+ Kind == APValue::ComplexInt)
+ return ConstantExpr::Create(Importer.getToContext(), ToSubExpr,
+ E->getAPValueResult());
return ConstantExpr::Create(Importer.getToContext(), ToSubExpr);
}
Modified: cfe/trunk/lib/AST/Expr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Expr.cpp?rev=363493&r1=363492&r2=363493&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Expr.cpp (original)
+++ cfe/trunk/lib/AST/Expr.cpp Sat Jun 15 03:24:47 2019
@@ -229,6 +229,110 @@ SourceLocation Expr::getExprLoc() const
// Primary Expressions.
//===----------------------------------------------------------------------===//
+static void AssertResultStorageKind(ConstantExpr::ResultStorageKind Kind) {
+ assert((Kind == ConstantExpr::RSK_APValue ||
+ Kind == ConstantExpr::RSK_Int64 || Kind == ConstantExpr::RSK_None) &&
+ "Invalid StorageKind Value");
+}
+
+ConstantExpr::ResultStorageKind
+ConstantExpr::getStorageKind(const APValue &Value) {
+ switch (Value.getKind()) {
+ case APValue::None:
+ return ConstantExpr::RSK_None;
+ case APValue::Int:
+ if (!Value.getInt().needsCleanup())
+ return ConstantExpr::RSK_Int64;
+ LLVM_FALLTHROUGH;
+ default:
+ return ConstantExpr::RSK_APValue;
+ }
+}
+
+void ConstantExpr::DefaultInit(ResultStorageKind StorageKind) {
+ ConstantExprBits.ResultKind = StorageKind;
+ if (StorageKind == RSK_APValue)
+ ::new (getTrailingObjects<APValue>()) APValue();
+}
+
+ConstantExpr::ConstantExpr(Expr *subexpr, ResultStorageKind StorageKind)
+ : FullExpr(ConstantExprClass, subexpr) {
+ DefaultInit(StorageKind);
+}
+
+ConstantExpr *ConstantExpr::Create(const ASTContext &Context, Expr *E,
+ ResultStorageKind StorageKind) {
+ assert(!isa<ConstantExpr>(E));
+ AssertResultStorageKind(StorageKind);
+ unsigned Size = totalSizeToAlloc<APValue, uint64_t>(
+ StorageKind == ConstantExpr::RSK_APValue,
+ StorageKind == ConstantExpr::RSK_Int64);
+ void *Mem = Context.Allocate(Size, alignof(ConstantExpr));
+ ConstantExpr *Self = new (Mem) ConstantExpr(E, StorageKind);
+ if (StorageKind == ConstantExpr::RSK_APValue)
+ Context.AddAPValueCleanup(&Self->APValueResult());
+ return Self;
+}
+
+ConstantExpr *ConstantExpr::Create(const ASTContext &Context, Expr *E,
+ const APValue &Result) {
+ ResultStorageKind StorageKind = getStorageKind(Result);
+ ConstantExpr *Self = Create(Context, E, StorageKind);
+ Self->SetResult(Result);
+ return Self;
+}
+
+ConstantExpr::ConstantExpr(ResultStorageKind StorageKind, EmptyShell Empty)
+ : FullExpr(ConstantExprClass, Empty) {
+ DefaultInit(StorageKind);
+}
+
+ConstantExpr *ConstantExpr::CreateEmpty(const ASTContext &Context,
+ ResultStorageKind StorageKind,
+ EmptyShell Empty) {
+ AssertResultStorageKind(StorageKind);
+ unsigned Size = totalSizeToAlloc<APValue, uint64_t>(
+ StorageKind == ConstantExpr::RSK_APValue,
+ StorageKind == ConstantExpr::RSK_Int64);
+ void *Mem = Context.Allocate(Size, alignof(ConstantExpr));
+ ConstantExpr *Self = new (Mem) ConstantExpr(StorageKind, Empty);
+ if (StorageKind == ConstantExpr::RSK_APValue)
+ Context.AddAPValueCleanup(&Self->APValueResult());
+ return Self;
+}
+
+void ConstantExpr::MoveIntoResult(APValue &Value) {
+ assert(getStorageKind(Value) == ConstantExprBits.ResultKind &&
+ "Invalid storage for this value kind");
+ switch (ConstantExprBits.ResultKind) {
+ case RSK_None:
+ return;
+ case RSK_Int64:
+ Int64Result() = *Value.getInt().getRawData();
+ ConstantExprBits.BitWidth = Value.getInt().getBitWidth();
+ ConstantExprBits.IsUnsigned = Value.getInt().isUnsigned();
+ return;
+ case RSK_APValue:
+ APValueResult() = std::move(Value);
+ return;
+ }
+ llvm_unreachable("Invalid ResultKind Bits");
+}
+
+APValue ConstantExpr::getAPValueResult() const {
+ switch (ConstantExprBits.ResultKind) {
+ case ConstantExpr::RSK_APValue:
+ return APValueResult();
+ case ConstantExpr::RSK_Int64:
+ return APValue(
+ llvm::APSInt(llvm::APInt(ConstantExprBits.BitWidth, Int64Result()),
+ ConstantExprBits.IsUnsigned));
+ case ConstantExpr::RSK_None:
+ return APValue();
+ }
+ llvm_unreachable("invalid ResultKind");
+}
+
/// Compute the type-, value-, and instantiation-dependence of a
/// declaration reference
/// based on the declaration being referenced.
@@ -840,7 +944,7 @@ FloatingLiteral::FloatingLiteral(const A
FloatingLiteral::FloatingLiteral(const ASTContext &C, EmptyShell Empty)
: Expr(FloatingLiteralClass, Empty) {
- setRawSemantics(IEEEhalf);
+ setRawSemantics(llvm::APFloatBase::S_IEEEhalf);
FloatingLiteralBits.IsExact = false;
}
@@ -855,41 +959,6 @@ FloatingLiteral::Create(const ASTContext
return new (C) FloatingLiteral(C, Empty);
}
-const llvm::fltSemantics &FloatingLiteral::getSemantics() const {
- switch(FloatingLiteralBits.Semantics) {
- case IEEEhalf:
- return llvm::APFloat::IEEEhalf();
- case IEEEsingle:
- return llvm::APFloat::IEEEsingle();
- case IEEEdouble:
- return llvm::APFloat::IEEEdouble();
- case x87DoubleExtended:
- return llvm::APFloat::x87DoubleExtended();
- case IEEEquad:
- return llvm::APFloat::IEEEquad();
- case PPCDoubleDouble:
- return llvm::APFloat::PPCDoubleDouble();
- }
- llvm_unreachable("Unrecognised floating semantics");
-}
-
-void FloatingLiteral::setSemantics(const llvm::fltSemantics &Sem) {
- if (&Sem == &llvm::APFloat::IEEEhalf())
- FloatingLiteralBits.Semantics = IEEEhalf;
- else if (&Sem == &llvm::APFloat::IEEEsingle())
- FloatingLiteralBits.Semantics = IEEEsingle;
- else if (&Sem == &llvm::APFloat::IEEEdouble())
- FloatingLiteralBits.Semantics = IEEEdouble;
- else if (&Sem == &llvm::APFloat::x87DoubleExtended())
- FloatingLiteralBits.Semantics = x87DoubleExtended;
- else if (&Sem == &llvm::APFloat::IEEEquad())
- FloatingLiteralBits.Semantics = IEEEquad;
- else if (&Sem == &llvm::APFloat::PPCDoubleDouble())
- FloatingLiteralBits.Semantics = PPCDoubleDouble;
- else
- llvm_unreachable("Unknown floating semantics");
-}
-
/// getValueAsApproximateDouble - This returns the value as an inaccurate
/// double. Note that this may cause loss of precision, but is useful for
/// debugging dumps, etc.
Modified: cfe/trunk/lib/AST/TextNodeDumper.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/TextNodeDumper.cpp?rev=363493&r1=363492&r2=363493&view=diff
==============================================================================
--- cfe/trunk/lib/AST/TextNodeDumper.cpp (original)
+++ cfe/trunk/lib/AST/TextNodeDumper.cpp Sat Jun 15 03:24:47 2019
@@ -223,6 +223,7 @@ void TextNodeDumper::Visit(const Decl *D
return;
}
+ Context = &D->getASTContext();
{
ColorScope Color(OS, ShowColors, DeclKindNameColor);
OS << D->getDeclKindName() << "Decl";
@@ -689,6 +690,14 @@ void TextNodeDumper::VisitCaseStmt(const
OS << " gnu_range";
}
+void TextNodeDumper::VisitConstantExpr(const ConstantExpr *Node) {
+ if (Node->getResultAPValueKind() != APValue::None) {
+ ColorScope Color(OS, ShowColors, ValueColor);
+ OS << " ";
+ Node->getAPValueResult().printPretty(OS, *Context, Node->getType());
+ }
+}
+
void TextNodeDumper::VisitCallExpr(const CallExpr *Node) {
if (Node->usesADL())
OS << " adl";
Modified: cfe/trunk/lib/Sema/SemaOverload.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOverload.cpp?rev=363493&r1=363492&r2=363493&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaOverload.cpp (original)
+++ cfe/trunk/lib/Sema/SemaOverload.cpp Sat Jun 15 03:24:47 2019
@@ -5514,7 +5514,7 @@ static ExprResult CheckConvertedConstant
if (Notes.empty()) {
// It's a constant expression.
- return ConstantExpr::Create(S.Context, Result.get());
+ return ConstantExpr::Create(S.Context, Result.get(), Value);
}
}
Modified: cfe/trunk/lib/Serialization/ASTReader.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReader.cpp?rev=363493&r1=363492&r2=363493&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReader.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReader.cpp Sat Jun 15 03:24:47 2019
@@ -9102,6 +9102,62 @@ ASTReader::ReadSourceRange(ModuleFile &F
return SourceRange(beg, end);
}
+static FixedPointSemantics
+ReadFixedPointSemantics(const SmallVectorImpl<uint64_t> &Record,
+ unsigned &Idx) {
+ unsigned Width = Record[Idx++];
+ unsigned Scale = Record[Idx++];
+ uint64_t Tmp = Record[Idx++];
+ bool IsSigned = Tmp & 0x1;
+ bool IsSaturated = Tmp & 0x2;
+ bool HasUnsignedPadding = Tmp & 0x4;
+ return FixedPointSemantics(Width, Scale, IsSigned, IsSaturated,
+ HasUnsignedPadding);
+}
+
+APValue ASTReader::ReadAPValue(const RecordData &Record, unsigned &Idx) {
+ unsigned Kind = Record[Idx++];
+ switch (Kind) {
+ case APValue::None:
+ return APValue();
+ case APValue::Indeterminate:
+ return APValue::IndeterminateValue();
+ case APValue::Int:
+ return APValue(ReadAPSInt(Record, Idx));
+ case APValue::Float: {
+ const llvm::fltSemantics &FloatSema = llvm::APFloatBase::EnumToSemantics(
+ static_cast<llvm::APFloatBase::Semantics>(Record[Idx++]));
+ return APValue(ReadAPFloat(Record, FloatSema, Idx));
+ }
+ case APValue::FixedPoint: {
+ FixedPointSemantics FPSema = ReadFixedPointSemantics(Record, Idx);
+ return APValue(APFixedPoint(ReadAPInt(Record, Idx), FPSema));
+ }
+ case APValue::ComplexInt: {
+ llvm::APSInt First = ReadAPSInt(Record, Idx);
+ return APValue(std::move(First), ReadAPSInt(Record, Idx));
+ }
+ case APValue::ComplexFloat: {
+ const llvm::fltSemantics &FloatSema1 = llvm::APFloatBase::EnumToSemantics(
+ static_cast<llvm::APFloatBase::Semantics>(Record[Idx++]));
+ llvm::APFloat First = ReadAPFloat(Record, FloatSema1, Idx);
+ const llvm::fltSemantics &FloatSema2 = llvm::APFloatBase::EnumToSemantics(
+ static_cast<llvm::APFloatBase::Semantics>(Record[Idx++]));
+ return APValue(std::move(First), ReadAPFloat(Record, FloatSema2, Idx));
+ }
+ case APValue::LValue:
+ case APValue::Vector:
+ case APValue::Array:
+ case APValue::Struct:
+ case APValue::Union:
+ case APValue::MemberPointer:
+ case APValue::AddrLabelDiff:
+ // TODO : Handle all these APValue::ValueKind.
+ return APValue();
+ }
+ llvm_unreachable("Invalid APValue::ValueKind");
+}
+
/// Read an integral value
llvm::APInt ASTReader::ReadAPInt(const RecordData &Record, unsigned &Idx) {
unsigned BitWidth = Record[Idx++];
Modified: cfe/trunk/lib/Serialization/ASTReaderStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderStmt.cpp?rev=363493&r1=363492&r2=363493&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReaderStmt.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReaderStmt.cpp Sat Jun 15 03:24:47 2019
@@ -533,6 +533,18 @@ void ASTStmtReader::VisitExpr(Expr *E) {
void ASTStmtReader::VisitConstantExpr(ConstantExpr *E) {
VisitExpr(E);
+ E->ConstantExprBits.ResultKind = Record.readInt();
+ switch (E->ConstantExprBits.ResultKind) {
+ case ConstantExpr::RSK_Int64: {
+ E->Int64Result() = Record.readInt();
+ uint64_t tmp = Record.readInt();
+ E->ConstantExprBits.IsUnsigned = tmp & 0x1;
+ E->ConstantExprBits.BitWidth = tmp >> 1;
+ break;
+ }
+ case ConstantExpr::RSK_APValue:
+ E->APValueResult() = Record.readAPValue();
+ }
E->setSubExpr(Record.readSubExpr());
}
@@ -590,7 +602,8 @@ void ASTStmtReader::VisitFixedPointLiter
void ASTStmtReader::VisitFloatingLiteral(FloatingLiteral *E) {
VisitExpr(E);
- E->setRawSemantics(static_cast<Stmt::APFloatSemantics>(Record.readInt()));
+ E->setRawSemantics(
+ static_cast<llvm::APFloatBase::Semantics>(Record.readInt()));
E->setExact(Record.readInt());
E->setValue(Record.getContext(), Record.readAPFloat(E->getSemantics()));
E->setLocation(ReadSourceLocation());
@@ -2510,7 +2523,11 @@ Stmt *ASTReader::ReadStmtFromStream(Modu
break;
case EXPR_CONSTANT:
- S = new (Context) ConstantExpr(Empty);
+ S = ConstantExpr::CreateEmpty(
+ Context,
+ static_cast<ConstantExpr::ResultStorageKind>(
+ Record[ASTStmtReader::NumExprFields]),
+ Empty);
break;
case EXPR_PREDEFINED:
Modified: cfe/trunk/lib/Serialization/ASTWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriter.cpp?rev=363493&r1=363492&r2=363493&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTWriter.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTWriter.cpp Sat Jun 15 03:24:47 2019
@@ -5399,6 +5399,61 @@ void ASTRecordWriter::AddAPFloat(const l
AddAPInt(Value.bitcastToAPInt());
}
+static void WriteFixedPointSemantics(ASTRecordWriter &Record,
+ FixedPointSemantics FPSema) {
+ Record.push_back(FPSema.getWidth());
+ Record.push_back(FPSema.getScale());
+ Record.push_back(FPSema.isSigned() | FPSema.isSaturated() << 1 |
+ FPSema.hasUnsignedPadding() << 2);
+}
+
+void ASTRecordWriter::AddAPValue(const APValue &Value) {
+ APValue::ValueKind Kind = Value.getKind();
+ push_back(static_cast<uint64_t>(Kind));
+ switch (Kind) {
+ case APValue::None:
+ case APValue::Indeterminate:
+ return;
+ case APValue::Int:
+ AddAPSInt(Value.getInt());
+ return;
+ case APValue::Float:
+ push_back(static_cast<uint64_t>(
+ llvm::APFloatBase::SemanticsToEnum(Value.getFloat().getSemantics())));
+ AddAPFloat(Value.getFloat());
+ return;
+ case APValue::FixedPoint: {
+ WriteFixedPointSemantics(*this, Value.getFixedPoint().getSemantics());
+ AddAPSInt(Value.getFixedPoint().getValue());
+ return;
+ }
+ case APValue::ComplexInt: {
+ AddAPSInt(Value.getComplexIntReal());
+ AddAPSInt(Value.getComplexIntImag());
+ return;
+ }
+ case APValue::ComplexFloat: {
+ push_back(static_cast<uint64_t>(llvm::APFloatBase::SemanticsToEnum(
+ Value.getComplexFloatReal().getSemantics())));
+ AddAPFloat(Value.getComplexFloatReal());
+ push_back(static_cast<uint64_t>(llvm::APFloatBase::SemanticsToEnum(
+ Value.getComplexFloatImag().getSemantics())));
+ AddAPFloat(Value.getComplexFloatImag());
+ return;
+ }
+ case APValue::LValue:
+ case APValue::Vector:
+ case APValue::Array:
+ case APValue::Struct:
+ case APValue::Union:
+ case APValue::MemberPointer:
+ case APValue::AddrLabelDiff:
+ // TODO : Handle all these APValue::ValueKind.
+ return;
+ }
+ llvm_unreachable("Invalid APValue::ValueKind");
+}
+
void ASTWriter::AddIdentifierRef(const IdentifierInfo *II, RecordDataImpl &Record) {
Record.push_back(getIdentifierRef(II));
}
Modified: cfe/trunk/lib/Serialization/ASTWriterStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriterStmt.cpp?rev=363493&r1=363492&r2=363493&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTWriterStmt.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTWriterStmt.cpp Sat Jun 15 03:24:47 2019
@@ -432,6 +432,16 @@ void ASTStmtWriter::VisitExpr(Expr *E) {
void ASTStmtWriter::VisitConstantExpr(ConstantExpr *E) {
VisitExpr(E);
+ Record.push_back(static_cast<uint64_t>(E->ConstantExprBits.ResultKind));
+ switch (E->ConstantExprBits.ResultKind) {
+ case ConstantExpr::RSK_Int64:
+ Record.push_back(E->Int64Result());
+ Record.push_back(E->ConstantExprBits.IsUnsigned |
+ E->ConstantExprBits.BitWidth << 1);
+ break;
+ case ConstantExpr::RSK_APValue:
+ Record.AddAPValue(E->APValueResult());
+ }
Record.AddStmt(E->getSubExpr());
Code = serialization::EXPR_CONSTANT;
}
Modified: cfe/trunk/test/AST/ast-dump-color.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/AST/ast-dump-color.cpp?rev=363493&r1=363492&r2=363493&view=diff
==============================================================================
--- cfe/trunk/test/AST/ast-dump-color.cpp (original)
+++ cfe/trunk/test/AST/ast-dump-color.cpp Sat Jun 15 03:24:47 2019
@@ -49,13 +49,13 @@ struct Invalid {
//CHECK: {{^}}[[Blue]]| | |-[[RESET]][[MAGENTA]]IntegerLiteral[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:10:11[[RESET]]> [[Green]]'int'[[RESET]][[Cyan:.\[0;36m]][[RESET]][[Cyan]][[RESET]][[CYAN]] 1[[RESET]]{{$}}
//CHECK: {{^}}[[Blue]]| | `-[[RESET]][[MAGENTA]]CompoundStmt[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:14[[RESET]], [[Yellow]]line:15:3[[RESET]]>{{$}}
//CHECK: {{^}}[[Blue]]| | |-[[RESET]][[MAGENTA]]CaseStmt[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:11:3[[RESET]], [[Yellow]]line:12:27[[RESET]]>{{$}}
-//CHECK: {{^}}[[Blue]]| | | |-[[RESET]][[MAGENTA]]ConstantExpr[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:11:8[[RESET]]> [[Green]]'int'[[RESET]][[Cyan]][[RESET]][[Cyan]][[RESET]]{{$}}
+//CHECK: {{^}}[[Blue]]| | | |-[[RESET]][[MAGENTA]]ConstantExpr[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:11:8[[RESET]]> [[Green]]'int'[[RESET]][[Cyan]][[RESET]][[Cyan]][[RESET]][[CYAN]] 1[[RESET]]{{$}}
//CHECK: {{^}}[[Blue]]| | | | `-[[RESET]][[MAGENTA]]IntegerLiteral[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:8[[RESET]]> [[Green]]'int'[[RESET]][[Cyan]][[RESET]][[Cyan]][[RESET]][[CYAN]] 1[[RESET]]{{$}}
//CHECK: {{^}}[[Blue]]| | | `-[[RESET]][[MAGENTA]]AttributedStmt[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:12:5[[RESET]], [[Yellow]]col:27[[RESET]]>{{$}}
//CHECK: {{^}}[[Blue]]| | | |-[[RESET]][[BLUE]]FallThroughAttr[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:7[[RESET]], [[Yellow]]col:14[[RESET]]>{{$}}
//CHECK: {{^}}[[Blue]]| | | `-[[RESET]][[MAGENTA]]NullStmt[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:27[[RESET]]>{{$}}
//CHECK: {{^}}[[Blue]]| | `-[[RESET]][[MAGENTA]]CaseStmt[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:13:3[[RESET]], [[Yellow]]line:14:5[[RESET]]>{{$}}
-//CHECK: {{^}}[[Blue]]| | |-[[RESET]][[MAGENTA]]ConstantExpr[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:13:8[[RESET]]> [[Green]]'int'[[RESET]][[Cyan]][[RESET]][[Cyan]][[RESET]]{{$}}
+//CHECK: {{^}}[[Blue]]| | |-[[RESET]][[MAGENTA]]ConstantExpr[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:13:8[[RESET]]> [[Green]]'int'[[RESET]][[Cyan]][[RESET]][[Cyan]][[RESET]][[CYAN]] 2[[RESET]]{{$}}
//CHECK: {{^}}[[Blue]]| | | `-[[RESET]][[MAGENTA]]IntegerLiteral[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:8[[RESET]]> [[Green]]'int'[[RESET]][[Cyan]][[RESET]][[Cyan]][[RESET]][[CYAN]] 2[[RESET]]{{$}}
//CHECK: {{^}}[[Blue]]| | `-[[RESET]][[MAGENTA]]NullStmt[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:14:5[[RESET]]>{{$}}
//CHECK: {{^}}[[Blue]]| `-[[RESET]][[Blue]]FullComment[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:8:4[[RESET]], [[Yellow]]col:11[[RESET]]>{{$}}
More information about the cfe-commits
mailing list