compiler: better abstraction layer for diagnostics.
authorThan McIntosh <thanm@google.com>
Fri, 23 Sep 2016 19:36:45 +0000 (19:36 +0000)
committerIan Lance Taylor <ian@gcc.gnu.org>
Fri, 23 Sep 2016 19:36:45 +0000 (19:36 +0000)
    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

22 files changed:
gcc/go/ChangeLog
gcc/go/Make-lang.in
gcc/go/go-gcc-diagnostics.cc [new file with mode: 0644]
gcc/go/go-location.h
gcc/go/go-system.h
gcc/go/gofrontend/MERGE
gcc/go/gofrontend/ast-dump.cc
gcc/go/gofrontend/backend.h
gcc/go/gofrontend/escape.cc
gcc/go/gofrontend/expressions.cc
gcc/go/gofrontend/go-diagnostics.cc [new file with mode: 0644]
gcc/go/gofrontend/go-diagnostics.h [new file with mode: 0644]
gcc/go/gofrontend/go.cc
gcc/go/gofrontend/gogo.cc
gcc/go/gofrontend/import-archive.cc
gcc/go/gofrontend/import.cc
gcc/go/gofrontend/lex.cc
gcc/go/gofrontend/parse.cc
gcc/go/gofrontend/parse.h
gcc/go/gofrontend/statements.cc
gcc/go/gofrontend/statements.h
gcc/go/gofrontend/types.cc

index 25e52745bf77ddb871725e22aecefe426574b44a..2af23240e42d8333371935cd34effda5d5f49725 100644 (file)
@@ -1,3 +1,13 @@
+2016-09-23  Than McIntosh  <thanm@google.com>
+
+       * 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.
+
 2016-09-23  Chris Manghane  <cmang@google.com>
 
        PR go/77701
index e7011f9d2420303ea251198f3eb572b88219f33f..7235f19af17e4bedb7835fb66f99272bca2ecadc 100644 (file)
@@ -54,8 +54,10 @@ GO_OBJS = \
        go/export.o \
        go/expressions.o \
        go/go-backend.o \
+       go/go-diagnostics.o \
        go/go-dump.o \
        go/go-gcc.o \
+       go/go-gcc-diagnostics.o \
        go/go-lang.o \
        go/go-linemap.o \
        go/go-optimize.o \
@@ -227,6 +229,7 @@ GOINCLUDES = -I $(srcdir)/go -I $(srcdir)/go/gofrontend
 CFLAGS-go/go-gcc.o += $(GOINCLUDES)
 CFLAGS-go/go-linemap.o += $(GOINCLUDES)
 CFLAGS-go/go-sha1.o += $(GOINCLUDES)
+CFLAGS-go/go-gcc-diagnostics.o += $(GOINCLUDES)
 
 go/%.o: go/gofrontend/%.cc
        $(COMPILE) $(GOINCLUDES) $<
diff --git a/gcc/go/go-gcc-diagnostics.cc b/gcc/go/go-gcc-diagnostics.cc
new file mode 100644 (file)
index 0000000..893b31e
--- /dev/null
@@ -0,0 +1,61 @@
+// go-gcc-diagnostics.cc -- GCC implementation of go diagnostics interface.
+// Copyright (C) 2016 Free Software Foundation, Inc.
+// Contributed by Than McIntosh, Google.
+
+// This file is part of GCC.
+
+// GCC is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3, or (at your option) any later
+// version.
+
+// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with GCC; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+#include "go-system.h"
+#include "go-diagnostics.h"
+
+void
+go_be_error_at(const Location location, const std::string& errmsg)
+{
+  source_location gcc_loc = location.gcc_location();
+  error_at(gcc_loc, "%s", errmsg.c_str());
+}
+
+
+void
+go_be_warning_at(const Location location,
+                 int opt, const std::string& warningmsg)
+{
+  source_location gcc_loc = location.gcc_location();
+  warning_at(gcc_loc, opt, "%s", warningmsg.c_str());
+}
+
+void
+go_be_fatal_error(const Location location,
+                  const std::string& fatalmsg)
+{
+  source_location gcc_loc = location.gcc_location();
+  fatal_error(gcc_loc, "%s", fatalmsg.c_str());
+}
+
+void
+go_be_inform(const Location location,
+             const std::string& infomsg)
+{
+  source_location gcc_loc = location.gcc_location();
+  inform(gcc_loc, "%s", infomsg.c_str());
+}
+
+void
+go_be_get_quotechars(const char** open_qu, const char** close_qu)
+{
+  *open_qu = open_quote;
+  *close_qu = close_quote;
+}
index f2731d96862456d46b260668a7f53deb3def3cce..90258ea1a29d97512636d45a7b8a3273775ef776 100644 (file)
@@ -26,10 +26,6 @@ class Location
   gcc_location() const
   { return this->gcc_loc_; }
 
-  // Temporary hack till error_at and warning_at can deal with a Location.
-  operator source_location() const
-  { return this->gcc_loc_; }
-
  private:
   source_location gcc_loc_;
 };
@@ -42,4 +38,10 @@ operator<(Location loca, Location locb)
   return loca.gcc_location() < locb.gcc_location();
 }
 
+inline bool
+operator==(Location loca, Location locb)
+{
+  return loca.gcc_location() == locb.gcc_location();
+}
+
 #endif // !defined(GO_LOCATION_H)
index cb7e74500cf3c61667e12fa0f39199771824a011..d348d5c533a553a9d1f18234cc71c3f69acd0b70 100644 (file)
@@ -30,6 +30,7 @@
 #include <map>
 #include <set>
 #include <vector>
+#include <sstream>
 
 #if defined(HAVE_UNORDERED_MAP)
 
index ece695428a6651b73f38635a6545ee492aab978a..a3457cfcfbc69f2a721b6e2a72cdaa6d76f25f34 100644 (file)
@@ -1,4 +1,4 @@
-4f84c5e0210e674163f3f6462da6f5be9e5b0a36
+57bf3f21005c4508003f65207282c057e3526ec0
 
 The first line of this file holds the git revision number of the last
 merge done from the gofrontend repository.
index 8dad18c4f05cd09be58f0515cbad7cb23facdc3b..94bf5ef4369309d0e9e361b1db7bb49c72191f56 100644 (file)
@@ -16,6 +16,7 @@
 #include "ast-dump.h"
 #include "go-c.h"
 #include "go-dump.h"
+#include "go-diagnostics.h"
 
 // The -fgo-dump-ast flag to activate AST dumps.
 
@@ -173,7 +174,8 @@ Ast_dump_context::dump(Gogo* gogo, const char* basename)
 
   if (out.fail())
     {
-      error("cannot open %s:%m, -fgo-dump-ast ignored", dumpname.c_str());
+      go_error_at(Linemap::unknown_location(),
+                 "cannot open %s:%m, -fgo-dump-ast ignored", dumpname.c_str());
       return;
     }
 
index 5593fcb47062e5e0fc4beb52d527bb41b35ecc7b..3b9d3a6202ab842a3b7b3d4324306402f10ebffc 100644 (file)
@@ -55,7 +55,7 @@ class Backend
     Location location;
 
     Btyped_identifier()
-      : name(), btype(NULL), location(UNKNOWN_LOCATION)
+        : name(), btype(NULL), location(Linemap::unknown_location())
     { }
 
     Btyped_identifier(const std::string& a_name, Btype* a_btype,
index ea4978bb5550b53963f9dfe76d4279abc28df76a..1c810769d229fb9e2542e19a0cae500e6aed4543 100644 (file)
@@ -17,6 +17,7 @@
 #include "escape.h"
 #include "ast-dump.h"
 #include "go-optimize.h"
+#include "go-diagnostics.h"
 
 // class Node.
 
@@ -737,9 +738,9 @@ Gogo::analyze_escape()
            {
              Node::Escape_state* state = (*n)->state(context, NULL);
              if (((*n)->encoding() & ESCAPE_MASK) == int(Node::ESCAPE_NONE))
-               inform((*n)->location(), "%s %s does not escape",
-                      strip_packed_prefix(this, debug_function_name(state->fn)).c_str(),
-                      (*n)->ast_format(this).c_str());
+               go_inform((*n)->location(), "%s %s does not escape",
+                         strip_packed_prefix(this, debug_function_name(state->fn)).c_str(),
+                         (*n)->ast_format(this).c_str());
            }
          // TODO(cmang): Which objects in context->noesc actually don't escape.
        }
@@ -1039,9 +1040,9 @@ Escape_analysis_assign::statement(Block*, size_t*, Statement* s)
     {
       Node* n = Node::make_node(s);
       std::string fn_name = this->context_->current_function_name();
-      inform(s->location(), "[%d] %s esc: %s",
-            this->context_->loop_depth(), fn_name.c_str(),
-            n->ast_format(gogo).c_str());
+      go_inform(s->location(), "[%d] %s esc: %s",
+               this->context_->loop_depth(), fn_name.c_str(),
+               n->ast_format(gogo).c_str());
     }
 
   switch (s->classification())
@@ -1074,9 +1075,9 @@ Escape_analysis_assign::statement(Block*, size_t*, Statement* s)
            std::string label_type = (label_stmt->label()->looping()
                                      ? "looping"
                                      : "nonlooping");
-           inform(s->location(), "%s %s label",
-                  label_stmt->label()->name().c_str(),
-                  label_type.c_str());
+           go_inform(s->location(), "%s %s label",
+                     label_stmt->label()->name().c_str(),
+                     label_type.c_str());
          }
       }
       break;
@@ -1163,7 +1164,7 @@ Escape_analysis_assign::expression(Expression** pexpr)
       && n->is_big(this->context_))
     {
       if (debug_level > 1)
-       inform((*pexpr)->location(), "too large for stack");
+       go_inform((*pexpr)->location(), "too large for stack");
       n->set_encoding(Node::ESCAPE_HEAP);
       (*pexpr)->address_taken(true);
       this->assign(this->context_->sink(), n);
@@ -1176,9 +1177,9 @@ Escape_analysis_assign::expression(Expression** pexpr)
     {
       Node* n = Node::make_node(*pexpr);
       std::string fn_name = this->context_->current_function_name();
-      inform((*pexpr)->location(), "[%d] %s esc: %s",
-            this->context_->loop_depth(), fn_name.c_str(),
-            n->ast_format(gogo).c_str());
+      go_inform((*pexpr)->location(), "[%d] %s esc: %s",
+               this->context_->loop_depth(), fn_name.c_str(),
+               n->ast_format(gogo).c_str());
     }
 
   switch ((*pexpr)->classification())
@@ -1210,7 +1211,7 @@ Escape_analysis_assign::expression(Expression** pexpr)
                  this->assign_deref(this->context_->sink(), appended);
 
                  if (debug_level > 2)
-                   error_at((*pexpr)->location(),
+                   go_error_at((*pexpr)->location(),
                             "special treatment of append(slice1, slice2...)");
 
                  // The content of the original slice leaks as well.
@@ -1507,9 +1508,9 @@ Escape_analysis_assign::call(Call_expression* call)
            ++p)
        {
          if (debug_level > 2)
-           inform(call->location(),
-                  "esccall:: indirect call <- %s, untracked",
-                  (*p)->ast_format(gogo).c_str());
+           go_inform(call->location(),
+                     "esccall:: indirect call <- %s, untracked",
+                     (*p)->ast_format(gogo).c_str());
          this->assign(this->context_->sink(), *p);
        }
 
@@ -1523,8 +1524,8 @@ Escape_analysis_assign::call(Call_expression* call)
       && !fntype->is_tagged())
     {
       if (debug_level > 2)
-       inform(call->location(), "esccall:: %s in recursive group",
-              call_node->ast_format(gogo).c_str());
+       go_inform(call->location(), "esccall:: %s in recursive group",
+                 call_node->ast_format(gogo).c_str());
 
       Function* f = fn->named_object()->func_value();
       const Bindings* callee_bindings = f->block()->bindings();
@@ -1592,8 +1593,8 @@ Escape_analysis_assign::call(Call_expression* call)
          for (; p != arg_nodes.end(); ++p)
            {
              if (debug_level > 2)
-               inform(call->location(), "esccall:: ... <- %s, untracked",
-                      (*p)->ast_format(gogo).c_str());
+               go_inform(call->location(), "esccall:: ... <- %s, untracked",
+                         (*p)->ast_format(gogo).c_str());
              this->assign(this->context_->sink(), *p);
            }
        }
@@ -1602,12 +1603,14 @@ Escape_analysis_assign::call(Call_expression* call)
     }
 
   if (debug_level > 2)
-    inform(call->location(), "esccall:: %s not recursive",
-          call_node->ast_format(gogo).c_str());
+    go_inform(call->location(), "esccall:: %s not recursive",
+             call_node->ast_format(gogo).c_str());
 
   Node::Escape_state* call_state = call_node->state(this->context_, NULL);
   if (!call_state->retvals.empty())
-    error("esc already decorated call %s", call_node->ast_format(gogo).c_str());
+    go_error_at(Linemap::unknown_location(),
+               "esc already decorated call %s",
+               call_node->ast_format(gogo).c_str());
   this->context_->init_retvals(call_node, fntype);
 
   // Receiver.
@@ -1676,8 +1679,8 @@ Escape_analysis_assign::call(Call_expression* call)
       for (; p != arg_nodes.end(); ++p)
        {
          if (debug_level > 2)
-           inform(call->location(), "esccall:: ... <- %s, untracked",
-                  (*p)->ast_format(gogo).c_str());
+           go_inform(call->location(), "esccall:: ... <- %s, untracked",
+                      (*p)->ast_format(gogo).c_str());
          this->assign(this->context_->sink(), *p);
        }
     }
@@ -1695,13 +1698,13 @@ Escape_analysis_assign::assign(Node* dst, Node* src)
   Gogo* gogo = this->context_->gogo();
   int debug_level = gogo->debug_escape_level();
   if (debug_level > 1)
