diff options
author | Chris Lattner <sabre@nondot.org> | 2001-07-25 22:47:55 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2001-07-25 22:47:55 +0000 |
commit | e5a57ee363ecceb1f0047da7d8e72460965ec102 (patch) | |
tree | 22226613c39a2e2028cb781020aca3e9b27591d6 /lib/Bytecode/Reader/InstructionReader.cpp | |
parent | 8b81bf5046cdc76d217396c1f42bb7d784619e5e (diff) |
Add support for extern varargs methods & varargs method calls
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@297 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Bytecode/Reader/InstructionReader.cpp')
-rw-r--r-- | lib/Bytecode/Reader/InstructionReader.cpp | 54 |
1 files changed, 36 insertions, 18 deletions
diff --git a/lib/Bytecode/Reader/InstructionReader.cpp b/lib/Bytecode/Reader/InstructionReader.cpp index 3af40f2d81..f1dcf08e79 100644 --- a/lib/Bytecode/Reader/InstructionReader.cpp +++ b/lib/Bytecode/Reader/InstructionReader.cpp @@ -196,30 +196,48 @@ bool BytecodeParser::ParseInstruction(const uchar *&Buf, const uchar *EndBuf, Method *M = (Method*)getValue(Raw.Ty, Raw.Arg1); if (M == 0) return true; + vector<Value *> Params; const MethodType::ParamTypes &PL = M->getMethodType()->getParamTypes(); - MethodType::ParamTypes::const_iterator It = PL.begin(); - vector<Value *> Params; - switch (Raw.NumOperands) { - case 0: cerr << "Invalid call instruction encountered!\n"; - return true; - case 1: break; - case 2: Params.push_back(getValue(*It++, Raw.Arg2)); break; - case 3: Params.push_back(getValue(*It++, Raw.Arg2)); - if (It == PL.end()) return true; - Params.push_back(getValue(*It++, Raw.Arg3)); break; - default: - Params.push_back(getValue(*It++, Raw.Arg2)); - { - vector<unsigned> &args = *Raw.VarArgs; - for (unsigned i = 0; i < args.size(); i++) { - if (It == PL.end()) return true; - Params.push_back(getValue(*It++, args[i])); + if (!M->getType()->isMethodType()->isVarArg()) { + MethodType::ParamTypes::const_iterator It = PL.begin(); + + switch (Raw.NumOperands) { + case 0: cerr << "Invalid call instruction encountered!\n"; + return true; + case 1: break; + case 2: Params.push_back(getValue(*It++, Raw.Arg2)); break; + case 3: Params.push_back(getValue(*It++, Raw.Arg2)); + if (It == PL.end()) return true; + Params.push_back(getValue(*It++, Raw.Arg3)); break; + default: + Params.push_back(getValue(*It++, Raw.Arg2)); + { + vector<unsigned> &args = *Raw.VarArgs; + for (unsigned i = 0; i < args.size(); i++) { + if (It == PL.end()) return true; + // TODO: Check getValue for null! + Params.push_back(getValue(*It++, args[i])); + } } + delete Raw.VarArgs; + } + if (It != PL.end()) return true; + } else { + // The first parameter does not have a type specifier... because there + // must be at least one concrete argument to a vararg type... + Params.push_back(getValue(PL.front(), Raw.Arg2)); + + vector<unsigned> &args = *Raw.VarArgs; + if ((args.size() & 1) != 0) return true; // Must be pairs of type/value + for (unsigned i = 0; i < args.size(); i+=2) { + Value *Ty = getValue(Type::TypeTy, args[i]); + if (!Ty) return true; + // TODO: Check getValue for null! + Params.push_back(getValue(Ty->castTypeAsserting(), args[i+1])); } delete Raw.VarArgs; } - if (It != PL.end()) return true; Res = new CallInst(M, Params); return false; |