Patchwork [gccgo] Localize identifiers in error messages

login
register
mail settings
Submitter Ian Taylor
Date Nov. 17, 2010, 7:37 p.m.
Message ID <mcr4obfzqq6.fsf@google.com>
Download mbox | patch
Permalink /patch/71615/
State New
Headers show

Comments

Ian Taylor - Nov. 17, 2010, 7:37 p.m.
This patch consistently localizes identifiers in error messages.  This
ensures that hidden names will always be displayed in a user friendly
form.  It also localizes Go's UTF-8 identifiers for the user's
environment, in the unlikely event that somebody is using UTF-8
identifiers but not using a UTF-8 locale.  Committed to gccgo branch.

Ian

Patch

diff -r 90de8536250b go/expressions.cc
--- a/go/expressions.cc	Tue Nov 16 22:14:07 2010 -0800
+++ b/go/expressions.cc	Wed Nov 17 11:32:36 2010 -0800
@@ -1242,9 +1242,8 @@ 
     {
       if (this->is_composite_literal_key_)
 	return this;
-      const std::string& n(this->named_object_->name());
       error_at(location, "reference to undefined name %qs",
-	       Gogo::unpack_hidden_name(n).c_str());
+	       this->named_object_->message_name().c_str());
       return Expression::make_error(location);
     }
   switch (real->classification())
@@ -1257,7 +1256,7 @@ 
       if (this->is_composite_literal_key_)
 	return this;
       error_at(location, "reference to undefined type %qs",
-	       Gogo::unpack_hidden_name(real->name()).c_str());
+	       real->message_name().c_str());
       return Expression::make_error(location);
     case Named_object::NAMED_OBJECT_VAR:
       return Expression::make_var_reference(real, location);
@@ -9749,7 +9748,7 @@ 
       if (method == NULL)
 	{
 	  error_at(this->location(), "method %qs not in interface",
-		   this->name_.c_str());
+		   Gogo::message_name(this->name_).c_str());
 	  this->set_is_error();
 	}
     }
@@ -9861,17 +9860,20 @@ 
     {
       if (!is_ambiguous)
 	error_at(location, "type %<%s%> has no method %<%s%>",
-		 nt->message_name().c_str(), name.c_str());
+		 nt->message_name().c_str(),
+		 Gogo::message_name(name).c_str());
       else
 	error_at(location, "method %<%s%> is ambiguous in type %<%s%>",
-		 name.c_str(), nt->message_name().c_str());
+		 Gogo::message_name(name).c_str(),
+		 nt->message_name().c_str());
       return Expression::make_error(location);
     }
 
   if (!is_pointer && !method->is_value_method())
     {
       error_at(location, "method requires pointer (use %<(*%s).%s)%>",
-	       nt->message_name().c_str(), name.c_str());
+	       nt->message_name().c_str(),
+	       Gogo::message_name(name).c_str());
       return Expression::make_error(location);
     }
 
@@ -11342,7 +11344,7 @@ 
       if (sf == NULL)
 	{
 	  error_at(name_expr->location(), "unknown field %qs in %qs",
-		   Gogo::unpack_hidden_name(name).c_str(),
+		   Gogo::message_name(name).c_str(),
 		   (type->named_type() != NULL
 		    ? type->named_type()->message_name().c_str()
 		    : "unnamed struct"));
@@ -11352,7 +11354,7 @@ 
 	{
 	  error_at(name_expr->location(),
 		   "duplicate value for field %qs in %qs",
-		   Gogo::unpack_hidden_name(name).c_str(),
+		   Gogo::message_name(name).c_str(),
 		   (type->named_type() != NULL
 		    ? type->named_type()->message_name().c_str()
 		    : "unnamed struct"));
diff -r 90de8536250b go/gogo-tree.cc
--- a/go/gogo-tree.cc	Tue Nov 16 22:14:07 2010 -0800
+++ b/go/gogo-tree.cc	Wed Nov 17 11:32:36 2010 -0800
@@ -593,13 +593,13 @@ 
 				      p2->var()->var_value()->preinit(),
 				      var))
 		{
-		  std::string n1 = Gogo::unpack_hidden_name(var->name());
-		  std::string n2 = Gogo::unpack_hidden_name(p2->var()->name());
 		  error_at(var->location(),
 			   ("initialization expressions for %qs and "
 			    "%qs depend upon each other"),
-			   n1.c_str(), n2.c_str());
-		  inform(p2->var()->location(), "%qs defined here", n2.c_str());
+			   var->message_name().c_str(),
+			   p2->var()->message_name().c_str());
+		  inform(p2->var()->location(), "%qs defined here",
+			 p2->var()->message_name().c_str());
 		  p2 = var_inits->end();
 		}
 	      else
