Skip to content

[clang][CodeGen][NFC] Make ConstExprEmitter a ConstStmtVisitor #89041

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 23, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
108 changes: 56 additions & 52 deletions clang/lib/CodeGen/CGExprConstant.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -564,12 +564,13 @@ class ConstStructBuilder {

public:
static llvm::Constant *BuildStruct(ConstantEmitter &Emitter,
InitListExpr *ILE, QualType StructTy);
const InitListExpr *ILE,
QualType StructTy);
static llvm::Constant *BuildStruct(ConstantEmitter &Emitter,
const APValue &Value, QualType ValTy);
static bool UpdateStruct(ConstantEmitter &Emitter,
ConstantAggregateBuilder &Const, CharUnits Offset,
InitListExpr *Updater);
const InitListExpr *Updater);

private:
ConstStructBuilder(ConstantEmitter &Emitter,
Expand All @@ -586,7 +587,7 @@ class ConstStructBuilder {
bool AppendBitField(const FieldDecl *Field, uint64_t FieldOffset,
llvm::ConstantInt *InitExpr, bool AllowOverwrite = false);

bool Build(InitListExpr *ILE, bool AllowOverwrite);
bool Build(const InitListExpr *ILE, bool AllowOverwrite);
bool Build(const APValue &Val, const RecordDecl *RD, bool IsPrimaryBase,
const CXXRecordDecl *VTableClass, CharUnits BaseOffset);
llvm::Constant *Finalize(QualType Ty);
Expand Down Expand Up @@ -635,7 +636,7 @@ bool ConstStructBuilder::AppendBitField(
static bool EmitDesignatedInitUpdater(ConstantEmitter &Emitter,
ConstantAggregateBuilder &Const,
CharUnits Offset, QualType Type,
InitListExpr *Updater) {
const InitListExpr *Updater) {
if (Type->isRecordType())
return ConstStructBuilder::UpdateStruct(Emitter, Const, Offset, Updater);

Expand All @@ -647,7 +648,7 @@ static bool EmitDesignatedInitUpdater(ConstantEmitter &Emitter,
llvm::Type *ElemTy = Emitter.CGM.getTypes().ConvertTypeForMem(ElemType);

llvm::Constant *FillC = nullptr;
if (Expr *Filler = Updater->getArrayFiller()) {
if (const Expr *Filler = Updater->getArrayFiller()) {
if (!isa<NoInitExpr>(Filler)) {
FillC = Emitter.tryEmitAbstractForMemory(Filler, ElemType);
if (!FillC)
Expand All @@ -658,7 +659,7 @@ static bool EmitDesignatedInitUpdater(ConstantEmitter &Emitter,
unsigned NumElementsToUpdate =
FillC ? CAT->getZExtSize() : Updater->getNumInits();
for (unsigned I = 0; I != NumElementsToUpdate; ++I, Offset += ElemSize) {
Expr *Init = nullptr;
const Expr *Init = nullptr;
if (I < Updater->getNumInits())
Init = Updater->getInit(I);

Expand All @@ -667,7 +668,7 @@ static bool EmitDesignatedInitUpdater(ConstantEmitter &Emitter,
return false;
} else if (!Init || isa<NoInitExpr>(Init)) {
continue;
} else if (InitListExpr *ChildILE = dyn_cast<InitListExpr>(Init)) {
} else if (const auto *ChildILE = dyn_cast<InitListExpr>(Init)) {
if (!EmitDesignatedInitUpdater(Emitter, Const, Offset, ElemType,
ChildILE))
return false;
Expand All @@ -683,7 +684,7 @@ static bool EmitDesignatedInitUpdater(ConstantEmitter &Emitter,
return true;
}

bool ConstStructBuilder::Build(InitListExpr *ILE, bool AllowOverwrite) {
bool ConstStructBuilder::Build(const InitListExpr *ILE, bool AllowOverwrite) {
RecordDecl *RD = ILE->getType()->castAs<RecordType>()->getDecl();
const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD);

Expand Down Expand Up @@ -711,7 +712,7 @@ bool ConstStructBuilder::Build(InitListExpr *ILE, bool AllowOverwrite) {

// Get the initializer. A struct can include fields without initializers,
// we just use explicit null values for them.
Expr *Init = nullptr;
const Expr *Init = nullptr;
if (ElementNo < ILE->getNumInits())
Init = ILE->getInit(ElementNo++);
if (Init && isa<NoInitExpr>(Init))
Expand Down Expand Up @@ -879,7 +880,7 @@ llvm::Constant *ConstStructBuilder::Finalize(QualType Type) {
}

llvm::Constant *ConstStructBuilder::BuildStruct(ConstantEmitter &Emitter,
InitListExpr *ILE,
const InitListExpr *ILE,
QualType ValTy) {
ConstantAggregateBuilder Const(Emitter.CGM);
ConstStructBuilder Builder(Emitter, Const, CharUnits::Zero());
Expand All @@ -906,7 +907,8 @@ llvm::Constant *ConstStructBuilder::BuildStruct(ConstantEmitter &Emitter,

bool ConstStructBuilder::UpdateStruct(ConstantEmitter &Emitter,
ConstantAggregateBuilder &Const,
CharUnits Offset, InitListExpr *Updater) {
CharUnits Offset,
const InitListExpr *Updater) {
return ConstStructBuilder(Emitter, Const, Offset)
.Build(Updater, /*AllowOverwrite*/ true);
}
Expand Down Expand Up @@ -1013,8 +1015,8 @@ EmitArrayConstant(CodeGenModule &CGM, llvm::ArrayType *DesiredType,
//
// Constant folding is currently missing support for a few features supported
// here: CK_ToUnion, CK_ReinterpretMemberPointer, and DesignatedInitUpdateExpr.
class ConstExprEmitter :
public StmtVisitor<ConstExprEmitter, llvm::Constant*, QualType> {
class ConstExprEmitter
: public ConstStmtVisitor<ConstExprEmitter, llvm::Constant *, QualType> {
CodeGenModule &CGM;
ConstantEmitter &Emitter;
llvm::LLVMContext &VMContext;
Expand All @@ -1027,43 +1029,42 @@ class ConstExprEmitter :
// Visitor Methods
//===--------------------------------------------------------------------===//

llvm::Constant *VisitStmt(Stmt *S, QualType T) {
return nullptr;
}
llvm::Constant *VisitStmt(const Stmt *S, QualType T) { return nullptr; }

llvm::Constant *VisitConstantExpr(ConstantExpr *CE, QualType T) {
llvm::Constant *VisitConstantExpr(const ConstantExpr *CE, QualType T) {
if (llvm::Constant *Result = Emitter.tryEmitConstantExpr(CE))
return Result;
return Visit(CE->getSubExpr(), T);
}

llvm::Constant *VisitParenExpr(ParenExpr *PE, QualType T) {
llvm::Constant *VisitParenExpr(const ParenExpr *PE, QualType T) {
return Visit(PE->getSubExpr(), T);
}

llvm::Constant *
VisitSubstNonTypeTemplateParmExpr(SubstNonTypeTemplateParmExpr *PE,
VisitSubstNonTypeTemplateParmExpr(const SubstNonTypeTemplateParmExpr *PE,
QualType T) {
return Visit(PE->getReplacement(), T);
}

llvm::Constant *VisitGenericSelectionExpr(GenericSelectionExpr *GE,
llvm::Constant *VisitGenericSelectionExpr(const GenericSelectionExpr *GE,
QualType T) {
return Visit(GE->getResultExpr(), T);
}

llvm::Constant *VisitChooseExpr(ChooseExpr *CE, QualType T) {
llvm::Constant *VisitChooseExpr(const ChooseExpr *CE, QualType T) {
return Visit(CE->getChosenSubExpr(), T);
}

llvm::Constant *VisitCompoundLiteralExpr(CompoundLiteralExpr *E, QualType T) {
llvm::Constant *VisitCompoundLiteralExpr(const CompoundLiteralExpr *E,
QualType T) {
return Visit(E->getInitializer(), T);
}

llvm::Constant *VisitCastExpr(CastExpr *E, QualType destType) {
llvm::Constant *VisitCastExpr(const CastExpr *E, QualType destType) {
if (const auto *ECE = dyn_cast<ExplicitCastExpr>(E))
CGM.EmitExplicitCastExprType(ECE, Emitter.CGF);
Expr *subExpr = E->getSubExpr();
const Expr *subExpr = E->getSubExpr();

switch (E->getCastKind()) {
case CK_ToUnion: {
Expand Down Expand Up @@ -1117,7 +1118,8 @@ class ConstExprEmitter :
// interesting conversions should be done in Evaluate(). But as a
// special case, allow compound literals to support the gcc extension
// allowing "struct x {int x;} x = (struct x) {};".
if (auto *E = dyn_cast<CompoundLiteralExpr>(subExpr->IgnoreParens()))
if (const auto *E =
dyn_cast<CompoundLiteralExpr>(subExpr->IgnoreParens()))
return Visit(E->getInitializer(), destType);
return nullptr;
}
Expand Down Expand Up @@ -1232,21 +1234,22 @@ class ConstExprEmitter :
llvm_unreachable("Invalid CastKind");
}

llvm::Constant *VisitCXXDefaultInitExpr(CXXDefaultInitExpr *DIE, QualType T) {
llvm::Constant *VisitCXXDefaultInitExpr(const CXXDefaultInitExpr *DIE,
QualType T) {
// No need for a DefaultInitExprScope: we don't handle 'this' in a
// constant expression.
return Visit(DIE->getExpr(), T);
}

llvm::Constant *VisitExprWithCleanups(ExprWithCleanups *E, QualType T) {
llvm::Constant *VisitExprWithCleanups(const ExprWithCleanups *E, QualType T) {
return Visit(E->getSubExpr(), T);
}

llvm::Constant *VisitIntegerLiteral(IntegerLiteral *I, QualType T) {
llvm::Constant *VisitIntegerLiteral(const IntegerLiteral *I, QualType T) {
return llvm::ConstantInt::get(CGM.getLLVMContext(), I->getValue());
}

llvm::Constant *EmitArrayInitialization(InitListExpr *ILE, QualType T) {
llvm::Constant *EmitArrayInitialization(const InitListExpr *ILE, QualType T) {
auto *CAT = CGM.getContext().getAsConstantArrayType(ILE->getType());
assert(CAT && "can't emit array init for non-constant-bound array");
unsigned NumInitElements = ILE->getNumInits();
Expand All @@ -1260,7 +1263,7 @@ class ConstExprEmitter :

// Initialize remaining array elements.
llvm::Constant *fillC = nullptr;
if (Expr *filler = ILE->getArrayFiller()) {
if (const Expr *filler = ILE->getArrayFiller()) {
fillC = Emitter.tryEmitAbstractForMemory(filler, EltType);
if (!fillC)
return nullptr;
Expand All @@ -1275,7 +1278,7 @@ class ConstExprEmitter :

llvm::Type *CommonElementType = nullptr;
for (unsigned i = 0; i < NumInitableElts; ++i) {
Expr *Init = ILE->getInit(i);
const Expr *Init = ILE->getInit(i);
llvm::Constant *C = Emitter.tryEmitPrivateForMemory(Init, EltType);
if (!C)
return nullptr;
Expand All @@ -1292,16 +1295,17 @@ class ConstExprEmitter :
fillC);
}

llvm::Constant *EmitRecordInitialization(InitListExpr *ILE, QualType T) {
llvm::Constant *EmitRecordInitialization(const InitListExpr *ILE,
QualType T) {
return ConstStructBuilder::BuildStruct(Emitter, ILE, T);
}

llvm::Constant *VisitImplicitValueInitExpr(ImplicitValueInitExpr* E,
llvm::Constant *VisitImplicitValueInitExpr(const ImplicitValueInitExpr *E,
QualType T) {
return CGM.EmitNullConstant(T);
}

llvm::Constant *VisitInitListExpr(InitListExpr *ILE, QualType T) {
llvm::Constant *VisitInitListExpr(const InitListExpr *ILE, QualType T) {
if (ILE->isTransparent())
return Visit(ILE->getInit(0), T);

Expand All @@ -1314,8 +1318,9 @@ class ConstExprEmitter :
return nullptr;
}

llvm::Constant *VisitDesignatedInitUpdateExpr(DesignatedInitUpdateExpr *E,
QualType destType) {
llvm::Constant *
VisitDesignatedInitUpdateExpr(const DesignatedInitUpdateExpr *E,
QualType destType) {
auto C = Visit(E->getBase(), destType);
if (!C)
return nullptr;
Expand All @@ -1329,12 +1334,13 @@ class ConstExprEmitter :

llvm::Type *ValTy = CGM.getTypes().ConvertType(destType);
bool HasFlexibleArray = false;
if (auto *RT = destType->getAs<RecordType>())
if (const auto *RT = destType->getAs<RecordType>())
HasFlexibleArray = RT->getDecl()->hasFlexibleArrayMember();
return Const.build(ValTy, HasFlexibleArray);
}

llvm::Constant *VisitCXXConstructExpr(CXXConstructExpr *E, QualType Ty) {
llvm::Constant *VisitCXXConstructExpr(const CXXConstructExpr *E,
QualType Ty) {
if (!E->getConstructor()->isTrivial())
return nullptr;

Expand All @@ -1344,13 +1350,13 @@ class ConstExprEmitter :
assert(E->getConstructor()->isCopyOrMoveConstructor() &&
"trivial ctor has argument but isn't a copy/move ctor");

Expr *Arg = E->getArg(0);
const Expr *Arg = E->getArg(0);
assert(CGM.getContext().hasSameUnqualifiedType(Ty, Arg->getType()) &&
"argument to copy ctor is of wrong type");

// Look through the temporary; it's just converting the value to an
// lvalue to pass it to the constructor.
if (auto *MTE = dyn_cast<MaterializeTemporaryExpr>(Arg))
if (const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(Arg))
return Visit(MTE->getSubExpr(), Ty);
// Don't try to support arbitrary lvalue-to-rvalue conversions for now.
return nullptr;
Expand All @@ -1359,12 +1365,12 @@ class ConstExprEmitter :
return CGM.EmitNullConstant(Ty);
}

llvm::Constant *VisitStringLiteral(StringLiteral *E, QualType T) {
llvm::Constant *VisitStringLiteral(const StringLiteral *E, QualType T) {
// This is a string literal initializing an array in an initializer.
return CGM.GetConstantArrayFromStringLiteral(E);
}

llvm::Constant *VisitObjCEncodeExpr(ObjCEncodeExpr *E, QualType T) {
llvm::Constant *VisitObjCEncodeExpr(const ObjCEncodeExpr *E, QualType T) {
// This must be an @encode initializing an array in a static initializer.
// Don't emit it as the address of the string, emit the string data itself
// as an inline array.
Expand All @@ -1383,14 +1389,14 @@ class ConstExprEmitter :
return Visit(E->getSubExpr(), T);
}

llvm::Constant *VisitUnaryMinus(UnaryOperator *U, QualType T) {
llvm::Constant *VisitUnaryMinus(const UnaryOperator *U, QualType T) {
if (llvm::Constant *C = Visit(U->getSubExpr(), T))
if (auto *CI = dyn_cast<llvm::ConstantInt>(C))
return llvm::ConstantInt::get(CGM.getLLVMContext(), -CI->getValue());
return nullptr;
}

llvm::Constant *VisitPackIndexingExpr(PackIndexingExpr *E, QualType T) {
llvm::Constant *VisitPackIndexingExpr(const PackIndexingExpr *E, QualType T) {
return Visit(E->getSelectedExpr(), T);
}

Expand Down Expand Up @@ -1696,8 +1702,7 @@ llvm::Constant *ConstantEmitter::tryEmitPrivateForVarInit(const VarDecl &D) {

if (!destType->isReferenceType()) {
QualType nonMemoryDestType = getNonMemoryType(CGM, destType);
if (llvm::Constant *C = ConstExprEmitter(*this).Visit(const_cast<Expr *>(E),
nonMemoryDestType))
if (llvm::Constant *C = ConstExprEmitter(*this).Visit(E, nonMemoryDestType))
return emitForMemory(C, destType);
}

Expand Down Expand Up @@ -1777,8 +1782,7 @@ llvm::Constant *ConstantEmitter::tryEmitPrivate(const Expr *E,
assert(!destType->isVoidType() && "can't emit a void constant");

if (!destType->isReferenceType())
if (llvm::Constant *C =
ConstExprEmitter(*this).Visit(const_cast<Expr *>(E), destType))
if (llvm::Constant *C = ConstExprEmitter(*this).Visit(E, destType))
return C;

Expr::EvalResult Result;
Expand Down Expand Up @@ -2022,7 +2026,7 @@ ConstantLValue
ConstantLValueEmitter::VisitObjCBoxedExpr(const ObjCBoxedExpr *E) {
assert(E->isExpressibleAsConstantInitializer() &&
"this boxed expression can't be emitted as a compile-time constant");
auto *SL = cast<StringLiteral>(E->getSubExpr()->IgnoreParenCasts());
const auto *SL = cast<StringLiteral>(E->getSubExpr()->IgnoreParenCasts());
return emitConstantObjCStringLiteral(SL, E->getType(), CGM);
}

Expand All @@ -2048,12 +2052,12 @@ ConstantLValueEmitter::VisitCallExpr(const CallExpr *E) {
builtin != Builtin::BI__builtin___NSStringMakeConstantString)
return nullptr;

auto literal = cast<StringLiteral>(E->getArg(0)->IgnoreParenCasts());
const auto *Literal = cast<StringLiteral>(E->getArg(0)->IgnoreParenCasts());
if (builtin == Builtin::BI__builtin___NSStringMakeConstantString) {
return CGM.getObjCRuntime().GenerateConstantString(literal);
return CGM.getObjCRuntime().GenerateConstantString(Literal);
} else {
// FIXME: need to deal with UCN conversion issues.
return CGM.GetAddrOfConstantCFString(literal);
return CGM.GetAddrOfConstantCFString(Literal);
}
}

Expand Down