class ABIArgInfo {
public:
enum Kind {
- Default,
-
Direct, /// Pass the argument directly using the normal
/// converted LLVM type.
/// are all scalar types or are themselves expandable
/// types.
- KindFirst=Default, KindLast=Expand
+ KindFirst=Direct, KindLast=Expand
};
private:
TypeData(TD),
UIntData(0) {}
public:
- ABIArgInfo() : TheKind(Default), TypeData(0), UIntData(0) {}
+ ABIArgInfo() : TheKind(Direct), TypeData(0), UIntData(0) {}
- static ABIArgInfo getDefault() {
- return ABIArgInfo(Default);
- }
static ABIArgInfo getDirect() {
return ABIArgInfo(Direct);
}
}
Kind getKind() const { return TheKind; }
- bool isDefault() const { return TheKind == Default; }
bool isDirect() const { return TheKind == Direct; }
bool isStructRet() const { return TheKind == StructRet; }
bool isIgnore() const { return TheKind == Ignore; }
ABIArgInfo X86_32ABIInfo::classifyReturnType(QualType RetTy,
ASTContext &Context) const {
- if (CodeGenFunction::hasAggregateLLVMType(RetTy)) {
+ if (RetTy->isVoidType()) {
+ return ABIArgInfo::getIgnore();
+ } else if (CodeGenFunction::hasAggregateLLVMType(RetTy)) {
// Classify "single element" structs as their element type.
const FieldDecl *SeltFD = isSingleElementStruct(RetTy);
if (SeltFD) {
return ABIArgInfo::getStructRet();
}
} else {
- return ABIArgInfo::getDefault();
+ return ABIArgInfo::getDirect();
}
}
return ABIArgInfo::getByVal(0);
} else {
- return ABIArgInfo::getDefault();
+ return ABIArgInfo::getDirect();
}
}
ABIArgInfo X86_64ABIInfo::classifyArgumentType(QualType Ty,
ASTContext &Context) const {
- return ABIArgInfo::getDefault();
+ if (CodeGenFunction::hasAggregateLLVMType(Ty)) {
+ return ABIArgInfo::getByVal(0);
+ } else {
+ return ABIArgInfo::getDirect();
+ }
}
ABIArgInfo DefaultABIInfo::classifyReturnType(QualType RetTy,
ASTContext &Context) const {
- return ABIArgInfo::getDefault();
+ if (RetTy->isVoidType()) {
+ return ABIArgInfo::getIgnore();
+ } else if (CodeGenFunction::hasAggregateLLVMType(RetTy)) {
+ return ABIArgInfo::getStructRet();
+ } else {
+ return ABIArgInfo::getDirect();
+ }
}
ABIArgInfo DefaultABIInfo::classifyArgumentType(QualType Ty,
ASTContext &Context) const {
- return ABIArgInfo::getDefault();
+ if (CodeGenFunction::hasAggregateLLVMType(Ty)) {
+ return ABIArgInfo::getByVal(0);
+ } else {
+ return ABIArgInfo::getDirect();
+ }
}
const ABIInfo &CodeGenTypes::getABIInfo() const {
assert(!Ty->isArrayType() &&
"Array types cannot be passed directly.");
ABIArgInfo Info = CGT.getABIInfo().classifyReturnType(Ty, CGT.getContext());
- // Ensure default on aggregate types is StructRet.
- if (Info.isDefault() && CodeGenFunction::hasAggregateLLVMType(Ty))
- return ABIArgInfo::getStructRet();
return Info;
}
assert(!Ty->isArrayType() &&
"Array types cannot be passed directly.");
ABIArgInfo Info = CGT.getABIInfo().classifyArgumentType(Ty, CGT.getContext());
- // Ensure default on aggregate types is ByVal.
- if (Info.isDefault() && CodeGenFunction::hasAggregateLLVMType(Ty))
- return ABIArgInfo::getByVal(0);
return Info;
}
case ABIArgInfo::Expand:
assert(0 && "Invalid ABI kind for return argument");
- case ABIArgInfo::Default:
- if (RetTy->isVoidType()) {
- ResultType = llvm::Type::VoidTy;
- } else {
- ResultType = ConvertType(RetTy);
- }
- break;
-
case ABIArgInfo::Direct:
ResultType = ConvertType(RetTy);
break;
assert(AI.getByValAlignment() == 0 && "FIXME: alignment unhandled");
break;
- case ABIArgInfo::Default:
case ABIArgInfo::Direct:
ArgTys.push_back(Ty);
break;
unsigned Index = 1;
const ABIArgInfo &RetAI = FI.getReturnInfo();
switch (RetAI.getKind()) {
- case ABIArgInfo::Default:
case ABIArgInfo::Direct:
if (RetTy->isPromotableIntegerType()) {
if (RetTy->isSignedIntegerType()) {
assert(AI.getByValAlignment() == 0 && "FIXME: alignment unhandled");
break;
- case ABIArgInfo::Default:
case ABIArgInfo::Direct:
if (ParamType->isPromotableIntegerType()) {
if (ParamType->isSignedIntegerType()) {
switch (ArgI.getKind()) {
case ABIArgInfo::ByVal:
- case ABIArgInfo::Default:
case ABIArgInfo::Direct: {
assert(AI != Fn->arg_end() && "Argument mismatch!");
llvm::Value* V = AI;
}
break;
- case ABIArgInfo::Default:
case ABIArgInfo::Direct:
RV = Builder.CreateLoad(ReturnValue);
break;
Args.push_back(CreateTempAlloca(ConvertType(RetTy)));
break;
- case ABIArgInfo::Default:
case ABIArgInfo::Direct:
case ABIArgInfo::Ignore:
case ABIArgInfo::Coerce:
RValue RV = I->first;
switch (ArgInfo.getKind()) {
- case ABIArgInfo::ByVal: // Default is byval
- case ABIArgInfo::Default:
+ case ABIArgInfo::ByVal: // Direct is byval
case ABIArgInfo::Direct:
if (RV.isScalar()) {
Args.push_back(RV.getScalarVal());
else
return RValue::get(Builder.CreateLoad(Args[0]));
- case ABIArgInfo::Default:
- return RValue::get(RetTy->isVoidType() ? 0 : CI);
-
case ABIArgInfo::Direct:
assert((!RetTy->isAnyComplexType() &&
- CodeGenFunction::hasAggregateLLVMType(RetTy)) &&
- "FIXME: Implemented return for non-scalar direct types.");
+ !CodeGenFunction::hasAggregateLLVMType(RetTy)) &&
+ "FIXME: Implement return for non-scalar direct types.");
return RValue::get(CI);
case ABIArgInfo::Ignore:
if (RetTy->isVoidType())
return RValue::get(0);
+
+ // If we are ignoring an argument that had a result, make sure to
+ // construct the appropriate return value for our caller.
if (CodeGenFunction::hasAggregateLLVMType(RetTy)) {
llvm::Value *Res =
llvm::UndefValue::get(llvm::PointerType::getUnqual(ConvertType(RetTy)));