@@ -627,8 +627,7 @@ 
 	  if (init != NULL && expression_requires(init, preinit, var))
 	    error_at(var->location(),
 		     "initialization expression for %qs depends upon itself",
-		     Gogo::unpack_hidden_name(var->name()).c_str());
-
+		     var->message_name().c_str());
 	  ready.splice(ready.end(), *var_inits, p1);
 	}
     }
@@ -988,7 +987,8 @@ 
       break;
 
     case NAMED_OBJECT_TYPE_DECLARATION:
-      error("reference to undefined type %qs", IDENTIFIER_POINTER(name));
+      error("reference to undefined type %qs",
+	    this->message_name().c_str());
       return error_mark_node;
 
     case NAMED_OBJECT_VAR:
diff -r 90de8536250b go/gogo.cc
--- a/go/gogo.cc	Tue Nov 16 22:14:07 2010 -0800
+++ b/go/gogo.cc	Wed Nov 17 11:32:36 2010 -0800
@@ -6,6 +6,7 @@ 
 
 #include "go-system.h"
 
+#include "go-c.h"
 #include "go-dump.h"
 #include "lex.h"
 #include "types.h"
@@ -222,6 +223,14 @@ 
 			 loc);
 }
 
+// Munge name for use in an error message.
+
+std::string
+Gogo::message_name(const std::string& name)
+{
+  return go_localize_identifier(Gogo::unpack_hidden_name(name).c_str());
+}
+
 // Get the package name.
 
 const std::string&
@@ -240,7 +249,7 @@ 
   if (this->package_ != NULL && this->package_->name() != package_name)
     {
       error_at(location, "expected package %<%s%>",
-	       this->package_->name().c_str());
+	       Gogo::message_name(this->package_->name()).c_str());
       return;
     }
 
@@ -341,11 +350,13 @@ 
       if (p->init_name() == init_name
 	  && (p->package_name() != package_name || p->priority() != prio))
 	{
-	  error("duplicate package initialization name %qs", init_name.c_str());
+	  error("duplicate package initialization name %qs",
+		Gogo::message_name(init_name).c_str());
 	  inform(UNKNOWN_LOCATION, "used by package %qs at priority %d",
-		 p->package_name().c_str(), p->priority());
+		 Gogo::message_name(p->package_name()).c_str(),
+		 p->priority());
 	  inform(UNKNOWN_LOCATION, " and by package %qs at priority %d",
-		 package_name.c_str(), prio);
+		 Gogo::message_name(package_name).c_str(), prio);
 	  return;
 	}
     }
@@ -1037,7 +1048,7 @@ 
 	  && !package->uses_sink_alias()
 	  && !saw_errors())
 	error_at(package->location(), "imported and not used: %s",
-		 package->name().c_str());
+		 Gogo::message_name(package->name()).c_str());
       package->clear_is_imported();
       package->clear_uses_sink_alias();
       package->clear_used();
@@ -2571,9 +2582,10 @@ 
 	}
       else
 	{
-	  error_at(location, "redefinition of label %qs", label_name.c_str());
+	  error_at(location, "redefinition of label %qs",
+		   Gogo::message_name(label_name).c_str());
 	  inform(label->location(), "previous definition of %qs was here",
-		 label_name.c_str());
+		 Gogo::message_name(label_name).c_str());
 	  return new Label(label_name);
 	}
     }
@@ -3610,8 +3622,11 @@ 
 Named_object::message_name() const
 {
   if (this->package_ == NULL)
-    return this->name_;
-  return this->package_->name() + '.' + this->name_;
+    return Gogo::message_name(this->name_);
+  std::string ret = Gogo::message_name(this->package_->name());
+  ret += '.';
+  ret += Gogo::message_name(this->name_);
+  return ret;
 }
 
 // Set the type when a declaration is defined.
