Skip to content
6 changes: 3 additions & 3 deletions clang/lib/CodeGen/ABIInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,9 @@ bool ABIInfo::isOHOSFamily() const {
return getTarget().getTriple().isOHOSFamily();
}

Address ABIInfo::EmitMSVAArg(CodeGenFunction &CGF, Address VAListAddr,
QualType Ty) const {
return Address::invalid();
RValue ABIInfo::EmitMSVAArg(CodeGenFunction &CGF, Address VAListAddr,
QualType Ty, AggValueSlot Slot) const {
return RValue::getIgnored();
}

bool ABIInfo::isHomogeneousAggregateBaseType(QualType Ty) const {
Expand Down
14 changes: 8 additions & 6 deletions clang/lib/CodeGen/ABIInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ class CGCXXABI;
class CGFunctionInfo;
class CodeGenFunction;
class CodeGenTypes;
class RValue;
class AggValueSlot;

// FIXME: All of this stuff should be part of the target interface
// somehow. It is currently here because it is not clear how to factor
Expand Down Expand Up @@ -75,18 +77,18 @@ class ABIInfo {
// the ABI information any lower than CodeGen. Of course, for
// VAArg handling it has to be at this level; there is no way to
// abstract this out.
virtual CodeGen::Address EmitVAArg(CodeGen::CodeGenFunction &CGF,
CodeGen::Address VAListAddr,
QualType Ty) const = 0;
virtual RValue EmitVAArg(CodeGen::CodeGenFunction &CGF,
CodeGen::Address VAListAddr, QualType Ty,
AggValueSlot Slot) const = 0;

bool isAndroid() const;
bool isOHOSFamily() const;

/// Emit the target dependent code to load a value of
/// \arg Ty from the \c __builtin_ms_va_list pointed to by \arg VAListAddr.
virtual CodeGen::Address EmitMSVAArg(CodeGen::CodeGenFunction &CGF,
CodeGen::Address VAListAddr,
QualType Ty) const;
virtual RValue EmitMSVAArg(CodeGen::CodeGenFunction &CGF,
CodeGen::Address VAListAddr, QualType Ty,
AggValueSlot Slot) const;

virtual bool isHomogeneousAggregateBaseType(QualType Ty) const;

Expand Down
23 changes: 13 additions & 10 deletions clang/lib/CodeGen/ABIInfoImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,9 +71,12 @@ void DefaultABIInfo::computeInfo(CGFunctionInfo &FI) const {
I.info = classifyArgumentType(I.type);
}

Address DefaultABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
QualType Ty) const {
return EmitVAArgInstr(CGF, VAListAddr, Ty, classifyArgumentType(Ty));
RValue DefaultABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
QualType Ty, AggValueSlot Slot) const {
return CGF.EmitLoadOfAnyValue(
CGF.MakeAddrLValue(
EmitVAArgInstr(CGF, VAListAddr, Ty, classifyArgumentType(Ty)), Ty),
Slot);
}

ABIArgInfo CodeGen::coerceToIntArray(QualType Ty, ASTContext &Context,
Expand Down Expand Up @@ -199,12 +202,12 @@ CodeGen::emitVoidPtrDirectVAArg(CodeGenFunction &CGF, Address VAListAddr,
return Addr.withElementType(DirectTy);
}

Address CodeGen::emitVoidPtrVAArg(CodeGenFunction &CGF, Address VAListAddr,
QualType ValueTy, bool IsIndirect,
TypeInfoChars ValueInfo,
CharUnits SlotSizeAndAlign,
bool AllowHigherAlign,
bool ForceRightAdjust) {
RValue CodeGen::emitVoidPtrVAArg(CodeGenFunction &CGF, Address VAListAddr,
QualType ValueTy, bool IsIndirect,
TypeInfoChars ValueInfo,
CharUnits SlotSizeAndAlign,
bool AllowHigherAlign, AggValueSlot Slot,
bool ForceRightAdjust) {
// The size and alignment of the value that was passed directly.
CharUnits DirectSize, DirectAlign;
if (IsIndirect) {
Expand All @@ -230,7 +233,7 @@ Address CodeGen::emitVoidPtrVAArg(CodeGenFunction &CGF, Address VAListAddr,
Addr = Address(CGF.Builder.CreateLoad(Addr), ElementTy, ValueInfo.Align);
}

return Addr;
return CGF.EmitLoadOfAnyValue(CGF.MakeAddrLValue(Addr, ValueTy), Slot);
}

Address CodeGen::emitMergePHI(CodeGenFunction &CGF, Address Addr1,
Expand Down
13 changes: 7 additions & 6 deletions clang/lib/CodeGen/ABIInfoImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ class DefaultABIInfo : public ABIInfo {

void computeInfo(CGFunctionInfo &FI) const override;

Address EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
QualType Ty) const override;
RValue EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, QualType Ty,
AggValueSlot Slot) const override;
};

// Helper for coercing an aggregate argument or return value into an integer
Expand Down Expand Up @@ -112,10 +112,11 @@ Address emitVoidPtrDirectVAArg(CodeGenFunction &CGF, Address VAListAddr,
/// \param ForceRightAdjust - Default is false. On big-endian platform and
/// if the argument is smaller than a slot, set this flag will force
/// right-adjust the argument in its slot irrespective of the type.
Address emitVoidPtrVAArg(CodeGenFunction &CGF, Address VAListAddr,
QualType ValueTy, bool IsIndirect,
TypeInfoChars ValueInfo, CharUnits SlotSizeAndAlign,
bool AllowHigherAlign, bool ForceRightAdjust = false);
RValue emitVoidPtrVAArg(CodeGenFunction &CGF, Address VAListAddr,
QualType ValueTy, bool IsIndirect,
TypeInfoChars ValueInfo, CharUnits SlotSizeAndAlign,
bool AllowHigherAlign, AggValueSlot Slot,
bool ForceRightAdjust = false);

Address emitMergePHI(CodeGenFunction &CGF, Address Addr1,
llvm::BasicBlock *Block1, Address Addr2,
Expand Down
12 changes: 6 additions & 6 deletions clang/lib/CodeGen/CGCall.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5989,12 +5989,12 @@ CGCallee CGCallee::prepareConcreteCallee(CodeGenFunction &CGF) const {

/* VarArg handling */

Address CodeGenFunction::EmitVAArg(VAArgExpr *VE, Address &VAListAddr) {
VAListAddr = VE->isMicrosoftABI()
? EmitMSVAListRef(VE->getSubExpr())
: EmitVAListRef(VE->getSubExpr());
RValue CodeGenFunction::EmitVAArg(VAArgExpr *VE, Address &VAListAddr,
AggValueSlot Slot) {
VAListAddr = VE->isMicrosoftABI() ? EmitMSVAListRef(VE->getSubExpr())
: EmitVAListRef(VE->getSubExpr());
QualType Ty = VE->getType();
if (VE->isMicrosoftABI())
return CGM.getTypes().getABIInfo().EmitMSVAArg(*this, VAListAddr, Ty);
return CGM.getTypes().getABIInfo().EmitVAArg(*this, VAListAddr, Ty);
return CGM.getTypes().getABIInfo().EmitMSVAArg(*this, VAListAddr, Ty, Slot);
return CGM.getTypes().getABIInfo().EmitVAArg(*this, VAListAddr, Ty, Slot);
}
15 changes: 15 additions & 0 deletions clang/lib/CodeGen/CGExpr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2161,6 +2161,21 @@ static RValue EmitLoadOfMatrixLValue(LValue LV, SourceLocation Loc,
return RValue::get(CGF.EmitLoadOfScalar(LV, Loc));
}

RValue CodeGenFunction::EmitLoadOfAnyValue(LValue LV, AggValueSlot Slot,
SourceLocation Loc) {
QualType Ty = LV.getType();
switch (getEvaluationKind(Ty)) {
case TEK_Scalar:
return EmitLoadOfLValue(LV, Loc);
case TEK_Complex:
return RValue::getComplex(EmitLoadOfComplex(LV, Loc));
case TEK_Aggregate:
EmitAggFinalDestCopy(Ty, Slot, LV, EVK_NonRValue);
return Slot.asRValue();
}
llvm_unreachable("bad evaluation kind");
}

/// EmitLoadOfLValue - Given an expression that represents a value lvalue, this
/// method emits the address of the lvalue, then loads the result as an rvalue,
/// returning the rvalue.
Expand Down
30 changes: 16 additions & 14 deletions clang/lib/CodeGen/CGExprAgg.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,15 +78,11 @@ class AggExprEmitter : public StmtVisitor<AggExprEmitter> {
/// then loads the result into DestPtr.
void EmitAggLoadOfLValue(const Expr *E);

enum ExprValueKind {
EVK_RValue,
EVK_NonRValue
};

/// EmitFinalDestCopy - Perform the final copy to DestPtr, if desired.
/// SrcIsRValue is true if source comes from an RValue.
void EmitFinalDestCopy(QualType type, const LValue &src,
ExprValueKind SrcValueKind = EVK_NonRValue);
CodeGenFunction::ExprValueKind SrcValueKind =
CodeGenFunction::EVK_NonRValue);
void EmitFinalDestCopy(QualType type, RValue src);
void EmitCopy(QualType type, const AggValueSlot &dest,
const AggValueSlot &src);
Expand Down Expand Up @@ -348,12 +344,13 @@ void AggExprEmitter::withReturnValueSlot(
void AggExprEmitter::EmitFinalDestCopy(QualType type, RValue src) {
assert(src.isAggregate() && "value must be aggregate value!");
LValue srcLV = CGF.MakeAddrLValue(src.getAggregateAddress(), type);
EmitFinalDestCopy(type, srcLV, EVK_RValue);
EmitFinalDestCopy(type, srcLV, CodeGenFunction::EVK_RValue);
}

/// EmitFinalDestCopy - Perform the final copy to DestPtr, if desired.
void AggExprEmitter::EmitFinalDestCopy(QualType type, const LValue &src,
ExprValueKind SrcValueKind) {
void AggExprEmitter::EmitFinalDestCopy(
QualType type, const LValue &src,
CodeGenFunction::ExprValueKind SrcValueKind) {
// If Dest is ignored, then we're evaluating an aggregate expression
// in a context that doesn't care about the result. Note that loads
// from volatile l-values force the existence of a non-ignored
Expand All @@ -365,7 +362,7 @@ void AggExprEmitter::EmitFinalDestCopy(QualType type, const LValue &src,
LValue DstLV = CGF.MakeAddrLValue(
Dest.getAddress(), Dest.isVolatile() ? type.withVolatile() : type);

if (SrcValueKind == EVK_RValue) {
if (SrcValueKind == CodeGenFunction::EVK_RValue) {
if (type.isNonTrivialToPrimitiveDestructiveMove() == QualType::PCK_Struct) {
if (Dest.isPotentiallyAliased())
CGF.callCStructMoveAssignmentOperator(DstLV, src);
Expand Down Expand Up @@ -1317,15 +1314,13 @@ void AggExprEmitter::VisitChooseExpr(const ChooseExpr *CE) {

void AggExprEmitter::VisitVAArgExpr(VAArgExpr *VE) {
Address ArgValue = Address::invalid();
Address ArgPtr = CGF.EmitVAArg(VE, ArgValue);
CGF.EmitVAArg(VE, ArgValue, Dest);

// If EmitVAArg fails, emit an error.
if (!ArgPtr.isValid()) {
if (!ArgValue.isValid()) {
CGF.ErrorUnsupported(VE, "aggregate va_arg expression");
return;
}

EmitFinalDestCopy(VE->getType(), CGF.MakeAddrLValue(ArgPtr, VE->getType()));
}

void AggExprEmitter::VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E) {
Expand Down Expand Up @@ -2027,6 +2022,13 @@ LValue CodeGenFunction::EmitAggExprToLValue(const Expr *E) {
return LV;
}

void CodeGenFunction::EmitAggFinalDestCopy(QualType Type, AggValueSlot Dest,
const LValue &Src,
ExprValueKind SrcKind) {
return AggExprEmitter(*this, Dest, Dest.isIgnored())
.EmitFinalDestCopy(Type, Src, SrcKind);
}

AggValueSlot::Overlap_t
CodeGenFunction::getOverlapForFieldInit(const FieldDecl *FD) {
if (!FD->hasAttr<NoUniqueAddressAttr>() || !FD->getType()->isRecordType())
Expand Down
7 changes: 3 additions & 4 deletions clang/lib/CodeGen/CGExprComplex.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1448,18 +1448,17 @@ ComplexPairTy ComplexExprEmitter::VisitInitListExpr(InitListExpr *E) {

ComplexPairTy ComplexExprEmitter::VisitVAArgExpr(VAArgExpr *E) {
Address ArgValue = Address::invalid();
Address ArgPtr = CGF.EmitVAArg(E, ArgValue);
RValue RV = CGF.EmitVAArg(E, ArgValue);

if (!ArgPtr.isValid()) {
if (!ArgValue.isValid()) {
CGF.ErrorUnsupported(E, "complex va_arg expression");
llvm::Type *EltTy =
CGF.ConvertType(E->getType()->castAs<ComplexType>()->getElementType());
llvm::Value *U = llvm::UndefValue::get(EltTy);
return ComplexPairTy(U, U);
}

return EmitLoadOfLValue(CGF.MakeAddrLValue(ArgPtr, E->getType()),
E->getExprLoc());
return RV.getComplexVal();
}

//===----------------------------------------------------------------------===//
Expand Down
23 changes: 2 additions & 21 deletions clang/lib/CodeGen/CGExprScalar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5357,28 +5357,9 @@ Value *ScalarExprEmitter::VisitVAArgExpr(VAArgExpr *VE) {
CGF.EmitVariablyModifiedType(Ty);

Address ArgValue = Address::invalid();
Address ArgPtr = CGF.EmitVAArg(VE, ArgValue);
RValue ArgPtr = CGF.EmitVAArg(VE, ArgValue);

llvm::Type *ArgTy = ConvertType(VE->getType());

// If EmitVAArg fails, emit an error.
if (!ArgPtr.isValid()) {
CGF.ErrorUnsupported(VE, "va_arg expression");
return llvm::UndefValue::get(ArgTy);
}

// FIXME Volatility.
llvm::Value *Val = Builder.CreateLoad(ArgPtr);

// If EmitVAArg promoted the type, we must truncate it.
if (ArgTy != Val->getType()) {
if (ArgTy->isPointerTy() && !Val->getType()->isPointerTy())
Val = Builder.CreateIntToPtr(Val, ArgTy);
else
Val = Builder.CreateTrunc(Val, ArgTy);
}

return Val;
return ArgPtr.getScalarVal();
}

Value *ScalarExprEmitter::VisitBlockExpr(const BlockExpr *block) {
Expand Down
15 changes: 14 additions & 1 deletion clang/lib/CodeGen/CodeGenFunction.h
Original file line number Diff line number Diff line change
Expand Up @@ -3014,7 +3014,8 @@ class CodeGenFunction : public CodeGenTypeCache {
/// \returns A pointer to the argument.
// FIXME: We should be able to get rid of this method and use the va_arg
// instruction in LLVM instead once it works well enough.
Address EmitVAArg(VAArgExpr *VE, Address &VAListAddr);
RValue EmitVAArg(VAArgExpr *VE, Address &VAListAddr,
AggValueSlot Slot = AggValueSlot::ignored());

/// emitArrayLength - Compute the length of an array, even if it's a
/// VLA, and drill down to the base element type.
Expand Down Expand Up @@ -4215,6 +4216,11 @@ class CodeGenFunction : public CodeGenTypeCache {
RValue EmitLoadOfBitfieldLValue(LValue LV, SourceLocation Loc);
RValue EmitLoadOfGlobalRegLValue(LValue LV);

/// Like EmitLoadOfLValue but also handles complex and aggregate types.
RValue EmitLoadOfAnyValue(LValue V,
AggValueSlot Slot = AggValueSlot::ignored(),
SourceLocation Loc = {});

/// EmitStoreThroughLValue - Store the specified rvalue into the specified
/// lvalue, where both are guaranteed to the have the same type, and that type
/// is 'Ty'.
Expand Down Expand Up @@ -4775,6 +4781,13 @@ class CodeGenFunction : public CodeGenTypeCache {
/// aggregate type into a temporary LValue.
LValue EmitAggExprToLValue(const Expr *E);

enum ExprValueKind { EVK_RValue, EVK_NonRValue };

/// EmitAggFinalDestCopy - Emit copy of the specified aggregate into
/// destination address.
void EmitAggFinalDestCopy(QualType Type, AggValueSlot Dest, const LValue &Src,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It feels strange to be adding this API now... but I guess it's fine? The alternative would be to use EmitAggregateCopy directly. It only really makes a difference for structs containing pointers to ObjC types, which can't be passed by va_arg anyway, but I guess it's better for EmitLoadOfAnyValue to be fully general in case we add other uses in the future.

ExprValueKind SrcKind);

/// Build all the stores needed to initialize an aggregate at Dest with the
/// value Val.
void EmitAggregateStore(llvm::Value *Val, Address Dest, bool DestIsVolatile);
Expand Down
Loading