Commit a93d30d5 authored by Simon Zünd's avatar Simon Zünd Committed by Commit Bot

[torque] Improve error message when calling macros

Current situation: When calling a macro with the wrong parameter types
the error message will say "macro not found".

This CL changes the message to "macro with parameter types not found"
and lists possible candidates.

R=tebbi@chromium.org

Bug: v8:7793
Change-Id: I6724c4030cbbf4ca1af008b33797b2dd9d18808b
Reviewed-on: https://chromium-review.googlesource.com/1101694
Commit-Queue: Simon Zünd <szuend@google.com>
Reviewed-by: 's avatarTobias Tebbi <tebbi@chromium.org>
Cr-Commit-Position: refs/heads/master@{#53780}
parent e0204550
...@@ -25,6 +25,17 @@ Signature FileVisitor::MakeSignature(const CallableNodeSignature* signature) { ...@@ -25,6 +25,17 @@ Signature FileVisitor::MakeSignature(const CallableNodeSignature* signature) {
return result; return result;
} }
namespace {
void PrintMacroSignatures(std::stringstream& s,
const std::vector<Macro*>& macros) {
for (Macro* m : macros) {
s << "\n " << m->signature();
}
}
} // namespace
Callable* FileVisitor::LookupCall(const std::string& name, Callable* FileVisitor::LookupCall(const std::string& name,
const Arguments& arguments) { const Arguments& arguments) {
Callable* result = nullptr; Callable* result = nullptr;
...@@ -36,22 +47,34 @@ Callable* FileVisitor::LookupCall(const std::string& name, ...@@ -36,22 +47,34 @@ Callable* FileVisitor::LookupCall(const std::string& name,
result = RuntimeFunction::cast(declarable); result = RuntimeFunction::cast(declarable);
} else if (declarable->IsMacroList()) { } else if (declarable->IsMacroList()) {
std::vector<Macro*> candidates; std::vector<Macro*> candidates;
std::vector<Macro*> macros_with_same_name;
for (Macro* m : MacroList::cast(declarable)->list()) { for (Macro* m : MacroList::cast(declarable)->list()) {
if (IsCompatibleSignature(m->signature(), parameter_types, if (IsCompatibleSignature(m->signature(), parameter_types,
arguments.labels)) { arguments.labels)) {
candidates.push_back(m); candidates.push_back(m);
} else if (m->name() == name) {
macros_with_same_name.push_back(m);
} }
} }
if (candidates.empty() && macros_with_same_name.empty()) {
return nullptr;
} else if (candidates.empty()) {
std::stringstream stream;
stream << "cannot find macro with name \"" << name
<< "\" and parameter type(s) (" << parameter_types
<< "), candidates are:";
PrintMacroSignatures(stream, macros_with_same_name);
ReportError(stream.str());
}
auto is_better_candidate = [&](Macro* a, Macro* b) { auto is_better_candidate = [&](Macro* a, Macro* b) {
return ParameterDifference(a->signature().parameter_types.types, return ParameterDifference(a->signature().parameter_types.types,
parameter_types) parameter_types)
.StrictlyBetterThan(ParameterDifference( .StrictlyBetterThan(ParameterDifference(
b->signature().parameter_types.types, parameter_types)); b->signature().parameter_types.types, parameter_types));
}; };
if (candidates.empty()) {
return nullptr;
}
Macro* best = *std::min_element(candidates.begin(), candidates.end(), Macro* best = *std::min_element(candidates.begin(), candidates.end(),
is_better_candidate); is_better_candidate);
for (Macro* candidate : candidates) { for (Macro* candidate : candidates) {
...@@ -59,10 +82,7 @@ Callable* FileVisitor::LookupCall(const std::string& name, ...@@ -59,10 +82,7 @@ Callable* FileVisitor::LookupCall(const std::string& name,
std::stringstream s; std::stringstream s;
s << "ambiguous macro \"" << name << "\" with types (" s << "ambiguous macro \"" << name << "\" with types ("
<< parameter_types << "), candidates:"; << parameter_types << "), candidates:";
for (Macro* m : candidates) { PrintMacroSignatures(s, candidates);
s << "\n (" << m->signature().parameter_types << ") => "
<< m->signature().return_type;
}
ReportError(s.str()); ReportError(s.str());
} }
} }
......
...@@ -160,8 +160,16 @@ std::ostream& operator<<(std::ostream& os, const Signature& sig) { ...@@ -160,8 +160,16 @@ std::ostream& operator<<(std::ostream& os, const Signature& sig) {
os << "..."; os << "...";
} }
os << ")"; os << ")";
if (!sig.return_type->IsVoid()) { os << ": " << sig.return_type;
os << ": " << sig.return_type;
if (sig.labels.empty()) return os;
os << " labels ";
for (size_t i = 0; i < sig.labels.size(); ++i) {
if (i > 0) os << ", ";
os << sig.labels[i].name;
if (sig.labels[i].types.size() > 0) os << "(" << sig.labels[i].types << ")";
} }
return os; return os;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment