void AMXStackFramePrinter::PrintArgumentList(const AMXStackFrame &frame) { AMXStackFrame prev_frame = frame.GetPrevious(); if (prev_frame) { // Although the symbol's code start address points at the state // switch code block, function arguments actually use the real // function address for the code start because in different states // they may be not the same. cell arg_address = frame.caller_address(); if (UsesAutomata(frame)) { arg_address = GetRealFunctionAddress(frame.amx(), frame.caller_address(), frame.return_address()); } std::vector<AMXDebugSymbol> args; int num_actual_args = 0; if (HaveDebugInfo()) { std::remove_copy_if(debug_info_->GetSymbols().begin(), debug_info_->GetSymbols().end(), std::back_inserter(args), std::not1(IsArgumentOf(arg_address))); std::sort(args.begin(), args.end()); num_actual_args = static_cast<int>(args.size()); } else { static const int kMaxRawArgs = 10; num_actual_args = std::min(kMaxRawArgs, GetNumArgs(frame.amx(), prev_frame.address())); } // Print a comma-separated list of arguments and their values. // If debug info is not available argument names are omitted, // so only the values are printed. for (int i = 0; i < num_actual_args; i++) { if (i > 0) { *stream_ << ", "; } if (HaveDebugInfo()) { PrintArgument(prev_frame, args[i], i); } else { PrintArgument(prev_frame, i); } } // If the number of actual arguments passed to the function exceeds // that obtained via debug info the function may take a variable // number of arguments. In this case we don't evaluate them but just // just say that they are present as we can't say anything about // their names and types. int num_var_args = GetNumArgs(frame.amx(), prev_frame.address()) - num_actual_args; if (num_var_args > 0) { if (num_actual_args != 0) { *stream_ << ", "; } PrintVariableArguments(num_var_args); } } }
ArgDef ArgSet::GetArg (int index) const { assert (index >= 0); assert (index < GetNumArgs()); return _args[index]; }