@@ -3707,7 +3722,7 @@ 
     case NAMED_OBJECT_TYPE_DECLARATION:
       error_at(this->type_declaration_value()->location(),
 	       "attempt to export %<%s%> which was declared but not defined",
-	       this->name_.c_str());
+	       this->message_name().c_str());
       break;
 
     case NAMED_OBJECT_FUNC_DECLARATION:
@@ -3961,7 +3976,7 @@ 
       break;
     }
 
-  std::string n = Gogo::unpack_hidden_name(old_object->name());
+  std::string n = old_object->message_name();
   if (reason.empty())
     error_at(new_object->location(), "redefinition of %qs", n.c_str());
   else
diff -r 90de8536250b go/gogo.h
--- a/go/gogo.h	Tue Nov 16 22:14:07 2010 -0800
+++ b/go/gogo.h	Wed Nov 17 11:32:36 2010 -0800
@@ -148,6 +148,11 @@ 
     return name.substr(1, name.rfind('.') - 1);
   }
 
+  // Given a name which may or may not have been hidden, return the
+  // name to use in an error message.
+  static std::string
+  message_name(const std::string& name);
+
   // Return whether a name is the blank identifier _.
   static bool
   is_sink_name(const std::string& name)
diff -r 90de8536250b go/import.cc
--- a/go/import.cc	Tue Nov 16 22:14:07 2010 -0800
+++ b/go/import.cc	Wed Nov 17 11:32:36 2010 -0800
@@ -601,7 +601,8 @@ 
   else if (!no->is_type_declaration() && !no->is_type())
     {
       error_at(this->location_, "imported %<%s.%s%> both type and non-type",
-	       package->name().c_str(), type_name.c_str());
+	       Gogo::message_name(package->name()).c_str(),
+	       Gogo::message_name(type_name).c_str());
       stream->set_saw_error();
       return Type::make_error_type();
     }
diff -r 90de8536250b go/parse.cc
--- a/go/parse.cc	Tue Nov 16 22:14:07 2010 -0800
+++ b/go/parse.cc	Wed Nov 17 11:32:36 2010 -0800
@@ -320,8 +320,10 @@ 
 	  named_object = package->package_value()->lookup(s);
 	  if (named_object != NULL)
 	    {
+	      const std::string& packname(package->package_value()->name());
 	      error_at(location, "invalid reference to hidden type %<%s.%s%>",
-		       package->package_value()->name().c_str(), name.c_str());
+		       Gogo::message_name(packname).c_str(),
+		       Gogo::message_name(name).c_str());
 	      issue_error = false;
 	    }
 	}
@@ -487,11 +489,8 @@ 
 	{
 	  if (pi->field_name() == pj->field_name()
 	      && !Gogo::is_sink_name(pi->field_name()))
-	    {
-	      std::string name = pi->field_name();
-	      error_at(pi->location(), "duplicate field name %<%s%>",
-		       Gogo::unpack_hidden_name(name).c_str());
-	    }
+	    error_at(pi->location(), "duplicate field name %<%s%>",
+		     Gogo::message_name(pi->field_name()).c_str());
 	}
     }
 
@@ -864,9 +863,8 @@ 
 		    type = Type::make_forward_declaration(no);
 		  else
 		    {
-		      std::string n = Gogo::unpack_hidden_name(p->name());
 		      error_at(p->location(), "expected %<%s%> to be a type",
-			       n.c_str());
+			       Gogo::message_name(p->name()).c_str());
 		      type = Type::make_error_type();
 		    }
 		  tret->push_back(Typed_identifier("", type, p->location()));
@@ -2133,9 +2131,9 @@ 
 	    && !named_object->type_value()->is_visible())
 	  {
 	    gcc_assert(package != NULL);
-	    const std::string& pname(package->name());
 	    error_at(location, "invalid reference to hidden type %<%s.%s%>",
-		     Gogo::unpack_hidden_name(pname).c_str(), id.c_str());
+		     Gogo::message_name(package->name()).c_str(),
+		     Gogo::message_name(id).c_str());
 	    return Expression::make_error(location);
 	  }
 
