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;  | 
