From e5a57ee363ecceb1f0047da7d8e72460965ec102 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Wed, 25 Jul 2001 22:47:55 +0000 Subject: 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 --- lib/Bytecode/Reader/InstructionReader.cpp | 54 ++++++++++++++++++++----------- 1 file changed, 36 insertions(+), 18 deletions(-) (limited to 'lib/Bytecode/Reader/InstructionReader.cpp') 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 Params; const MethodType::ParamTypes &PL = M->getMethodType()->getParamTypes(); - MethodType::ParamTypes::const_iterator It = PL.begin(); - vector 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 &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 &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 &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; -- cgit v1.2.3-18-g5258