@@ -2144,18 +2142,17 @@ 
 	  {
 	    if (package != NULL)
 	      {
-		const std::string& pname(package->name());
+		std::string n1 = Gogo::message_name(package->name());
+		std::string n2 = Gogo::message_name(id);
 		if (!is_exported)
 		  error_at(location,
 			   ("invalid reference to unexported identifier "
 			    "%<%s.%s%>"),
-			   Gogo::unpack_hidden_name(pname).c_str(),
-			   id.c_str());
+			   n1.c_str(), n2.c_str());
 		else
 		  error_at(location,
 			   "reference to undefined identifier %<%s.%s%>",
-			   Gogo::unpack_hidden_name(pname).c_str(),
-			   id.c_str());
+			   n1.c_str(), n2.c_str());
 		return Expression::make_error(location);
 	      }
 
@@ -4449,7 +4446,7 @@ 
 	  error_at(token->location(),
 		   ("break label %qs not associated with "
 		    "for or switch or select"),
-		   token->identifier().c_str());
+		   Gogo::message_name(token->identifier()).c_str());
 	  this->advance_token();
 	  return;
 	}
@@ -4501,7 +4498,7 @@ 
 	{
 	  error_at(token->location(),
 		   "continue label %qs not associated with for",
-		   token->identifier().c_str());
+		   Gogo::message_name(token->identifier()).c_str());
 	  this->advance_token();
 	  return;
 	}
diff -r 90de8536250b go/statements.cc
--- a/go/statements.cc	Tue Nov 16 22:14:07 2010 -0800
+++ b/go/statements.cc	Wed Nov 17 11:32:36 2010 -0800
@@ -2718,7 +2718,7 @@ 
   if (!this->label_->is_defined())
     {
       error_at(this->location(), "reference to undefined label %qs",
-	       this->label_->name().c_str());
+	       Gogo::message_name(this->label_->name()).c_str());
       this->set_is_error();
     }
 }
diff -r 90de8536250b go/types.cc
--- a/go/types.cc	Tue Nov 16 22:14:07 2010 -0800
+++ b/go/types.cc	Wed Nov 17 11:32:36 2010 -0800
@@ -3472,7 +3472,7 @@ 
 	  if (reason != NULL)
 	    {
 	      std::string within_name = within->named_object()->message_name();
-	      std::string name = Gogo::unpack_hidden_name(pf->field_name());
+	      std::string name = Gogo::message_name(pf->field_name());
 	      size_t bufsize = 200 + within_name.length() + name.length();
 	      char* buf = new char[bufsize];
 	      snprintf(buf, bufsize,
@@ -5542,7 +5542,7 @@ 
 	    {
 	      if (!is_recursive)
 		error_at(p->location(), "inherited method %qs is ambiguous",
-			 Gogo::unpack_hidden_name(q->name()).c_str());
+			 Gogo::message_name(q->name()).c_str());
 	    }
 	}
       ++from;
@@ -5659,8 +5659,7 @@ 
 	      char buf[200];
 	      snprintf(buf, sizeof buf,
 		       _("need explicit conversion; missing method %s%s%s"),
-		       open_quote,
-		       Gogo::unpack_hidden_name(p->name()).c_str(),
+		       open_quote, Gogo::message_name(p->name()).c_str(),
 		       close_quote);
 	      reason->assign(buf);
 	    }
@@ -5672,19 +5671,17 @@ 
 	{
 	  if (reason != NULL)
 	    {
-	      size_t len = 200 + p->name().length() + subreason.length();
+	      std::string n = Gogo::message_name(p->name());
+	      size_t len = 100 + n.length() + subreason.length();
 	      char* buf = new char[len];
 	      if (subreason.empty())
 		snprintf(buf, len, _("incompatible type for method %s%s%s"),
-			 open_quote,
-			 Gogo::unpack_hidden_name(p->name()).c_str(),
-			 close_quote);
+			 open_quote, n.c_str(), close_quote);
 	      else
 		snprintf(buf, len,
 			 _("incompatible type for method %s%s%s (%s)"),
-			 open_quote,
-			 Gogo::unpack_hidden_name(p->name()).c_str(),
-			 close_quote, subreason.c_str());
+			 open_quote, n.c_str(), close_quote,
+			 subreason.c_str());
 	      reason->assign(buf);
 	      delete[] buf;
 	    }
