Skip to content

Commit

Permalink
[clang][NFC] Refactor ConstantExpr::ResultStorageKind
Browse files Browse the repository at this point in the history
This patch converts `ConstantExpr::ResultStorageKind` to a scoped enum in namespace scoped `ConstantResultStorageKind`. This patch makes it possible to forward-declare this enum where it's necessery, e.g. for `preferred_type` annotation for bit-fields.
  • Loading branch information
Endilll committed Nov 4, 2023
1 parent 51d15d1 commit cd60229
Show file tree
Hide file tree
Showing 6 changed files with 74 additions and 73 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ bool PopulateSwitch::prepare(const Selection &Sel) {

// We need a stored value in order to continue; currently both C and ObjC
// enums won't have one.
if (CE->getResultStorageKind() == ConstantExpr::RSK_None)
if (CE->getResultStorageKind() == ConstantResultStorageKind::None)
return false;
auto Iter = ExpectedCases.find(Normalize(CE->getResultAsAPSInt()));
if (Iter != ExpectedCases.end())
Expand Down
39 changes: 19 additions & 20 deletions clang/include/clang/AST/Expr.h
Original file line number Diff line number Diff line change
Expand Up @@ -1049,6 +1049,9 @@ class FullExpr : public Expr {
}
};

/// Describes the kind of result that can be tail-allocated.
enum class ConstantResultStorageKind { None, Int64, APValue };

/// ConstantExpr - An expression that occurs in a constant context and
/// optionally the result of evaluating the expression.
class ConstantExpr final
Expand All @@ -1061,51 +1064,47 @@ class ConstantExpr final
friend class ASTStmtReader;
friend class ASTStmtWriter;

public:
/// Describes the kind of result that can be tail-allocated.
enum ResultStorageKind { RSK_None, RSK_Int64, RSK_APValue };

private:
size_t numTrailingObjects(OverloadToken<APValue>) const {
return ConstantExprBits.ResultKind == ConstantExpr::RSK_APValue;
return getResultStorageKind() == ConstantResultStorageKind::APValue;
}
size_t numTrailingObjects(OverloadToken<uint64_t>) const {
return ConstantExprBits.ResultKind == ConstantExpr::RSK_Int64;
return getResultStorageKind() == ConstantResultStorageKind::Int64;
}

