aboutsummaryrefslogtreecommitdiff
path: root/gcc/go/gofrontend/gogo.cc
diff options
context:
space:
mode:
authorThan McIntosh <thanm@google.com>2016-09-23 19:36:45 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2016-09-23 19:36:45 +0000
commit56bafc49a02cbff82b628e83c35e36d1872fdcc8 (patch)
treea45167990fa1fe860cc44939f3ec887785089c27 /gcc/go/gofrontend/gogo.cc
parent34a594e85618002815e2faf3b515ba1d7446a55b (diff)
downloadgcc-56bafc49a02cbff82b628e83c35e36d1872fdcc8.zip
gcc-56bafc49a02cbff82b628e83c35e36d1872fdcc8.tar.gz
gcc-56bafc49a02cbff82b628e83c35e36d1872fdcc8.tar.bz2
compiler: better abstraction layer for diagnostics.
Introduce an abstraction layer for reporting diagnostics, so as to avoid directly using the native GCC interfaces such as "error_at", "warning_at", "open_quote", "close_quote", etc. The new interfaces have the same look and feel as the GCC equivalents, but make calls into back-end functions to allow the back end to select the proper final reporting routine. Reviewed-on: https://go-review.googlesource.com/29191 * go-gcc-diagnostics.cc: New file. * go-location.h (Location): Remove operator source_location. Add operator==. * go-system.h: #include <sstream>. * Make-lang.in (GO_OBJS): Add go/go-diagnostics.o and go/go-gcc-diagnostics.o. (CFLAGS-go/go-gcc-diagnostics.o): New variable. From-SVN: r240453
Diffstat (limited to 'gcc/go/gofrontend/gogo.cc')
-rw-r--r--gcc/go/gofrontend/gogo.cc251
1 files changed, 132 insertions, 119 deletions
diff --git a/gcc/go/gofrontend/gogo.cc b/gcc/go/gofrontend/gogo.cc
index 20c3420..7617815 100644
--- a/gcc/go/gofrontend/gogo.cc
+++ b/gcc/go/gofrontend/gogo.cc
@@ -11,6 +11,7 @@
#include "filenames.h"
#include "go-c.h"
+#include "go-diagnostics.h"
#include "go-dump.h"
#include "go-optimize.h"
#include "lex.h"
@@ -333,8 +334,8 @@ Gogo::set_package_name(const std::string& package_name,
if (this->package_ != NULL)
{
if (this->package_->package_name() != package_name)
- error_at(location, "expected package %<%s%>",
- Gogo::message_name(this->package_->package_name()).c_str());
+ go_error_at(location, "expected package %<%s%>",
+ Gogo::message_name(this->package_->package_name()).c_str());
return;
}
@@ -397,7 +398,7 @@ Gogo::import_package(const std::string& filename,
{
if (filename.empty())
{
- error_at(location, "import path is empty");
+ go_error_at(location, "import path is empty");
return;
}
@@ -409,32 +410,33 @@ Gogo::import_package(const std::string& filename,
int adv = Lex::fetch_char(pf, &c);
if (adv == 0)
{
- error_at(location, "import path contains invalid UTF-8 sequence");
+ go_error_at(location, "import path contains invalid UTF-8 sequence");
return;
}
if (c == '\0')
{
- error_at(location, "import path contains NUL");
+ go_error_at(location, "import path contains NUL");
return;
}
if (c < 0x20 || c == 0x7f)
{
- error_at(location, "import path contains control character");
+ go_error_at(location, "import path contains control character");
return;
}
if (c == '\\')
{
- error_at(location, "import path contains backslash; use slash");
+ go_error_at(location, "import path contains backslash; use slash");
return;
}
if (Lex::is_unicode_space(c))
{
- error_at(location, "import path contains space character");
+ go_error_at(location, "import path contains space character");
return;
}
if (c < 0x7f && strchr("!\"#$%&'()*,:;<=>?[]^`{|}", c) != NULL)
{
- error_at(location, "import path contains invalid character '%c'", c);
+ go_error_at(location,
+ "import path contains invalid character '%c'", c);
return;
}
pf += adv;
@@ -442,12 +444,12 @@ Gogo::import_package(const std::string& filename,
if (IS_ABSOLUTE_PATH(filename.c_str()))
{
- error_at(location, "import path cannot be absolute path");
+ go_error_at(location, "import path cannot be absolute path");
return;
}
if (local_name == "init")
- error_at(location, "cannot import package as init");
+ go_error_at(location, "cannot import package as init");
if (filename == "unsafe")
{
@@ -495,7 +497,7 @@ Gogo::import_package(const std::string& filename,
this->relative_import_path_);
if (stream == NULL)
{
- error_at(location, "import file %qs not found", filename.c_str());
+ go_error_at(location, "import file %qs not found", filename.c_str());
return;
}
@@ -505,9 +507,9 @@ Gogo::import_package(const std::string& filename,
if (package != NULL)
{
if (package->pkgpath() == this->pkgpath())
- error_at(location,
- ("imported package uses same package path as package "
- "being compiled (see -fgo-pkgpath option)"));
+ go_error_at(location,
+ ("imported package uses same package path as package "
+ "being compiled (see -fgo-pkgpath option)"));
this->imports_.insert(std::make_pair(filename, package));
}
@@ -544,12 +546,13 @@ Gogo::add_import_init_fn(const std::string& package_name,
// an error about it.
if (ii->package_name() != package_name)
{
- error("duplicate package initialization name %qs",
- Gogo::message_name(init_name).c_str());
- inform(UNKNOWN_LOCATION, "used by package %qs",
- Gogo::message_name(ii->package_name()).c_str());
- inform(UNKNOWN_LOCATION, " and by package %qs",
- Gogo::message_name(package_name).c_str());
+ go_error_at(Linemap::unknown_location(),
+ "duplicate package initialization name %qs",
+ Gogo::message_name(init_name).c_str());
+ go_inform(Linemap::unknown_location(), "used by package %qs",
+ Gogo::message_name(ii->package_name()).c_str());
+ go_inform(Linemap::unknown_location(), " and by package %qs",
+ Gogo::message_name(package_name).c_str());
}
ii->set_priority(prio);
return;
@@ -1126,13 +1129,13 @@ sort_var_inits(Gogo* gogo, Var_inits* var_inits)
var);
if (ins.first->second)
{
- error_at(var->location(),
- ("initialization expressions for %qs and "
- "%qs depend upon each other"),
- var->message_name().c_str(),
- p2var->message_name().c_str());
- inform(p2->var()->location(), "%qs defined here",
- p2var->message_name().c_str());
+ go_error_at(var->location(),
+ ("initialization expressions for %qs and "
+ "%qs depend upon each other"),
+ var->message_name().c_str(),
+ p2var->message_name().c_str());
+ go_inform(p2->var()->location(), "%qs defined here",
+ p2var->message_name().c_str());
init_loop = true;
break;
}
@@ -1192,9 +1195,9 @@ sort_var_inits(Gogo* gogo, Var_inits* var_inits)
Named_object* dep = gogo->var_depends_on(var->var_value());
if (init != NULL && dep == NULL
&& expression_requires(init, preinit, NULL, var))
- error_at(var->location(),
- "initialization expression for %qs depends upon itself",
- var->message_name().c_str());
+ go_error_at(var->location(),
+ "initialization expression for %qs depends upon itself",
+ var->message_name().c_str());
}
}
@@ -1322,10 +1325,10 @@ Gogo::write_globals()
{
if (expression_requires(var->init(), NULL,
this->var_depends_on(var), no))
- error_at(no->location(),
- "initialization expression for %qs depends "
- "upon itself",
- no->message_name().c_str());
+ go_error_at(no->location(),
+ "initialization expression for %qs depends "
+ "upon itself",
+ no->message_name().c_str());
this->backend()->global_variable_set_init(bvar, var_binit);
}
else if (is_sink)
@@ -1664,8 +1667,8 @@ Gogo::start_function(const std::string& name, Function_type* type,
{
if ((type->parameters() != NULL && !type->parameters()->empty())
|| (type->results() != NULL && !type->results()->empty()))
- error_at(location,
- "func init must have no arguments and no return values");
+ go_error_at(location,
+ "func init must have no arguments and no return values");
// There can be multiple "init" functions, so give them each a
// different name.
static int init_count;
@@ -1761,8 +1764,9 @@ Gogo::start_function(const std::string& name, Function_type* type,
}
else
{
- error_at(type->receiver()->location(),
- "invalid receiver type (receiver must be a named type)");
+ go_error_at(type->receiver()->location(),
+ ("invalid receiver type (receiver must "
+ "be a named type)"));
ret = Named_object::make_function(name, NULL, function);
}
}
@@ -1874,8 +1878,8 @@ Gogo::declare_function(const std::string& name, Function_type* type,
}
else
{
- error_at(type->receiver()->location(),
- "invalid receiver type (receiver must be a named type)");
+ go_error_at(type->receiver()->location(),
+ "invalid receiver type (receiver must be a named type)");
return Named_object::make_erroneous_name(name);
}
}
@@ -2084,16 +2088,16 @@ Gogo::add_linkname(const std::string& go_name, bool is_exported,
this->package_->bindings()->lookup(this->pack_hidden_name(go_name,
is_exported));
if (no == NULL)
- error_at(loc, "%s is not defined", go_name.c_str());
+ go_error_at(loc, "%s is not defined", go_name.c_str());
else if (no->is_function())
no->func_value()->set_asm_name(ext_name);
else if (no->is_function_declaration())
no->func_declaration_value()->set_asm_name(ext_name);
else
- error_at(loc,
- ("%s is not a function; "
- "//go:linkname is only supported for functions"),
- go_name.c_str());
+ go_error_at(loc,
+ ("%s is not a function; "
+ "//go:linkname is only supported for functions"),
+ go_name.c_str());
}
// Mark all local variables used. This is used when some types of
@@ -2185,13 +2189,13 @@ Gogo::define_global_names()
if (global_no->is_type())
{
if (no->type_declaration_value()->has_methods())
- error_at(no->location(),
- "may not define methods for global type");
+ go_error_at(no->location(),
+ "may not define methods for global type");
no->set_type_value(global_no->type_value());
}
else
{
- error_at(no->location(), "expected type");
+ go_error_at(no->location(), "expected type");
Type* errtype = Type::make_error_type();
Named_object* err =
Named_object::make_type("erroneous_type", NULL, errtype,
@@ -2223,18 +2227,18 @@ Gogo::define_global_names()
if (pf != this->file_block_names_.end())
{
std::string n = p->second->message_name();
- error_at(p->second->location(),
- "%qs defined as both imported name and global name",
- n.c_str());
- inform(pf->second, "%qs imported here", n.c_str());
+ go_error_at(p->second->location(),
+ "%qs defined as both imported name and global name",
+ n.c_str());
+ go_inform(pf->second, "%qs imported here", n.c_str());
}
// No package scope identifier may be named "init".
if (!p->second->is_function()
&& Gogo::unpack_hidden_name(p->second->name()) == "init")
{
- error_at(p->second->location(),
- "cannot declare init - must be func");
+ go_error_at(p->second->location(),
+ "cannot declare init - must be func");
}
}
}
@@ -2265,15 +2269,15 @@ Gogo::clear_file_scope()
std::string pkg_name = package->package_name();
if (p1->first != pkg_name && p1->first[0] != '.')
{
- error_at(p1->second->location(),
- "imported and not used: %s as %s",
- Gogo::message_name(pkg_name).c_str(),
- Gogo::message_name(p1->first).c_str());
+ go_error_at(p1->second->location(),
+ "imported and not used: %s as %s",
+ Gogo::message_name(pkg_name).c_str(),
+ Gogo::message_name(p1->first).c_str());
}
else
- error_at(p1->second->location(),
- "imported and not used: %s",
- Gogo::message_name(pkg_name).c_str());
+ go_error_at(p1->second->location(),
+ "imported and not used: %s",
+ Gogo::message_name(pkg_name).c_str());
}
}
}
@@ -3078,11 +3082,11 @@ Check_types_traverse::variable(Named_object* named_object)
&& !Type::are_assignable(var->type(), init->type(), &reason))
{
if (reason.empty())
- error_at(var->location(), "incompatible type in initialization");
+ go_error_at(var->location(), "incompatible type in initialization");
else
- error_at(var->location(),
- "incompatible type in initialization (%s)",
- reason.c_str());
+ go_error_at(var->location(),
+ "incompatible type in initialization (%s)",
+ reason.c_str());
init = Expression::make_error(named_object->location());
var->clear_init();
}
@@ -3102,10 +3106,10 @@ Check_types_traverse::variable(Named_object* named_object)
// initialization.
if (fntype->is_builtin())
{
- error_at(init->location(),
- "invalid use of special builtin function %qs; "
- "must be called",
- no->message_name().c_str());
+ go_error_at(init->location(),
+ "invalid use of special builtin function %qs; "
+ "must be called",
+ no->message_name().c_str());
}
}
if (!var->is_used()
@@ -3115,8 +3119,8 @@ Check_types_traverse::variable(Named_object* named_object)
&& !var->type()->is_error()
&& (init == NULL || !init->is_error_expression())
&& !Lex::is_invalid_identifier(named_object->name()))
- error_at(var->location(), "%qs declared and not used",
- named_object->message_name().c_str());
+ go_error_at(var->location(), "%qs declared and not used",
+ named_object->message_name().c_str());
}
return TRAVERSE_CONTINUE;
}
@@ -3135,21 +3139,21 @@ Check_types_traverse::constant(Named_object* named_object, bool)
&& !ctype->is_string_type())
{
if (ctype->is_nil_type())
- error_at(constant->location(), "const initializer cannot be nil");
+ go_error_at(constant->location(), "const initializer cannot be nil");
else if (!ctype->is_error())
- error_at(constant->location(), "invalid constant type");
+ go_error_at(constant->location(), "invalid constant type");
constant->set_error();
}
else if (!constant->expr()->is_constant())
{
- error_at(constant->expr()->location(), "expression is not constant");
+ go_error_at(constant->expr()->location(), "expression is not constant");
constant->set_error();
}
else if (!Type::are_assignable(constant->type(), constant->expr()->type(),
NULL))
{
- error_at(constant->location(),
- "initialization expression has wrong type");
+ go_error_at(constant->location(),
+ "initialization expression has wrong type");
constant->set_error();
}
return TRAVERSE_CONTINUE;
@@ -4389,8 +4393,8 @@ Check_return_statements_traverse::function(Named_object* no)
return TRAVERSE_CONTINUE;
if (func->block()->may_fall_through())
- error_at(func->block()->end_location(),
- "missing return at end of function");
+ go_error_at(func->block()->end_location(),
+ "missing return at end of function");
return TRAVERSE_CONTINUE;
}
@@ -4454,7 +4458,8 @@ Gogo::write_c_header()
out.open(this->c_header_.c_str());
if (out.fail())
{
- error("cannot open %s: %m", this->c_header_.c_str());
+ go_error_at(Linemap::unknown_location(),
+ "cannot open %s: %m", this->c_header_.c_str());
return;
}
@@ -4562,7 +4567,8 @@ Gogo::write_c_header()
out.close();
if (out.fail())
- error("error writing to %s: %m", this->c_header_.c_str());
+ go_error_at(Linemap::unknown_location(),
+ "error writing to %s: %m", this->c_header_.c_str());
}
// Find the blocks in order to convert named types defined in blocks.
@@ -4836,10 +4842,10 @@ Function::add_label_definition(Gogo* gogo, const std::string& label_name,
label = ins.first->second;
if (label->is_defined())
{
- error_at(location, "label %qs already defined",
- Gogo::message_name(label_name).c_str());
- inform(label->location(), "previous definition of %qs was here",
- Gogo::message_name(label_name).c_str());
+ go_error_at(location, "label %qs already defined",
+ Gogo::message_name(label_name).c_str());
+ go_inform(label->location(), "previous definition of %qs was here",
+ Gogo::message_name(label_name).c_str());
return new Label(label_name);
}
}
@@ -4905,8 +4911,8 @@ Function::check_labels() const
{
Label* label = p->second;
if (!label->is_used())
- error_at(label->location(), "label %qs defined and not used",
- Gogo::message_name(label->name()).c_str());
+ go_error_at(label->location(), "label %qs defined and not used",
+ Gogo::message_name(label->name()).c_str());
}
}
@@ -5680,7 +5686,7 @@ Block::Block(Block* enclosing, Location location)
? NULL
: enclosing->bindings())),
start_location_(location),
- end_location_(UNKNOWN_LOCATION)
+ end_location_(Linemap::unknown_location())
{
}
@@ -5966,8 +5972,8 @@ Bindings_snapshot::check_goto_block(Location loc, const Block* bfrom,
{
if (pb == NULL)
{
- error_at(loc, "goto jumps into block");
- inform(bto->start_location(), "goto target block starts here");
+ go_error_at(loc, "goto jumps into block");
+ go_inform(bto->start_location(), "goto target block starts here");
return false;
}
}
@@ -5995,8 +6001,8 @@ Bindings_snapshot::check_goto_defs(Location loc, const Block* block,
go_assert(p != block->bindings()->end_definitions());
std::string n = (*p)->message_name();
- error_at(loc, "goto jumps over declaration of %qs", n.c_str());
- inform((*p)->location(), "%qs defined here", n.c_str());
+ go_error_at(loc, "goto jumps over declaration of %qs", n.c_str());
+ go_inform((*p)->location(), "%qs defined here", n.c_str());
}
}
@@ -6206,7 +6212,7 @@ Variable::type_from_tuple(Expression* expr, bool report_error) const
else
{
if (report_error)
- error_at(this->location(), "invalid tuple definition");
+ go_error_at(this->location(), "invalid tuple definition");
return Type::make_error_type();
}
}
@@ -6250,15 +6256,16 @@ Variable::type_from_range(Expression* expr, bool get_index_type,
else
{
if (report_error)
- error_at(this->location(),
- "invalid definition of value variable for channel range");
+ go_error_at(this->location(),
+ ("invalid definition of value variable "
+ "for channel range"));
return Type::make_error_type();
}
}
else
{
if (report_error)
- error_at(this->location(), "invalid type for range clause");
+ go_error_at(this->location(), "invalid type for range clause");
return Type::make_error_type();
}
}
@@ -6274,7 +6281,7 @@ Variable::type_from_chan_element(Expression* expr, bool report_error) const
else
{
if (report_error)
- error_at(this->location(), "expected channel");
+ go_error_at(this->location(), "expected channel");
return Type::make_error_type();
}
}
@@ -6305,7 +6312,7 @@ Variable::type()
{
if (this->type_ == NULL || !this->type_->is_error_type())
{
- error_at(this->location_, "variable initializer refers to itself");
+ go_error_at(this->location_, "variable initializer refers to itself");
this->type_ = Type::make_error_type();
}
return this->type_;
@@ -6413,17 +6420,17 @@ Variable::determine_type()
if (type->is_void_type())
{
- error_at(this->location_, "variable has no type");
+ go_error_at(this->location_, "variable has no type");
type = Type::make_error_type();
}
else if (type->is_nil_type())
{
- error_at(this->location_, "variable defined to nil type");
+ go_error_at(this->location_, "variable defined to nil type");
type = Type::make_error_type();
}
else if (type->is_call_multiple_result_type())
{
- error_at(this->location_,
+ go_error_at(this->location_,
"single variable set to multiple-value function call");
type = Type::make_error_type();
}
@@ -7070,9 +7077,9 @@ Named_object::export_named_object(Export* exp) const
break;
case NAMED_OBJECT_TYPE_DECLARATION:
- error_at(this->type_declaration_value()->location(),
- "attempt to export %<%s%> which was declared but not defined",
- this->message_name().c_str());
+ go_error_at(this->type_declaration_value()->location(),
+ "attempt to export %<%s%> which was declared but not defined",
+ this->message_name().c_str());
break;
case NAMED_OBJECT_FUNC_DECLARATION:
@@ -7217,8 +7224,9 @@ Named_object::get_backend(Gogo* gogo, std::vector<Bexpression*>& const_decls,
break;
case NAMED_OBJECT_TYPE_DECLARATION:
- error("reference to undefined type %qs",
- this->message_name().c_str());
+ go_error_at(Linemap::unknown_location(),
+ "reference to undefined type %qs",
+ this->message_name().c_str());
return;
case NAMED_OBJECT_VAR:
@@ -7450,7 +7458,9 @@ Bindings::new_definition(Named_object* old_object, Named_object* new_object)
if (new_object->is_function_declaration())
{
if (!new_object->func_declaration_value()->asm_name().empty())
- sorry("__asm__ for function definitions");
+ go_error_at(Linemap::unknown_location(),
+ ("sorry, not implemented: "
+ "__asm__ for function definitions"));
Function_type* old_type = old_object->func_value()->type();
Function_type* new_type =
new_object->func_declaration_value()->type();
@@ -7469,7 +7479,9 @@ Bindings::new_definition(Named_object* old_object, Named_object* new_object)
if (old_type->is_valid_redeclaration(new_type, &reason))
{
if (!old_object->func_declaration_value()->asm_name().empty())
- sorry("__asm__ for function definitions");
+ go_error_at(Linemap::unknown_location(),
+ ("sorry, not implemented: "
+ "__asm__ for function definitions"));
old_object->set_function_value(new_object->func_value());
this->named_objects_.push_back(old_object);
return old_object;
@@ -7484,15 +7496,15 @@ Bindings::new_definition(Named_object* old_object, Named_object* new_object)
std::string n = old_object->message_name();
if (reason.empty())
- error_at(new_object->location(), "redefinition of %qs", n.c_str());
+ go_error_at(new_object->location(), "redefinition of %qs", n.c_str());
else
- error_at(new_object->location(), "redefinition of %qs: %s", n.c_str(),
- reason.c_str());
+ go_error_at(new_object->location(), "redefinition of %qs: %s", n.c_str(),
+ reason.c_str());
old_object->set_is_redefinition();
new_object->set_is_redefinition();
- inform(old_object->location(), "previous definition of %qs was here",
- n.c_str());
+ go_inform(old_object->location(), "previous definition of %qs was here",
+ n.c_str());
return old_object;
}
@@ -7798,10 +7810,11 @@ Package::set_package_name(const std::string& package_name, Location location)
if (this->package_name_.empty())
this->package_name_ = package_name;
else if (this->package_name_ != package_name)
- error_at(location,
- "saw two different packages with the same package path %s: %s, %s",
- this->pkgpath_.c_str(), this->package_name_.c_str(),
- package_name.c_str());
+ go_error_at(location,
+ ("saw two different packages with "
+ "the same package path %s: %s, %s"),
+ this->pkgpath_.c_str(), this->package_name_.c_str(),
+ package_name.c_str());
}
// Return the pkgpath symbol, which is a prefix for symbols defined in
@@ -7851,8 +7864,8 @@ Package::forget_usage(Expression* usage) const
this->fake_uses_.erase(p);
if (this->fake_uses_.empty())
- error_at(this->location(), "imported and not used: %s",
- Gogo::message_name(this->package_name()).c_str());
+ go_error_at(this->location(), "imported and not used: %s",
+ Gogo::message_name(this->package_name()).c_str());
}
// Clear the used field for the next file. If the only usages of this package