@@ -5786,19 +5783,17 @@ 
 	{
 	  if (reason != NULL)
 	    {
-	      char buf[200];
-
+	      std::string n = Gogo::message_name(p->name());
+	      size_t len = n.length() + 100;
+	      char* buf = new char[len];
 	      if (is_ambiguous)
-		snprintf(buf, sizeof buf, _("ambiguous method %s%s%s"),
-			 open_quote,
-			 Gogo::unpack_hidden_name(p->name()).c_str(),
-			 close_quote);
+		snprintf(buf, len, _("ambiguous method %s%s%s"),
+			 open_quote, n.c_str(), close_quote);
 	      else
-		snprintf(buf, sizeof buf, _("missing method %s%s%s"),
-			 open_quote,
-			 Gogo::unpack_hidden_name(p->name()).c_str(),
-			 close_quote);
+		snprintf(buf, len, _("missing method %s%s%s"),
+			 open_quote, n.c_str(), close_quote);
 	      reason->assign(buf);
+	      delete[] buf;
 	    }
 	  return false;
 	}
@@ -5811,19 +5806,17 @@ 
 	{
 	  if (reason != NULL)
 	    {
-	      size_t len = 200 + p->name().length() + subreason.length();
+	      std::string n = Gogo::message_name(p->name());
+	      size_t len = 100 + n.length() + subreason.length();
 	      char* buf = new char[len];
 	      if (subreason.empty())
 		snprintf(buf, len, _("incompatible type for method %s%s%s"),
-			 open_quote,
-			 Gogo::unpack_hidden_name(p->name()).c_str(),
-			 close_quote);
+			 open_quote, n.c_str(), close_quote);
 	      else
 		snprintf(buf, len,
 			 _("incompatible type for method %s%s%s (%s)"),
-			 open_quote,
-			 Gogo::unpack_hidden_name(p->name()).c_str(),
-			 close_quote, subreason.c_str());
+			 open_quote, n.c_str(), close_quote,
+			 subreason.c_str());
 	      reason->assign(buf);
 	      delete[] buf;
 	    }
@@ -5834,12 +5827,11 @@ 
 	{
 	  if (reason != NULL)
 	    {
-	      size_t len = 200 + p->name().length();
+	      std::string n = Gogo::message_name(p->name());
+	      size_t len = 100 + n.length();
 	      char* buf = new char[len];
 	      snprintf(buf, len, _("method %s%s%s requires a pointer"),
-		       open_quote,
-		       Gogo::unpack_hidden_name(p->name()).c_str(),
-		       close_quote);
+		       open_quote, n.c_str(), close_quote);
 	      reason->assign(buf);
 	      delete[] buf;
 	    }
@@ -6690,7 +6682,7 @@ 
   if (find.found())
     {
       error_at(this->location_, "invalid recursive type %qs",
-	       this->name().c_str());
+	       this->message_name().c_str());
       this->is_error_ = true;
       return false;
     }
@@ -6716,14 +6708,14 @@ 
 		{
 		  error_at(p->second->location(),
 			   "method %qs redeclares struct field name",
-			   Gogo::unpack_hidden_name(name).c_str());
+			   Gogo::message_name(name).c_str());
 		  found_dup = true;
 		}
 	      if (it != NULL && it->find_method(name) != NULL)
 		{
 		  error_at(p->second->location(),
 			   "method %qs redeclares interface method name",
-			   Gogo::unpack_hidden_name(name).c_str());
+			   Gogo::message_name(name).c_str());
 		  found_dup = true;
 		}
 	    }
@@ -7554,30 +7546,33 @@ 
     {
       if (!ambig1.empty())
 	error_at(location, "%qs is ambiguous via %qs and %qs",
-		 Gogo::unpack_hidden_name(name).c_str(),
-		 ambig1.c_str(), ambig2.c_str());
+		 Gogo::message_name(name).c_str(),
+		 Gogo::message_name(ambig1).c_str(),
+		 Gogo::message_name(ambig2).c_str());
       else if (found_pointer_method)
 	error_at(location, "method requires a pointer");
       else if (nt == NULL && st == NULL && it == NULL)
 	error_at(location,
 		 ("reference to field %qs in object which "
 		  "has no fields or methods"),
-		 name.c_str());
+		 Gogo::message_name(name).c_str());
       else
 	{
 	  bool is_unexported;
-	  std::string unpacked = Gogo::unpack_hidden_name(name);
 	  if (!Gogo::is_hidden_name(name))
 	    is_unexported = false;
 	  else
-	    is_unexported = Type::is_unexported_field_or_method(gogo, type,
-								unpacked);
+	    {
+	      std::string unpacked = Gogo::unpack_hidden_name(name);
+	      is_unexported = Type::is_unexported_field_or_method(gogo, type,
+								  unpacked);
+	    }
 	  if (is_unexported)
 	    error_at(location, "reference to unexported field or method %qs",
-		     unpacked.c_str());
+		     Gogo::message_name(name).c_str());
 	  else
 	    error_at(location, "reference to undefined field or method %qs",
-		     unpacked.c_str());
+		     Gogo::message_name(name).c_str());
 	}
       return Expression::make_error(location);
     }