-    inform(dst->location(), "[%d] %s escassign: %s(%s)[%s] = %s(%s)[%s]",
-          this->context_->loop_depth(),
-          strip_packed_prefix(gogo, this->context_->current_function_name()).c_str(),
-          dst->ast_format(gogo).c_str(), dst->details().c_str(),
-          dst->op_format().c_str(),
-          src->ast_format(gogo).c_str(), src->details().c_str(),
-          src->op_format().c_str());
+    go_inform(dst->location(), "[%d] %s escassign: %s(%s)[%s] = %s(%s)[%s]",
+             this->context_->loop_depth(),
+             strip_packed_prefix(gogo, this->context_->current_function_name()).c_str(),
+             dst->ast_format(gogo).c_str(), dst->details().c_str(),
+             dst->op_format().c_str(),
+             src->ast_format(gogo).c_str(), src->details().c_str(),
+             src->op_format().c_str());
 
   if (dst->expr() != NULL)
     {
@@ -2123,8 +2126,8 @@ Escape_analysis_assign::assign_from_note(std::string* note,
     }
 
   if (this->context_->gogo()->debug_escape_level() > 2)
-    inform(src->location(), "assignfromtag:: src=  em=%s",
-          Escape_note::make_tag(enc).c_str());
+    go_inform(src->location(), "assignfromtag:: src=  em=%s",
+             Escape_note::make_tag(enc).c_str());
 
   if (enc == Node::ESCAPE_UNKNOWN)
     {
@@ -2194,8 +2197,8 @@ Escape_analysis_assign::flows(Node* dst, Node* src)
 
   Gogo* gogo = this->context_->gogo();
   if (gogo->debug_escape_level() > 2)
-    inform(Linemap::unknown_location(), "flows:: %s <- %s",
-          dst->ast_format(gogo).c_str(), src->ast_format(gogo).c_str());
+    go_inform(Linemap::unknown_location(), "flows:: %s <- %s",
+              dst->ast_format(gogo).c_str(), src->ast_format(gogo).c_str());
 
   if (dst_state->flows.empty())
     this->context_->add_dst(dst);
@@ -2355,18 +2358,18 @@ Escape_analysis_flood::flood(Level level, Node* dst, Node* src,
   Gogo* gogo = this->context_->gogo();
   int debug_level = gogo->debug_escape_level();
   if (debug_level > 1)
-    inform(Linemap::unknown_location(),
-          "escwalk: level:{%d %d} depth:%d "
-          "op=%s %s(%s) "
-          "scope:%s[%d] "
-          "extraloopdepth=%d",
-          level.value(), level.suffix_value(), this->context_->pdepth(),
-          src->op_format().c_str(),
-          src->ast_format(gogo).c_str(),
-          src->details().c_str(),
-          debug_function_name(src_state->fn).c_str(),
-          src_state->loop_depth,
-          extra_loop_depth);
+    go_inform(Linemap::unknown_location(),
+             "escwalk: level:{%d %d} depth:%d "
+             "op=%s %s(%s) "
+             "scope:%s[%d] "
+             "extraloopdepth=%d",
+             level.value(), level.suffix_value(), this->context_->pdepth(),
+             src->op_format().c_str(),
+             src->ast_format(gogo).c_str(),
+             src->details().c_str(),
+             debug_function_name(src_state->fn).c_str(),
+             src_state->loop_depth,
+             extra_loop_depth);
 
   this->context_->increase_pdepth();
 
@@ -2400,15 +2403,17 @@ Escape_analysis_flood::flood(Level level, Node* dst, Node* src,
       if (debug_level != 0)
        {
          if (debug_level == 1)
-           inform(src->location(),
-                  "leaking param: %s to result %s level=%d",
-                  src->ast_format(gogo).c_str(), dst->ast_format(gogo).c_str(),
-                  level.value());
+           go_inform(src->location(),
+                     "leaking param: %s to result %s level=%d",
+                     src->ast_format(gogo).c_str(),
+                     dst->ast_format(gogo).c_str(),
+                     level.value());
          else
-           inform(src->location(),
-                  "leaking param: %s to result %s level={%d %d}",
-                  src->ast_format(gogo).c_str(), dst->ast_format(gogo).c_str(),
-                  level.value(), level.suffix_value());
+           go_inform(src->location(),
+                     "leaking param: %s to result %s level={%d %d}",
+                     src->ast_format(gogo).c_str(),
+                     dst->ast_format(gogo).c_str(),
+                     level.value(), level.suffix_value());
        }
 
       if ((src->encoding() & ESCAPE_MASK) != Node::ESCAPE_RETURN)
@@ -2446,8 +2451,8 @@ Escape_analysis_flood::flood(Level level, Node* dst, Node* src,
                           Node::ESCAPE_NONE);
       src->set_encoding(enc);
       if (debug_level != 0)
-       inform(src->location(), "mark escaped content: %s",
-              src->ast_format(gogo).c_str());
+       go_inform(src->location(), "mark escaped content: %s",
+                 src->ast_format(gogo).c_str());
     }
 
   // A src object leaks if its value or address is assigned to a dst object
@@ -2468,13 +2473,13 @@ Escape_analysis_flood::flood(Level level, Node* dst, Node* src,
                               Node::ESCAPE_NONE);
          src->set_encoding(enc);
          if (debug_level != 0)
-           inform(src->location(), "leaking param content: %s",
-                  src->ast_format(gogo).c_str());
+           go_inform(src->location(), "leaking param content: %s",
+                     src->ast_format(gogo).c_str());
        }
       else
        {
          if (debug_level != 0)
-           inform(src->location(), "leaking param");
+           go_inform(src->location(), "leaking param");
          src->set_encoding(Node::ESCAPE_SCOPE);
        }
     }
@@ -2484,8 +2489,8 @@ Escape_analysis_flood::flood(Level level, Node* dst, Node* src,
       if (e->enclosed_var_expression() != NULL)
        {
          if (src_leaks && debug_level != 0)
-           inform(src->location(), "leaking closure reference %s",
-                  src->ast_format(gogo).c_str());
+           go_inform(src->location(), "leaking closure reference %s",
+                     src->ast_format(gogo).c_str());
 
          Node* enclosed_node =
            Node::make_node(e->enclosed_var_expression()->variable());
@@ -2511,19 +2516,19 @@ Escape_analysis_flood::flood(Level level, Node* dst, Node* src,
              src->set_encoding(Node::ESCAPE_HEAP);
              if (debug_level != 0)
                {
-                 inform(underlying->location(), "moved to heap: %s",
-                        underlying_node->ast_format(gogo).c_str());
+                 go_inform(underlying->location(), "moved to heap: %s",
+                            underlying_node->ast_format(gogo).c_str());
 
                  if (debug_level > 1)
-                   inform(src->location(),
-                          "%s escapes to heap, level={%d %d}, "
-                          "dst.eld=%d, src.eld=%d",
-                          src->ast_format(gogo).c_str(), level.value(),
-                          level.suffix_value(), dst_state->loop_depth,
-                          mod_loop_depth);
+                   go_inform(src->location(),
+                             "%s escapes to heap, level={%d %d}, "
+                             "dst.eld=%d, src.eld=%d",
+                             src->ast_format(gogo).c_str(), level.value(),
+                             level.suffix_value(), dst_state->loop_depth,
+                             mod_loop_depth);
                  else
-                   inform(src->location(), "%s escapes to heap",
-                          src->ast_format(gogo).c_str());
+                   go_inform(src->location(), "%s escapes to heap",
+                             src->ast_format(gogo).c_str());
                }
 
              this->flood(level.decrease(), dst,
@@ -2553,8 +2558,8 @@ Escape_analysis_flood::flood(Level level, Node* dst, Node* src,
            {
              src->set_encoding(Node::ESCAPE_HEAP);
              if (debug_level != 0)
-               inform(src->location(), "%s escapes to heap",
-                      src->ast_format(gogo).c_str());
+               go_inform(src->location(), "%s escapes to heap",
+                         src->ast_format(gogo).c_str());
              extra_loop_depth = mod_loop_depth;
            }
        }
@@ -2598,8 +2603,8 @@ Escape_analysis_flood::flood(Level level, Node* dst, Node* src,
                        {
                          src->set_encoding(Node::ESCAPE_HEAP);
                          if (debug_level != 0)
-                           inform(src->location(), "%s escapes to heap",
-                                  src->ast_format(gogo).c_str());
+                           go_inform(src->location(), "%s escapes to heap",
+                                     src->ast_format(gogo).c_str());
                          extra_loop_depth = mod_loop_depth;
                        }
                      break;
@@ -2616,8 +2621,8 @@ Escape_analysis_flood::flood(Level level, Node* dst, Node* src,
                  // so if this leaks, this call must be done on the heap.
                  src->set_encoding(Node::ESCAPE_HEAP);
                  if (debug_level != 0)
-                   inform(src->location(), "%s escapes to heap",
-                          src->ast_format(gogo).c_str());
+                   go_inform(src->location(), "%s escapes to heap",
+                             src->ast_format(gogo).c_str());
                }
            }
        }
@@ -2626,8 +2631,8 @@ Escape_analysis_flood::flood(Level level, Node* dst, Node* src,
          // Calls to Runtime::NEW get lowered into an allocation expression.
          src->set_encoding(Node::ESCAPE_HEAP);
          if (debug_level != 0)
-           inform(src->location(), "%s escapes to heap",
-                  src->ast_format(gogo).c_str());
+           go_inform(src->location(), "%s escapes to heap",
+                      src->ast_format(gogo).c_str());
        }
       else if ((e->field_reference_expression() != NULL
                && e->field_reference_expression()->expr()->unary_expression() == NULL)
@@ -2703,10 +2708,10 @@ Gogo::propagate_escape(Escape_context* context, Node* dst)
   Node::Escape_state* state = dst->state(context, NULL);
   Gogo* gogo = context->gogo();
   if (gogo->debug_escape_level() > 1)
-    inform(Linemap::unknown_location(), "escflood:%d: dst %s scope:%s[%d]",
-          context->flood_id(), dst->ast_format(gogo).c_str(),
-          debug_function_name(state->fn).c_str(),
-          state->loop_depth);
+    go_inform(Linemap::unknown_location(), "escflood:%d: dst %s scope:%s[%d]",
+             context->flood_id(), dst->ast_format(gogo).c_str(),
+             debug_function_name(state->fn).c_str(),
+             state->loop_depth);
 
   Escape_analysis_flood eaf(context);
   for (std::set<Node*>::const_iterator p = state->flows.begin();
index 84c578dd7b1a07bf1b515d29bede33fa4424b6c8..5342e45754dc0b6773941f9bd4fdc1ddcd79c115 100644 (file)
@@ -10,6 +10,7 @@
 
 #include "go-c.h"
 #include "gogo.h"
+#include "go-diagnostics.h"
 #include "types.h"
 #include "export.h"
 #include "import.h"
@@ -107,7 +108,7 @@ Expression::set_is_error()
 void
 Expression::report_error(const char* msg)
 {
-  error_at(this->location_, "%s", msg);
+  go_error_at(this->location_, "%s", msg);
   this->set_is_error();
 }
 
@@ -1139,9 +1140,9 @@ Func_expression::get_code_pointer(Gogo* gogo, Named_object* no, Location loc)
   // can't take their address.
   if (fntype->is_builtin())
     {
-      error_at(loc,
-              "invalid use of special builtin function %qs; must be called",
-              no->message_name().c_str());
+      go_error_at(loc,
+                 "invalid use of special builtin function %qs; must be called",
+                 no->message_name().c_str());
       return gogo->backend()->error_expression();
     }
 
@@ -1178,10 +1179,10 @@ Func_expression::do_get_backend(Translate_context* context)
        {
          if (no->func_declaration_value()->type()->is_builtin())
            {
-             error_at(this->location(),
-                      ("invalid use of special builtin function %qs; "
-                       "must be called"),
-                      no->message_name().c_str());
+             go_error_at(this->location(),
+                         ("invalid use of special builtin function %qs; "
+                          "must be called"),
+                         no->message_name().c_str());
              return gogo->backend()->error_expression();
            }
          descriptor = no->func_declaration_value()->descriptor(gogo, no);
@@ -1447,8 +1448,8 @@ Unknown_expression::do_lower(Gogo*, Named_object*, Statement_inserter*, int)
          if (this->is_composite_literal_key_)
            return this;
          if (!this->no_error_message_)
-           error_at(location, "reference to undefined name %qs",
-                    this->named_object_->message_name().c_str());
+           go_error_at(location, "reference to undefined name %qs",
+                       this->named_object_->message_name().c_str());
          return Expression::make_error(location);
        }
     }
@@ -1462,8 +1463,8 @@ Unknown_expression::do_lower(Gogo*, Named_object*, Statement_inserter*, int)
       if (this->is_composite_literal_key_)
        return this;
       if (!this->no_error_message_)
-       error_at(location, "reference to undefined type %qs",
-                real->message_name().c_str());
+       go_error_at(location, "reference to undefined type %qs",
+                   real->message_name().c_str());
       return Expression::make_error(location);
     case Named_object::NAMED_OBJECT_VAR:
       real->var_value()->set_is_used();
@@ -1475,7 +1476,7 @@ Unknown_expression::do_lower(Gogo*, Named_object*, Statement_inserter*, int)
       if (this->is_composite_literal_key_)
        return this;
       if (!this->no_error_message_)
-       error_at(location, "unexpected reference to package");
+       go_error_at(location, "unexpected reference to package");
       return Expression::make_error(location);
     default:
       go_unreachable();
@@ -1726,7 +1727,7 @@ String_expression::do_import(Import* imp)
            }
          else
            {
-             error_at(imp->location(), "bad string constant");
+             go_error_at(imp->location(), "bad string constant");
              return Expression::make_error(imp->location());
            }
        }
@@ -2036,8 +2037,8 @@ Integer_expression::do_get_backend(Translate_context* context)
       else
         {
           if (!saw_errors())
-            error_at(this->location(),
-                     "unknown type for large integer constant");
+            go_error_at(this->location(),
+                        "unknown type for large integer constant");
           return context->gogo()->backend()->error_expression();
         }
     }
@@ -2088,8 +2089,8 @@ Integer_expression::do_import(Import* imp)
        pos = plus_pos;
       else
        {
-         error_at(imp->location(), "bad number in import data: %qs",
-                  num.c_str());
+         go_error_at(imp->location(), "bad number in import data: %qs",
+                     num.c_str());
          return Expression::make_error(imp->location());
        }
       if (pos == std::string::npos)
@@ -2099,8 +2100,8 @@ Integer_expression::do_import(Import* imp)
          std::string real_str = num.substr(0, pos);
          if (mpfr_init_set_str(real, real_str.c_str(), 10, GMP_RNDN) != 0)
            {
-             error_at(imp->location(), "bad number in import data: %qs",
-                      real_str.c_str());
+             go_error_at(imp->location(), "bad number in import data: %qs",
+                         real_str.c_str());
              return Expression::make_error(imp->location());
            }
        }
@@ -2114,8 +2115,8 @@ Integer_expression::do_import(Import* imp)
       mpfr_t imag;
       if (mpfr_init_set_str(imag, imag_str.c_str(), 10, GMP_RNDN) != 0)
        {
-         error_at(imp->location(), "bad number in import data: %qs",
-                  imag_str.c_str());
+         go_error_at(imp->location(), "bad number in import data: %qs",
+                     imag_str.c_str());
          return Expression::make_error(imp->location());
        }
       mpc_t cval;
@@ -2137,8 +2138,8 @@ Integer_expression::do_import(Import* imp)
       mpz_t val;
       if (mpz_init_set_str(val, num.c_str(), 10) != 0)
        {
-         error_at(imp->location(), "bad number in import data: %qs",
-                  num.c_str());
+         go_error_at(imp->location(), "bad number in import data: %qs",
+                     num.c_str());
          return Expression::make_error(imp->location());
        }
       Expression* ret;
@@ -2154,8 +2155,8 @@ Integer_expression::do_import(Import* imp)
       mpfr_t val;
       if (mpfr_init_set_str(val, num.c_str(), 10, GMP_RNDN) != 0)
        {
-         error_at(imp->location(), "bad number in import data: %qs",
-                  num.c_str());
+         go_error_at(imp->location(), "bad number in import data: %qs",
+                     num.c_str());
          return Expression::make_error(imp->location());
        }
       Expression* ret = Expression::make_float(&val, NULL, imp->location());
@@ -2758,8 +2759,8 @@ Const_expression::do_lower(Gogo* gogo, Named_object*,
     {
       if (iota_value == -1)
        {
-         error_at(this->location(),
-                  "iota is only defined in const declarations");
+         go_error_at(this->location(),
+                     "iota is only defined in const declarations");
          iota_value = 0;
        }
       return Expression::make_integer_ul(iota_value, NULL, this->location());
@@ -3215,7 +3216,7 @@ Type_conversion_expression::do_lower(Gogo*, Named_object*,
                      int adv = Lex::fetch_char(p, &c);
                      if (adv == 0)
                        {
-                         warning_at(this->location(), 0,
+                         go_warning_at(this->location(), 0,
                                     "invalid UTF-8 encoding");
                          adv = 1;
                        }
@@ -3374,7 +3375,7 @@ Type_conversion_expression::do_check_types(Gogo*)
   if (Type::are_convertible(type, expr_type, &reason))
     return;
 
-  error_at(this->location(), "%s", reason.c_str());
+  go_error_at(this->location(), "%s", reason.c_str());
   this->set_is_error();
 }
 
@@ -3691,8 +3692,8 @@ Unary_expression::do_lower(Gogo*, Named_object*, Statement_inserter*, int)
                  // *&x == x.
                  if (!ue->expr_->is_addressable() && !ue->create_temp_)
                    {
-                     error_at(ue->location(),
-                              "invalid operand for unary %<&%>");
+                     go_error_at(ue->location(),
+                                 "invalid operand for unary %<&%>");
                      this->set_is_error();
                    }
                  return ue->expr_;
@@ -3706,7 +3707,7 @@ Unary_expression::do_lower(Gogo*, Named_object*, Statement_inserter*, int)
   // having to deal with TYPE_VOID in other places.
   if (op == OPERATOR_MULT && expr->type()->is_unsafe_pointer_type())
     {
-      error_at(this->location(), "invalid indirect of %<unsafe.Pointer%>");
+      go_error_at(this->location(), "invalid indirect of %<unsafe.Pointer%>");
       return Expression::make_error(this->location());
     }
 
@@ -4116,7 +4117,7 @@ Unary_expression::do_check_types(Gogo*)
        {
          if (!this->create_temp_)
            {
-             error_at(this->location(), "invalid operand for unary %<&%>");
+             go_error_at(this->location(), "invalid operand for unary %<&%>");
              this->set_is_error();
            }
        }
@@ -4723,7 +4724,7 @@ Binary_expression::eval_integer(Operator op, const Numeric_constant* left_nc,
       mpz_add(val, left_val, right_val);
       if (mpz_sizeinbase(val, 2) > 0x100000)
        {
-         error_at(location, "constant addition overflow");
+         go_error_at(location, "constant addition overflow");
           nc->set_invalid();
          mpz_set_ui(val, 1);
        }
@@ -4732,7 +4733,7 @@ Binary_expression::eval_integer(Operator op, const Numeric_constant* left_nc,
       mpz_sub(val, left_val, right_val);
       if (mpz_sizeinbase(val, 2) > 0x100000)
        {
-         error_at(location, "constant subtraction overflow");
+         go_error_at(location, "constant subtraction overflow");
           nc->set_invalid();
          mpz_set_ui(val, 1);
        }
@@ -4747,7 +4748,7 @@ Binary_expression::eval_integer(Operator op, const Numeric_constant* left_nc,
       mpz_mul(val, left_val, right_val);
       if (mpz_sizeinbase(val, 2) > 0x100000)
        {
-         error_at(location, "constant multiplication overflow");
+         go_error_at(location, "constant multiplication overflow");
           nc->set_invalid();
          mpz_set_ui(val, 1);
        }
@@ -4757,7 +4758,7 @@ Binary_expression::eval_integer(Operator op, const Numeric_constant* left_nc,
        mpz_tdiv_q(val, left_val, right_val);
       else
        {
-         error_at(location, "division by zero");
+         go_error_at(location, "division by zero");
           nc->set_invalid();
          mpz_set_ui(val, 0);
        }
@@ -4767,7 +4768,7 @@ Binary_expression::eval_integer(Operator op, const Numeric_constant* left_nc,
        mpz_tdiv_r(val, left_val, right_val);
       else
        {
-         error_at(location, "division by zero");
+         go_error_at(location, "division by zero");
           nc->set_invalid();
          mpz_set_ui(val, 0);
        }
@@ -4779,7 +4780,7 @@ Binary_expression::eval_integer(Operator op, const Numeric_constant* left_nc,
          mpz_mul_2exp(val, left_val, shift);
        else
          {
-           error_at(location, "shift count overflow");
+           go_error_at(location, "shift count overflow");
             nc->set_invalid();
            mpz_set_ui(val, 1);
          }
@@ -4791,7 +4792,7 @@ Binary_expression::eval_integer(Operator op, const Numeric_constant* left_nc,
        unsigned long shift = mpz_get_ui(right_val);
        if (mpz_cmp_ui(right_val, shift) != 0)
          {
-           error_at(location, "shift count overflow");
+           go_error_at(location, "shift count overflow");
             nc->set_invalid();
            mpz_set_ui(val, 1);
          }
@@ -4886,7 +4887,7 @@ Binary_expression::eval_float(Operator op, const Numeric_constant* left_nc,
        mpfr_div(val, left_val, right_val, GMP_RNDN);
       else
        {
-         error_at(location, "division by zero");
+         go_error_at(location, "division by zero");
           nc->set_invalid();
          mpfr_set_ui(val, 0, GMP_RNDN);
        }
@@ -4951,7 +4952,7 @@ Binary_expression::eval_complex(Operator op, const Numeric_constant* left_nc,
     case OPERATOR_DIV:
       if (mpc_cmp_si(right_val, 0) == 0)
        {
-         error_at(location, "division by zero");
+         go_error_at(location, "division by zero");
           nc->set_invalid();
          mpc_set_ui(val, 0, MPC_RNDNN);
          break;
@@ -5542,7 +5543,7 @@ Binary_expression::check_operator_type(Operator op, Type* type, Type* otype,
       if (!type->is_boolean_type()
           || !otype->is_boolean_type())
        {
-         error_at(location, "expected boolean type");
+         go_error_at(location, "expected boolean type");
          return false;
        }
       break;
@@ -5553,7 +5554,7 @@ Binary_expression::check_operator_type(Operator op, Type* type, Type* otype,
        std::string reason;
        if (!Type::are_compatible_for_comparison(true, type, otype, &reason))
          {
-           error_at(location, "%s", reason.c_str());
+           go_error_at(location, "%s", reason.c_str());
            return false;
          }
       }
@@ -5567,7 +5568,7 @@ Binary_expression::check_operator_type(Operator op, Type* type, Type* otype,
        std::string reason;
        if (!Type::are_compatible_for_comparison(false, type, otype, &reason))
          {
-           error_at(location, "%s", reason.c_str());
+           go_error_at(location, "%s", reason.c_str());
            return false;
          }
       }
@@ -5578,7 +5579,7 @@ Binary_expression::check_operator_type(Operator op, Type* type, Type* otype,
       if ((!type->is_numeric_type() && !type->is_string_type())
           || (!otype->is_numeric_type() && !otype->is_string_type()))
        {
-         error_at(location,
+         go_error_at(location,
                   "expected integer, floating, complex, or string type");
          return false;
        }
@@ -5592,7 +5593,7 @@ Binary_expression::check_operator_type(Operator op, Type* type, Type* otype,
     case OPERATOR_DIVEQ:
       if (!type->is_numeric_type() || !otype->is_numeric_type())
        {
-         error_at(location, "expected integer, floating, or complex type");
+         go_error_at(location, "expected integer, floating, or complex type");
          return false;
        }
       break;
@@ -5609,7 +5610,7 @@ Binary_expression::check_operator_type(Operator op, Type* type, Type* otype,
     case OPERATOR_BITCLEAREQ:
       if (type->integer_type() == NULL || otype->integer_type() == NULL)
        {
-         error_at(location, "expected integer type");
+         go_error_at(location, "expected integer type");
          return false;
        }
       break;
@@ -6135,7 +6136,7 @@ Binary_expression::do_import(Import* imp)
     }
   else
     {
-      error_at(imp->location(), "unrecognized binary operator");
+      go_error_at(imp->location(), "unrecognized binary operator");
       return Expression::make_error(imp->location());
     }
 
@@ -6925,7 +6926,7 @@ Builtin_call_expression::do_lower(Gogo* gogo, Named_object* function,
            Expression* arg = args->front();
            if (!arg->is_type_expression())
              {
-               error_at(arg->location(), "expected type");
+               go_error_at(arg->location(), "expected type");
                this->set_is_error();
              }
            else
@@ -6959,10 +6960,10 @@ Builtin_call_expression::do_lower(Gogo* gogo, Named_object* function,
        if (!slice_type->is_slice_type())
          {
            if (slice_type->is_nil_type())
-             error_at(args->front()->location(), "use of untyped nil");
+             go_error_at(args->front()->location(), "use of untyped nil");
            else
-             error_at(args->front()->location(),
-                      "argument 1 must be a slice");
+             go_error_at(args->front()->location(),
+                         "argument 1 must be a slice");
            this->set_is_error();
            return this;
          }
@@ -7103,7 +7104,7 @@ Builtin_call_expression::lower_make()
   Expression* first_arg = *parg;
   if (!first_arg->is_type_expression())
     {
-      error_at(first_arg->location(), "expected type");
+      go_error_at(first_arg->location(), "expected type");
       this->set_is_error();
       return Expression::make_error(this->location());
     }
@@ -7235,12 +7236,12 @@ Builtin_call_expression::check_int_value(Expression* e, bool is_length)
        case Numeric_constant::NC_UL_VALID:
          break;
        case Numeric_constant::NC_UL_NOTINT:
-         error_at(e->location(), "non-integer %s argument to make",
-                  is_length ? "len" : "cap");
+         go_error_at(e->location(), "non-integer %s argument to make",
+                     is_length ? "len" : "cap");
          return false;
        case Numeric_constant::NC_UL_NEGATIVE:
-         error_at(e->location(), "negative %s argument to make",
-                  is_length ? "len" : "cap");
+         go_error_at(e->location(), "negative %s argument to make",
+                     is_length ? "len" : "cap");
          return false;
        case Numeric_constant::NC_UL_BIG:
          // We don't want to give a compile-time error for a 64-bit
@@ -7256,8 +7257,8 @@ Builtin_call_expression::check_int_value(Expression* e, bool is_length)
       Type* int_type = Type::lookup_integer_type("int");
       if (bits >= int_type->integer_type()->bits())
        {
-         error_at(e->location(), "%s argument too large for make",
-                  is_length ? "len" : "cap");
+         go_error_at(e->location(), "%s argument too large for make",
+                     is_length ? "len" : "cap");
          return false;
        }
 
@@ -7267,8 +7268,8 @@ Builtin_call_expression::check_int_value(Expression* e, bool is_length)
   if (e->type()->integer_type() != NULL)
     return true;
 
-  error_at(e->location(), "non-integer %s argument to make",
-          is_length ? "len" : "cap");
+  go_error_at(e->location(), "non-integer %s argument to make",
+             is_length ? "len" : "cap");
   return false;
 }
 
@@ -7976,7 +7977,7 @@ Builtin_call_expression::do_check_types(Gogo*)
        if (args == NULL)
          {
            if (this->code_ == BUILTIN_PRINT)
-             warning_at(this->location(), 0,
+             go_warning_at(this->location(), 0,
                         "no arguments for builtin function %<%s%>",
                         (this->code_ == BUILTIN_PRINT
                          ? "print"
@@ -8136,8 +8137,9 @@ Builtin_call_expression::do_check_types(Gogo*)
              this->report_error(_("argument 2 has invalid type"));
            else
              {
-               error_at(this->location(), "argument 2 has invalid type (%s)",
-                        reason.c_str());
+               go_error_at(this->location(),
+                           "argument 2 has invalid type (%s)",
+                           reason.c_str());
                this->set_is_error();
              }
          }
@@ -8618,7 +8620,7 @@ Builtin_call_expression::do_export(Export* exp) const
   Numeric_constant nc;
   if (!this->numeric_constant_value(&nc))
     {
-      error_at(this->location(), "value is not constant");
+      go_error_at(this->location(), "value is not constant");
       return;
     }
 
@@ -8794,8 +8796,8 @@ Call_expression::do_lower(Gogo* gogo, Named_object* function,
              // the ellipsis operator should be applied to.  If we unpack the
              // the call into its individual results here, the ellipsis will be
              // applied to the last result.
-             error_at(call->location(),
-                      _("multiple-value argument in single-value context"));
+             go_error_at(call->location(),
+                         _("multiple-value argument in single-value context"));
              return Expression::make_error(call->location());
            }
 
@@ -8998,8 +9000,8 @@ Call_expression::lower_varargs(Gogo* gogo, Named_object* function,
            this->report_error(_("too many arguments"));
          else
            {
-             error_at(this->location(),
-                      _("invalid use of %<...%> with non-slice"));
+             go_error_at(this->location(),
+                         _("invalid use of %<...%> with non-slice"));
              this->set_is_error();
            }
          return;
@@ -9365,11 +9367,11 @@ Call_expression::check_argument_type(int i, const Type* parameter_type,
       if (!issued_error)
        {
          if (reason.empty())
-           error_at(argument_location, "argument %d has incompatible type", i);
+           go_error_at(argument_location, "argument %d has incompatible type", i);
          else
-           error_at(argument_location,
-                    "argument %d has incompatible type (%s)",
-                    i, reason.c_str());
+           go_error_at(argument_location,
+                       "argument %d has incompatible type (%s)",
+                       i, reason.c_str());
        }
       this->set_is_error();
       return false;
@@ -9418,9 +9420,9 @@ Call_expression::do_check_types(Gogo*)
            this->report_error(_("incompatible type for receiver"));
          else
            {
-             error_at(this->location(),
-                      "incompatible type for receiver (%s)",
-                      reason.c_str());
+             go_error_at(this->location(),
+                          "incompatible type for receiver (%s)",
+                          reason.c_str());
              this->set_is_error();
            }
        }
@@ -9432,8 +9434,8 @@ Call_expression::do_check_types(Gogo*)
     {
       if (!fntype->is_varargs())
        {
-         error_at(this->location(),
-                  _("invalid use of %<...%> calling non-variadic function"));
+         go_error_at(this->location(),
+                      _("invalid use of %<...%> calling non-variadic function"));
          this->set_is_error();
          return;
        }
@@ -9910,7 +9912,7 @@ Index_expression::do_lower(Gogo*, Named_object*, Statement_inserter*, int)
     }
   else if (left->is_type_expression())
     {
-      error_at(location, "attempt to index type expression");
+      go_error_at(location, "attempt to index type expression");
       return Expression::make_error(location);
     }
   else if (type->array_type() != NULL)
@@ -9935,7 +9937,7 @@ Index_expression::do_lower(Gogo*, Named_object*, Statement_inserter*, int)
     {
       if (cap != NULL)
         {
-          error_at(location, "invalid 3-index slice of string");
+          go_error_at(location, "invalid 3-index slice of string");
           return Expression::make_error(location);
         }
       return Expression::make_string_index(left, start, end, location);
@@ -9944,15 +9946,15 @@ Index_expression::do_lower(Gogo*, Named_object*, Statement_inserter*, int)
     {
       if (end != NULL || cap != NULL)
        {
-         error_at(location, "invalid slice of map");
+         go_error_at(location, "invalid slice of map");
          return Expression::make_error(location);
        }
       return Expression::make_map_index(left, start, location);
     }
   else
     {
-      error_at(location,
-              "attempt to index object which is not array, string, or map");
+      go_error_at(location,
+                  "attempt to index object which is not array, string, or map");
       return Expression::make_error(location);
     }
 }
@@ -10138,7 +10140,7 @@ Array_index_expression::do_check_types(Gogo*)
                  ? mpz_cmp(ival, lval) >= 0
                  : mpz_cmp(ival, lval) > 0)))
        {
-         error_at(this->start_->location(), "array index out of bounds");
+         go_error_at(this->start_->location(), "array index out of bounds");
          this->set_is_error();
        }
     }
@@ -10154,7 +10156,7 @@ Array_index_expression::do_check_types(Gogo*)
              || mpz_sizeinbase(eval, 2) >= int_bits
              || (lval_valid && mpz_cmp(eval, lval) > 0))
            {
-             error_at(this->end_->location(), "array index out of bounds");
+             go_error_at(this->end_->location(), "array index out of bounds");
              this->set_is_error();
            }
          else if (ival_valid && mpz_cmp(ival, eval) > 0)
@@ -10170,19 +10172,19 @@ Array_index_expression::do_check_types(Gogo*)
               || mpz_sizeinbase(cval, 2) >= int_bits
               || (lval_valid && mpz_cmp(cval, lval) > 0))
             {
-              error_at(this->cap_->location(), "array index out of bounds");
+              go_error_at(this->cap_->location(), "array index out of bounds");
               this->set_is_error();
             }
          else if (ival_valid && mpz_cmp(ival, cval) > 0)
            {
-             error_at(this->cap_->location(),
-                      "invalid slice index: capacity less than start");
+             go_error_at(this->cap_->location(),
+                          "invalid slice index: capacity less than start");
              this->set_is_error();
            }
           else if (eval_valid && mpz_cmp(eval, cval) > 0)
             {
-              error_at(this->cap_->location(),
-                       "invalid slice index: capacity less than length");
+              go_error_at(this->cap_->location(),
+                          "invalid slice index: capacity less than length");
               this->set_is_error();
             }
           mpz_clear(cval);
@@ -10611,7 +10613,7 @@ String_index_expression::do_check_types(Gogo*)
                  ? mpz_cmp_ui(ival, sval.length()) >= 0
                  : mpz_cmp_ui(ival, sval.length()) > 0)))
        {
-         error_at(this->start_->location(), "string index out of bounds");
+         go_error_at(this->start_->location(), "string index out of bounds");
          this->set_is_error();
        }
     }
@@ -10624,7 +10626,7 @@ String_index_expression::do_check_types(Gogo*)
          if (mpz_sgn(eval) < 0
              || (sval_valid && mpz_cmp_ui(eval, sval.length()) > 0))
            {
-             error_at(this->end_->location(), "string index out of bounds");
+             go_error_at(this->end_->location(), "string index out of bounds");
              this->set_is_error();
            }
          else if (ival_valid && mpz_cmp(ival, eval) > 0)
@@ -10854,8 +10856,8 @@ Map_index_expression::do_check_types(Gogo*)
        this->report_error(_("incompatible type for map index"));
       else
        {
-         error_at(this->location(), "incompatible type for map index (%s)",
-                  reason.c_str());
+         go_error_at(this->location(), "incompatible type for map index (%s)",
+                      reason.c_str());
          this->set_is_error();
        }
     }
@@ -11226,8 +11228,8 @@ Interface_field_reference_expression::do_check_types(Gogo*)
        interface_type->find_method(this->name_);
       if (method == NULL)
        {
-         error_at(this->location(), "method %qs not in interface",
-                  Gogo::message_name(this->name_).c_str());
+         go_error_at(this->location(), "method %qs not in interface",
+                      Gogo::message_name(this->name_).c_str());
          this->set_is_error();
        }
     }
@@ -11505,9 +11507,9 @@ Selector_expression::lower_method_expression(Gogo* gogo)
   Named_type* nt = type->named_type();
   if (nt == NULL)
     {
-      error_at(location,
-              ("method expression requires named type or "
-               "pointer to named type"));
+      go_error_at(location,
+                  ("method expression requires named type or "
+                   "pointer to named type"));
       return Expression::make_error(location);
     }
 
@@ -11525,23 +11527,23 @@ Selector_expression::lower_method_expression(Gogo* gogo)
       || (left_type->named_type() != NULL && left_type->points_to() != NULL))
     {
       if (!is_ambiguous)
-       error_at(location, "type %<%s%s%> has no method %<%s%>",
-                is_pointer ? "*" : "",
-                nt->message_name().c_str(),
-                Gogo::message_name(name).c_str());
+       go_error_at(location, "type %<%s%s%> has no method %<%s%>",
+                    is_pointer ? "*" : "",
+                    nt->message_name().c_str(),
+                    Gogo::message_name(name).c_str());
       else
-       error_at(location, "method %<%s%s%> is ambiguous in type %<%s%>",
-                Gogo::message_name(name).c_str(),
-                is_pointer ? "*" : "",
-                nt->message_name().c_str());
+       go_error_at(location, "method %<%s%s%> is ambiguous in type %<%s%>",
+                    Gogo::message_name(name).c_str(),
+                    is_pointer ? "*" : "",
+                    nt->message_name().c_str());
       return Expression::make_error(location);
     }
 
   if (method != NULL && !is_pointer && !method->is_value_method())
     {
-      error_at(location, "method requires pointer (use %<(*%s).%s%>)",
-              nt->message_name().c_str(),
-              Gogo::message_name(name).c_str());
+      go_error_at(location, "method requires pointer (use %<(*%s).%s%>)",
+                  nt->message_name().c_str(),
+                  Gogo::message_name(name).c_str());
       return Expression::make_error(location);
     }
 
@@ -11916,14 +11918,14 @@ Struct_construction_expression::do_check_types(Gogo*)
       if (!Type::are_assignable(pf->type(), (*pv)->type(), &reason))
        {
          if (reason.empty())
-           error_at((*pv)->location(),
-                    "incompatible type for field %d in struct construction",
-                    i + 1);
+           go_error_at((*pv)->location(),
+                        "incompatible type for field %d in struct construction",
+                        i + 1);
          else
-           error_at((*pv)->location(),
-                    ("incompatible type for field %d in "
-                     "struct construction (%s)"),
-                    i + 1, reason.c_str());
+           go_error_at((*pv)->location(),
+                        ("incompatible type for field %d in "
+                         "struct construction (%s)"),
+                        i + 1, reason.c_str());
          this->set_is_error();
        }
     }
@@ -12138,9 +12140,9 @@ Array_construction_expression::do_check_types(Gogo*)
       if (*pv != NULL
          && !Type::are_assignable(element_type, (*pv)->type(), NULL))
        {
-         error_at((*pv)->location(),
-                  "incompatible type for element %d in composite literal",
-                  i + 1);
+         go_error_at((*pv)->location(),
+                      "incompatible type for element %d in composite literal",
+                      i + 1);
          this->set_is_error();
        }
     }
@@ -12588,17 +12590,17 @@ Map_construction_expression::do_check_types(Gogo*)
     {
       if (!Type::are_assignable(key_type, (*pv)->type(), NULL))
        {
-         error_at((*pv)->location(),
-                  "incompatible type for element %d key in map construction",
-                  i + 1);
+         go_error_at((*pv)->location(),
+                      "incompatible type for element %d key in map construction",
+                      i + 1);
          this->set_is_error();
        }
       ++pv;
       if (!Type::are_assignable(val_type, (*pv)->type(), NULL))
        {
-         error_at((*pv)->location(),
-                  ("incompatible type for element %d value "
-                   "in map construction"),
+         go_error_at((*pv)->location(),
+                      ("incompatible type for element %d value "
+                       "in map construction"),
                   i + 1);
          this->set_is_error();
        }
@@ -12779,9 +12781,9 @@ Composite_literal_expression::do_lower(Gogo* gogo, Named_object* function,
       else
        {
          if (!type->is_error())
-           error_at(this->location(),
-                    ("may only omit types within composite literals "
-                     "of slice, array, or map type"));
+           go_error_at(this->location(),
+                        ("may only omit types within composite literals "
+                         "of slice, array, or map type"));
          return Expression::make_error(this->location());
        }
     }
@@ -12805,9 +12807,9 @@ Composite_literal_expression::do_lower(Gogo* gogo, Named_object* function,
     ret = this->lower_map(gogo, function, inserter, type);
   else
     {
-      error_at(this->location(),
-              ("expected struct, slice, array, or map type "
-               "for composite literal"));
+      go_error_at(this->location(),
+                  ("expected struct, slice, array, or map type "
+                   "for composite literal"));
       return Expression::make_error(this->location());
     }
 
@@ -12837,10 +12839,10 @@ Composite_literal_expression::lower_struct(Gogo* gogo, Type* type)
            {
              if (Gogo::is_hidden_name(pf->field_name())
                  || pf->is_embedded_builtin(gogo))
-               error_at(this->location(),
-                        "assignment of unexported field %qs in %qs literal",
-                        Gogo::message_name(pf->field_name()).c_str(),
-                        type->named_type()->message_name().c_str());
+               go_error_at(this->location(),
+                            "assignment of unexported field %qs in %qs literal",
+                            Gogo::message_name(pf->field_name()).c_str(),
+                            type->named_type()->message_name().c_str());
            }
        }
 
@@ -12865,7 +12867,8 @@ Composite_literal_expression::lower_struct(Gogo* gogo, Type* type)
 
       if (name_expr == NULL)
        {
-         error_at(val->location(), "mixture of field and value initializers");
+         go_error_at(val->location(),
+                      "mixture of field and value initializers");
          return Expression::make_error(location);
        }
 
@@ -12921,7 +12924,7 @@ Composite_literal_expression::lower_struct(Gogo* gogo, Type* type)
        }
       if (bad_key)
        {
-         error_at(name_expr->location(), "expected struct field name");
+         go_error_at(name_expr->location(), "expected struct field name");
          return Expression::make_error(location);
        }
 
@@ -12952,21 +12955,21 @@ Composite_literal_expression::lower_struct(Gogo* gogo, Type* type)
       const Struct_field* sf = st->find_local_field(name, &index);
       if (sf == NULL)
        {
-         error_at(name_expr->location(), "unknown field %qs in %qs",
-                  Gogo::message_name(name).c_str(),
-                  (type->named_type() != NULL
-                   ? type->named_type()->message_name().c_str()
-                   : "unnamed struct"));
+         go_error_at(name_expr->location(), "unknown field %qs in %qs",
+                      Gogo::message_name(name).c_str(),
+                      (type->named_type() != NULL
+                       ? type->named_type()->message_name().c_str()
+                       : "unnamed struct"));
          return Expression::make_error(location);
        }
       if (vals[index] != NULL)
        {
-         error_at(name_expr->location(),
-                  "duplicate value for field %qs in %qs",
-                  Gogo::message_name(name).c_str(),
-                  (type->named_type() != NULL
-                   ? type->named_type()->message_name().c_str()
-                   : "unnamed struct"));
+         go_error_at(name_expr->location(),
+                      "duplicate value for field %qs in %qs",
+                      Gogo::message_name(name).c_str(),
+                      (type->named_type() != NULL
+                       ? type->named_type()->message_name().c_str()
+                       : "unnamed struct"));
          return Expression::make_error(location);
        }
 
@@ -12974,10 +12977,10 @@ Composite_literal_expression::lower_struct(Gogo* gogo, Type* type)
          && type->named_type()->named_object()->package() != NULL
          && (Gogo::is_hidden_name(sf->field_name())
              || sf->is_embedded_builtin(gogo)))
-       error_at(name_expr->location(),
-                "assignment of unexported field %qs in %qs literal",
-                Gogo::message_name(sf->field_name()).c_str(),
-                type->named_type()->message_name().c_str());
+       go_error_at(name_expr->location(),
+                    "assignment of unexported field %qs in %qs literal",
+                    Gogo::message_name(sf->field_name()).c_str(),
+                    type->named_type()->message_name().c_str());
 
       vals[index] = val;
       traverse_order->push_back(index);
@@ -12987,16 +12990,16 @@ Composite_literal_expression::lower_struct(Gogo* gogo, Type* type)
     {
       // This is a weird case like bug462 in the testsuite.
       if (external_expr == NULL)
-       error_at(this->location(), "unknown field in %qs literal",
-                (type->named_type() != NULL
-                 ? type->named_type()->message_name().c_str()
-                 : "unnamed struct"));
+       go_error_at(this->location(), "unknown field in %qs literal",
+                    (type->named_type() != NULL
+                     ? type->named_type()->message_name().c_str()
+                     : "unnamed struct"));
       else
-       error_at(external_expr->location(), "unknown field %qs in %qs",
-                external_no->message_name().c_str(),
-                (type->named_type() != NULL
-                 ? type->named_type()->message_name().c_str()
-                 : "unnamed struct"));
+       go_error_at(external_expr->location(), "unknown field %qs in %qs",
+                    external_no->message_name().c_str(),
+                    (type->named_type() != NULL
+                     ? type->named_type()->message_name().c_str()
+                     : "unnamed struct"));
       return Expression::make_error(location);
     }
 
@@ -13064,8 +13067,8 @@ Composite_literal_expression::lower_array(Type* type)
          Numeric_constant nc;
          if (!index_expr->numeric_constant_value(&nc))
            {
-             error_at(index_expr->location(),
-                      "index expression is not integer constant");
+             go_error_at(index_expr->location(),
+                          "index expression is not integer constant");
              return Expression::make_error(location);
            }
 
@@ -13074,14 +13077,15 @@ Composite_literal_expression::lower_array(Type* type)
            case Numeric_constant::NC_UL_VALID:
              break;
            case Numeric_constant::NC_UL_NOTINT:
-             error_at(index_expr->location(),
-                      "index expression is not integer constant");
+             go_error_at(index_expr->location(),
+                          "index expression is not integer constant");
              return Expression::make_error(location);
            case Numeric_constant::NC_UL_NEGATIVE:
-             error_at(index_expr->location(), "index expression is negative");
+             go_error_at(index_expr->location(),
+                          "index expression is negative");
              return Expression::make_error(location);
            case Numeric_constant::NC_UL_BIG:
-             error_at(index_expr->location(), "index value overflow");
+             go_error_at(index_expr->location(), "index value overflow");
              return Expression::make_error(location);
            default:
              go_unreachable();
@@ -13092,15 +13096,16 @@ Composite_literal_expression::lower_array(Type* type)
          if (sizeof(index) <= static_cast<size_t>(inttype->bits() * 8)
              && index >> (inttype->bits() - 1) != 0)
            {
-             error_at(index_expr->location(), "index value overflow");
+             go_error_at(index_expr->location(), "index value overflow");
              return Expression::make_error(location);
            }
 
          if (std::find(indexes->begin(), indexes->end(), index)
              != indexes->end())
            {
-             error_at(index_expr->location(), "duplicate value for index %lu",
-                      index);
+             go_error_at(index_expr->location(),
+                          "duplicate value for index %lu",
+                          index);
              return Expression::make_error(location);
            }
 
@@ -13178,7 +13183,7 @@ Composite_literal_expression::make_array(
          if (sizeof(size) <= static_cast<size_t>(it->bits() * 8)
              && size >> (it->bits() - 1) != 0)
            {
-             error_at(location, "too many elements in composite literal");
+             go_error_at(location, "too many elements in composite literal");
              return Expression::make_error(location);
            }
        }
@@ -13200,7 +13205,8 @@ Composite_literal_expression::make_array(
            {
              if (this->vals_->size() > val)
                {
-                 error_at(location, "too many elements in composite literal");
+                 go_error_at(location,
+                              "too many elements in composite literal");
                  return Expression::make_error(location);
                }
            }
@@ -13209,9 +13215,9 @@ Composite_literal_expression::make_array(
              unsigned long max = indexes->back();
              if (max >= val)
                {
-                 error_at(location,
-                          ("some element keys in composite literal "
-                           "are out of range"));
+                 go_error_at(location,
+                              ("some element keys in composite literal "
+                               "are out of range"));
                  return Expression::make_error(location);
                }
            }
@@ -13237,7 +13243,7 @@ Composite_literal_expression::lower_map(Gogo* gogo, Named_object* function,
     {
       if (!this->has_keys_)
        {
-         error_at(location, "map composite literal must have keys");
+         go_error_at(location, "map composite literal must have keys");
          return Expression::make_error(location);
        }
 
@@ -13248,8 +13254,9 @@ Composite_literal_expression::lower_map(Gogo* gogo, Named_object* function,
          if (*p == NULL)
            {
              ++p;
-             error_at((*p)->location(),
-                      "map composite literal must have keys for every value");
+             go_error_at((*p)->location(),
+                          ("map composite literal must "
+                           "have keys for every value"));
              return Expression::make_error(location);
            }
          // Make sure we have lowered the key; it may not have been
@@ -13434,10 +13441,10 @@ Type_guard_expression::do_check_types(Gogo*)
                this->report_error(_("impossible type assertion: "
                                     "type does not implement interface"));
              else
-               error_at(this->location(),
-                        ("impossible type assertion: "
-                         "type does not implement interface (%s)"),
-                        reason.c_str());
+               go_error_at(this->location(),
+                            ("impossible type assertion: "
+                             "type does not implement interface (%s)"),
+                            reason.c_str());
            }
          this->set_is_error();
        }
@@ -14873,7 +14880,7 @@ Expression::import_expression(Import* imp)
     return Type_conversion_expression::do_import(imp);
   else
     {
-      error_at(imp->location(), "import error: expected expression");
+      go_error_at(imp->location(), "import error: expected expression");
       return Expression::make_error(imp->location());
     }
 }
@@ -15313,8 +15320,8 @@ Numeric_constant::check_int_type(Integer_type* type, bool issue_error,
        {
          if (issue_error)
             {
-              error_at(location,
-                       "floating point constant truncated to integer");
+              go_error_at(location,
+                          "floating point constant truncated to integer");
               this->set_invalid();
             }
          return false;
@@ -15329,7 +15336,7 @@ Numeric_constant::check_int_type(Integer_type* type, bool issue_error,
        {
          if (issue_error)
             {
-              error_at(location, "complex constant truncated to integer");
+              go_error_at(location, "complex constant truncated to integer");
               this->set_invalid();
             }
          return false;
@@ -15370,7 +15377,7 @@ Numeric_constant::check_int_type(Integer_type* type, bool issue_error,
 
   if (!ret && issue_error)
     {
-      error_at(location, "integer constant overflow");
+      go_error_at(location, "integer constant overflow");
       this->set_invalid();
     }
 
@@ -15402,7 +15409,7 @@ Numeric_constant::check_float_type(Float_type* type, bool issue_error,
          if (issue_error)
             {
               this->set_invalid();
-              error_at(location, "complex constant truncated to float");
+              go_error_at(location, "complex constant truncated to float");
             }
          return false;
        }
@@ -15467,7 +15474,7 @@ Numeric_constant::check_float_type(Float_type* type, bool issue_error,
 
   if (!ret && issue_error)
     {
-      error_at(location, "floating point constant overflow");
+      go_error_at(location, "floating point constant overflow");
       this->set_invalid();
     }
 
@@ -15525,7 +15532,7 @@ Numeric_constant::check_complex_type(Complex_type* type, bool issue_error,
     {
       if (issue_error)
         {
-          error_at(location, "complex real part overflow");
+          go_error_at(location, "complex real part overflow");
           this->set_invalid();
         }
       ret = false;
@@ -15538,7 +15545,7 @@ Numeric_constant::check_complex_type(Complex_type* type, bool issue_error,
     {
       if (issue_error)
         {
-          error_at(location, "complex imaginary part overflow");
+          go_error_at(location, "complex imaginary part overflow");
           this->set_invalid();
         }
       ret = false;
diff --git a/gcc/go/gofrontend/go-diagnostics.cc b/gcc/go/gofrontend/go-diagnostics.cc
new file mode 100644 (file)
index 0000000..21e45b3
--- /dev/null
@@ -0,0 +1,177 @@
+// go-diagnostics.cc -- Go error/warning diagnostics utilities.
+
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "go-diagnostics.h"
+
+static std::string
+mformat_value()
+{
+  return std::string(xstrerror(errno));
+}
+
+// Rewrite a format string to expand any extensions not
+// supported by sprintf(). See comments in go-diagnostics.h
+// for list of supported format specifiers.
+
+static std::string
+expand_format(const char* fmt)
+{
+  std::stringstream ss;
+  for (const char* c = fmt; *c; ++c)
+    {
+      if (*c != '%')
+        {
+          ss << *c;
+          continue;
+        }
+      c++;
+      switch (*c)
+        {
+          case '\0':
+            {
+              // malformed format string
+              go_unreachable();
+            }
+          case '%':
+            {
+              ss << "%";
+              break;
+            }
+          case 'm':
+            {
+              ss << mformat_value();
+              break;
+            }
+          case '<':
+            {
+              ss << go_open_quote();
+              break;
+            }
+          case '>':
+            {
+              ss << go_close_quote();
+              break;
+            }
+          case 'q':
+            {
+              ss << go_open_quote();
+              c++;
+              if (*c == 'm')
+                {
+                  ss << mformat_value();
+                }
+              else
+                {
+                  ss << "%" << *c;
+                }
+              ss << go_close_quote();
+              break;
+            }
+          default:
+            {
+              ss << "%" << *c;
+            }
+        }
+    }
+  return ss.str();
+}
+
+// Expand message format specifiers, using a combination of
+// expand_format above to handle extensions (ex: %m, %q) and vasprintf()
+// to handle regular printf-style formatting. A pragma is being used here to
+// suppress this warning:
+//
+//   warning: function â€˜std::__cxx11::string expand_message(const char*, __va_list_tag*)’ might be a candidate for â€˜gnu_printf’ format attribute [-Wsuggest-attribute=format]
+//
+// What appears to be happening here is that the checker is deciding that
+// because of the call to vasprintf() (which has attribute gnu_printf), the
+// calling function must need to have attribute gnu_printf as well, even
+// though there is already an attribute declaration for it.
+
+static std::string
+expand_message(const char* fmt, va_list ap) GO_ATTRIBUTE_GCC_DIAG(1,0);
+
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wsuggest-attribute=format"
+
+static std::string
+expand_message(const char* fmt, va_list ap)
+{
+  char* mbuf = 0;
+  std::string expanded_fmt = expand_format(fmt);
+  int nwr = vasprintf(&mbuf, expanded_fmt.c_str(), ap);
+  if (nwr == -1)
+    {
+      // memory allocation failed
+      go_be_error_at(Linemap::unknown_location(),
+                     "memory allocation failed in vasprintf");
+      go_assert(0);
+    }
+  std::string rval = std::string(mbuf);
+  free(mbuf);
+  return rval;
+}
+
+#pragma GCC diagnostic pop
+
+static const char* cached_open_quote = NULL;
+static const char* cached_close_quote = NULL;
+
+const char*
+go_open_quote()
+{
+  if (cached_open_quote == NULL)
+    go_be_get_quotechars(&cached_open_quote, &cached_close_quote);
+  return cached_open_quote;
+}
+
+const char*
+go_close_quote()
+{
+  if (cached_close_quote == NULL)
+    go_be_get_quotechars(&cached_open_quote, &cached_close_quote);
+  return cached_close_quote;
+}
+
+void
+go_error_at(const Location location, const char* fmt, ...)
+{
+  va_list ap;
+
+  va_start(ap, fmt);
+  go_be_error_at(location, expand_message(fmt, ap));
+  va_end(ap);
+}
+
+void
+go_warning_at(const Location location, int opt, const char* fmt, ...)
+{
+  va_list ap;
+
+  va_start(ap, fmt);
+  go_be_warning_at(location, opt, expand_message(fmt, ap));
+  va_end(ap);
+}
+
+void
+go_fatal_error(const Location location, const char* fmt, ...)
+{
+  va_list ap;
+
+  va_start(ap, fmt);
+  go_be_fatal_error(location, expand_message(fmt, ap));
+  va_end(ap);
+}
+
+void
+go_inform(const Location location, const char* fmt, ...)
+{
+  va_list ap;
+
+  va_start(ap, fmt);
+  go_be_inform(location, expand_message(fmt, ap));
+  va_end(ap);
+}
diff --git a/gcc/go/gofrontend/go-diagnostics.h b/gcc/go/gofrontend/go-diagnostics.h
new file mode 100644 (file)
index 0000000..70c97cb
--- /dev/null
@@ -0,0 +1,64 @@
+// go-diagnostics.h -- interface to diagnostic reporting   -*- C++ -*-
+
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#ifndef GO_DIAGNOSTICS_H
+#define GO_DIAGNOSTICS_H
+
+#include "go-linemap.h"
+
+#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1)
+#define GO_ATTRIBUTE_GCC_DIAG(m, n) __attribute__ ((__format__ (__gcc_tdiag__, m, n))) __attribute__ ((__nonnull__ (m)))
+#else
+#define GO_ATTRIBUTE_GCC_DIAG(m,  n)
+#endif
+
+// These declarations define the interface through which the frontend
+// reports errors and warnings. These functions accept printf-like
+// format specifiers (e.g. %d, %f, %s, etc), with the following additional
+// extensions:
+//
+//  1.  'q' qualifier may be applied to a specifier to add quoting, e.g.
+//      %qd produces a quoted decimal output, %qs a quoted string output.
+//      [This extension is supported only with single-character format
+//      specifiers].
+//
+//  2.  %m specifier outputs value of "strerror(errno)" at time of call.
+//
+//  3.  %< outputs an opening quote, %> a closing quote.
+//
+// All other format specifiers are as defined by 'sprintf'. The final resulting
+// message is then sent to the back end via go_be_error_at/go_be_warning_at.
+
+extern void go_error_at(const Location, const char* fmt, ...)
+    GO_ATTRIBUTE_GCC_DIAG(2,3);
+extern void go_warning_at(const Location, int opt, const char* fmt, ...)
+    GO_ATTRIBUTE_GCC_DIAG(3,4);
+extern void go_fatal_error(const Location, const char* fmt, ...)
+    GO_ATTRIBUTE_GCC_DIAG(2,3);
+extern void go_inform(const Location, const char* fmt, ...)
+    GO_ATTRIBUTE_GCC_DIAG(2,3);
+
+// These interfaces provide a way for the front end to ask for
+// the open/close quote characters it should use when formatting
+// diagnostics (warnings, errors).
+extern const char* go_open_quote();
+extern const char* go_close_quote();
+
+// These interfaces are used by utilities above to pass warnings and
+// errors (once format specifiers have been expanded) to the back end,
+// and to determine quoting style. Avoid calling these routines directly;
+// instead use the equivalent routines above. The back end is required to
+// implement these routines.
+
+extern void go_be_error_at(const Location, const std::string& errmsg);
+extern void go_be_warning_at(const Location, int opt,
+                             const std::string& warningmsg);
+extern void go_be_fatal_error(const Location, const std::string& errmsg);
+extern void go_be_inform(const Location, const std::string& infomsg);
+extern void go_be_get_quotechars(const char** open_quote,
+                                 const char** close_quote);
+
+#endif // !defined(GO_DIAGNOSTICS_H)
index d0f523bdfe8764fd13791c4ceb4b280046884566..927f29d81330324e128824ca7402a50648290b8d 100644 (file)
@@ -7,6 +7,7 @@
 #include "go-system.h"
 
 #include "go-c.h"
+#include "go-diagnostics.h"
 
 #include "lex.h"
 #include "parse.h"
@@ -68,8 +69,8 @@ go_parse_input_files(const char** filenames, unsigned int filename_count,
        {
          file = fopen(filename, "r");
          if (file == NULL)
-           fatal_error(Linemap::unknown_location(),
-                       "cannot open %s: %m", filename);
+           go_fatal_error(Linemap::unknown_location(),
+                          "cannot open %s: %m", filename);
        }
 
       Lex lexer(filename, file, ::gogo->linemap());
@@ -88,9 +89,9 @@ go_parse_input_files(const char** filenames, unsigned int filename_count,
              for (Lex::Linknames::const_iterator p = linknames->begin();
                   p != linknames->end();
                   ++p)
-               error_at(p->second.loc,
-                        ("//go:linkname only allowed in Go files that "
-                         "import \"unsafe\""));
+               go_error_at(p->second.loc,
+                           ("//go:linkname only allowed in Go files that "
+                            "import \"unsafe\""));
            }
          all_linknames.insert(linknames->begin(), linknames->end());
        }
index 20c34208d5bf6fa04022537de3821311e5946096..7617815c98bbc11b7dcdccf8d85948d34a6ca86d 100644 (file)
@@ -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
index 7d7f426059de4cdaca56cf75d1002082462a2653..18d1fdc24bd84a7fcd68ef00722e792cf4e60943 100644 (file)
@@ -6,6 +6,7 @@
 
 #include "go-system.h"
 
+#include "go-diagnostics.h"
 #include "import.h"
 
 #ifndef O_BINARY
@@ -144,7 +145,7 @@ Archive_file::initialize()
   struct stat st;
   if (fstat(this->fd_, &st) < 0)
     {
-      error_at(this->location_, "%s: %m", this->filename_.c_str());
+      go_error_at(this->location_, "%s: %m", this->filename_.c_str());
       return false;
     }
   this->filesize_ = st.st_size;
@@ -153,7 +154,7 @@ Archive_file::initialize()
   if (::lseek(this->fd_, 0, SEEK_SET) < 0
       || ::read(this->fd_, buf, sizeof(armagt)) != sizeof(armagt))
     {
-      error_at(this->location_, "%s: %m", this->filename_.c_str());
+      go_error_at(this->location_, "%s: %m", this->filename_.c_str());
       return false;
     }
   this->is_thin_archive_ = memcmp(buf, armagt, sizeof(armagt)) == 0;
@@ -183,7 +184,7 @@ Archive_file::initialize()
       char* rdbuf = new char[size];
       if (::read(this->fd_, rdbuf, size) != size)
        {
-         error_at(this->location_, "%s: could not read extended names",
+         go_error_at(this->location_, "%s: could not read extended names",
                   filename.c_str());
          delete[] rdbuf;
          return false;
@@ -203,7 +204,7 @@ Archive_file::read(off_t offset, off_t size, char* buf)
   if (::lseek(this->fd_, offset, SEEK_SET) < 0
       || ::read(this->fd_, buf, size) != size)
     {
-      error_at(this->location_, "%s: %m", this->filename_.c_str());
+      go_error_at(this->location_, "%s: %m", this->filename_.c_str());
       return false;
     }
   return true;
@@ -219,20 +220,20 @@ Archive_file::read_header(off_t off, std::string* pname, off_t* size,
   Archive_header hdr;
   if (::lseek(this->fd_, off, SEEK_SET) < 0)
     {
-      error_at(this->location_, "%s: %m", this->filename_.c_str());
+      go_error_at(this->location_, "%s: %m", this->filename_.c_str());
       return false;
     }
   ssize_t got = ::read(this->fd_, &hdr, sizeof hdr);
   if (got != sizeof hdr)
     {
       if (got < 0)
-       error_at(this->location_, "%s: %m", this->filename_.c_str());
+       go_error_at(this->location_, "%s: %m", this->filename_.c_str());
       else if (got > 0)
-       error_at(this->location_, "%s: short archive header at %ld",
-                this->filename_.c_str(), static_cast<long>(off));
+       go_error_at(this->location_, "%s: short archive header at %ld",
+                   this->filename_.c_str(), static_cast<long>(off));
       else
-       error_at(this->location_, "%s: unexpected EOF at %ld",
-                this->filename_.c_str(), static_cast<long>(off));
+       go_error_at(this->location_, "%s: unexpected EOF at %ld",
+                   this->filename_.c_str(), static_cast<long>(off));
     }
   off_t local_nested_off;
   if (!this->interpret_header(&hdr, off, pname, size, &local_nested_off))
@@ -252,8 +253,8 @@ Archive_file::interpret_header(const Archive_header* hdr, off_t off,
 {
   if (memcmp(hdr->ar_fmag, arfmag, sizeof arfmag) != 0)
     {
-      error_at(this->location_, "%s: malformed archive header at %lu",
-              this->filename_.c_str(), static_cast<unsigned long>(off));
+      go_error_at(this->location_, "%s: malformed archive header at %lu",
+                 this->filename_.c_str(), static_cast<unsigned long>(off));
       return false;
     }
 
@@ -272,8 +273,8 @@ Archive_file::interpret_header(const Archive_header* hdr, off_t off,
       || *size < 0
       || (*size == LONG_MAX && errno == ERANGE))
     {
-      error_at(this->location_, "%s: malformed archive header size at %lu",
-              this->filename_.c_str(), static_cast<unsigned long>(off));
+      go_error_at(this->location_, "%s: malformed archive header size at %lu",
+                 this->filename_.c_str(), static_cast<unsigned long>(off));
       return false;
     }
 
@@ -284,8 +285,9 @@ Archive_file::interpret_header(const Archive_header* hdr, off_t off,
       if (name_end == NULL
          || name_end - hdr->ar_name >= static_cast<int>(sizeof hdr->ar_name))
        {
-         error_at(this->location_, "%s: malformed archive header name at %lu",
-                  this->filename_.c_str(), static_cast<unsigned long>(off));
+         go_error_at(this->location_,
+                     "%s: malformed archive header name at %lu",
+                     this->filename_.c_str(), static_cast<unsigned long>(off));
          return false;
        }
       pname->assign(hdr->ar_name, name_end - hdr->ar_name);
@@ -321,8 +323,8 @@ Archive_file::interpret_header(const Archive_header* hdr, off_t off,
          || (x == LONG_MAX && errno == ERANGE)
          || static_cast<size_t>(x) >= this->extended_names_.size())
        {
-         error_at(this->location_, "%s: bad extended name index at %lu",
-                  this->filename_.c_str(), static_cast<unsigned long>(off));
+         go_error_at(this->location_, "%s: bad extended name index at %lu",
+                     this->filename_.c_str(), static_cast<unsigned long>(off));
          return false;
        }
 
@@ -331,8 +333,9 @@ Archive_file::interpret_header(const Archive_header* hdr, off_t off,
       if (static_cast<size_t>(name_end - name) > this->extended_names_.size()
          || name_end[-1] != '/')
        {
-         error_at(this->location_, "%s: bad extended name entry at header %lu",
-                  this->filename_.c_str(), static_cast<unsigned long>(off));
+         go_error_at(this->location_,
+                     "%s: bad extended name entry at header %lu",
+                     this->filename_.c_str(), static_cast<unsigned long>(off));
          return false;
        }
       pname->assign(name, name_end - 1 - name);
@@ -380,8 +383,8 @@ Archive_file::get_file_and_offset(off_t off, const std::string& hdrname,
          int nfd = open(filename.c_str(), O_RDONLY | O_BINARY);
          if (nfd < 0)
            {
-             error_at(this->location_, "%s: can't open nested archive %s",
-                      this->filename_.c_str(), filename.c_str());
+             go_error_at(this->location_, "%s: can't open nested archive %s",
+                         this->filename_.c_str(), filename.c_str());
              return false;
            }
          nfile = new Archive_file(filename, nfd, this->location_);
@@ -406,7 +409,7 @@ Archive_file::get_file_and_offset(off_t off, const std::string& hdrname,
   *memfd = open(filename.c_str(), O_RDONLY | O_BINARY);
   if (*memfd < 0)
     {
-      error_at(this->location_, "%s: %m", filename.c_str());
+      go_error_at(this->location_, "%s: %m", filename.c_str());
       return false;
     }
   *memoff = 0;
@@ -499,10 +502,10 @@ Archive_iterator::read_next_header()
        {
          if (filesize != this->off_)
            {
-             error_at(this->afile_->location(),
-                      "%s: short archive header at %lu",
-                      this->afile_->filename().c_str(),
-                      static_cast<unsigned long>(this->off_));
+             go_error_at(this->afile_->location(),
+                         "%s: short archive header at %lu",
+                         this->afile_->filename().c_str(),
+                         static_cast<unsigned long>(this->off_));
              this->off_ = filesize;
            }
          this->header_.off = filesize;
index d150020a4a36f0f6333de66421ca4070f9dc430e..2694cea4797309e2b29e508b3e8182b2e3d3bccf 100644 (file)
@@ -9,6 +9,7 @@
 #include "filenames.h"
 
 #include "go-c.h"
+#include "go-diagnostics.h"
 #include "gogo.h"
 #include "lex.h"
 #include "types.h"
@@ -132,7 +133,7 @@ Import::try_package_in_directory(const std::string& filename,
   if (fd < 0)
     {
       if (errno != ENOENT && errno != EISDIR)
-       warning_at(location, 0, "%s: %m", filename.c_str());
+       go_warning_at(location, 0, "%s: %m", filename.c_str());
 
       fd = Import::try_suffixes(&found_filename);
       if (fd < 0)
@@ -146,8 +147,8 @@ Import::try_package_in_directory(const std::string& filename,
 
   close(fd);
 
-  error_at(location, "%s exists but does not contain any Go export data",
-          found_filename.c_str());
+  go_error_at(location, "%s exists but does not contain any Go export data",
+             found_filename.c_str());
 
   return NULL;
 }
@@ -211,7 +212,7 @@ Import::find_export_data(const std::string& filename, int fd, Location location)
 
   if (lseek(fd, 0, SEEK_SET) < 0)
     {
-      error_at(location, "lseek %s failed: %m", filename.c_str());
+      go_error_at(location, "lseek %s failed: %m", filename.c_str());
       return NULL;
     }
 
@@ -247,10 +248,10 @@ Import::find_object_export_data(const std::string& filename,
   if (errmsg != NULL)
     {
       if (err == 0)
-       error_at(location, "%s: %s", filename.c_str(), errmsg);
+       go_error_at(location, "%s: %s", filename.c_str(), errmsg);
       else
-       error_at(location, "%s: %s: %s", filename.c_str(), errmsg,
-                xstrerror(err));
+       go_error_at(location, "%s: %s: %s", filename.c_str(), errmsg,
+                   xstrerror(err));
       return NULL;
     }
 
@@ -307,9 +308,9 @@ Import::import(Gogo* gogo, const std::string& local_name,
        }
       else
        {
-         error_at(this->location_,
-                  ("error in import data at %d: invalid magic string"),
-                  stream->pos());
+         go_error_at(this->location_,
+                     ("error in import data at %d: invalid magic string"),
+                     stream->pos());
          return NULL;
        }
 
@@ -382,11 +383,11 @@ Import::import(Gogo* gogo, const std::string& local_name,
            break;
          else
            {
-             error_at(this->location_,
-                      ("error in import data at %d: "
-                       "expected %<const%>, %<type%>, %<var%>, "
-                       "%<func%>, or %<checksum%>"),
-                      stream->pos());
+             go_error_at(this->location_,
+                         ("error in import data at %d: "
+                          "expected %<const%>, %<type%>, %<var%>, "
+                          "%<func%>, or %<checksum%>"),
+                         stream->pos());
              stream->set_saw_error();
              return NULL;
            }
@@ -664,9 +665,9 @@ Import::read_type()
          : (static_cast<size_t>(index) >= this->types_.size()
             || this->types_[index] == NULL))
        {
-         error_at(this->location_,
-                  "error in import data at %d: bad type index %d",
-                  stream->pos(), index);
+         go_error_at(this->location_,
+                     "error in import data at %d: bad type index %d",
+                     stream->pos(), index);
          stream->set_saw_error();
          return Type::make_error_type();
        }
@@ -677,9 +678,9 @@ Import::read_type()
   if (c != ' ')
     {
       if (!stream->saw_error())
-       error_at(this->location_,
-                "error in import data at %d: expect %< %> or %<>%>'",
-                stream->pos());
+       go_error_at(this->location_,
+                   "error in import data at %d: expect %< %> or %<>%>'",
+                   stream->pos());
       stream->set_saw_error();
       stream->advance(1);
       return Type::make_error_type();
@@ -689,9 +690,9 @@ Import::read_type()
       || (static_cast<size_t>(index) < this->types_.size()
          && this->types_[index] != NULL))
     {
-      error_at(this->location_,
-              "error in import data at %d: type index already defined",
-              stream->pos());
+      go_error_at(this->location_,
+                 "error in import data at %d: type index already defined",
+                 stream->pos());
       stream->set_saw_error();
       return Type::make_error_type();
     }
@@ -768,8 +769,8 @@ Import::read_type()
     no = package->add_type_declaration(type_name, this->location_);
   else if (!no->is_type_declaration() && !no->is_type())
     {
-      error_at(this->location_, "imported %<%s.%s%> both type and non-type",
-              pkgpath.c_str(), Gogo::message_name(type_name).c_str());
+      go_error_at(this->location_, "imported %<%s.%s%> both type and non-type",
+                 pkgpath.c_str(), Gogo::message_name(type_name).c_str());
       stream->set_saw_error();
       return Type::make_error_type();
     }
@@ -866,9 +867,10 @@ Import::read_escape()
 
       if (c != '>')
        {
-         error_at(this->location(),
-                  "error in import data at %d: expect %< %> or %<>%>, got %c",
-                  stream->pos(), c);
+         go_error_at(this->location(),
+                     ("error in import data at %d: "
+                      "expect %< %> or %<>%>, got %c"),
+                     stream->pos(), c);
          stream->set_saw_error();
          stream->advance(1);
          escape = Escape_note::make_tag(Node::ESCAPE_UNKNOWN);
@@ -961,8 +963,8 @@ Import::string_to_int(const std::string &s, bool is_neg_ok, int* ret)
   long prio = strtol(s.c_str(), &end, 10);
   if (*end != '\0' || prio > 0x7fffffff || (prio < 0 && !is_neg_ok))
     {
-      error_at(this->location_, "invalid integer in import data at %d",
-              this->stream_->pos());
+      go_error_at(this->location_, "invalid integer in import data at %d",
+                 this->stream_->pos());
       this->stream_->set_saw_error();
       return false;
     }
@@ -1018,8 +1020,8 @@ Import::Stream::require_bytes(Location location, const char* bytes,
       || memcmp(bytes, read, length) != 0)
     {
       if (!this->saw_error_)
-       error_at(location, "import error at %d: expected %<%.*s%>",
-                this->pos(), static_cast<int>(length), bytes);
+       go_error_at(location, "import error at %d: expected %<%.*s%>",
+                   this->pos(), static_cast<int>(length), bytes);
       this->saw_error_ = true;
       return;
     }
@@ -1033,7 +1035,7 @@ Stream_from_file::Stream_from_file(int fd)
 {
   if (lseek(fd, 0, SEEK_SET) != 0)
     {
-      error("lseek failed: %m");
+      go_fatal_error(Linemap::unknown_location(), "lseek failed: %m");
       this->set_saw_error();
     }
 }
@@ -1061,7 +1063,7 @@ Stream_from_file::do_peek(size_t length, const char** bytes)
   if (got < 0)
     {
       if (!this->saw_error())
-       error("read failed: %m");
+       go_fatal_error(Linemap::unknown_location(), "read failed: %m");
       this->set_saw_error();
       return false;
     }
@@ -1069,7 +1071,7 @@ Stream_from_file::do_peek(size_t length, const char** bytes)
   if (lseek(this->fd_, - got, SEEK_CUR) != 0)
     {
       if (!this->saw_error())
-       error("lseek failed: %m");
+       go_fatal_error(Linemap::unknown_location(), "lseek failed: %m");
       this->set_saw_error();
       return false;
     }
@@ -1091,7 +1093,7 @@ Stream_from_file::do_advance(size_t skip)
   if (lseek(this->fd_, skip, SEEK_CUR) != 0)
     {
       if (!this->saw_error())
-       error("lseek failed: %m");
+       go_fatal_error(Linemap::unknown_location(), "lseek failed: %m");
       this->set_saw_error();
     }
   if (!this->data_.empty())
index 05705f581c91c903c55565ff196c1d319deab731..b040edde2be68f6d428495935df7f8ae4e9fff5b 100644 (file)
@@ -5,6 +5,7 @@
 // license that can be found in the LICENSE file.
 
 #include "go-system.h"
+#include "go-diagnostics.h"
 
 #include "lex.h"
 
@@ -477,7 +478,7 @@ Lex::get_line()
        {
          size_t ns = 2 * size + 1;
          if (ns < size || static_cast<ssize_t>(ns) < 0)
-           error_at(this->location(), "out of memory");
+           go_error_at(this->location(), "out of memory");
          char* nb = new char[ns];
          memcpy(nb, buf, cur);
          delete[] buf;
@@ -743,9 +744,9 @@ Lex::next_token()
                  return this->gather_identifier();
 
                if (!issued_error)
-                 error_at(this->location(),
-                          "invalid character 0x%x in input file",
-                          ci);
+                 go_error_at(this->location(),
+                             "invalid character 0x%x in input file",
+                             ci);
 
                p = pend;
 
@@ -834,7 +835,7 @@ Lex::advance_one_utf8_char(const char* p, unsigned int* value,
 
   if (*p == '\0')
     {
-      error_at(this->location(), "invalid NUL byte");
+      go_error_at(this->location(), "invalid NUL byte");
       *issued_error = true;
       *value = 0;
       return p + 1;
@@ -843,7 +844,7 @@ Lex::advance_one_utf8_char(const char* p, unsigned int* value,
   int adv = Lex::fetch_char(p, value);
   if (adv == 0)
     {
-      error_at(this->location(), "invalid UTF-8 encoding");
+      go_error_at(this->location(), "invalid UTF-8 encoding");
       *issued_error = true;
       return p + 1;
     }
@@ -851,7 +852,7 @@ Lex::advance_one_utf8_char(const char* p, unsigned int* value,
   // Warn about byte order mark, except at start of file.
   if (*value == 0xfeff && (this->lineno_ != 1 || this->lineoff_ != 0))
     {
-      error_at(this->location(), "Unicode (UTF-8) BOM in middle of file");
+      go_error_at(this->location(), "Unicode (UTF-8) BOM in middle of file");
       *issued_error = true;
     }
 
@@ -890,9 +891,9 @@ Lex::gather_identifier()
                break;
 
              this->lineoff_ = p - this->linebuf_;
-             error_at(this->location(),
-                      "invalid character 0x%x in identifier",
-                      cc);
+             go_error_at(this->location(),
+                         "invalid character 0x%x in identifier",
+                         cc);
              if (!has_non_ascii_char)
                {
                  buf.assign(pstart, p - pstart);
@@ -925,9 +926,9 @@ Lex::gather_identifier()
              // handling behavior if we swallow this character after
              // giving an error.
              if (!issued_error)
-               error_at(this->location(),
-                        "invalid character 0x%x in identifier",
-                        ci);
+               go_error_at(this->location(),
+                           "invalid character 0x%x in identifier",
+                           ci);
              is_invalid = true;
            }
          if (is_first)
@@ -1109,9 +1110,9 @@ Lex::gather_number()
           if (r != 0)
             {
               if (base == 8)
-                error_at(this->location(), "invalid octal literal");
+                go_error_at(this->location(), "invalid octal literal");
               else
-                error_at(this->location(), "invalid hex literal");
+                go_error_at(this->location(), "invalid hex literal");
             }
 
          if (neg)
@@ -1225,7 +1226,7 @@ Lex::advance_one_char(const char* p, bool is_single_quote, unsigned int* value,
       if (is_single_quote
          && (*value == '\'' || *value == '\n')
          && !issued_error)
-       error_at(this->location(), "invalid character literal");
+       go_error_at(this->location(), "invalid character literal");
       return ret;
     }
   else
@@ -1244,12 +1245,12 @@ Lex::advance_one_char(const char* p, bool is_single_quote, unsigned int* value,
                        + Lex::octal_value(p[2]));
              if (*value > 255)
                {
-                 error_at(this->location(), "invalid octal constant");
+                 go_error_at(this->location(), "invalid octal constant");
                  *value = 255;
                }
              return p + 3;
            }
-             error_at(this->location(), "invalid octal character");
+             go_error_at(this->location(), "invalid octal character");
          return (p[1] >= '0' && p[1] <= '7'
                  ? p + 2
                  : p + 1);
@@ -1261,7 +1262,7 @@ Lex::advance_one_char(const char* p, bool is_single_quote, unsigned int* value,
              *value = (Lex::hex_val(p[1]) << 4) + Lex::hex_val(p[2]);
              return p + 3;
            }
-         error_at(this->location(), "invalid hex character");
+         go_error_at(this->location(), "invalid hex character");
          return (Lex::is_hex_digit(p[1])
                  ? p + 2
                  : p + 1);
@@ -1292,12 +1293,12 @@ Lex::advance_one_char(const char* p, bool is_single_quote, unsigned int* value,
          return p + 1;
        case '\'':
          if (!is_single_quote)
-           error_at(this->location(), "invalid quoted character");
+           go_error_at(this->location(), "invalid quoted character");
          *value = '\'';
          return p + 1;
        case '"':
          if (is_single_quote)
-           error_at(this->location(), "invalid quoted character");
+           go_error_at(this->location(), "invalid quoted character");
          *value = '"';
          return p + 1;
 
@@ -1311,15 +1312,15 @@ Lex::advance_one_char(const char* p, bool is_single_quote, unsigned int* value,
                        + Lex::hex_val(p[4]));
              if (*value >= 0xd800 && *value < 0xe000)
                {
-                 error_at(this->location(),
-                          "invalid unicode code point 0x%x",
-                          *value);
+                 go_error_at(this->location(),
+                             "invalid unicode code point 0x%x",
+                             *value);
                  // Use the replacement character.
                  *value = 0xfffd;
                }
              return p + 5;
            }
-         error_at(this->location(), "invalid little unicode code point");
+         go_error_at(this->location(), "invalid little unicode code point");
          return p + 1;
 
        case 'U':
@@ -1339,18 +1340,19 @@ Lex::advance_one_char(const char* p, bool is_single_quote, unsigned int* value,
              if (*value > 0x10ffff
                  || (*value >= 0xd800 && *value < 0xe000))
                {
-                 error_at(this->location(), "invalid unicode code point 0x%x",
-                          *value);
+                 go_error_at(this->location(),
+                             "invalid unicode code point 0x%x",
+                             *value);
                  // Use the replacement character.
                  *value = 0xfffd;
                }
              return p + 9;
            }
-         error_at(this->location(), "invalid big unicode code point");
+         go_error_at(this->location(), "invalid big unicode code point");
          return p + 1;
 
        default:
-         error_at(this->location(), "invalid character after %<\\%>");
+         go_error_at(this->location(), "invalid character after %<\\%>");
          *value = *p;
          return p + 1;
        }
@@ -1382,15 +1384,15 @@ Lex::append_char(unsigned int v, bool is_character, std::string* str,
     {
       if (v > 0x10ffff)
        {
-         warning_at(location, 0,
-                    "unicode code point 0x%x out of range in string", v);
+         go_warning_at(location, 0,
+                       "unicode code point 0x%x out of range in string", v);
          // Turn it into the "replacement character".
          v = 0xfffd;
        }
       if (v >= 0xd800 && v < 0xe000)
        {
-         warning_at(location, 0,
-                    "unicode code point 0x%x is invalid surrogate pair", v);
+         go_warning_at(location, 0,
+                       "unicode code point 0x%x is invalid surrogate pair", v);
          v = 0xfffd;
        }
       if (v <= 0xffff)
@@ -1427,7 +1429,7 @@ Lex::gather_character()
 
   if (*p != '\'')
     {
-      error_at(this->location(), "unterminated character constant");
+      go_error_at(this->location(), "unterminated character constant");
       this->lineoff_ = p - this->linebuf_;
       return this->make_invalid_token();
     }
@@ -1461,7 +1463,7 @@ Lex::gather_string()
       p = this->advance_one_char(p, false, &c, &is_character);
       if (p >= pend)
        {
-         error_at(this->location(), "unterminated string");
+         go_error_at(this->location(), "unterminated string");
          --p;
          break;
        }
@@ -1505,7 +1507,7 @@ Lex::gather_raw_string()
       this->lineoff_ = p - this->linebuf_;
       if (!this->require_line())
        {
-         error_at(location, "unterminated raw string");
+         go_error_at(location, "unterminated raw string");
          return Token::make_string_token(value, location);
        }
       p = this->linebuf_ + this->lineoff_;
@@ -1685,7 +1687,7 @@ Lex::skip_c_comment(bool* found_newline)
     {
       if (!this->require_line())
        {
-         error_at(this->location(), "unterminated comment");
+         go_error_at(this->location(), "unterminated comment");
          return false;
        }
 
@@ -1861,7 +1863,7 @@ Lex::skip_cpp_comment()
            }
        }
       if (go_name.empty() || ext_name.empty())
-       error_at(loc, "usage: //go:linkname localname linkname");
+       go_error_at(loc, "usage: //go:linkname localname linkname");
       else
        {
          if (this->linknames_ == NULL)
index 6b45ebf4fd07b32e178a074936b4eb9dfa3a6d65..81525a741d7c4bc0b1f4df6a46ff3b23a7f825ce 100644 (file)
@@ -8,6 +8,7 @@
 
 #include "lex.h"
 #include "gogo.h"
+#include "go-diagnostics.h"
 #include "types.h"
 #include "statements.h"
 #include "expressions.h"
@@ -109,7 +110,7 @@ Parse::identifier_list(Typed_identifier_list* til)
     {
       if (!token->is_identifier())
        {
-         error_at(this->location(), "expected identifier");
+         go_error_at(this->location(), "expected identifier");
          return;
        }
       std::string name =
@@ -172,7 +173,7 @@ Parse::qualified_ident(std::string* pname, Named_object** ppackage)
   const Token* token = this->peek_token();
   if (!token->is_identifier())
     {
-      error_at(this->location(), "expected identifier");
+      go_error_at(this->location(), "expected identifier");
       return false;
     }
 
@@ -191,7 +192,7 @@ Parse::qualified_ident(std::string* pname, Named_object** ppackage)
   Named_object* package = this->gogo_->lookup(name, NULL);
   if (package == NULL || !package->is_package())
     {
-      error_at(this->location(), "expected package");
+      go_error_at(this->location(), "expected package");
       // We expect . IDENTIFIER; skip both.
       if (this->advance_token()->is_identifier())
        this->advance_token();
@@ -203,7 +204,7 @@ Parse::qualified_ident(std::string* pname, Named_object** ppackage)
   token = this->advance_token();
   if (!token->is_identifier())
     {
-      error_at(this->location(), "expected identifier");
+      go_error_at(this->location(), "expected identifier");
       return false;
     }
 
@@ -211,7 +212,7 @@ Parse::qualified_ident(std::string* pname, Named_object** ppackage)
 
   if (name == "_")
     {
-      error_at(this->location(), "invalid use of %<_%>");
+      go_error_at(this->location(), "invalid use of %<_%>");
       name = Gogo::erroneous_name();
     }
 
@@ -269,13 +270,13 @@ Parse::type()
       else
        {
          if (!ret->is_error_type())
-           error_at(this->location(), "expected %<)%>");
+           go_error_at(this->location(), "expected %<)%>");
        }
       return ret;
     }
   else
     {
-      error_at(token->location(), "expected type");
+      go_error_at(token->location(), "expected type");
       return Type::make_error_type();
     }
 }
@@ -329,9 +330,10 @@ Parse::type_name(bool issue_error)
            {
              Package* p = package->package_value();
              const std::string& packname(p->package_name());
-             error_at(location, "invalid reference to hidden type %<%s.%s%>",
-                      Gogo::message_name(packname).c_str(),
-                      Gogo::message_name(name).c_str());
+             go_error_at(location,
+                         "invalid reference to hidden type %<%s.%s%>",
+                         Gogo::message_name(packname).c_str(),
+                         Gogo::message_name(name).c_str());
              issue_error = false;
            }
        }
@@ -345,9 +347,9 @@ Parse::type_name(bool issue_error)
       else
        {
          const std::string& packname(package->package_value()->package_name());
-         error_at(location, "reference to undefined identifier %<%s.%s%>",
-                  Gogo::message_name(packname).c_str(),
-                  Gogo::message_name(name).c_str());
+         go_error_at(location, "reference to undefined identifier %<%s.%s%>",
+                     Gogo::message_name(packname).c_str(),
+                     Gogo::message_name(name).c_str());
          issue_error = false;
          ok = false;
        }
@@ -365,7 +367,7 @@ Parse::type_name(bool issue_error)
   if (!ok)
     {
       if (issue_error)
-       error_at(location, "expected type");
+       go_error_at(location, "expected type");
       return Type::make_error_type();
     }
 
@@ -405,14 +407,14 @@ Parse::array_type(bool may_use_ellipsis)
        }
       else
        {
-         error_at(this->location(),
-                  "use of %<[...]%> outside of array literal");
+         go_error_at(this->location(),
+                     "use of %<[...]%> outside of array literal");
          length = Expression::make_error(this->location());
          this->advance_token();
        }
       if (!this->peek_token()->is_op(OPERATOR_RSQUARE))
        {
-         error_at(this->location(), "expected %<]%>");
+         go_error_at(this->location(), "expected %<]%>");
          return Type::make_error_type();
        }
       this->advance_token();
@@ -436,7 +438,7 @@ Parse::map_type()
   go_assert(this->peek_token()->is_keyword(KEYWORD_MAP));
   if (!this->advance_token()->is_op(OPERATOR_LSQUARE))
     {
-      error_at(this->location(), "expected %<[%>");
+      go_error_at(this->location(), "expected %<[%>");
       return Type::make_error_type();
     }
   this->advance_token();
@@ -445,7 +447,7 @@ Parse::map_type()
 
   if (!this->peek_token()->is_op(OPERATOR_RSQUARE))
     {
-      error_at(this->location(), "expected %<]%>");
+      go_error_at(this->location(), "expected %<]%>");
       return Type::make_error_type();
     }
   this->advance_token();
@@ -470,10 +472,10 @@ Parse::struct_type()
       Location token_loc = this->location();
       if (this->peek_token()->is_op(OPERATOR_SEMICOLON)
          && this->advance_token()->is_op(OPERATOR_LCURLY))
-       error_at(token_loc, "unexpected semicolon or newline before %<{%>");
+       go_error_at(token_loc, "unexpected semicolon or newline before %<{%>");
       else
        {
-         error_at(this->location(), "expected %<{%>");
+         go_error_at(this->location(), "expected %<{%>");
          return Type::make_error_type();
        }
     }
@@ -487,7 +489,7 @@ Parse::struct_type()
        this->advance_token();
       else if (!this->peek_token()->is_op(OPERATOR_RCURLY))
        {
-         error_at(this->location(), "expected %<;%> or %<}%> or newline");
+         go_error_at(this->location(), "expected %<;%> or %<}%> or newline");
          if (!this->skip_past_error(OPERATOR_RCURLY))
            return Type::make_error_type();
        }
@@ -506,8 +508,8 @@ Parse::struct_type()
        {
          if (pi->field_name() == pj->field_name()
              && !Gogo::is_sink_name(pi->field_name()))
-           error_at(pi->location(), "duplicate field name %<%s%>",
-                    Gogo::message_name(pi->field_name()).c_str());
+           go_error_at(pi->location(), "duplicate field name %<%s%>",
+                       Gogo::message_name(pi->field_name()).c_str());
        }
     }
 
@@ -545,7 +547,7 @@ Parse::field_decl(Struct_field_list* sfl)
     }
   else
     {
-      error_at(this->location(), "expected field name");
+      go_error_at(this->location(), "expected field name");
       this->gogo_->mark_locals_used();
       while (!token->is_op(OPERATOR_SEMICOLON)
             && !token->is_op(OPERATOR_RCURLY)
@@ -561,7 +563,7 @@ Parse::field_decl(Struct_field_list* sfl)
          this->advance_token();
          if (!this->peek_token()->is_identifier())
            {
-             error_at(this->location(), "expected field name");
+             go_error_at(this->location(), "expected field name");
              this->gogo_->mark_locals_used();
              while (!token->is_op(OPERATOR_SEMICOLON)
                     && !token->is_op(OPERATOR_RCURLY)
@@ -596,7 +598,7 @@ Parse::field_decl(Struct_field_list* sfl)
          token = this->peek_token();
          if (!token->is_identifier())
            {
-             error_at(this->location(), "expected identifier");
+             go_error_at(this->location(), "expected identifier");
              return;
            }
          std::string name =
@@ -657,7 +659,7 @@ Parse::channel_type()
     {
       if (!this->advance_token()->is_keyword(KEYWORD_CHAN))
        {
-         error_at(this->location(), "expected %<chan%>");
+         go_error_at(this->location(), "expected %<chan%>");
          return Type::make_error_type();
        }
       send = false;
@@ -679,13 +681,13 @@ Parse::channel_type()
     {
       token = this->peek_token();
       if (token->is_op(OPERATOR_RCURLY))
-       error_at(this->location(), "unexpected %<}%> in channel type");
+       go_error_at(this->location(), "unexpected %<}%> in channel type");
       else if (token->is_op(OPERATOR_RPAREN))
-       error_at(this->location(), "unexpected %<)%> in channel type");
+       go_error_at(this->location(), "unexpected %<)%> in channel type");
       else if (token->is_op(OPERATOR_COMMA))
-       error_at(this->location(), "unexpected comma in channel type");
+       go_error_at(this->location(), "unexpected comma in channel type");
       else
-       error_at(this->location(), "expected channel element type");
+       go_error_at(this->location(), "expected channel element type");
       return Type::make_error_type();
     }
 
@@ -710,11 +712,11 @@ Parse::check_signature_names(const Typed_identifier_list* params,
       std::pair<Parse::Names::iterator, bool> ins = names->insert(val);
       if (!ins.second)
        {
-         error_at(p->location(), "redefinition of %qs",
-                  Gogo::message_name(p->name()).c_str());
-         inform(ins.first->second->location(),
-                "previous definition of %qs was here",
-                Gogo::message_name(p->name()).c_str());
+         go_error_at(p->location(), "redefinition of %qs",
+                     Gogo::message_name(p->name()).c_str());
+         go_inform(ins.first->second->location(),
+                   "previous definition of %qs was here",
+                   Gogo::message_name(p->name()).c_str());
        }
     }
 }
@@ -770,7 +772,7 @@ Parse::parameters(Typed_identifier_list** pparams, bool* is_varargs)
 
   if (!this->peek_token()->is_op(OPERATOR_LPAREN))
     {
-      error_at(this->location(), "expected %<(%>");
+      go_error_at(this->location(), "expected %<(%>");
       return false;
     }
 
@@ -790,7 +792,7 @@ Parse::parameters(Typed_identifier_list** pparams, bool* is_varargs)
 
   if (!token->is_op(OPERATOR_RPAREN))
     {
-      error_at(this->location(), "expected %<)%>");
+      go_error_at(this->location(), "expected %<)%>");
       return false;
     }
   this->advance_token();
@@ -929,7 +931,8 @@ Parse::parameter_list(bool* is_varargs)
                type = this->type();
              else
                {
-                 error_at(this->location(), "%<...%> only permits one name");
+                 go_error_at(this->location(),
+                             "%<...%> only permits one name");
                  saw_error = true;
                  this->advance_token();
                  type = this->type();
@@ -960,8 +963,8 @@ Parse::parameter_list(bool* is_varargs)
                    type = Type::make_forward_declaration(no);
                  else
                    {
-                     error_at(p->location(), "expected %<%s%> to be a type",
-                              Gogo::message_name(p->name()).c_str());
+                     go_error_at(p->location(), "expected %<%s%> to be a type",
+                                 Gogo::message_name(p->name()).c_str());
                      saw_error = true;
                      type = Type::make_error_type();
                    }
@@ -985,7 +988,7 @@ Parse::parameter_list(bool* is_varargs)
        break;
       if (is_varargs != NULL && *is_varargs)
        {
-         error_at(this->location(), "%<...%> must be last parameter");
+         go_error_at(this->location(), "%<...%> must be last parameter");
          saw_error = true;
        }
       this->parameter_decl(parameters_have_names, ret, is_varargs, &mix_error,
@@ -993,7 +996,7 @@ Parse::parameter_list(bool* is_varargs)
     }
   if (mix_error)
     {
-      error_at(location, "invalid named/anonymous mix");
+      go_error_at(location, "invalid named/anonymous mix");
       saw_error = true;
     }
   if (saw_error)
@@ -1024,7 +1027,7 @@ Parse::parameter_decl(bool parameters_have_names,
          else
            {
              if (is_varargs == NULL)
-               error_at(this->location(), "invalid use of %<...%>");
+               go_error_at(this->location(), "invalid use of %<...%>");
              else
                *is_varargs = true;
              this->advance_token();
@@ -1073,12 +1076,12 @@ Parse::parameter_decl(bool parameters_have_names,
        {
          if (is_varargs == NULL)
            {
-             error_at(this->location(), "invalid use of %<...%>");
+             go_error_at(this->location(), "invalid use of %<...%>");
              *saw_error = true;
            }
          else if (new_count > orig_count + 1)
            {
-             error_at(this->location(), "%<...%> only permits one name");
+             go_error_at(this->location(), "%<...%> only permits one name");
              *saw_error = true;
            }
          else
@@ -1129,10 +1132,10 @@ Parse::block()
       Location loc = this->location();
       if (this->peek_token()->is_op(OPERATOR_SEMICOLON)
          && this->advance_token()->is_op(OPERATOR_LCURLY))
-       error_at(loc, "unexpected semicolon or newline before %<{%>");
+       go_error_at(loc, "unexpected semicolon or newline before %<{%>");
       else
        {
-         error_at(this->location(), "expected %<{%>");
+         go_error_at(this->location(), "expected %<{%>");
          return Linemap::unknown_location();
        }
     }
@@ -1146,7 +1149,7 @@ Parse::block()
       if (!token->is_op(OPERATOR_RCURLY))
        {
          if (!token->is_eof() || !saw_errors())
-           error_at(this->location(), "expected %<}%>");
+           go_error_at(this->location(), "expected %<}%>");
 
          this->gogo_->mark_locals_used();
 
@@ -1193,10 +1196,10 @@ Parse::interface_type(bool record)
       Location token_loc = this->location();
       if (this->peek_token()->is_op(OPERATOR_SEMICOLON)
          && this->advance_token()->is_op(OPERATOR_LCURLY))
-       error_at(token_loc, "unexpected semicolon or newline before %<{%>");
+       go_error_at(token_loc, "unexpected semicolon or newline before %<{%>");
       else
        {
-         error_at(this->location(), "expected %<{%>");
+         go_error_at(this->location(), "expected %<{%>");
          return Type::make_error_type();
        }
     }
@@ -1214,7 +1217,7 @@ Parse::interface_type(bool record)
        }
       if (!this->peek_token()->is_op(OPERATOR_RCURLY))
        {
-         error_at(this->location(), "expected %<}%>");
+         go_error_at(this->location(), "expected %<}%>");
          while (!this->advance_token()->is_op(OPERATOR_RCURLY))
            {
              if (this->peek_token()->is_eof())
@@ -1250,7 +1253,7 @@ Parse::method_spec(Typed_identifier_list* methods)
   const Token* token = this->peek_token();
   if (!token->is_identifier())
     {
-      error_at(this->location(), "expected identifier");
+      go_error_at(this->location(), "expected identifier");
       return;
     }
 
@@ -1262,7 +1265,8 @@ Parse::method_spec(Typed_identifier_list* methods)
     {
       // This is a MethodName.
       if (name == "_")
-       error_at(this->location(), "methods must have a unique non-blank name");
+       go_error_at(this->location(),
+                    "methods must have a unique non-blank name");
       name = this->gogo_->pack_hidden_name(name, is_exported);
       Type* type = this->signature(NULL, location);
       if (type == NULL)
@@ -1279,10 +1283,10 @@ Parse::method_spec(Typed_identifier_list* methods)
              && !this->peek_token()->is_op(OPERATOR_RCURLY)))
        {
          if (this->peek_token()->is_op(OPERATOR_COMMA))
-           error_at(this->location(),
-                    "name list not allowed in interface type");
+           go_error_at(this->location(),
+                       "name list not allowed in interface type");
          else
-           error_at(location, "expected signature or type name");
+           go_error_at(location, "expected signature or type name");
          this->gogo_->mark_locals_used();
          token = this->peek_token();
          while (!token->is_eof()
@@ -1307,8 +1311,8 @@ Parse::declaration()
 
   unsigned int pragmas = this->lex_->get_and_clear_pragmas();
   if (pragmas != 0 && !token->is_keyword(KEYWORD_FUNC))
-    warning_at(token->location(), 0,
-              "ignoring magic comment before non-function");
+    go_warning_at(token->location(), 0,
+                 "ignoring magic comment before non-function");
 
   if (token->is_keyword(KEYWORD_CONST))
     this->const_decl();
@@ -1320,7 +1324,7 @@ Parse::declaration()
     this->function_decl(pragmas);
   else
     {
-      error_at(this->location(), "expected declaration");
+      go_error_at(this->location(), "expected declaration");
       this->advance_token();
     }
 }
@@ -1343,7 +1347,7 @@ Parse::decl(void (Parse::*pfn)(void*), void* varg)
   if (this->peek_token()->is_eof())
     {
       if (!saw_errors())
-       error_at(this->location(), "unexpected end of file");
+       go_error_at(this->location(), "unexpected end of file");
       return;
     }
 
@@ -1356,7 +1360,7 @@ Parse::decl(void (Parse::*pfn)(void*), void* varg)
          this->list(pfn, varg, true);
          if (!this->peek_token()->is_op(OPERATOR_RPAREN))
            {
-             error_at(this->location(), "missing %<)%>");
+             go_error_at(this->location(), "missing %<)%>");
              while (!this->advance_token()->is_op(OPERATOR_RPAREN))
                {
                  if (this->peek_token()->is_eof())
@@ -1382,7 +1386,7 @@ Parse::list(void (Parse::*pfn)(void*), void* varg, bool follow_is_paren)
         || this->peek_token()->is_op(OPERATOR_COMMA))
     {
       if (this->peek_token()->is_op(OPERATOR_COMMA))
-       error_at(this->location(), "unexpected comma");
+       go_error_at(this->location(), "unexpected comma");
       if (this->advance_token()->is_op(follow))
        break;
       (this->*pfn)(varg);
@@ -1413,7 +1417,8 @@ Parse::const_decl()
            this->advance_token();
          else if (!this->peek_token()->is_op(OPERATOR_RPAREN))
            {
-             error_at(this->location(), "expected %<;%> or %<)%> or newline");
+             go_error_at(this->location(),
+                         "expected %<;%> or %<)%> or newline");
              if (!this->skip_past_error(OPERATOR_RPAREN))
                return;
            }
@@ -1446,7 +1451,7 @@ Parse::const_spec(Type** last_type, Expression_list** last_expr_list)
     {
       if (*last_expr_list == NULL)
        {
-         error_at(this->location(), "expected %<=%>");
+         go_error_at(this->location(), "expected %<=%>");
          return;
        }
       type = *last_type;
@@ -1473,7 +1478,7 @@ Parse::const_spec(Type** last_type, Expression_list** last_expr_list)
     {
       if (pe == expr_list->end())
        {
-         error_at(this->location(), "not enough initializers");
+         go_error_at(this->location(), "not enough initializers");
          return;
        }
       if (type != NULL)
@@ -1493,7 +1498,7 @@ Parse::const_spec(Type** last_type, Expression_list** last_expr_list)
        }
     }
   if (pe != expr_list->end())
-    error_at(this->location(), "too many initializers");
+    go_error_at(this->location(), "too many initializers");
 
   this->increment_iota();
 
@@ -1518,7 +1523,7 @@ Parse::type_spec(void*)
   const Token* token = this->peek_token();
   if (!token->is_identifier())
     {
-      error_at(this->location(), "expected identifier");
+      go_error_at(this->location(), "expected identifier");
       return;
     }
   std::string name = token->identifier();
@@ -1547,8 +1552,8 @@ Parse::type_spec(void*)
     type = this->type();
   else
     {
-      error_at(this->location(),
-              "unexpected semicolon or newline in type declaration");
+      go_error_at(this->location(),
+                 "unexpected semicolon or newline in type declaration");
       type = Type::make_error_type();
       this->advance_token();
     }
@@ -1570,7 +1575,7 @@ Parse::type_spec(void*)
              && (ftype->forward_declaration_type()->named_object()
                  == named_type))
            {
-             error_at(location, "invalid recursive type");
+             go_error_at(location, "invalid recursive type");
              type = Type::make_error_type();
            }
 
@@ -1669,7 +1674,7 @@ Parse::init_vars(const Typed_identifier_list* til, Type* type,
   if (init != NULL && init->size() != til->size())
     {
       if (init->empty() || !init->front()->is_error_expression())
-       error_at(location, "wrong number of initializations");
+       go_error_at(location, "wrong number of initializations");
       init = NULL;
       if (type == NULL)
        type = Type::make_error_type();
@@ -1701,7 +1706,7 @@ Parse::init_vars(const Typed_identifier_list* til, Type* type,
   if (init != NULL)
     go_assert(pexpr == init->end());
   if (is_coloneq && !any_new)
-    error_at(location, "variables redeclared but no variable is new");
+    go_error_at(location, "variables redeclared but no variable is new");
   this->finish_init_vars(vars, vals, location);
 }
 
@@ -1761,7 +1766,7 @@ Parse::init_vars_from_call(const Typed_identifier_list* vars, Type* type,
     }
 
   if (is_coloneq && !any_new)
-    error_at(location, "variables redeclared but no variable is new");
+    go_error_at(location, "variables redeclared but no variable is new");
 
   this->finish_init_vars(ivars, ivals, location);
 
@@ -1804,7 +1809,7 @@ Parse::init_vars_from_map(const Typed_identifier_list* vars, Type* type,
   Expression* present_var = Expression::make_var_reference(no, location);
 
   if (is_coloneq && !any_new)
-    error_at(location, "variables redeclared but no variable is new");
+    go_error_at(location, "variables redeclared but no variable is new");
 
   Statement* s = Statement::make_tuple_map_assignment(val_var, present_var,
                                                      index, location);
@@ -1869,7 +1874,7 @@ Parse::init_vars_from_receive(const Typed_identifier_list* vars, Type* type,
   Expression* received_var = Expression::make_var_reference(no, location);
 
   if (is_coloneq && !any_new)
-    error_at(location, "variables redeclared but no variable is new");
+    go_error_at(location, "variables redeclared but no variable is new");
 
   Statement* s = Statement::make_tuple_receive_assignment(val_var,
                                                          received_var,
@@ -1940,7 +1945,7 @@ Parse::init_vars_from_type_guard(const Typed_identifier_list* vars,
                                                             location);
 
   if (is_coloneq && !any_new)
-    error_at(location, "variables redeclared but no variable is new");
+    go_error_at(location, "variables redeclared but no variable is new");
 
   if (!this->gogo_->in_global_scope())
     this->gogo_->add_statement(s);
@@ -2133,8 +2138,8 @@ Parse::simple_var_decl_or_assignment(const std::string& name,
                  id = this->gogo_->pack_hidden_name(id, is_id_exported);
                  ins = uniq_idents.insert(id);
                  if (!ins.second && !Gogo::is_sink_name(id))
-                   error_at(id_location, "multiple assignments to %s",
-                            Gogo::message_name(id).c_str());
+                   go_error_at(id_location, "multiple assignments to %s",
+                               Gogo::message_name(id).c_str());
                  til.push_back(Typed_identifier(id, NULL, location));
                }
              else
@@ -2187,7 +2192,7 @@ Parse::simple_var_decl_or_assignment(const std::string& name,
   const Token* token = this->advance_token();
 
   if (!dup_name.empty())
-    error_at(dup_loc, "multiple assignments to %s", dup_name.c_str());
+    go_error_at(dup_loc, "multiple assignments to %s", dup_name.c_str());
 
   if (p_range_clause != NULL && token->is_keyword(KEYWORD_RANGE))
     {
@@ -2259,7 +2264,7 @@ Parse::function_decl(unsigned int pragmas)
 
   if (!token->is_identifier())
     {
-      error_at(this->location(), "expected function name");
+      go_error_at(this->location(), "expected function name");
       return;
     }
 
@@ -2277,19 +2282,19 @@ Parse::function_decl(unsigned int pragmas)
     {
       if (!this->advance_token()->is_op(OPERATOR_LPAREN))
        {
-         error_at(this->location(), "expected %<(%>");
+         go_error_at(this->location(), "expected %<(%>");
          return;
        }
       token = this->advance_token();
       if (!token->is_string())
        {
-         error_at(this->location(), "expected string");
+         go_error_at(this->location(), "expected string");
          return;
        }
       std::string asm_name = token->string_value();
       if (!this->advance_token()->is_op(OPERATOR_RPAREN))
        {
-         error_at(this->location(), "expected %<)%>");
+         go_error_at(this->location(), "expected %<)%>");
          return;
        }
       this->advance_token();
@@ -2306,8 +2311,8 @@ Parse::function_decl(unsigned int pragmas)
     {
       Location semi_loc = this->location();
       if (this->advance_token()->is_op(OPERATOR_LCURLY))
-       error_at(this->location(),
-                "unexpected semicolon or newline before %<{%>");
+       go_error_at(this->location(),
+                   "unexpected semicolon or newline before %<{%>");
       else
        this->unget_token(Token::make_operator_token(OPERATOR_SEMICOLON,
                                                     semi_loc));
@@ -2347,28 +2352,28 @@ Parse::function_decl(unsigned int pragmas)
            {
              if (pragma_check[i].decl_ok)
                continue;
-             warning_at(location, 0,
-                        ("ignoring magic //go:%s comment "
-                         "before declaration"),
-                        pragma_check[i].name);
+             go_warning_at(location, 0,
+                           ("ignoring magic //go:%s comment "
+                            "before declaration"),
+                           pragma_check[i].name);
            }
          else if (rec == NULL)
            {
              if (pragma_check[i].func_ok)
                continue;
-             warning_at(location, 0,
-                        ("ignoring magic //go:%s comment "
-                         "before function definition"),
-                        pragma_check[i].name);
+             go_warning_at(location, 0,
+                           ("ignoring magic //go:%s comment "
+                            "before function definition"),
+                           pragma_check[i].name);
            }
          else
            {
              if (pragma_check[i].method_ok)
                continue;
-             warning_at(location, 0,
-                        ("ignoring magic //go:%s comment "
-                         "before method definition"),
-                        pragma_check[i].name);
+             go_warning_at(location, 0,
+                           ("ignoring magic //go:%s comment "
+                            "before method definition"),
+                           pragma_check[i].name);
            }
 
          pragmas &= ~ pragma_check[i].bit;
@@ -2445,12 +2450,12 @@ Parse::receiver()
     return NULL;
   else if (til == NULL || til->empty())
     {
-      error_at(location, "method has no receiver");
+      go_error_at(location, "method has no receiver");
       return NULL;
     }
   else if (til->size() > 1)
     {
-      error_at(location, "method has multiple receivers");
+      go_error_at(location, "method has multiple receivers");
       return NULL;
     }
   else
@@ -2489,7 +2494,7 @@ Parse::operand(bool may_be_sink, bool* is_parenthesized)
            if (!this->advance_token()->is_op(OPERATOR_DOT)
                || !this->advance_token()->is_identifier())
              {
-               error_at(location, "unexpected reference to package");
+               go_error_at(location, "unexpected reference to package");
                return Expression::make_error(location);
              }
            package = named_object->package_value();
@@ -2509,9 +2514,9 @@ Parse::operand(bool may_be_sink, bool* is_parenthesized)
            && !named_object->type_value()->is_visible())
          {
            go_assert(package != NULL);
-           error_at(location, "invalid reference to hidden type %<%s.%s%>",
-                    Gogo::message_name(package->package_name()).c_str(),
-                    Gogo::message_name(id).c_str());
+           go_error_at(location, "invalid reference to hidden type %<%s.%s%>",
+                       Gogo::message_name(package->package_name()).c_str(),
+                       Gogo::message_name(id).c_str());
            return Expression::make_error(location);
          }
 
@@ -2523,14 +2528,14 @@ Parse::operand(bool may_be_sink, bool* is_parenthesized)
                std::string n1 = Gogo::message_name(package->package_name());
                std::string n2 = Gogo::message_name(id);
                if (!is_exported)
-                 error_at(location,
-                          ("invalid reference to unexported identifier "
-                           "%<%s.%s%>"),
-                          n1.c_str(), n2.c_str());
+                 go_error_at(location,
+                             ("invalid reference to unexported identifier "
+                              "%<%s.%s%>"),
+                             n1.c_str(), n2.c_str());
                else
-                 error_at(location,
-                          "reference to undefined identifier %<%s.%s%>",
-                          n1.c_str(), n2.c_str());
+                 go_error_at(location,
+                             "reference to undefined identifier %<%s.%s%>",
+                             n1.c_str(), n2.c_str());
                return Expression::make_error(location);
              }
 
@@ -2567,7 +2572,7 @@ Parse::operand(bool may_be_sink, bool* is_parenthesized)
              return Expression::make_sink(location);
            else
              {
-               error_at(location, "cannot use _ as value");
+               go_error_at(location, "cannot use _ as value");
                return Expression::make_error(location);
              }
          case Named_object::NAMED_OBJECT_FUNC:
@@ -2652,7 +2657,7 @@ Parse::operand(bool may_be_sink, bool* is_parenthesized)
          ret = this->expression(PRECEDENCE_NORMAL, may_be_sink, true, NULL,
                                 NULL);
          if (!this->peek_token()->is_op(OPERATOR_RPAREN))
-           error_at(this->location(), "missing %<)%>");
+           go_error_at(this->location(), "missing %<)%>");
          else
            this->advance_token();
          if (is_parenthesized != NULL)
@@ -2672,7 +2677,7 @@ Parse::operand(bool may_be_sink, bool* is_parenthesized)
       break;
     }
 
-  error_at(this->location(), "expected operand");
+  go_error_at(this->location(), "expected operand");
   return Expression::make_error(this->location());
 }
 
@@ -2877,10 +2882,11 @@ Parse::composite_lit(Type* type, int depth, Location location)
       else
        {
          if (token->is_op(OPERATOR_SEMICOLON))
-           error_at(this->location(),
-                    "need trailing comma before newline in composite literal");
+           go_error_at(this->location(),
+                       ("need trailing comma before newline "
+                        "in composite literal"));
          else
-           error_at(this->location(), "expected %<,%> or %<}%>");
+           go_error_at(this->location(), "expected %<,%> or %<}%>");
 
          this->gogo_->mark_locals_used();
          int depth = 0;
@@ -3073,13 +3079,13 @@ Parse::primary_expr(bool may_be_sink, bool may_be_composite_lit,
              Type* t = ret->type();
              if (t->named_type() != NULL
                  || t->forward_declaration_type() != NULL)
-               error_at(start_loc,
-                        _("parentheses required around this composite literal "
-                          "to avoid parsing ambiguity"));
+               go_error_at(start_loc,
+                           _("parentheses required around this composite "
+                             "literal to avoid parsing ambiguity"));
            }
          else if (operand_is_parenthesized)
-           error_at(start_loc,
-                    "cannot parenthesize type in composite literal");
+           go_error_at(start_loc,
+                       "cannot parenthesize type in composite literal");
          ret = this->composite_lit(ret->type(), 0, ret->location());
        }
       else if (this->peek_token()->is_op(OPERATOR_LPAREN))
@@ -3093,12 +3099,12 @@ Parse::primary_expr(bool may_be_sink, bool may_be_composite_lit,
            this->advance_token();
          if (this->peek_token()->is_op(OPERATOR_ELLIPSIS))
            {
-             error_at(this->location(),
-                      "invalid use of %<...%> in type conversion");
+             go_error_at(this->location(),
+                         "invalid use of %<...%> in type conversion");
              this->advance_token();
            }
          if (!this->peek_token()->is_op(OPERATOR_RPAREN))
-           error_at(this->location(), "expected %<)%>");
+           go_error_at(this->location(), "expected %<)%>");
          else
            this->advance_token();
          if (expr->is_error_expression())
@@ -3110,8 +3116,8 @@ Parse::primary_expr(bool may_be_sink, bool may_be_composite_lit,
                  && t->array_type()->length() != NULL
                  && t->array_type()->length()->is_nil_expression())
                {
-                 error_at(ret->location(),
-                          "use of %<[...]%> outside of array literal");
+                 go_error_at(ret->location(),
+                             "use of %<[...]%> outside of array literal");
                  ret = Expression::make_error(loc);
                }
              else
@@ -3177,7 +3183,7 @@ Parse::selector(Expression* left, bool* is_type_switch)
                                      token->is_identifier_exported());
       if (token->identifier() == "_")
        {
-         error_at(this->location(), "invalid use of %<_%>");
+         go_error_at(this->location(), "invalid use of %<_%>");
          name = Gogo::erroneous_name();
        }
       this->advance_token();
@@ -3195,14 +3201,14 @@ Parse::selector(Expression* left, bool* is_type_switch)
            *is_type_switch = true;
          else
            {
-             error_at(this->location(),
-                      "use of %<.(type)%> outside type switch");
+             go_error_at(this->location(),
+                         "use of %<.(type)%> outside type switch");
              type = Type::make_error_type();
            }
          this->advance_token();
        }
       if (!this->peek_token()->is_op(OPERATOR_RPAREN))
-       error_at(this->location(), "missing %<)%>");
+       go_error_at(this->location(), "missing %<)%>");
       else
        this->advance_token();
       if (is_type_switch != NULL && *is_type_switch)
@@ -3211,7 +3217,7 @@ Parse::selector(Expression* left, bool* is_type_switch)
     }
   else
     {
-      error_at(this->location(), "expected identifier or %<(%>");
+      go_error_at(this->location(), "expected identifier or %<(%>");
       return left;
     }
 }
@@ -3240,7 +3246,8 @@ Parse::index(Expression* expr)
        end = Expression::make_nil(this->location());
       else if (this->peek_token()->is_op(OPERATOR_COLON))
        {
-         error_at(this->location(), "middle index required in 3-index slice");
+         go_error_at(this->location(),
+                     "middle index required in 3-index slice");
          end = Expression::make_error(this->location());
        }
       else
@@ -3252,14 +3259,15 @@ Parse::index(Expression* expr)
     {
       if (this->advance_token()->is_op(OPERATOR_RSQUARE))
        {
-         error_at(this->location(), "final index required in 3-index slice");
+         go_error_at(this->location(),
+                     "final index required in 3-index slice");
          cap = Expression::make_error(this->location());
        }
       else
         cap = this->expression(PRECEDENCE_NORMAL, false, true, NULL, NULL);
     }
   if (!this->peek_token()->is_op(OPERATOR_RSQUARE))
-    error_at(this->location(), "missing %<]%>");
+    go_error_at(this->location(), "missing %<]%>");
   else
     this->advance_token();
   return Expression::make_index(expr, start, end, cap, location);
@@ -3289,7 +3297,7 @@ Parse::call(Expression* func)
     token = this->advance_token();
   if (!token->is_op(OPERATOR_RPAREN))
     {
-      error_at(this->location(), "missing %<)%>");
+      go_error_at(this->location(), "missing %<)%>");
       if (!this->skip_past_error(OPERATOR_RPAREN))
        return Expression::make_error(this->location());
     }
@@ -3356,7 +3364,7 @@ Parse::id_to_expression(const std::string& name, Location location,
     case Named_object::NAMED_OBJECT_ERRONEOUS:
       return Expression::make_error(location);
     default:
-      error_at(this->location(), "unexpected type of identifier");
+      go_error_at(this->location(), "unexpected type of identifier");
       return Expression::make_error(location);
     }
 }
@@ -3561,7 +3569,7 @@ Parse::unary_expr(bool may_be_sink, bool may_be_composite_lit,
              if (ct == NULL)
                {
                  // This is probably impossible.
-                 error_at(location, "expected channel type");
+                 go_error_at(location, "expected channel type");
                  return Expression::make_error(location);
                }
              else if (ct->may_receive())
@@ -3633,7 +3641,7 @@ Parse::reassociate_chan_direction(Channel_type *ct, Location location)
   Channel_type* ele = ct->element_type()->channel_type();
   if (ele == NULL)
     {
-      error_at(location, "parse error");
+      go_error_at(location, "parse error");
       return Type::make_error_type();
     }
   Type* sub = ele;
@@ -3702,7 +3710,7 @@ Parse::statement(Label* label)
            this->for_stat(label);
            break;
          default:
-           error_at(this->location(), "expected statement");
+           go_error_at(this->location(), "expected statement");
            this->advance_token();
            break;
          }
@@ -3751,7 +3759,7 @@ Parse::statement(Label* label)
       break;
 
     default:
-      error_at(this->location(), "expected statement");
+      go_error_at(this->location(), "expected statement");
       this->advance_token();
       break;
     }
@@ -3847,7 +3855,7 @@ Parse::labeled_stmt(const std::string& label_name, Location location)
       if (label != NULL)
         label->set_is_used();
 
-      error_at(location, "missing statement after label");
+      go_error_at(location, "missing statement after label");
       this->unget_token(Token::make_operator_token(OPERATOR_SEMICOLON,
                                                   location));
       return;
@@ -3960,7 +3968,7 @@ Parse::simple_stat(bool may_be_composite_lit, bool* return_exp,
       if (token->is_op(OPERATOR_COLONEQ))
        {
          if (!exp->is_error_expression())
-           error_at(token->location(), "non-name on left side of %<:=%>");
+           go_error_at(token->location(), "non-name on left side of %<:=%>");
          this->gogo_->mark_locals_used();
          while (!token->is_op(OPERATOR_SEMICOLON)
                 && !token->is_eof())
@@ -3997,7 +4005,7 @@ Parse::statement_list()
       else
        {
          if (!this->peek_token()->is_eof() || !saw_errors())
-           error_at(this->location(), "expected %<;%> or %<}%> or newline");
+           go_error_at(this->location(), "expected %<;%> or %<}%> or newline");
          if (!this->skip_past_error(OPERATOR_RCURLY))
            return;
        }
@@ -4104,7 +4112,7 @@ Parse::tuple_assignment(Expression_list* lhs, bool may_be_composite_lit,
       && !token->is_op(OPERATOR_ANDEQ)
       && !token->is_op(OPERATOR_BITCLEAREQ))
     {
-      error_at(this->location(), "expected assignment operator");
+      go_error_at(this->location(), "expected assignment operator");
       return;
     }
   Operator op = token->op();
@@ -4118,7 +4126,7 @@ Parse::tuple_assignment(Expression_list* lhs, bool may_be_composite_lit,
   if (p_range_clause != NULL && token->is_keyword(KEYWORD_RANGE))
     {
       if (op != OPERATOR_EQ)
-       error_at(this->location(), "range clause requires %<=%>");
+       go_error_at(this->location(), "range clause requires %<=%>");
       this->range_clause_expr(lhs, p_range_clause);
       return;
     }
@@ -4136,7 +4144,7 @@ Parse::tuple_assignment(Expression_list* lhs, bool may_be_composite_lit,
       if ((*pe)->is_error_expression())
        return;
       if (op != OPERATOR_EQ && (*pe)->is_sink_expression())
-       error_at((*pe)->location(), "cannot use _ as value");
+       go_error_at((*pe)->location(), "cannot use _ as value");
     }
   for (Expression_list::const_iterator pe = vals->begin();
        pe != vals->end();
@@ -4156,7 +4164,7 @@ Parse::tuple_assignment(Expression_list* lhs, bool may_be_composite_lit,
       if (lhs->size() > 1)
        {
          if (op != OPERATOR_EQ)
-           error_at(location, "multiple values only permitted with %<=%>");
+           go_error_at(location, "multiple values only permitted with %<=%>");
          s = Statement::make_tuple_assignment(lhs, vals, location);
        }
       else
@@ -4176,7 +4184,7 @@ Parse::tuple_assignment(Expression_list* lhs, bool may_be_composite_lit,
           && (call = (*vals->begin())->call_expression()) != NULL)
     {
       if (op != OPERATOR_EQ)
-       error_at(location, "multiple results only permitted with %<=%>");
+       go_error_at(location, "multiple results only permitted with %<=%>");
       call->set_expected_result_count(lhs->size());
       delete vals;
       vals = new Expression_list;
@@ -4190,7 +4198,7 @@ Parse::tuple_assignment(Expression_list* lhs, bool may_be_composite_lit,
           && (map_index = (*vals->begin())->index_expression()) != NULL)
     {
       if (op != OPERATOR_EQ)
-       error_at(location, "two values from map requires %<=%>");
+       go_error_at(location, "two values from map requires %<=%>");
       Expression* val = lhs->front();
       Expression* present = lhs->back();
       Statement* s = Statement::make_tuple_map_assignment(val, present,
@@ -4202,7 +4210,7 @@ Parse::tuple_assignment(Expression_list* lhs, bool may_be_composite_lit,
           && (receive = (*vals->begin())->receive_expression()) != NULL)
     {
       if (op != OPERATOR_EQ)
-       error_at(location, "two values from receive requires %<=%>");
+       go_error_at(location, "two values from receive requires %<=%>");
       Expression* val = lhs->front();
       Expression* success = lhs->back();
       Expression* channel = receive->channel();
@@ -4216,7 +4224,7 @@ Parse::tuple_assignment(Expression_list* lhs, bool may_be_composite_lit,
           && (type_guard = (*vals->begin())->type_guard_expression()) != NULL)
     {
       if (op != OPERATOR_EQ)
-       error_at(location, "two values from type guard requires %<=%>");
+       go_error_at(location, "two values from type guard requires %<=%>");
       Expression* val = lhs->front();
       Expression* ok = lhs->back();
       Expression* expr = type_guard->expr();
@@ -4228,7 +4236,8 @@ Parse::tuple_assignment(Expression_list* lhs, bool may_be_composite_lit,
     }
   else
     {
-      error_at(location, "number of variables does not match number of values");
+      go_error_at(location, ("number of variables does not "
+                             "match number of values"));
     }
 }
 
@@ -4252,7 +4261,7 @@ Parse::go_or_defer_stat()
   Call_expression* call_expr = expr->call_expression();
   if (is_parenthesized || call_expr == NULL)
     {
-      error_at(expr_location, "argument to go/defer must be function call");
+      go_error_at(expr_location, "argument to go/defer must be function call");
       return;
     }
 
@@ -4295,8 +4304,8 @@ Parse::return_stat()
          if (no == NULL)
            go_assert(saw_errors());
          else if (!no->is_result_variable())
-           error_at(location, "%qs is shadowed during return",
-                    (*p)->message_name().c_str());
+           go_error_at(location, "%qs is shadowed during return",
+                       (*p)->message_name().c_str());
        }
     }
 }
@@ -4334,19 +4343,19 @@ Parse::if_stat()
       else if (saw_simple_stat)
        {
          if (saw_send_stmt)
-           error_at(this->location(),
-                    ("send statement used as value; "
-                     "use select for non-blocking send"));
+           go_error_at(this->location(),
+                       ("send statement used as value; "
+                        "use select for non-blocking send"));
          else
-           error_at(this->location(),
-                    "expected %<;%> after statement in if expression");
+           go_error_at(this->location(),
+                       "expected %<;%> after statement in if expression");
          if (!this->expression_may_start_here())
            cond = Expression::make_error(this->location());
        }
       if (cond == NULL && this->peek_token()->is_op(OPERATOR_LCURLY))
        {
-         error_at(this->location(),
-                  "missing condition in if statement");
+         go_error_at(this->location(),
+                     "missing condition in if statement");
          cond = Expression::make_error(this->location());
        }
       if (cond == NULL)
@@ -4358,7 +4367,7 @@ Parse::if_stat()
     {
       Location semi_loc = this->location();
       if (this->advance_token()->is_op(OPERATOR_LCURLY))
-       error_at(semi_loc, "missing %<{%> after if clause");
+       go_error_at(semi_loc, "missing %<{%> after if clause");
       // Otherwise we will get an error when we call this->block
       // below.
     }
@@ -4372,7 +4381,7 @@ Parse::if_stat()
     {
       Location semi_loc = this->location();
       if (this->advance_token()->is_keyword(KEYWORD_ELSE))
-       error_at(this->location(),
+       go_error_at(this->location(),
                 "unexpected semicolon or newline before %<else%>");
       else
        this->unget_token(Token::make_operator_token(OPERATOR_SEMICOLON,
@@ -4390,7 +4399,7 @@ Parse::if_stat()
        this->block();
       else
        {
-         error_at(this->location(), "expected %<if%> or %<{%>");
+         go_error_at(this->location(), "expected %<if%> or %<{%>");
          this->statement(NULL);
        }
       else_block = this->gogo_->finish_block(this->location());
@@ -4444,12 +4453,12 @@ Parse::switch_stat(Label* label)
       else if (saw_simple_stat)
        {
          if (saw_send_stmt)
-           error_at(this->location(),
-                    ("send statement used as value; "
-                     "use select for non-blocking send"));
+           go_error_at(this->location(),
+                       ("send statement used as value; "
+                        "use select for non-blocking send"));
          else
-           error_at(this->location(),
-                    "expected %<;%> after statement in switch expression");
+           go_error_at(this->location(),
+                       "expected %<;%> after statement in switch expression");
        }
       if (!this->peek_token()->is_op(OPERATOR_LCURLY))
        {
@@ -4482,7 +4491,8 @@ Parse::switch_stat(Label* label)
                      if (switch_val == NULL
                          || !switch_val->is_error_expression())
                        {
-                         error_at(id_loc, "expected type switch assignment");
+                         go_error_at(id_loc,
+                                     "expected type switch assignment");
                          switch_val = Expression::make_error(id_loc);
                        }
                    }
@@ -4507,10 +4517,10 @@ Parse::switch_stat(Label* label)
       Location token_loc = this->location();
       if (this->peek_token()->is_op(OPERATOR_SEMICOLON)
          && this->advance_token()->is_op(OPERATOR_LCURLY))
-       error_at(token_loc, "missing %<{%> after switch clause");
+       go_error_at(token_loc, "missing %<{%> after switch clause");
       else if (this->peek_token()->is_op(OPERATOR_COLONEQ))
        {
-         error_at(token_loc, "invalid variable name");
+         go_error_at(token_loc, "invalid variable name");
          this->advance_token();
          this->expression(PRECEDENCE_NORMAL, false, false,
                           &type_switch.found, NULL);
@@ -4530,7 +4540,7 @@ Parse::switch_stat(Label* label)
        }
       else
        {
-         error_at(this->location(), "expected %<{%>");
+         go_error_at(this->location(), "expected %<{%>");
          if (have_type_switch_block)
            this->gogo_->add_block(this->gogo_->finish_block(this->location()),
                                   location);
@@ -4577,7 +4587,7 @@ Parse::expr_switch_body(Label* label, Expression* switch_val,
       if (this->peek_token()->is_eof())
        {
          if (!saw_errors())
-           error_at(this->location(), "missing %<}%>");
+           go_error_at(this->location(), "missing %<}%>");
          return NULL;
        }
       this->expr_case_clause(case_clauses, &saw_default);
@@ -4605,7 +4615,7 @@ Parse::expr_case_clause(Case_clauses* clauses, bool* saw_default)
   if (!this->peek_token()->is_op(OPERATOR_COLON))
     {
       if (!saw_errors())
-       error_at(this->location(), "expected %<:%>");
+       go_error_at(this->location(), "expected %<:%>");
       return;
     }
   else
@@ -4627,14 +4637,15 @@ Parse::expr_case_clause(Case_clauses* clauses, bool* saw_default)
       if (this->advance_token()->is_op(OPERATOR_SEMICOLON))
        this->advance_token();
       if (this->peek_token()->is_op(OPERATOR_RCURLY))
-       error_at(fallthrough_loc, _("cannot fallthrough final case in switch"));
+       go_error_at(fallthrough_loc,
+                   _("cannot fallthrough final case in switch"));
     }
 
   if (is_default)
     {
       if (*saw_default)
        {
-         error_at(location, "multiple defaults in switch");
+         go_error_at(location, "multiple defaults in switch");
          return;
        }
       *saw_default = true;
@@ -4664,7 +4675,7 @@ Parse::expr_switch_case(bool* is_default)
   else
     {
       if (!saw_errors())
-       error_at(this->location(), "expected %<case%> or %<default%>");
+       go_error_at(this->location(), "expected %<case%> or %<default%>");
       if (!token->is_op(OPERATOR_RCURLY))
        this->advance_token();
       return NULL;
@@ -4684,8 +4695,8 @@ Parse::type_switch_body(Label* label, const Type_switch& type_switch,
     {
       if (Gogo::is_sink_name(var_name))
         {
-          error_at(type_switch.location,
-                   "no new variables on left side of %<:=%>");
+         go_error_at(type_switch.location,
+                     "no new variables on left side of %<:=%>");
           var_name.clear();
         }
       else
@@ -4709,7 +4720,7 @@ Parse::type_switch_body(Label* label, const Type_switch& type_switch,
     {
       if (this->peek_token()->is_eof())
        {
-         error_at(this->location(), "missing %<}%>");
+         go_error_at(this->location(), "missing %<}%>");
          return NULL;
        }
       this->type_case_clause(var_name, init, case_clauses, &saw_default,
@@ -4737,8 +4748,8 @@ Parse::type_switch_body(Label* label, const Type_switch& type_switch,
            }
        }
       if (!used)
-       error_at(type_switch.location, "%qs declared and not used",
-                Gogo::message_name(var_name).c_str());
+       go_error_at(type_switch.location, "%qs declared and not used",
+                   Gogo::message_name(var_name).c_str());
     }
   return statement;
 }
@@ -4759,7 +4770,7 @@ Parse::type_case_clause(const std::string& var_name, Expression* init,
   this->type_switch_case(&types, &is_default);
 
   if (!this->peek_token()->is_op(OPERATOR_COLON))
-    error_at(this->location(), "expected %<:%>");
+    go_error_at(this->location(), "expected %<:%>");
   else
     this->advance_token();
 
@@ -4789,8 +4800,8 @@ Parse::type_case_clause(const std::string& var_name, Expression* init,
 
   if (this->peek_token()->is_keyword(KEYWORD_FALLTHROUGH))
     {
-      error_at(this->location(),
-              "fallthrough is not permitted in a type switch");
+      go_error_at(this->location(),
+                 "fallthrough is not permitted in a type switch");
       if (this->advance_token()->is_op(OPERATOR_SEMICOLON))
        this->advance_token();
     }
@@ -4800,7 +4811,7 @@ Parse::type_case_clause(const std::string& var_name, Expression* init,
       go_assert(types.empty());
       if (*saw_default)
        {
-         error_at(location, "multiple defaults in type switch");
+         go_error_at(location, "multiple defaults in type switch");
          return;
        }
       *saw_default = true;
@@ -4858,7 +4869,7 @@ Parse::type_switch_case(std::vector<Type*>* types, bool* is_default)
     }
   else
     {
-      error_at(this->location(), "expected %<case%> or %<default%>");
+      go_error_at(this->location(), "expected %<case%> or %<default%>");
       if (!token->is_op(OPERATOR_RCURLY))
        this->advance_token();
     }
@@ -4878,10 +4889,10 @@ Parse::select_stat(Label* label)
       Location token_loc = token->location();
       if (token->is_op(OPERATOR_SEMICOLON)
          && this->advance_token()->is_op(OPERATOR_LCURLY))
-       error_at(token_loc, "unexpected semicolon or newline before %<{%>");
+       go_error_at(token_loc, "unexpected semicolon or newline before %<{%>");
       else
        {
-         error_at(this->location(), "expected %<{%>");
+         go_error_at(this->location(), "expected %<{%>");
          return;
        }
     }
@@ -4897,7 +4908,7 @@ Parse::select_stat(Label* label)
     {
       if (this->peek_token()->is_eof())
        {
-         error_at(this->location(), "expected %<}%>");
+         go_error_at(this->location(), "expected %<}%>");
          return;
        }
       this->comm_clause(select_clauses, &saw_default);
@@ -4931,7 +4942,7 @@ Parse::comm_clause(Select_clauses* clauses, bool* saw_default)
   if (this->peek_token()->is_op(OPERATOR_COLON))
     this->advance_token();
   else
-    error_at(this->location(), "expected colon");
+    go_error_at(this->location(), "expected colon");
 
   this->gogo_->start_block(this->location());
 
@@ -4962,7 +4973,7 @@ Parse::comm_clause(Select_clauses* clauses, bool* saw_default)
     {
       if (*saw_default)
        {
-         error_at(location, "multiple defaults in select");
+         go_error_at(location, "multiple defaults in select");
          return;
        }
       *saw_default = true;
@@ -5001,7 +5012,7 @@ Parse::comm_case(bool* is_send, Expression** channel, Expression** val,
     }
   else
     {
-      error_at(this->location(), "expected %<case%> or %<default%>");
+      go_error_at(this->location(), "expected %<case%> or %<default%>");
       if (!token->is_op(OPERATOR_RCURLY))
        this->advance_token();
       return false;
@@ -5038,13 +5049,13 @@ Parse::send_or_recv_stmt(bool* is_send, Expression** channel, Expression** val,
          if (re == NULL)
            {
              if (!e->is_error_expression())
-               error_at(this->location(), "expected receive expression");
+               go_error_at(this->location(), "expected receive expression");
              return false;
            }
          if (recv_var == "_")
            {
-             error_at(recv_var_loc,
-                      "no new variables on left side of %<:=%>");
+             go_error_at(recv_var_loc,
+                         "no new variables on left side of %<:=%>");
              recv_var = Gogo::erroneous_name();
            }
          *is_send = false;
@@ -5073,14 +5084,14 @@ Parse::send_or_recv_stmt(bool* is_send, Expression** channel, Expression** val,
                  if (re == NULL)
                    {
                      if (!e->is_error_expression())
-                       error_at(this->location(),
+                       go_error_at(this->location(),
                                 "expected receive expression");
                      return false;
                    }
                  if (recv_var == "_" && recv_closed == "_")
                    {
-                     error_at(recv_var_loc,
-                              "no new variables on left side of %<:=%>");
+                     go_error_at(recv_var_loc,
+                                 "no new variables on left side of %<:=%>");
                      recv_var = Gogo::erroneous_name();
                    }
                  *is_send = false;
@@ -5147,7 +5158,7 @@ Parse::send_or_recv_stmt(bool* is_send, Expression** channel, Expression** val,
     {
       if (!this->advance_token()->is_op(OPERATOR_CHANOP))
        {
-         error_at(this->location(), "missing %<<-%>");
+         go_error_at(this->location(), "missing %<<-%>");
          return false;
        }
       *is_send = false;
@@ -5172,9 +5183,9 @@ Parse::send_or_recv_stmt(bool* is_send, Expression** channel, Expression** val,
   if (saw_comma)
     {
       if (closed_is_id)
-       error_at(this->location(), "expected %<=%> or %<:=%>");
+       go_error_at(this->location(), "expected %<=%> or %<:=%>");
       else
-       error_at(this->location(), "expected %<=%>");
+       go_error_at(this->location(), "expected %<=%>");
       return false;
     }
 
@@ -5188,7 +5199,7 @@ Parse::send_or_recv_stmt(bool* is_send, Expression** channel, Expression** val,
       return true;
     }
 
-  error_at(this->location(), "expected %<<-%> or %<=%>");
+  go_error_at(this->location(), "expected %<<-%> or %<=%>");
   return false;
 }
 
@@ -5215,8 +5226,8 @@ Parse::for_stat(Label* label)
     {
       if (token->is_keyword(KEYWORD_VAR))
        {
-         error_at(this->location(),
-                  "var declaration not allowed in for initializer");
+         go_error_at(this->location(),
+                      "var declaration not allowed in for initializer");
          this->var_decl();
        }
 
@@ -5233,17 +5244,18 @@ Parse::for_stat(Label* label)
              if (cond == NULL && !range_clause.found)
                {
                  if (saw_send_stmt)
-                   error_at(this->location(),
-                            ("send statement used as value; "
-                             "use select for non-blocking send"));
+                   go_error_at(this->location(),
+                                ("send statement used as value; "
+                                 "use select for non-blocking send"));
                  else
-                   error_at(this->location(), "parse error in for statement");
+                   go_error_at(this->location(),
+                                "parse error in for statement");
                }
            }
          else
            {
              if (range_clause.found)
-               error_at(this->location(), "parse error after range clause");
+               go_error_at(this->location(), "parse error after range clause");
 
              if (cond != NULL)
                {
@@ -5263,7 +5275,7 @@ Parse::for_stat(Label* label)
     {
       Location semi_loc = this->location();
       if (this->advance_token()->is_op(OPERATOR_LCURLY))
-       error_at(semi_loc, "missing %<{%> after for clause");
+       go_error_at(semi_loc, "missing %<{%> after for clause");
       // Otherwise we will get an error when we call this->block
       // below.
     }
@@ -5334,7 +5346,7 @@ Parse::for_clause(Expression** cond, Block** post)
     *cond = NULL;
   else if (this->peek_token()->is_op(OPERATOR_LCURLY))
     {
-      error_at(this->location(), "missing %<{%> after for clause");
+      go_error_at(this->location(), "missing %<{%> after for clause");
       *cond = NULL;
       *post = NULL;
       return;
@@ -5342,7 +5354,7 @@ Parse::for_clause(Expression** cond, Block** post)
   else
     *cond = this->expression(PRECEDENCE_NORMAL, false, true, NULL, NULL);
   if (!this->peek_token()->is_op(OPERATOR_SEMICOLON))
-    error_at(this->location(), "expected semicolon");
+    go_error_at(this->location(), "expected semicolon");
   else
     this->advance_token();
 
@@ -5370,7 +5382,7 @@ Parse::range_clause_decl(const Typed_identifier_list* til,
   p_range_clause->found = true;
 
   if (til->size() > 2)
-    error_at(this->location(), "too many variables for range clause");
+    go_error_at(this->location(), "too many variables for range clause");
 
   this->advance_token();
   Expression* expr = this->expression(PRECEDENCE_NORMAL, false, false, NULL,
@@ -5405,7 +5417,7 @@ Parse::range_clause_decl(const Typed_identifier_list* til,
     }
 
   if (!any_new)
-    error_at(location, "variables redeclared but no variable is new");
+    go_error_at(location, "variables redeclared but no variable is new");
 }
 
 // The = version of RangeClause.  This is called with a list of
@@ -5421,7 +5433,7 @@ Parse::range_clause_expr(const Expression_list* vals,
 
   go_assert(vals->size() >= 1);
   if (vals->size() > 2)
-    error_at(this->location(), "too many variables for range clause");
+    go_error_at(this->location(), "too many variables for range clause");
 
   this->advance_token();
   p_range_clause->range = this->expression(PRECEDENCE_NORMAL, false, false,
@@ -5507,8 +5519,8 @@ Parse::break_stat()
     {
       if (this->break_stack_ == NULL || this->break_stack_->empty())
        {
-         error_at(this->location(),
-                  "break statement not within for or switch or select");
+         go_error_at(this->location(),
+                      "break statement not within for or switch or select");
          return;
        }
       enclosing = this->break_stack_->back().first;
@@ -5524,8 +5536,8 @@ Parse::break_stat()
          this->gogo_->add_label_reference(token->identifier(),
                                            Linemap::unknown_location(), false);
 
-         error_at(token->location(), "invalid break label %qs",
-                  Gogo::message_name(token->identifier()).c_str());
+         go_error_at(token->location(), "invalid break label %qs",
+                      Gogo::message_name(token->identifier()).c_str());
          this->advance_token();
          return;
        }
@@ -5564,7 +5576,7 @@ Parse::continue_stat()
     {
       if (this->continue_stack_ == NULL || this->continue_stack_->empty())
        {
-         error_at(this->location(), "continue statement not within for");
+         go_error_at(this->location(), "continue statement not within for");
          return;
        }
       enclosing = this->continue_stack_->back().first;
@@ -5580,8 +5592,8 @@ Parse::continue_stat()
          this->gogo_->add_label_reference(token->identifier(),
                                            Linemap::unknown_location(), false);
 
-         error_at(token->location(), "invalid continue label %qs",
-                  Gogo::message_name(token->identifier()).c_str());
+         go_error_at(token->location(), "invalid continue label %qs",
+                      Gogo::message_name(token->identifier()).c_str());
          this->advance_token();
          return;
        }
@@ -5609,7 +5621,7 @@ Parse::goto_stat()
   Location location = this->location();
   const Token* token = this->advance_token();
   if (!token->is_identifier())
-    error_at(this->location(), "expected label for goto");
+    go_error_at(this->location(), "expected label for goto");
   else
     {
       Label* label = this->gogo_->add_label_reference(token->identifier(),
@@ -5630,7 +5642,7 @@ Parse::package_clause()
   std::string name;
   if (!token->is_keyword(KEYWORD_PACKAGE))
     {
-      error_at(this->location(), "program must start with package clause");
+      go_error_at(this->location(), "program must start with package clause");
       name = "ERROR";
     }
   else
@@ -5641,14 +5653,14 @@ Parse::package_clause()
          name = token->identifier();
          if (name == "_")
            {
-             error_at(this->location(), "invalid package name _");
+             go_error_at(this->location(), "invalid package name _");
              name = Gogo::erroneous_name();
            }
          this->advance_token();
        }
       else
        {
-         error_at(this->location(), "package name must be an identifier");
+         go_error_at(this->location(), "package name must be an identifier");
          name = "ERROR";
        }
     }
@@ -5689,7 +5701,7 @@ Parse::import_spec(void*)
 
   if (!token->is_string())
     {
-      error_at(this->location(), "import statement not a string");
+      go_error_at(this->location(), "import statement not a string");
       this->advance_token();
       return;
     }
@@ -5712,8 +5724,8 @@ Parse::program()
   if (token->is_op(OPERATOR_SEMICOLON))
     token = this->advance_token();
   else
-    error_at(this->location(),
-            "expected %<;%> or newline after package clause");
+    go_error_at(this->location(),
+                "expected %<;%> or newline after package clause");
 
   while (token->is_keyword(KEYWORD_IMPORT))
     {
@@ -5722,8 +5734,8 @@ Parse::program()
       if (token->is_op(OPERATOR_SEMICOLON))
        token = this->advance_token();
       else
-       error_at(this->location(),
-                "expected %<;%> or newline after import declaration");
+       go_error_at(this->location(),
+                    "expected %<;%> or newline after import declaration");
     }
 
   while (!token->is_eof())
@@ -5732,7 +5744,7 @@ Parse::program()
        this->declaration();
       else
        {
-         error_at(this->location(), "expected declaration");
+         go_error_at(this->location(), "expected declaration");
          this->gogo_->mark_locals_used();
          do
            this->advance_token();
@@ -5749,12 +5761,13 @@ Parse::program()
       else if (!token->is_eof() || !saw_errors())
        {
          if (token->is_op(OPERATOR_CHANOP))
-           error_at(this->location(),
-                    ("send statement used as value; "
-                     "use select for non-blocking send"));
+           go_error_at(this->location(),
+                        ("send statement used as value; "
+                         "use select for non-blocking send"));
          else
-           error_at(this->location(),
-                    "expected %<;%> or newline after top level declaration");
+           go_error_at(this->location(),
+                        ("expected %<;%> or newline after top "
+                         "level declaration"));
          this->skip_past_error(OPERATOR_INVALID);
        }
     }
@@ -5815,7 +5828,7 @@ Parse::verify_not_sink(Expression* expr)
 {
   if (expr->is_sink_expression())
     {
-      error_at(expr->location(), "cannot use _ as value");
+      go_error_at(expr->location(), "cannot use _ as value");
       expr = Expression::make_error(expr->location());
     }
 
index a7118e77c17575b25d2709f27307980d96ab5eda..e13dcc97545259b77db0419ea9d5037c9b5367bb 100644 (file)
@@ -81,7 +81,8 @@ class Parse
     Expression* expr;
 
     Type_switch()
-      : found(false), name(), location(UNKNOWN_LOCATION), expr(NULL)
+        : found(false), name(), location(Linemap::unknown_location()),
+          expr(NULL)
     { }
   };
 
index 9e481741ad6152427f36850dd176cd9a311ecc99..390ad3a97b36e92f742d18dfe4389e9f0b0eaf18 100644 (file)
@@ -7,6 +7,7 @@
 #include "go-system.h"
 
 #include "go-c.h"
+#include "go-diagnostics.h"
 #include "types.h"
 #include "expressions.h"
 #include "gogo.h"
@@ -163,7 +164,7 @@ Statement::set_is_error()
 void
 Statement::report_error(const char* msg)
 {
-  error_at(this->location_, "%s", msg);
+  go_error_at(this->location_, "%s", msg);
   this->set_is_error();
 }
 
@@ -428,9 +429,9 @@ Temporary_statement::do_check_types(Gogo*)
       if (!Type::are_assignable(this->type_, this->init_->type(), &reason))
        {
          if (reason.empty())
-           error_at(this->location(), "incompatible types in assignment");
+           go_error_at(this->location(), "incompatible types in assignment");
          else
-           error_at(this->location(), "incompatible types in assignment (%s)",
+           go_error_at(this->location(), "incompatible types in assignment (%s)",
                     reason.c_str());
          this->set_is_error();
        }
@@ -767,10 +768,10 @@ Assignment_statement::do_check_types(Gogo*)
   if (!Type::are_assignable(lhs_type, rhs_type, &reason))
     {
       if (reason.empty())
-       error_at(this->location(), "incompatible types in assignment");
+       go_error_at(this->location(), "incompatible types in assignment");
       else
-       error_at(this->location(), "incompatible types in assignment (%s)",
-                reason.c_str());
+       go_error_at(this->location(), "incompatible types in assignment (%s)",
+                   reason.c_str());
       this->set_is_error();
     }
 
@@ -2669,11 +2670,12 @@ Return_statement::do_lower(Gogo*, Named_object* function, Block* enclosing,
       else
        {
          if (reason.empty())
-           error_at(e->location(), "incompatible type for return value %d", i);
+           go_error_at(e->location(),
+                       "incompatible type for return value %d", i);
          else
-           error_at(e->location(),
-                    "incompatible type for return value %d (%s)",
-                    i, reason.c_str());
+           go_error_at(e->location(),
+                       "incompatible type for return value %d (%s)",
+                       i, reason.c_str());
        }
     }
   go_assert(lhs->size() == rhs->size());
@@ -2850,8 +2852,8 @@ Goto_statement::do_check_types(Gogo*)
 {
   if (!this->label_->is_defined())
     {
-      error_at(this->location(), "reference to undefined label %qs",
-              Gogo::message_name(this->label_->name()).c_str());
+      go_error_at(this->location(), "reference to undefined label %qs",
+                 Gogo::message_name(this->label_->name()).c_str());
       this->set_is_error();
     }
 }
@@ -3274,8 +3276,8 @@ Case_clauses::Case_clause::check_types(Type* type)
          if (!Type::are_assignable(type, (*p)->type(), NULL)
              && !Type::are_assignable((*p)->type(), type, NULL))
            {
-             error_at((*p)->location(),
-                      "type mismatch between switch value and case clause");
+             go_error_at((*p)->location(),
+                         "type mismatch between switch value and case clause");
              return false;
            }
        }
@@ -3338,7 +3340,7 @@ Case_clauses::Case_clause::get_backend(Translate_context* context,
          if (!ins.second)
            {
              // Value was already present.
-             error_at(this->location_, "duplicate case in switch");
+             go_error_at(this->location_, "duplicate case in switch");
              e = Expression::make_error(this->location_);
            }
          cases->push_back(e->get_backend(context));
@@ -3722,8 +3724,8 @@ Switch_statement::do_lower(Gogo*, Named_object*, Block* enclosing,
       && !Type::are_compatible_for_comparison(true, this->val_->type(),
                                              Type::make_nil_type(), NULL))
     {
-      error_at(this->val_->location(),
-              "cannot switch on value whose type that may not be compared");
+      go_error_at(this->val_->location(),
+                 "cannot switch on value whose type that may not be compared");
       return Statement::make_error_statement(loc);
     }
 
@@ -3857,10 +3859,10 @@ Type_case_clauses::Type_case_clause::lower(Type* switch_val_type,
                                                                      &reason))
        {
          if (reason.empty())
-           error_at(this->location_, "impossible type switch case");
+           go_error_at(this->location_, "impossible type switch case");
          else
-           error_at(this->location_, "impossible type switch case (%s)",
-                    reason.c_str());
+           go_error_at(this->location_, "impossible type switch case (%s)",
+                       reason.c_str());
        }
 
       Expression* ref = Expression::make_temporary_reference(descriptor_temp,
@@ -4025,7 +4027,7 @@ Type_case_clauses::check_duplicates() const
        t = Type::make_nil_type();
       std::pair<Types_seen::iterator, bool> ins = types_seen.insert(t);
       if (!ins.second)
-       error_at(p->location(), "duplicate type in switch");
+       go_error_at(p->location(), "duplicate type in switch");
     }
 }
 
@@ -4255,7 +4257,7 @@ Send_statement::do_check_types(Gogo*)
   Channel_type* channel_type = type->channel_type();
   if (channel_type == NULL)
     {
-      error_at(this->location(), "left operand of %<<-%> must be channel");
+      go_error_at(this->location(), "left operand of %<<-%> must be channel");
       this->set_is_error();
       return;
     }
@@ -4656,14 +4658,14 @@ Select_clauses::Select_clause::check_types()
   Channel_type* ct = this->channel_->type()->channel_type();
   if (ct == NULL)
     {
-      error_at(this->channel_->location(), "expected channel");
+      go_error_at(this->channel_->location(), "expected channel");
       return;
     }
 
   if (this->is_send_ && !ct->may_send())
-    error_at(this->location(), "invalid send on receive-only channel");
+    go_error_at(this->location(), "invalid send on receive-only channel");
   else if (!this->is_send_ && !ct->may_receive())
-    error_at(this->location(), "invalid receive on send-only channel");
+    go_error_at(this->location(), "invalid receive on send-only channel");
 }
 
 // Whether this clause may fall through to the statement which follows
index 9ed8d7272ecccc8fbfdcd9e6ef601aec2765dc84..2d395d077baebefa2461ec1dbec253a853584126 100644 (file)
@@ -1624,7 +1624,7 @@ class Case_clauses
    public:
     Case_clause()
       : cases_(NULL), statements_(NULL), is_default_(false),
-       is_fallthrough_(false), location_(UNKNOWN_LOCATION)
+       is_fallthrough_(false), location_(Linemap::unknown_location())
     { }
 
     Case_clause(Expression_list* cases, bool is_default, Block* statements,
@@ -1811,7 +1811,7 @@ class Type_case_clauses
    public:
     Type_case_clause()
       : type_(NULL), statements_(NULL), is_default_(false),
-       location_(UNKNOWN_LOCATION)
+       location_(Linemap::unknown_location())
     { }
 
     Type_case_clause(Type* type, bool is_fallthrough, bool is_default,
index db5655ba06a0f410ac929973faa5364d655c0900..01af8f33db6ba78c9a5ca1c0eaf95609c4a8899e 100644 (file)
@@ -10,6 +10,7 @@
 
 #include "go-c.h"
 #include "gogo.h"
+#include "go-diagnostics.h"
 #include "operator.h"
 #include "expressions.h"
 #include "statements.h"
@@ -2594,12 +2595,13 @@ Type::backend_type_size(Gogo* gogo, int64_t *psize)
   if (*psize == -1)
     {
       if (this->named_type() != NULL)
-        error_at(this->named_type()->location(),
-                 "type %s larger than address space",
-                 Gogo::message_name(this->named_type()->name()).c_str());
+       go_error_at(this->named_type()->location(),
+                "type %s larger than address space",
+                Gogo::message_name(this->named_type()->name()).c_str());
       else
-        error("type %s larger than address space",
-              this->reflection(gogo).c_str());
+       go_error_at(Linemap::unknown_location(),
+                   "type %s larger than address space",
+                   this->reflection(gogo).c_str());
 
       // Make this an error type to avoid knock-on errors.
       this->classification_ = TYPE_ERROR;
@@ -2663,7 +2665,7 @@ Type::import_type(Import* imp)
     return Interface_type::do_import(imp);
   else
     {
-      error_at(imp->location(), "import error: expected type");
+      go_error_at(imp->location(), "import error: expected type");
       return Type::make_error_type();
     }
 }
@@ -4751,13 +4753,13 @@ Struct_type::do_verify()
        {
          if (t->named_type() != NULL && t->points_to() != NULL)
            {
-             error_at(p->location(), "embedded type may not be a pointer");
+             go_error_at(p->location(), "embedded type may not be a pointer");
              p->set_type(Type::make_error_type());
            }
          else if (t->points_to() != NULL
                   && t->points_to()->interface_type() != NULL)
            {
-             error_at(p->location(),
+             go_error_at(p->location(),
                       "embedded type may not be pointer to interface");
              p->set_type(Type::make_error_type());
            }
@@ -6116,7 +6118,7 @@ Array_type::verify_length()
 
   if (!this->length_->is_constant())
     {
-      error_at(this->length_->location(), "array bound is not constant");
+      go_error_at(this->length_->location(), "array bound is not constant");
       return false;
     }
 
@@ -6125,9 +6127,9 @@ Array_type::verify_length()
     {
       if (this->length_->type()->integer_type() != NULL
          || this->length_->type()->float_type() != NULL)
-       error_at(this->length_->location(), "array bound is not constant");
+       go_error_at(this->length_->location(), "array bound is not constant");
       else
-       error_at(this->length_->location(), "array bound is not numeric");
+       go_error_at(this->length_->location(), "array bound is not numeric");
       return false;
     }
 
@@ -6139,15 +6141,15 @@ Array_type::verify_length()
     case Numeric_constant::NC_UL_VALID:
       if (sizeof(val) >= tbits / 8 && val >> (tbits - 1) != 0)
        {
-         error_at(this->length_->location(), "array bound overflows");
+         go_error_at(this->length_->location(), "array bound overflows");
          return false;
        }
       break;
     case Numeric_constant::NC_UL_NOTINT:
-      error_at(this->length_->location(), "array bound truncated to integer");
+      go_error_at(this->length_->location(), "array bound truncated to integer");
       return false;
     case Numeric_constant::NC_UL_NEGATIVE:
-      error_at(this->length_->location(), "negative array bound");
+      go_error_at(this->length_->location(), "negative array bound");
       return false;
     case Numeric_constant::NC_UL_BIG:
       {
@@ -6158,7 +6160,7 @@ Array_type::verify_length()
        mpz_clear(val);
        if (bits >= tbits)
          {
-           error_at(this->length_->location(), "array bound overflows");
+           go_error_at(this->length_->location(), "array bound overflows");
            return false;
          }
       }
@@ -7040,7 +7042,7 @@ Map_type::do_verify()
 {
   // The runtime support uses "map[void]void".
   if (!this->key_type_->is_comparable() && !this->key_type_->is_void_type())
-    error_at(this->location_, "invalid map key type");
+    go_error_at(this->location_, "invalid map key type");
   return true;
 }
 
@@ -7173,14 +7175,14 @@ Map_type::do_type_descriptor(Gogo* gogo, Named_type* name)
   int64_t keysize;
   if (!this->key_type_->backend_type_size(gogo, &keysize))
     {
-      error_at(this->location_, "error determining map key type size");
+      go_error_at(this->location_, "error determining map key type size");
       return Expression::make_error(this->location_);
     }
 
   int64_t valsize;
   if (!this->val_type_->backend_type_size(gogo, &valsize))
     {
-      error_at(this->location_, "error determining map value type size");
+      go_error_at(this->location_, "error determining map value type size");
       return Expression::make_error(this->location_);
     }
 
@@ -7835,7 +7837,7 @@ Interface_type::finalize_methods()
       else if (this->find_method(p->name()) == NULL)
        this->all_methods_->push_back(*p);
       else
-       error_at(p->location(), "duplicate method %qs",
+       go_error_at(p->location(), "duplicate method %qs",
                 Gogo::message_name(p->name()).c_str());
     }
 
@@ -7852,14 +7854,14 @@ Interface_type::finalize_methods()
       if (it == NULL)
        {
          if (!t->is_error())
-           error_at(tl, "interface contains embedded non-interface");
+           go_error_at(tl, "interface contains embedded non-interface");
          continue;
        }
       if (it == this)
        {
          if (!issued_recursive_error)
            {
-             error_at(tl, "invalid recursive interface");
+             go_error_at(tl, "invalid recursive interface");
              issued_recursive_error = true;
            }
          continue;
@@ -7873,7 +7875,7 @@ Interface_type::finalize_methods()
            {
              if (*q == nt)
                {
-                 error_at(tl, "inherited interface loop");
+                 go_error_at(tl, "inherited interface loop");
                  break;
                }
            }
@@ -7895,7 +7897,7 @@ Interface_type::finalize_methods()
            this->all_methods_->push_back(Typed_identifier(q->name(),
                                                           q->type(), tl));
          else
-           error_at(tl, "inherited method %qs is ambiguous",
+           go_error_at(tl, "inherited method %qs is ambiguous",
                     Gogo::message_name(q->name()).c_str());
        }
     }
@@ -8045,8 +8047,8 @@ Interface_type::is_compatible_for_assign(const Interface_type* t,
              char buf[200];
              snprintf(buf, sizeof buf,
                       _("need explicit conversion; missing method %s%s%s"),
-                      open_quote, Gogo::message_name(p->name()).c_str(),
-                      close_quote);
+                      go_open_quote(), Gogo::message_name(p->name()).c_str(),
+                      go_close_quote());
              reason->assign(buf);
            }
          return false;
@@ -8062,11 +8064,11 @@ Interface_type::is_compatible_for_assign(const Interface_type* t,
              char* buf = new char[len];
              if (subreason.empty())
                snprintf(buf, len, _("incompatible type for method %s%s%s"),
-                        open_quote, n.c_str(), close_quote);
+                        go_open_quote(), n.c_str(), go_close_quote());
              else
                snprintf(buf, len,
                         _("incompatible type for method %s%s%s (%s)"),
-                        open_quote, n.c_str(), close_quote,
+                        go_open_quote(), n.c_str(), go_close_quote(),
                         subreason.c_str());
              reason->assign(buf);
              delete[] buf;
@@ -8181,10 +8183,10 @@ Interface_type::implements_interface(const Type* t, std::string* reason) const
              char* buf = new char[len];
              if (is_ambiguous)
                snprintf(buf, len, _("ambiguous method %s%s%s"),
-                        open_quote, n.c_str(), close_quote);
+                        go_open_quote(), n.c_str(), go_close_quote());
              else
                snprintf(buf, len, _("missing method %s%s%s"),
-                        open_quote, n.c_str(), close_quote);
+                        go_open_quote(), n.c_str(), go_close_quote());
              reason->assign(buf);
              delete[] buf;
            }
@@ -8204,11 +8206,11 @@ Interface_type::implements_interface(const Type* t, std::string* reason) const
              char* buf = new char[len];
              if (subreason.empty())
                snprintf(buf, len, _("incompatible type for method %s%s%s"),
-                        open_quote, n.c_str(), close_quote);
+                        go_open_quote(), n.c_str(), go_close_quote());
              else
                snprintf(buf, len,
                         _("incompatible type for method %s%s%s (%s)"),
-                        open_quote, n.c_str(), close_quote,
+                        go_open_quote(), n.c_str(), go_close_quote(),
                         subreason.c_str());
              reason->assign(buf);
              delete[] buf;
@@ -8225,7 +8227,7 @@ Interface_type::implements_interface(const Type* t, std::string* reason) const
              char* buf = new char[len];
              snprintf(buf, len,
                       _("method %s%s%s requires a pointer receiver"),
-                      open_quote, n.c_str(), close_quote);
+                      go_open_quote(), n.c_str(), go_close_quote());
              reason->assign(buf);
              delete[] buf;
            }
@@ -8243,7 +8245,7 @@ Interface_type::implements_interface(const Type* t, std::string* reason) const
              char* buf = new char[len];
              snprintf(buf, len,
                       _("method %s%s%s is marked go:nointerface"),
-                      open_quote, n.c_str(), close_quote);
+                      go_open_quote(), n.c_str(), go_close_quote());
              reason->assign(buf);
              delete[] buf;
            }
@@ -9177,8 +9179,8 @@ Named_type::finalize_methods(Gogo* gogo)
       for (Bindings::const_declarations_iterator p = lm->begin_declarations();
           p != lm->end_declarations();
           ++p)
-       error_at(p->second->location(),
-                "invalid pointer or interface receiver type");
+       go_error_at(p->second->location(),
+                   "invalid pointer or interface receiver type");
       delete this->local_methods_;
       this->local_methods_ = NULL;
       return;
@@ -9335,8 +9337,8 @@ Named_type::do_verify()
   Type::traverse(this->type_, &find);
   if (find.found())
     {
-      error_at(this->location_, "invalid recursive type %qs",
-              this->message_name().c_str());
+      go_error_at(this->location_, "invalid recursive type %qs",
+                 this->message_name().c_str());
       this->is_error_ = true;
       return false;
     }
@@ -9358,9 +9360,9 @@ Named_type::do_verify()
              const std::string& name(p->first);
              if (st != NULL && st->find_local_field(name, NULL) != NULL)
                {
-                 error_at(p->second->location(),
-                          "method %qs redeclares struct field name",
-                          Gogo::message_name(name).c_str());
+                 go_error_at(p->second->location(),
+                             "method %qs redeclares struct field name",
+                             Gogo::message_name(name).c_str());
                }
            }
        }
@@ -10547,9 +10549,9 @@ Type::bind_field_or_method(Gogo* gogo, const Type* type, Expression* expr,
          go_assert(m != NULL);
          if (dereferenced)
            {
-             error_at(location,
-                      "calling method %qs requires explicit dereference",
-                      Gogo::message_name(name).c_str());
+             go_error_at(location,
+                         "calling method %qs requires explicit dereference",
+                         Gogo::message_name(name).c_str());
              return Expression::make_error(location);
            }
          if (!m->is_value_method() && expr->type()->points_to() == NULL)
@@ -10566,16 +10568,16 @@ Type::bind_field_or_method(Gogo* gogo, const Type* type, Expression* expr,
          // An error was already reported.
        }
       else if (!ambig1.empty())
-       error_at(location, "%qs is ambiguous via %qs and %qs",
-                Gogo::message_name(name).c_str(), ambig1.c_str(),
-                ambig2.c_str());
+       go_error_at(location, "%qs is ambiguous via %qs and %qs",
+                   Gogo::message_name(name).c_str(), ambig1.c_str(),
+                   ambig2.c_str());
       else if (found_pointer_method)
-       error_at(location, "method requires a pointer receiver");
+       go_error_at(location, "method requires a pointer receiver");
       else if (nt == NULL && st == NULL && it == NULL)
-       error_at(location,
-                ("reference to field %qs in object which "
-                 "has no fields or methods"),
-                Gogo::message_name(name).c_str());
+       go_error_at(location,
+                   ("reference to field %qs in object which "
+                    "has no fields or methods"),
+                   Gogo::message_name(name).c_str());
       else
        {
          bool is_unexported;
@@ -10592,11 +10594,11 @@ Type::bind_field_or_method(Gogo* gogo, const Type* type, Expression* expr,
                                                                  &seen);
            }
          if (is_unexported)
-           error_at(location, "reference to unexported field or method %qs",
-                    Gogo::message_name(name).c_str());
+           go_error_at(location, "reference to unexported field or method %qs",
+                       Gogo::message_name(name).c_str());
          else
-           error_at(location, "reference to undefined field or method %qs",
-                    Gogo::message_name(name).c_str());
+           go_error_at(location, "reference to undefined field or method %qs",
+                       Gogo::message_name(name).c_str());
        }
       return Expression::make_error(location);
     }
@@ -10945,9 +10947,9 @@ Forward_declaration_type::warn() const
       // The name was not defined anywhere.
       if (!this->warned_)
        {
-         error_at(this->named_object_->location(),
-                  "use of undefined type %qs",
-                  no->message_name().c_str());
+         go_error_at(this->named_object_->location(),
+                     "use of undefined type %qs",
+                     no->message_name().c_str());
          this->warned_ = true;
        }
     }
@@ -10956,9 +10958,9 @@ Forward_declaration_type::warn() const
       // The name was seen as a type, but the type was never defined.
       if (no->type_declaration_value()->using_type())
        {
-         error_at(this->named_object_->location(),
-                  "use of undefined type %qs",
-                  no->message_name().c_str());
+         go_error_at(this->named_object_->location(),
+                     "use of undefined type %qs",
+                     no->message_name().c_str());
          this->warned_ = true;
        }
     }
@@ -10967,7 +10969,7 @@ Forward_declaration_type::warn() const
       // The name was defined, but not as a type.
       if (!this->warned_)
        {
-         error_at(this->named_object_->location(), "expected type");
+         go_error_at(this->named_object_->location(), "expected type");
          this->warned_ = true;
        }
     }