Skip to content
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

[CIR][CodeGen][NFC] centralized split std::initializer_list field #1235

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
122 changes: 64 additions & 58 deletions clang/lib/CIR/CodeGen/CIRGenExprAgg.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -296,64 +296,7 @@ class AggExprEmitter : public StmtVisitor<AggExprEmitter> {
void VisitCXXConstructExpr(const CXXConstructExpr *E);
void VisitCXXInheritedCtorInitExpr(const CXXInheritedCtorInitExpr *E);
void VisitLambdaExpr(LambdaExpr *E);
void VisitCXXStdInitializerListExpr(CXXStdInitializerListExpr *E) {
ASTContext &Ctx = CGF.getContext();
CIRGenFunction::SourceLocRAIIObject locRAIIObject{
CGF, CGF.getLoc(E->getSourceRange())};
// Emit an array containing the elements. The array is externally
// destructed if the std::initializer_list object is.
LValue Array = CGF.emitLValue(E->getSubExpr());
assert(Array.isSimple() && "initializer_list array not a simple lvalue");
Address ArrayPtr = Array.getAddress();

const ConstantArrayType *ArrayType =
Ctx.getAsConstantArrayType(E->getSubExpr()->getType());
assert(ArrayType && "std::initializer_list constructed from non-array");

RecordDecl *Record = E->getType()->castAs<RecordType>()->getDecl();
RecordDecl::field_iterator Field = Record->field_begin();
assert(Field != Record->field_end() &&
Ctx.hasSameType(Field->getType()->getPointeeType(),
ArrayType->getElementType()) &&
"Expected std::initializer_list first field to be const E *");
// Start pointer.
auto loc = CGF.getLoc(E->getSourceRange());
AggValueSlot Dest = EnsureSlot(loc, E->getType());
LValue DestLV = CGF.makeAddrLValue(Dest.getAddress(), E->getType());
LValue Start =
CGF.emitLValueForFieldInitialization(DestLV, *Field, Field->getName());
mlir::Value ArrayStart = ArrayPtr.emitRawPointer();
CGF.emitStoreThroughLValue(RValue::get(ArrayStart), Start);
++Field;
assert(Field != Record->field_end() &&
"Expected std::initializer_list to have two fields");

auto Builder = CGF.getBuilder();

auto sizeOp = Builder.getConstInt(loc, ArrayType->getSize());

mlir::Value Size = sizeOp.getRes();
Builder.getUIntNTy(ArrayType->getSizeBitWidth());
LValue EndOrLength =
CGF.emitLValueForFieldInitialization(DestLV, *Field, Field->getName());
if (Ctx.hasSameType(Field->getType(), Ctx.getSizeType())) {
// Length.
CGF.emitStoreThroughLValue(RValue::get(Size), EndOrLength);
} else {
// End pointer.
assert(Field->getType()->isPointerType() &&
Ctx.hasSameType(Field->getType()->getPointeeType(),
ArrayType->getElementType()) &&
"Expected std::initializer_list second field to be const E *");

auto ArrayEnd =
Builder.getArrayElement(loc, loc, ArrayPtr.getPointer(),
ArrayPtr.getElementType(), Size, false);
CGF.emitStoreThroughLValue(RValue::get(ArrayEnd), EndOrLength);
}
assert(++Field == Record->field_end() &&
"Expected std::initializer_list to only have two fields");
}
void VisitCXXStdInitializerListExpr(CXXStdInitializerListExpr *E);

void VisitExprWithCleanups(ExprWithCleanups *E);
void VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E) {
Expand Down Expand Up @@ -952,6 +895,69 @@ void AggExprEmitter::VisitLambdaExpr(LambdaExpr *E) {
}
}

void AggExprEmitter::VisitCXXStdInitializerListExpr(
CXXStdInitializerListExpr *E) {
ASTContext &Ctx = CGF.getContext();
CIRGenFunction::SourceLocRAIIObject locRAIIObject{
CGF, CGF.getLoc(E->getSourceRange())};
// Emit an array containing the elements. The array is externally
// destructed if the std::initializer_list object is.
LValue Array = CGF.emitLValue(E->getSubExpr());
assert(Array.isSimple() && "initializer_list array not a simple lvalue");
Address ArrayPtr = Array.getAddress();

const ConstantArrayType *ArrayType =
Ctx.getAsConstantArrayType(E->getSubExpr()->getType());
assert(ArrayType && "std::initializer_list constructed from non-array");

RecordDecl *Record = E->getType()->castAs<RecordType>()->getDecl();
RecordDecl::field_iterator Field = Record->field_begin();
assert(Field != Record->field_end() &&
Ctx.hasSameType(Field->getType()->getPointeeType(),
ArrayType->getElementType()) &&
"Expected std::initializer_list first field to be const E *");
const FieldDecl *StartField = *Field;
++Field;
assert(Field != Record->field_end() &&
"Expected std::initializer_list to have two fields");
const FieldDecl *EndOrLengthField = *Field;
++Field;
assert(Field == Record->field_end() &&
"Expected std::initializer_list to only have two fields");

// Start pointer.
auto loc = CGF.getLoc(E->getSourceRange());
AggValueSlot Dest = EnsureSlot(loc, E->getType());
LValue DestLV = CGF.makeAddrLValue(Dest.getAddress(), E->getType());
LValue Start = CGF.emitLValueForFieldInitialization(DestLV, StartField,
StartField->getName());
mlir::Value ArrayStart = ArrayPtr.emitRawPointer();
CGF.emitStoreThroughLValue(RValue::get(ArrayStart), Start);

auto Builder = CGF.getBuilder();

auto sizeOp = Builder.getConstInt(loc, ArrayType->getSize());

mlir::Value Size = sizeOp.getRes();
LValue EndOrLength = CGF.emitLValueForFieldInitialization(
DestLV, EndOrLengthField, EndOrLengthField->getName());
if (Ctx.hasSameType(EndOrLengthField->getType(), Ctx.getSizeType())) {
// Length.
CGF.emitStoreThroughLValue(RValue::get(Size), EndOrLength);
} else {
// End pointer.
assert(EndOrLengthField->getType()->isPointerType() &&
Ctx.hasSameType(EndOrLengthField->getType()->getPointeeType(),
ArrayType->getElementType()) &&
"Expected std::initializer_list second field to be const E *");

auto ArrayEnd =
Builder.getArrayElement(loc, loc, ArrayPtr.getPointer(),
ArrayPtr.getElementType(), Size, false);
CGF.emitStoreThroughLValue(RValue::get(ArrayEnd), EndOrLength);
}
}

void AggExprEmitter::VisitCastExpr(CastExpr *E) {
if (const auto *ECE = dyn_cast<ExplicitCastExpr>(E))
CGF.CGM.emitExplicitCastExprType(ECE, &CGF);
Expand Down
Loading