mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-08-17 21:29:20 +00:00
Indirect call with byval parameter requires a cast first.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@45911 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
cfad1b4f78
commit
7723ab3a51
@ -453,9 +453,14 @@ std::ostream &CWriter::printType(std::ostream &Out, const Type *Ty,
|
|||||||
unsigned Idx = 1;
|
unsigned Idx = 1;
|
||||||
for (FunctionType::param_iterator I = FTy->param_begin(),
|
for (FunctionType::param_iterator I = FTy->param_begin(),
|
||||||
E = FTy->param_end(); I != E; ++I) {
|
E = FTy->param_end(); I != E; ++I) {
|
||||||
|
const Type *ArgTy = *I;
|
||||||
|
if (PAL && PAL->paramHasAttr(Idx, ParamAttr::ByVal)) {
|
||||||
|
assert(isa<PointerType>(ArgTy));
|
||||||
|
ArgTy = cast<PointerType>(ArgTy)->getElementType();
|
||||||
|
}
|
||||||
if (I != FTy->param_begin())
|
if (I != FTy->param_begin())
|
||||||
FunctionInnards << ", ";
|
FunctionInnards << ", ";
|
||||||
printType(FunctionInnards, *I,
|
printType(FunctionInnards, ArgTy,
|
||||||
/*isSigned=*/PAL && PAL->paramHasAttr(Idx, ParamAttr::SExt), "");
|
/*isSigned=*/PAL && PAL->paramHasAttr(Idx, ParamAttr::SExt), "");
|
||||||
++Idx;
|
++Idx;
|
||||||
}
|
}
|
||||||
@ -495,6 +500,9 @@ std::ostream &CWriter::printType(std::ostream &Out, const Type *Ty,
|
|||||||
isa<VectorType>(PTy->getElementType()))
|
isa<VectorType>(PTy->getElementType()))
|
||||||
ptrName = "(" + ptrName + ")";
|
ptrName = "(" + ptrName + ")";
|
||||||
|
|
||||||
|
if (PAL)
|
||||||
|
// Must be a function ptr cast!
|
||||||
|
return printType(Out, PTy->getElementType(), false, ptrName, true, PAL);
|
||||||
return printType(Out, PTy->getElementType(), false, ptrName);
|
return printType(Out, PTy->getElementType(), false, ptrName);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2632,6 +2640,7 @@ void CWriter::visitCallInst(CallInst &I) {
|
|||||||
// If this is a call to a struct-return function, assign to the first
|
// If this is a call to a struct-return function, assign to the first
|
||||||
// parameter instead of passing it to the call.
|
// parameter instead of passing it to the call.
|
||||||
const ParamAttrsList *PAL = I.getParamAttrs();
|
const ParamAttrsList *PAL = I.getParamAttrs();
|
||||||
|
bool hasByVal = I.hasByValArgument();
|
||||||
bool isStructRet = I.isStructReturn();
|
bool isStructRet = I.isStructReturn();
|
||||||
if (isStructRet) {
|
if (isStructRet) {
|
||||||
bool isByVal = ByValParams.count(I.getOperand(1));
|
bool isByVal = ByValParams.count(I.getOperand(1));
|
||||||
@ -2645,8 +2654,8 @@ void CWriter::visitCallInst(CallInst &I) {
|
|||||||
|
|
||||||
if (!WroteCallee) {
|
if (!WroteCallee) {
|
||||||
// If this is an indirect call to a struct return function, we need to cast
|
// If this is an indirect call to a struct return function, we need to cast
|
||||||
// the pointer.
|
// the pointer. Ditto for indirect calls with byval arguments.
|
||||||
bool NeedsCast = isStructRet && !isa<Function>(Callee);
|
bool NeedsCast = (hasByVal || isStructRet) && !isa<Function>(Callee);
|
||||||
|
|
||||||
// GCC is a real PITA. It does not permit codegening casts of functions to
|
// GCC is a real PITA. It does not permit codegening casts of functions to
|
||||||
// function pointers if they are in a call (it generates a trap instruction
|
// function pointers if they are in a call (it generates a trap instruction
|
||||||
@ -2670,11 +2679,13 @@ void CWriter::visitCallInst(CallInst &I) {
|
|||||||
if (NeedsCast) {
|
if (NeedsCast) {
|
||||||
// Ok, just cast the pointer type.
|
// Ok, just cast the pointer type.
|
||||||
Out << "((";
|
Out << "((";
|
||||||
if (!isStructRet)
|
if (isStructRet)
|
||||||
printType(Out, I.getCalledValue()->getType());
|
|
||||||
else
|
|
||||||
printStructReturnPointerFunctionType(Out, PAL,
|
printStructReturnPointerFunctionType(Out, PAL,
|
||||||
cast<PointerType>(I.getCalledValue()->getType()));
|
cast<PointerType>(I.getCalledValue()->getType()));
|
||||||
|
else if (hasByVal)
|
||||||
|
printType(Out, I.getCalledValue()->getType(), false, "", true, PAL);
|
||||||
|
else
|
||||||
|
printType(Out, I.getCalledValue()->getType());
|
||||||
Out << ")(void*)";
|
Out << ")(void*)";
|
||||||
}
|
}
|
||||||
writeOperand(Callee);
|
writeOperand(Callee);
|
||||||
|
Loading…
Reference in New Issue
Block a user