uint64_t &Int64Result() {
assert(ConstantExprBits.ResultKind == ConstantExpr::RSK_Int64 &&
assert(getResultStorageKind() == ConstantResultStorageKind::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 &&
assert(getResultStorageKind() == ConstantResultStorageKind::APValue &&
"invalid accessor");
return *getTrailingObjects<APValue>();
}
APValue &APValueResult() const {
return const_cast<ConstantExpr *>(this)->APValueResult();
}

ConstantExpr(Expr *SubExpr, ResultStorageKind StorageKind,
ConstantExpr(Expr *SubExpr, ConstantResultStorageKind StorageKind,
bool IsImmediateInvocation);
ConstantExpr(EmptyShell Empty, ResultStorageKind StorageKind);
ConstantExpr(EmptyShell Empty, ConstantResultStorageKind StorageKind);

public:
static ConstantExpr *Create(const ASTContext &Context, Expr *E,
const APValue &Result);
static ConstantExpr *Create(const ASTContext &Context, Expr *E,
ResultStorageKind Storage = RSK_None,
bool IsImmediateInvocation = false);
static ConstantExpr *
Create(const ASTContext &Context, Expr *E,
ConstantResultStorageKind Storage = ConstantResultStorageKind::None,
bool IsImmediateInvocation = false);
static ConstantExpr *CreateEmpty(const ASTContext &Context,
ResultStorageKind StorageKind);
ConstantResultStorageKind StorageKind);

static ResultStorageKind getStorageKind(const APValue &Value);
static ResultStorageKind getStorageKind(const Type *T,
const ASTContext &Context);
static ConstantResultStorageKind getStorageKind(const APValue &Value);
static ConstantResultStorageKind getStorageKind(const Type *T,
const ASTContext &Context);

SourceLocation getBeginLoc() const LLVM_READONLY {
return SubExpr->getBeginLoc();
Expand All @@ -1126,8 +1125,8 @@ class ConstantExpr final
APValue::ValueKind getResultAPValueKind() const {
return static_cast<APValue::ValueKind>(ConstantExprBits.APValueKind);
}
ResultStorageKind getResultStorageKind() const {
return static_cast<ResultStorageKind>(ConstantExprBits.ResultKind);
ConstantResultStorageKind getResultStorageKind() const {
return static_cast<ConstantResultStorageKind>(ConstantExprBits.ResultKind);
}
bool isImmediateInvocation() const {
return ConstantExprBits.IsImmediateInvocation;
Expand Down
15 changes: 8 additions & 7 deletions clang/include/clang/AST/Stmt.h
Original file line number Diff line number Diff line change
Expand Up @@ -333,17 +333,18 @@ class alignas(void *) Stmt {
/// The kind of Result as defined by APValue::Kind.
unsigned APValueKind : 4;

/// When ResultKind == RSK_Int64, true if the tail-allocated integer is
/// unsigned.
/// When ResultKind == ConstantResultStorageKind::Int64, true if the
/// tail-allocated integer is unsigned.
unsigned IsUnsigned : 1;

/// When ResultKind == RSK_Int64. the BitWidth of the tail-allocated
/// integer. 7 bits because it is the minimal number of bits to represent a
/// value from 0 to 64 (the size of the tail-allocated integer).
/// When ResultKind == ConstantResultStorageKind::Int64. the BitWidth of the
/// tail-allocated integer. 7 bits because it is the minimal number of bits
/// to represent a value from 0 to 64 (the size of the tail-allocated
/// integer).
unsigned BitWidth : 7;

/// When ResultKind == RSK_APValue, true if the ASTContext will cleanup the
/// tail-allocated APValue.
/// When ResultKind == ConstantResultStorageKind::APValue, true if the
/// ASTContext will cleanup the tail-allocated APValue.
unsigned HasCleanup : 1;

/// True if this ConstantExpr was created for immediate invocation.
Expand Down
71 changes: 36 additions & 35 deletions clang/lib/AST/Expr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -281,85 +281,86 @@ 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) &&
static void AssertResultStorageKind(ConstantResultStorageKind Kind) {
assert((Kind == ConstantResultStorageKind::APValue ||
Kind == ConstantResultStorageKind::Int64 ||
Kind == ConstantResultStorageKind::None) &&
"Invalid StorageKind Value");
(void)Kind;
}

ConstantExpr::ResultStorageKind
ConstantExpr::getStorageKind(const APValue &Value) {
ConstantResultStorageKind ConstantExpr::getStorageKind(const APValue &Value) {
switch (Value.getKind()) {
case APValue::None:
case APValue::Indeterminate:
return ConstantExpr::RSK_None;
return ConstantResultStorageKind::None;
case APValue::Int:
if (!Value.getInt().needsCleanup())
return ConstantExpr::RSK_Int64;
return ConstantResultStorageKind::Int64;
[[fallthrough]];
default:
return ConstantExpr::RSK_APValue;
return ConstantResultStorageKind::APValue;
}
}

ConstantExpr::ResultStorageKind
ConstantResultStorageKind
ConstantExpr::getStorageKind(const Type *T, const ASTContext &Context) {
if (T->isIntegralOrEnumerationType() && Context.getTypeInfo(T).Width <= 64)
return ConstantExpr::RSK_Int64;
return ConstantExpr::RSK_APValue;
return ConstantResultStorageKind::Int64;
return ConstantResultStorageKind::APValue;
}

ConstantExpr::ConstantExpr(Expr *SubExpr, ResultStorageKind StorageKind,
ConstantExpr::ConstantExpr(Expr *SubExpr, ConstantResultStorageKind StorageKind,
bool IsImmediateInvocation)
: FullExpr(ConstantExprClass, SubExpr) {
ConstantExprBits.ResultKind = StorageKind;
ConstantExprBits.ResultKind = llvm::to_underlying(StorageKind);
ConstantExprBits.APValueKind = APValue::None;
ConstantExprBits.IsUnsigned = false;
ConstantExprBits.BitWidth = 0;
ConstantExprBits.HasCleanup = false;
ConstantExprBits.IsImmediateInvocation = IsImmediateInvocation;

if (StorageKind == ConstantExpr::RSK_APValue)
if (StorageKind == ConstantResultStorageKind::APValue)
::new (getTrailingObjects<APValue>()) APValue();
}

ConstantExpr *ConstantExpr::Create(const ASTContext &Context, Expr *E,
ResultStorageKind StorageKind,
ConstantResultStorageKind StorageKind,
bool IsImmediateInvocation) {
assert(!isa<ConstantExpr>(E));
AssertResultStorageKind(StorageKind);

unsigned Size = totalSizeToAlloc<APValue, uint64_t>(
StorageKind == ConstantExpr::RSK_APValue,
StorageKind == ConstantExpr::RSK_Int64);
StorageKind == ConstantResultStorageKind::APValue,
StorageKind == ConstantResultStorageKind::Int64);
void *Mem = Context.Allocate(Size, alignof(ConstantExpr));
return new (Mem) ConstantExpr(E, StorageKind, IsImmediateInvocation);
}

ConstantExpr *ConstantExpr::Create(const ASTContext &Context, Expr *E,
const APValue &Result) {
ResultStorageKind StorageKind = getStorageKind(Result);
ConstantResultStorageKind StorageKind = getStorageKind(Result);
ConstantExpr *Self = Create(Context, E, StorageKind);
Self->SetResult(Result, Context);
return Self;
}

ConstantExpr::ConstantExpr(EmptyShell Empty, ResultStorageKind StorageKind)
ConstantExpr::ConstantExpr(EmptyShell Empty,
ConstantResultStorageKind StorageKind)
: FullExpr(ConstantExprClass, Empty) {
ConstantExprBits.ResultKind = StorageKind;
ConstantExprBits.ResultKind = llvm::to_underlying(StorageKind);

if (StorageKind == ConstantExpr::RSK_APValue)
if (StorageKind == ConstantResultStorageKind::APValue)
::new (getTrailingObjects<APValue>()) APValue();
}

ConstantExpr *ConstantExpr::CreateEmpty(const ASTContext &Context,
ResultStorageKind StorageKind) {
ConstantResultStorageKind StorageKind) {
AssertResultStorageKind(StorageKind);

unsigned Size = totalSizeToAlloc<APValue, uint64_t>(
StorageKind == ConstantExpr::RSK_APValue,
StorageKind == ConstantExpr::RSK_Int64);
StorageKind == ConstantResultStorageKind::APValue,
StorageKind == ConstantResultStorageKind::Int64);
void *Mem = Context.Allocate(Size, alignof(ConstantExpr));
return new (Mem) ConstantExpr(EmptyShell(), StorageKind);
}
Expand All @@ -368,15 +369,15 @@ void ConstantExpr::MoveIntoResult(APValue &Value, const ASTContext &Context) {
assert((unsigned)getStorageKind(Value) <= ConstantExprBits.ResultKind &&
"Invalid storage for this value kind");
ConstantExprBits.APValueKind = Value.getKind();
switch (ConstantExprBits.ResultKind) {
case RSK_None:
switch (getResultStorageKind()) {
case ConstantResultStorageKind::None:
return;
case RSK_Int64:
case ConstantResultStorageKind::Int64:
Int64Result() = *Value.getInt().getRawData();
ConstantExprBits.BitWidth = Value.getInt().getBitWidth();
ConstantExprBits.IsUnsigned = Value.getInt().isUnsigned();
return;
case RSK_APValue:
case ConstantResultStorageKind::APValue:
if (!ConstantExprBits.HasCleanup && Value.needsCleanup()) {
ConstantExprBits.HasCleanup = true;
Context.addDestruction(&APValueResult());
Expand All @@ -388,10 +389,10 @@ void ConstantExpr::MoveIntoResult(APValue &Value, const ASTContext &Context) {
}

llvm::APSInt ConstantExpr::getResultAsAPSInt() const {
switch (ConstantExprBits.ResultKind) {
case ConstantExpr::RSK_APValue:
switch (getResultStorageKind()) {
case ConstantResultStorageKind::APValue:
return APValueResult().getInt();
case ConstantExpr::RSK_Int64:
case ConstantResultStorageKind::Int64:
return llvm::APSInt(llvm::APInt(ConstantExprBits.BitWidth, Int64Result()),
ConstantExprBits.IsUnsigned);
default:
Expand All @@ -401,14 +402,14 @@ llvm::APSInt ConstantExpr::getResultAsAPSInt() const {

APValue ConstantExpr::getAPValueResult() const {

switch (ConstantExprBits.ResultKind) {
case ConstantExpr::RSK_APValue:
switch (getResultStorageKind()) {
case ConstantResultStorageKind::APValue:
return APValueResult();
case ConstantExpr::RSK_Int64:
case ConstantResultStorageKind::Int64:
return APValue(
llvm::APSInt(llvm::APInt(ConstantExprBits.BitWidth, Int64Result()),
ConstantExprBits.IsUnsigned));
case ConstantExpr::RSK_None:
case ConstantResultStorageKind::None:
if (ConstantExprBits.APValueKind == APValue::Indeterminate)
return APValue::IndeterminateValue();
return APValue();
Expand Down
12 changes: 6 additions & 6 deletions clang/lib/Serialization/ASTReaderStmt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -534,8 +534,8 @@ void ASTStmtReader::VisitExpr(Expr *E) {
void ASTStmtReader::VisitConstantExpr(ConstantExpr *E) {
VisitExpr(E);

auto StorageKind = Record.readInt();
assert(E->ConstantExprBits.ResultKind == StorageKind && "Wrong ResultKind!");
auto StorageKind = static_cast<ConstantResultStorageKind>(Record.readInt());
assert(E->getResultStorageKind() == StorageKind && "Wrong ResultKind!");

E->ConstantExprBits.APValueKind = Record.readInt();
E->ConstantExprBits.IsUnsigned = Record.readInt();
Expand All @@ -544,14 +544,14 @@ void ASTStmtReader::VisitConstantExpr(ConstantExpr *E) {
E->ConstantExprBits.IsImmediateInvocation = Record.readInt();

switch (StorageKind) {
case ConstantExpr::RSK_None:
case ConstantResultStorageKind::None:
break;

case ConstantExpr::RSK_Int64:
case ConstantResultStorageKind::Int64:
E->Int64Result() = Record.readInt();
break;

case ConstantExpr::RSK_APValue:
case ConstantResultStorageKind::APValue:
E->APValueResult() = Record.readAPValue();
if (E->APValueResult().needsCleanup()) {
E->ConstantExprBits.HasCleanup = true;
Expand Down Expand Up @@ -2923,7 +2923,7 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) {

case EXPR_CONSTANT:
S = ConstantExpr::CreateEmpty(
Context, static_cast<ConstantExpr::ResultStorageKind>(
Context, static_cast<ConstantResultStorageKind>(
/*StorageKind=*/Record[ASTStmtReader::NumExprFields]));
break;

Expand Down
8 changes: 4 additions & 4 deletions clang/lib/Serialization/ASTWriterStmt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -564,13 +564,13 @@ void ASTStmtWriter::VisitConstantExpr(ConstantExpr *E) {
// HasCleanup not serialized since we can just query the APValue.
Record.push_back(E->ConstantExprBits.IsImmediateInvocation);

switch (E->ConstantExprBits.ResultKind) {
case ConstantExpr::RSK_None:
switch (E->getResultStorageKind()) {
case ConstantResultStorageKind::None:
break;
case ConstantExpr::RSK_Int64:
case ConstantResultStorageKind::Int64:
Record.push_back(E->Int64Result());
break;
case ConstantExpr::RSK_APValue:
case ConstantResultStorageKind::APValue:
Record.AddAPValue(E->APValueResult());
break;
default:
Expand Down

0 comments on commit cd60229

Please sign in to comment.