diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/AsmParser/llvmAsmParser.y | 26 | ||||
-rw-r--r-- | lib/VMCore/AsmWriter.cpp | 19 | ||||
-rw-r--r-- | lib/VMCore/Instructions.cpp | 62 | ||||
-rw-r--r-- | lib/VMCore/Verifier.cpp | 12 |
4 files changed, 68 insertions, 51 deletions
diff --git a/lib/AsmParser/llvmAsmParser.y b/lib/AsmParser/llvmAsmParser.y index 9f2e5acf93..b36e85c4a6 100644 --- a/lib/AsmParser/llvmAsmParser.y +++ b/lib/AsmParser/llvmAsmParser.y @@ -2531,7 +2531,7 @@ ReturnedVal : ResolvedVal { $$->push_back($1); CHECK_FOR_ERROR } - | ReturnedVal ',' ConstVal { + | ReturnedVal ',' ResolvedVal { ($$=$1)->push_back($3); CHECK_FOR_ERROR }; @@ -2580,28 +2580,7 @@ InstructionList : InstructionList Inst { BBTerminatorInst : RET ReturnedVal { // Return with a result... - if($2->size() == 1) - $$ = new ReturnInst($2->back()); - else { - - std::vector<const Type*> Elements; - std::vector<Constant*> Vals; - for (std::vector<Value *>::iterator I = $2->begin(), - E = $2->end(); I != E; ++I) { - Value *V = *I; - Constant *C = cast<Constant>(V); - Elements.push_back(V->getType()); - Vals.push_back(C); - } - - const StructType *STy = StructType::get(Elements); - PATypeHolder *PTy = - new PATypeHolder(HandleUpRefs(StructType::get(Elements))); - - Constant *CS = ConstantStruct::get(STy, Vals); // *$2); - $$ = new ReturnInst(CS); - delete PTy; - } + $$ = new ReturnInst(*$2); delete $2; CHECK_FOR_ERROR } @@ -3174,6 +3153,7 @@ MemoryInst : MALLOC Types OptCAlign { if (!GetResultInst::isValidOperands(TmpVal, $5)) GEN_ERROR("Invalid getresult operands"); $$ = new GetResultInst(TmpVal, $5); + delete $2; CHECK_FOR_ERROR } | GETELEMENTPTR Types ValueRef IndexList { diff --git a/lib/VMCore/AsmWriter.cpp b/lib/VMCore/AsmWriter.cpp index 5194af3723..8a7eec9b04 100644 --- a/lib/VMCore/AsmWriter.cpp +++ b/lib/VMCore/AsmWriter.cpp @@ -1304,23 +1304,8 @@ void AssemblyWriter::printInstruction(const Instruction &I) { Out << " }"; writeOperand(I.getOperand(0), false); Out << ", " << cast<GetResultInst>(I).getIndex(); - } else if (isa<ReturnInst>(I)) { - if (!Operand) - Out << " void"; - else { - if (I.getOperand(0)->getType()->isFirstClassType()) - writeOperand(I.getOperand(0), true); - else { - Constant *ROp = cast<Constant>(I.getOperand(0)); - const StructType *STy = cast<StructType>(ROp->getType()); - unsigned NumElems = STy->getNumElements(); - for (unsigned i = 0; i < NumElems; ++i) { - if (i) - Out << ","; - writeOperand(ROp->getOperand(i), true); - } - } - } + } else if (isa<ReturnInst>(I) && !Operand) { + Out << " void"; } else if (const CallInst *CI = dyn_cast<CallInst>(&I)) { // Print the calling convention being used. switch (CI->getCallingConv()) { diff --git a/lib/VMCore/Instructions.cpp b/lib/VMCore/Instructions.cpp index 457987a176..d1df30b103 100644 --- a/lib/VMCore/Instructions.cpp +++ b/lib/VMCore/Instructions.cpp @@ -573,34 +573,75 @@ bool InvokeInst::isStructReturn() const { ReturnInst::ReturnInst(const ReturnInst &RI) : TerminatorInst(Type::VoidTy, Instruction::Ret, - &RetVal, RI.getNumOperands()) { - if (RI.getNumOperands()) - RetVal.init(RI.RetVal, this); + OperandList, RI.getNumOperands()) { + unsigned N = RI.getNumOperands(); + Use *OL = OperandList = new Use[N]; + for (unsigned i = 0; i < N; ++i) + OL[i].init(RI.getOperand(i), this); } ReturnInst::ReturnInst(Value *retVal, Instruction *InsertBefore) - : TerminatorInst(Type::VoidTy, Instruction::Ret, &RetVal, 0, InsertBefore) { + : TerminatorInst(Type::VoidTy, Instruction::Ret, OperandList, 0, InsertBefore) { init(retVal); } ReturnInst::ReturnInst(Value *retVal, BasicBlock *InsertAtEnd) - : TerminatorInst(Type::VoidTy, Instruction::Ret, &RetVal, 0, InsertAtEnd) { + : TerminatorInst(Type::VoidTy, Instruction::Ret, OperandList, 0, InsertAtEnd) { init(retVal); } ReturnInst::ReturnInst(BasicBlock *InsertAtEnd) - : TerminatorInst(Type::VoidTy, Instruction::Ret, &RetVal, 0, InsertAtEnd) { + : TerminatorInst(Type::VoidTy, Instruction::Ret, OperandList, 0, InsertAtEnd) { } - +ReturnInst::ReturnInst(std::vector<Value *> &retVals, Instruction *InsertBefore) + : TerminatorInst(Type::VoidTy, Instruction::Ret, OperandList, retVals.size(), InsertBefore) { + init(retVals); +} +ReturnInst::ReturnInst(std::vector<Value *> &retVals, BasicBlock *InsertAtEnd) + : TerminatorInst(Type::VoidTy, Instruction::Ret, OperandList, retVals.size(), InsertAtEnd) { + init(retVals); +} +ReturnInst::ReturnInst(std::vector<Value *> &retVals) + : TerminatorInst(Type::VoidTy, Instruction::Ret, OperandList, retVals.size()) { + init(retVals); +} void ReturnInst::init(Value *retVal) { if (retVal && retVal->getType() != Type::VoidTy) { assert(!isa<BasicBlock>(retVal) && "Cannot return basic block. Probably using the incorrect ctor"); NumOperands = 1; - RetVal.init(retVal, this); + Use *OL = OperandList = new Use[1]; + OL[0].init(retVal, this); + } +} + +void ReturnInst::init(std::vector<Value *> &retVals) { + if (retVals.empty()) + return; + + NumOperands = retVals.size(); + if (NumOperands == 1) { + Value *V = retVals[0]; + if (V->getType() == Type::VoidTy) + return; + } + + Use *OL = OperandList = new Use[NumOperands]; + for (unsigned i = 0; i < NumOperands; ++i) { + Value *V = retVals[i]; + assert(!isa<BasicBlock>(V) && + "Cannot return basic block. Probably using the incorrect ctor"); + OL[i].init(V, this); } } +Value *ReturnInst::getReturnValue(unsigned n) const { + if (NumOperands) + return OperandList[n]; + else + return 0; +} + unsigned ReturnInst::getNumSuccessorsV() const { return getNumSuccessors(); } @@ -617,6 +658,10 @@ BasicBlock *ReturnInst::getSuccessorV(unsigned idx) const { return 0; } +ReturnInst::~ReturnInst() { + if (NumOperands) + delete [] OperandList; +} //===----------------------------------------------------------------------===// // UnwindInst Implementation @@ -2759,7 +2804,6 @@ bool GetResultInst::isValidOperands(const Value *Aggregate, unsigned Index) { return false; } - // Define these methods here so vtables don't get emitted into every translation // unit that uses these classes. diff --git a/lib/VMCore/Verifier.cpp b/lib/VMCore/Verifier.cpp index 427b95b36d..1a7100e5a4 100644 --- a/lib/VMCore/Verifier.cpp +++ b/lib/VMCore/Verifier.cpp @@ -576,14 +576,22 @@ void Verifier::visitTerminatorInst(TerminatorInst &I) { void Verifier::visitReturnInst(ReturnInst &RI) { Function *F = RI.getParent()->getParent(); - if (RI.getNumOperands() == 0) + unsigned N = RI.getNumOperands(); + if (N == 0) Assert2(F->getReturnType() == Type::VoidTy, "Found return instr that returns void in Function of non-void " "return type!", &RI, F->getReturnType()); - else + else if (N == 1) Assert2(F->getReturnType() == RI.getOperand(0)->getType(), "Function return type does not match operand " "type of return inst!", &RI, F->getReturnType()); + else { + const StructType *STy = cast<StructType>(F->getReturnType()); + for (unsigned i = 0; i < N; i++) + Assert2(STy->getElementType(i) == RI.getOperand(i)->getType(), + "Function return type does not match operand " + "type of return inst!", &RI, F->getReturnType()); + } // Check to make sure that the return value has necessary properties for // terminators... |