@@ -7844,7 +7839,7 @@ 
 	{
 	  error_at(this->named_object_->location(),
 		   "use of undefined type %qs",
-		   Gogo::unpack_hidden_name(no->name()).c_str());
+		   no->message_name().c_str());
 	  this->warned_ = true;
 	}
     }
@@ -7855,7 +7850,7 @@ 
 	{
 	  error_at(this->named_object_->location(),
 		   "use of undefined type %qs",
-		   Gogo::unpack_hidden_name(no->name()).c_str());
+		   no->message_name().c_str());
 	  this->warned_ = true;
 	}
     }
Index: Make-lang.in
===================================================================
--- Make-lang.in	(revision 166846)
+++ Make-lang.in	(working copy)
@@ -169,10 +169,10 @@  go/gogo-tree.o: go/gofrontend/gogo-tree.
 	$(TREE_H) $(GIMPLE_H) tree-iterator.h $(CGRAPH_H) langhooks.h \
 	convert.h output.h $(DIAGNOSTIC_H) $(RTL_H) $(GO_TYPES_H) \
 	$(GO_EXPRESSIONS_H) $(GO_STATEMENTS_H) $(GO_GOGO_H)
-go/gogo.o: go/gofrontend/gogo.cc $(GO_SYSTEM_H) go/gofrontend/go-dump.h \
-	$(GO_LEX_H) $(GO_TYPES_H) $(GO_STATEMENTS_H) $(GO_EXPRESSIONS_H) \
-	go/gofrontend/dataflow.h $(GO_IMPORT_H) go/gofrontend/export.h \
-	$(GO_GOGO_H)
+go/gogo.o: go/gofrontend/gogo.cc $(GO_SYSTEM_H) $(GO_C_H) \
+	go/gofrontend/go-dump.h $(GO_LEX_H) $(GO_TYPES_H) $(GO_STATEMENTS_H) \
+	$(GO_EXPRESSIONS_H) go/gofrontend/dataflow.h $(GO_IMPORT_H) \
+	go/gofrontend/export.h $(GO_GOGO_H)
 go/import.o: go/gofrontend/import.cc $(GO_SYSTEM_H) \
 	$(srcdir)/../include/filenames.h $(srcdir)/../include/simple-object.h \
 	$(GO_C_H) $(GO_GOGO_H) $(GO_TYPES_H) go/gofrontend/export.h \
Index: go-lang.c
===================================================================
--- go-lang.c	(revision 166840)
+++ go-lang.c	(working copy)
@@ -356,6 +356,14 @@  go_preserve_from_gc (tree t)
   go_gc_root = tree_cons (NULL_TREE, t, go_gc_root);
 }
 
+/* Convert an identifier for use in an error message.  */
+
+const char *
+go_localize_identifier (const char *ident)
+{
+  return identifier_to_locale (ident);
+}
+
 #undef LANG_HOOKS_NAME
 #undef LANG_HOOKS_INIT
 #undef LANG_HOOKS_OPTION_LANG_MASK
Index: go-c.h
===================================================================
--- go-c.h	(revision 166832)
+++ go-c.h	(working copy)
@@ -57,6 +57,8 @@  extern tree go_type_for_mode (enum machi
 
 extern void go_preserve_from_gc (tree);
 
+extern const char *go_localize_identifier (const char*);
+
 #if defined(__cplusplus) && !defined(ENABLE_BUILD_WITH_CXX)
 } /* End extern "C".  */
 #endif