Commit ec1e3ced authored by Daniel Clifford's avatar Daniel Clifford Committed by Commit Bot

[torque]: Improve error output

In the process, add a utility functions to automate printing out comma-separated
lists. Also make sure that the << operator applies to "const Type&" rather than
"const Type*" for consistency elsewhere and generally just good practice.

Bug: v8:7793
Change-Id: I488e8383c4a9496552e63601738d6bcca0ca6e80
Reviewed-on: https://chromium-review.googlesource.com/1111854
Commit-Queue: Daniel Clifford <danno@chromium.org>
Reviewed-by: 's avatarTobias Tebbi <tebbi@chromium.org>
Cr-Commit-Position: refs/heads/master@{#54038}
parent f703078a
...@@ -13,37 +13,57 @@ namespace torque { ...@@ -13,37 +13,57 @@ namespace torque {
std::ostream& operator<<(std::ostream& os, const Callable& m) { std::ostream& operator<<(std::ostream& os, const Callable& m) {
os << "callable " << m.name() << "(" << m.signature().parameter_types os << "callable " << m.name() << "(" << m.signature().parameter_types
<< "): " << m.signature().return_type; << "): " << *m.signature().return_type;
return os; return os;
} }
std::ostream& operator<<(std::ostream& os, const Variable& v) { std::ostream& operator<<(std::ostream& os, const Variable& v) {
os << "variable " << v.name() << ": " << v.type(); os << "variable " << v.name() << ": " << *v.type();
return os; return os;
} }
std::ostream& operator<<(std::ostream& os, const Builtin& b) { std::ostream& operator<<(std::ostream& os, const Builtin& b) {
os << "builtin " << b.signature().return_type << " " << b.name() os << "builtin " << *b.signature().return_type << " " << b.name()
<< b.signature().parameter_types; << b.signature().parameter_types;
return os; return os;
} }
std::ostream& operator<<(std::ostream& os, const RuntimeFunction& b) { std::ostream& operator<<(std::ostream& os, const RuntimeFunction& b) {
os << "runtime function " << b.signature().return_type << " " << b.name() os << "runtime function " << *b.signature().return_type << " " << b.name()
<< b.signature().parameter_types; << b.signature().parameter_types;
return os; return os;
} }
std::ostream& operator<<(std::ostream& os, const Generic& g) { void PrintLabel(std::ostream& os, const Label& l, bool with_names) {
os << "generic " << g.name() << "<"; os << l.name();
bool first = true; if (l.GetParameterCount() != 0) {
for (auto t : g.declaration()->generic_parameters) { os << "(";
if (!first) { if (with_names) {
os << ", "; PrintCommaSeparatedList(os, l.GetParameters(),
[](Variable* v) -> std::string {
std::stringstream stream;
stream << v->name();
stream << ": ";
stream << *(v->type());
return stream.str();
});
} else {
PrintCommaSeparatedList(
os, l.GetParameters(),
[](Variable* v) -> const Type& { return *(v->type()); });
} }
first = false; os << ")";
os << t << ": type";
} }
}
std::ostream& operator<<(std::ostream& os, const Label& l) {
PrintLabel(os, l, true);
return os;
}
std::ostream& operator<<(std::ostream& os, const Generic& g) {
os << "generic " << g.name() << "<";
PrintCommaSeparatedList(os, g.declaration()->generic_parameters);
os << ">"; os << ">";
return os; return os;
......
...@@ -337,9 +337,12 @@ class TypeAlias : public Declarable { ...@@ -337,9 +337,12 @@ class TypeAlias : public Declarable {
const Type* type_; const Type* type_;
}; };
void PrintLabel(std::ostream& os, const Label& l, bool with_names);
std::ostream& operator<<(std::ostream& os, const Callable& m); std::ostream& operator<<(std::ostream& os, const Callable& m);
std::ostream& operator<<(std::ostream& os, const Variable& v); std::ostream& operator<<(std::ostream& os, const Variable& v);
std::ostream& operator<<(std::ostream& os, const Builtin& b); std::ostream& operator<<(std::ostream& os, const Builtin& b);
std::ostream& operator<<(std::ostream& os, const Label& l);
std::ostream& operator<<(std::ostream& os, const RuntimeFunction& b); std::ostream& operator<<(std::ostream& os, const RuntimeFunction& b);
std::ostream& operator<<(std::ostream& os, const Generic& g); std::ostream& operator<<(std::ostream& os, const Generic& g);
......
...@@ -90,7 +90,7 @@ Builtin* DeclarationVisitor::BuiltinDeclarationCommon( ...@@ -90,7 +90,7 @@ Builtin* DeclarationVisitor::BuiltinDeclarationCommon(
declarations()->LookupGlobalType(OBJECT_TYPE_STRING))) { declarations()->LookupGlobalType(OBJECT_TYPE_STRING))) {
std::stringstream stream; std::stringstream stream;
stream << "second parameter to javascript builtin " << decl->name stream << "second parameter to javascript builtin " << decl->name
<< " is " << signature.types()[1] << " but should be Object"; << " is " << *signature.types()[1] << " but should be Object";
ReportError(stream.str()); ReportError(stream.str());
} }
} }
...@@ -256,7 +256,7 @@ void DeclarationVisitor::Visit(VarDeclarationStatement* stmt) { ...@@ -256,7 +256,7 @@ void DeclarationVisitor::Visit(VarDeclarationStatement* stmt) {
} }
declarations()->DeclareVariable(variable_name, type); declarations()->DeclareVariable(variable_name, type);
if (global_context_.verbose()) { if (global_context_.verbose()) {
std::cout << "declared variable " << variable_name << " with type " << type std::cout << "declared variable " << variable_name << " with type " << *type
<< "\n"; << "\n";
} }
if (stmt->initializer) { if (stmt->initializer) {
......
...@@ -25,102 +25,6 @@ Signature FileVisitor::MakeSignature(const CallableNodeSignature* signature) { ...@@ -25,102 +25,6 @@ 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->name() << m->signature();
}
}
} // namespace
Callable* FileVisitor::LookupCall(const std::string& name,
const Arguments& arguments) {
Callable* result = nullptr;
TypeVector parameter_types(arguments.parameters.GetTypeVector());
Declarable* declarable = declarations()->Lookup(name);
if (declarable->IsBuiltin()) {
result = Builtin::cast(declarable);
} else if (declarable->IsRuntimeFunction()) {
result = RuntimeFunction::cast(declarable);
} else if (declarable->IsMacroList()) {
std::vector<Macro*> candidates;
std::vector<Macro*> macros_with_same_name;
for (Macro* m : MacroList::cast(declarable)->list()) {
bool try_bool_context =
arguments.labels.size() == 0 &&
m->signature().return_type == TypeOracle::GetNeverType();
Label* true_label = nullptr;
Label* false_label = nullptr;
if (try_bool_context) {
true_label = declarations()->TryLookupLabel(kTrueLabelName);
false_label = declarations()->TryLookupLabel(kFalseLabelName);
}
if (IsCompatibleSignature(m->signature(), parameter_types,
arguments.labels) ||
(true_label && false_label &&
IsCompatibleSignature(m->signature(), parameter_types,
{true_label, false_label}))) {
candidates.push_back(m);
} else {
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) {
return ParameterDifference(a->signature().parameter_types.types,
parameter_types)
.StrictlyBetterThan(ParameterDifference(
b->signature().parameter_types.types, parameter_types));
};
Macro* best = *std::min_element(candidates.begin(), candidates.end(),
is_better_candidate);
for (Macro* candidate : candidates) {
if (candidate != best && !is_better_candidate(best, candidate)) {
std::stringstream s;
s << "ambiguous macro \"" << name << "\" with types ("
<< parameter_types << "), candidates:";
PrintMacroSignatures(s, candidates);
ReportError(s.str());
}
}
result = best;
} else {
std::stringstream stream;
stream << "can't call " << declarable->type_name() << " " << name
<< " because it's not callable"
<< ": call parameters were (" << parameter_types << ")";
ReportError(stream.str());
}
size_t caller_size = parameter_types.size();
size_t callee_size = result->signature().types().size();
if (caller_size != callee_size &&
!result->signature().parameter_types.var_args) {
std::stringstream stream;
stream << "parameter count mismatch calling " << *result << " - expected "
<< std::to_string(callee_size) << ", found "
<< std::to_string(caller_size);
ReportError(stream.str());
}
return result;
}
void FileVisitor::QueueGenericSpecialization( void FileVisitor::QueueGenericSpecialization(
const SpecializationKey& key, CallableNode* callable, const SpecializationKey& key, CallableNode* callable,
const CallableNodeSignature* signature, base::Optional<Statement*> body) { const CallableNodeSignature* signature, base::Optional<Statement*> body) {
......
...@@ -67,8 +67,6 @@ class FileVisitor { ...@@ -67,8 +67,6 @@ class FileVisitor {
return std::string("p_") + name; return std::string("p_") + name;
} }
Callable* LookupCall(const std::string& name, const Arguments& arguments);
Signature MakeSignature(const CallableNodeSignature* signature); Signature MakeSignature(const CallableNodeSignature* signature);
struct PendingSpecialization { struct PendingSpecialization {
......
This diff is collapsed.
...@@ -173,6 +173,8 @@ class ImplementationVisitor : public FileVisitor { ...@@ -173,6 +173,8 @@ class ImplementationVisitor : public FileVisitor {
ImplementationVisitor* visitor_; ImplementationVisitor* visitor_;
}; };
Callable* LookupCall(const std::string& name, const Arguments& arguments);
void GenerateChangedVarsFromControlSplit(AstNode* node); void GenerateChangedVarsFromControlSplit(AstNode* node);
const Type* GetCommonType(const Type* left, const Type* right); const Type* GetCommonType(const Type* left, const Type* right);
......
...@@ -83,15 +83,8 @@ std::string AbstractType::GetGeneratedTNodeTypeName() const { ...@@ -83,15 +83,8 @@ std::string AbstractType::GetGeneratedTNodeTypeName() const {
std::string FunctionPointerType::ToExplicitString() const { std::string FunctionPointerType::ToExplicitString() const {
std::stringstream result; std::stringstream result;
result << "builtin ("; result << "builtin (";
bool first = true; PrintCommaSeparatedList(result, parameter_types_);
for (const Type* t : parameter_types_) { result << ") => " << *return_type_;
if (!first) {
result << ", ";
first = false;
}
result << t;
}
result << ") => " << return_type_;
return result.str(); return result.str();
} }
...@@ -116,7 +109,7 @@ std::string UnionType::ToExplicitString() const { ...@@ -116,7 +109,7 @@ std::string UnionType::ToExplicitString() const {
result << " | "; result << " | ";
} }
first = false; first = false;
result << t; result << *t;
} }
result << ")"; result << ")";
return result.str(); return result.str();
...@@ -148,21 +141,23 @@ std::string UnionType::GetGeneratedTNodeTypeName() const { ...@@ -148,21 +141,23 @@ std::string UnionType::GetGeneratedTNodeTypeName() const {
return parent()->GetGeneratedTNodeTypeName(); return parent()->GetGeneratedTNodeTypeName();
} }
std::ostream& operator<<(std::ostream& os, const Signature& sig) { void PrintSignature(std::ostream& os, const Signature& sig, bool with_names) {
os << "("; os << "(";
for (size_t i = 0; i < sig.parameter_types.types.size(); ++i) { for (size_t i = 0; i < sig.parameter_types.types.size(); ++i) {
if (i > 0) os << ", "; if (i > 0) os << ", ";
if (!sig.parameter_names.empty()) os << sig.parameter_names[i] << ": "; if (with_names && !sig.parameter_names.empty()) {
os << sig.parameter_types.types[i]; os << sig.parameter_names[i] << ": ";
}
os << *sig.parameter_types.types[i];
} }
if (sig.parameter_types.var_args) { if (sig.parameter_types.var_args) {
if (sig.parameter_names.size()) os << ", "; if (sig.parameter_names.size()) os << ", ";
os << "..."; os << "...";
} }
os << ")"; os << ")";
os << ": " << sig.return_type; os << ": " << *sig.return_type;
if (sig.labels.empty()) return os; if (sig.labels.empty()) return;
os << " labels "; os << " labels ";
for (size_t i = 0; i < sig.labels.size(); ++i) { for (size_t i = 0; i < sig.labels.size(); ++i) {
...@@ -171,22 +166,20 @@ std::ostream& operator<<(std::ostream& os, const Signature& sig) { ...@@ -171,22 +166,20 @@ std::ostream& operator<<(std::ostream& os, const Signature& sig) {
if (sig.labels[i].types.size() > 0) os << "(" << sig.labels[i].types << ")"; if (sig.labels[i].types.size() > 0) os << "(" << sig.labels[i].types << ")";
} }
}
std::ostream& operator<<(std::ostream& os, const Signature& sig) {
PrintSignature(os, sig, true);
return os; return os;
} }
std::ostream& operator<<(std::ostream& os, const TypeVector& types) { std::ostream& operator<<(std::ostream& os, const TypeVector& types) {
for (size_t i = 0; i < types.size(); ++i) { PrintCommaSeparatedList(os, types);
if (i > 0) os << ", ";
os << types[i];
}
return os; return os;
} }
std::ostream& operator<<(std::ostream& os, const ParameterTypes& p) { std::ostream& operator<<(std::ostream& os, const ParameterTypes& p) {
for (size_t i = 0; i < p.types.size(); ++i) { PrintCommaSeparatedList(os, p.types);
if (i > 0) os << ", ";
os << p.types[i];
}
if (p.var_args) { if (p.var_args) {
if (p.types.size() > 0) os << ", "; if (p.types.size() > 0) os << ", ";
os << "..."; os << "...";
......
...@@ -268,8 +268,8 @@ class UnionType final : public Type { ...@@ -268,8 +268,8 @@ class UnionType final : public Type {
std::set<const Type*, TypeLess> types_; std::set<const Type*, TypeLess> types_;
}; };
inline std::ostream& operator<<(std::ostream& os, const Type* t) { inline std::ostream& operator<<(std::ostream& os, const Type& t) {
os << t->ToString(); os << t.ToString();
return os; return os;
} }
...@@ -344,6 +344,7 @@ struct Arguments { ...@@ -344,6 +344,7 @@ struct Arguments {
std::vector<Label*> labels; std::vector<Label*> labels;
}; };
void PrintSignature(std::ostream& os, const Signature& sig, bool with_names);
std::ostream& operator<<(std::ostream& os, const Signature& sig); std::ostream& operator<<(std::ostream& os, const Signature& sig);
bool IsAssignableFrom(const Type* to, const Type* from); bool IsAssignableFrom(const Type* to, const Type* from);
......
...@@ -36,6 +36,49 @@ class Deduplicator { ...@@ -36,6 +36,49 @@ class Deduplicator {
std::unordered_set<T, base::hash<T>> storage_; std::unordered_set<T, base::hash<T>> storage_;
}; };
template <class C, class T>
void PrintCommaSeparatedList(std::ostream& os, const T& list, C transform) {
bool first = true;
for (auto& e : list) {
if (first) {
first = false;
} else {
os << ", ";
}
os << transform(e);
}
}
template <class T,
typename std::enable_if<
std::is_pointer<typename T::value_type>::value, int>::type = 0>
void PrintCommaSeparatedList(std::ostream& os, const T& list) {
bool first = true;
for (auto& e : list) {
if (first) {
first = false;
} else {
os << ", ";
}
os << *e;
}
}
template <class T,
typename std::enable_if<
!std::is_pointer<typename T::value_type>::value, int>::type = 0>
void PrintCommaSeparatedList(std::ostream& os, const T& list) {
bool first = true;
for (auto& e : list) {
if (first) {
first = false;
} else {
os << ", ";
}
os << e;
}
}
} // namespace torque } // namespace torque
} // namespace internal } // namespace internal
} // namespace v8 } // namespace v8
......
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