compiler: Define and use backend-independent Location class.
authorSanjoy Das <thedigitalangel@gmail.com>
Tue, 29 Nov 2011 19:10:50 +0000 (19:10 +0000)
committerIan Lance Taylor <ian@gcc.gnu.org>
Tue, 29 Nov 2011 19:10:50 +0000 (19:10 +0000)
From Sanjoy Das.

* go-location.h: New file.
* go-linemap.cc: New file.
* go-gcc.cc: Change all uses of source_location to Location.
* Make-lang.in (GO_OBJS): Add go/go-linemap.o.
(GO_LINEMAP_H): New variable.
(GO_LEX_H): Use $(GO_LINEMAP_H).
(GO_GOGO_H, GO_TYPES_H, GO_IMPORT_H): Likewise.
(go/go-linemap.o): New target.

Co-Authored-By: Ian Lance Taylor <iant@google.com>
From-SVN: r181813

29 files changed:
gcc/go/ChangeLog
gcc/go/Make-lang.in
gcc/go/go-gcc.cc
gcc/go/go-linemap.cc [new file with mode: 0644]
gcc/go/go-location.h [new file with mode: 0644]
gcc/go/gofrontend/backend.h
gcc/go/gofrontend/dataflow.cc
gcc/go/gofrontend/export.cc
gcc/go/gofrontend/expressions.cc
gcc/go/gofrontend/expressions.h
gcc/go/gofrontend/go-linemap.h [new file with mode: 0644]
gcc/go/gofrontend/go.cc
gcc/go/gofrontend/gogo-tree.cc
gcc/go/gofrontend/gogo.cc
gcc/go/gofrontend/gogo.h
gcc/go/gofrontend/import-archive.cc
gcc/go/gofrontend/import.cc
gcc/go/gofrontend/import.h
gcc/go/gofrontend/lex.cc
gcc/go/gofrontend/lex.h
gcc/go/gofrontend/parse.cc
gcc/go/gofrontend/parse.h
gcc/go/gofrontend/runtime.cc
gcc/go/gofrontend/runtime.h
gcc/go/gofrontend/statements.cc
gcc/go/gofrontend/statements.h
gcc/go/gofrontend/types.cc
gcc/go/gofrontend/types.h
gcc/go/gofrontend/unsafe.cc

index 2eaf210..47910fd 100644 (file)
@@ -1,3 +1,15 @@
+2011-11-29  Sanjoy Das  <thedigitalangel@gmail.com>
+           Ian Lance Taylor  <iant@google.com>
+
+       * go-location.h: New file.
+       * go-linemap.cc: New file.
+       * go-gcc.cc: Change all uses of source_location to Location.
+       * Make-lang.in (GO_OBJS): Add go/go-linemap.o.
+       (GO_LINEMAP_H): New variable.
+       (GO_LEX_H): Use $(GO_LINEMAP_H).
+       (GO_GOGO_H, GO_TYPES_H, GO_IMPORT_H): Likewise.
+       (go/go-linemap.o): New target.
+
 2011-11-02  Rainer Orth  <ro@CeBiTec.Uni-Bielefeld.DE>
 
        * Make-lang.in (gospec.o): Pass SHLIB instead of SHLIB_LINK.
index 62a4d6f..08aaafb 100644 (file)
@@ -54,6 +54,7 @@ GO_OBJS = \
        go/go-dump.o \
        go/go-gcc.o \
        go/go-lang.o \
+       go/go-linemap.o \
        go/go-optimize.o \
        go/go.o \
        go/gogo-tree.o \
@@ -217,14 +218,15 @@ GO_SYSTEM_H = go/go-system.h $(CONFIG_H) $(SYSTEM_H) coretypes.h \
        $(DIAGNOSTIC_CORE_H) $(INPUT_H) intl.h
 
 GO_C_H = go/go-c.h $(MACHMODE_H)
-GO_LEX_H = go/gofrontend/lex.h go/gofrontend/operator.h
+GO_LINEMAP_H = go/gofrontend/go-linemap.h $(GO_SYSTEM_H) go/go-location.h
+GO_LEX_H = go/gofrontend/lex.h go/gofrontend/operator.h $(GO_LINEMAP_H)
 GO_PARSE_H = go/gofrontend/parse.h
-GO_GOGO_H = go/gofrontend/gogo.h
-GO_TYPES_H = go/gofrontend/types.h
+GO_GOGO_H = go/gofrontend/gogo.h $(GO_LINEMAP_H)
+GO_TYPES_H = go/gofrontend/types.h $(GO_LINEMAP_H)
 GO_STATEMENTS_H = go/gofrontend/statements.h go/gofrontend/operator.h
 GO_EXPRESSIONS_H = go/gofrontend/expressions.h go/gofrontend/operator.h
 GO_EXPORT_H = go/gofrontend/export.h go/gofrontend/string-dump.h
-GO_IMPORT_H = go/gofrontend/import.h $(GO_EXPORT_H)
+GO_IMPORT_H = go/gofrontend/import.h $(GO_EXPORT_H) $(GO_LINEMAP_H)
 GO_RUNTIME_H = go/gofrontend/runtime.h go/gofrontend/runtime.def
 GO_AST_DUMP_H = go/gofrontend/ast-dump.h go/gofrontend/string-dump.h
 
@@ -247,6 +249,9 @@ go/go-gcc.o: go/go-gcc.cc $(GO_SYSTEM_H) $(TREE_H) tree-iterator.h \
                go/gofrontend/backend.h
        $(CXX) -c $(GOINCLUDES) $(ALL_CPPFLAGS) $(ALL_CXXFLAGS) $< $(OUTPUT_OPTION)
 
+go/go-linemap.o: go/go-linemap.cc $(GO_SYSTEM_H) $(GO_LINEMAP_H)
+       $(CXX) -c $(GOINCLUDES) $(ALL_CPPFLAGS) $(ALL_CXXFLAGS) $< $(OUTPUT_OPTION)
+
 go/%.o: go/gofrontend/%.cc
        $(CXX) -c $(GOINCLUDES) $(ALL_CPPFLAGS) $(ALL_CXXFLAGS) $< $(OUTPUT_OPTION)
 
index dbdf95f..f5214db 100644 (file)
@@ -156,7 +156,7 @@ class Gcc_backend : public Backend
   function_type(const Btyped_identifier&,
                const std::vector<Btyped_identifier>&,
                const std::vector<Btyped_identifier>&,
-               source_location);
+               const Location);
 
   Btype*
   struct_type(const std::vector<Btyped_identifier>&);
@@ -165,7 +165,7 @@ class Gcc_backend : public Backend
   array_type(Btype*, Bexpression*);
 
   Btype*
-  placeholder_pointer_type(const std::string&, source_location, bool);
+  placeholder_pointer_type(const std::string&, Location, bool);
 
   bool
   set_placeholder_pointer_type(Btype*, Btype*);
@@ -174,20 +174,20 @@ class Gcc_backend : public Backend
   set_placeholder_function_type(Btype*, Btype*);
 
   Btype*
-  placeholder_struct_type(const std::string&, source_location);
+  placeholder_struct_type(const std::string&, Location);
 
   bool
   set_placeholder_struct_type(Btype* placeholder,
                              const std::vector<Btyped_identifier>&);
 
   Btype*
-  placeholder_array_type(const std::string&, source_location);
+  placeholder_array_type(const std::string&, Location);
 
   bool
   set_placeholder_array_type(Btype*, Btype*, Bexpression*);
 
   Btype*
-  named_type(const std::string&, Btype*, source_location);
+  named_type(const std::string&, Btype*, Location);
 
   Btype*
   circular_pointer_type(Btype*, bool);
@@ -213,21 +213,21 @@ class Gcc_backend : public Backend
   init_statement(Bvariable* var, Bexpression* init);
 
   Bstatement*
-  assignment_statement(Bexpression* lhs, Bexpression* rhs, source_location);
+  assignment_statement(Bexpression* lhs, Bexpression* rhs, Location);
 
   Bstatement*
   return_statement(Bfunction*, const std::vector<Bexpression*>&,
-                  source_location);
+                  Location);
 
   Bstatement*
   if_statement(Bexpression* condition, Bblock* then_block, Bblock* else_block,
-              source_location);
+              Location);
 
   Bstatement*
   switch_statement(Bexpression* value,
                   const std::vector<std::vector<Bexpression*> >& cases,
                   const std::vector<Bstatement*>& statements,
-                  source_location);
+                  Location);
 
   Bstatement*
   compound_statement(Bstatement*, Bstatement*);
@@ -239,7 +239,7 @@ class Gcc_backend : public Backend
 
   Bblock*
   block(Bfunction*, Bblock*, const std::vector<Bvariable*>&,
-       source_location, source_location);
+       Location, Location);
 
   void
   block_add_statements(Bblock*, const std::vector<Bstatement*>&);
@@ -260,46 +260,46 @@ class Gcc_backend : public Backend
                  Btype* btype,
                  bool is_external,
                  bool is_hidden,
-                 source_location location);
+                 Location location);
 
   void
   global_variable_set_init(Bvariable*, Bexpression*);
 
   Bvariable*
   local_variable(Bfunction*, const std::string&, Btype*, bool,
-                source_location);
+                Location);
 
   Bvariable*
   parameter_variable(Bfunction*, const std::string&, Btype*, bool,
-                    source_location);
+                    Location);
 
   Bvariable*
   temporary_variable(Bfunction*, Bblock*, Btype*, Bexpression*, bool,
-                    source_location, Bstatement**);
+                    Location, Bstatement**);
 
   Bvariable*
-  immutable_struct(const std::string&, bool, Btype*, source_location);
+  immutable_struct(const std::string&, bool, Btype*, Location);
 
   void
   immutable_struct_set_init(Bvariable*, const std::string&, bool, Btype*,
-                           source_location, Bexpression*);
+                           Location, Bexpression*);
 
   Bvariable*
-  immutable_struct_reference(const std::string&, Btype*, source_location);
+  immutable_struct_reference(const std::string&, Btype*, Location);
 
   // Labels.
 
   Blabel*
-  label(Bfunction*, const std::string& name, source_location);
+  label(Bfunction*, const std::string& name, Location);
 
   Bstatement*
   label_definition_statement(Blabel*);
 
   Bstatement*
-  goto_statement(Blabel*, source_location);
+  goto_statement(Blabel*, Location);
 
   Bexpression*
-  label_address(Blabel*, source_location);
+  label_address(Blabel*, Location);
 
  private:
   // Make a Bexpression from a tree.
@@ -432,7 +432,7 @@ Btype*
 Gcc_backend::function_type(const Btyped_identifier& receiver,
                           const std::vector<Btyped_identifier>& parameters,
                           const std::vector<Btyped_identifier>& results,
-                          source_location location)
+                          Location location)
 {
   tree args = NULL_TREE;
   tree* pp = &args;
@@ -482,8 +482,8 @@ Gcc_backend::function_type(const Btyped_identifier& receiver,
          if (field_type_tree == error_mark_node)
            return this->error_type();
          gcc_assert(TYPE_SIZE(field_type_tree) != NULL_TREE);
-         tree field = build_decl(location, FIELD_DECL, name_tree,
-                                 field_type_tree);
+         tree field = build_decl(location.gcc_location(), FIELD_DECL,
+                                  name_tree, field_type_tree);
          DECL_CONTEXT(field) = result;
          *pp = field;
          pp = &DECL_CHAIN(field);
@@ -526,7 +526,8 @@ Gcc_backend::fill_in_struct(Btype* fill,
       tree type_tree = p->btype->get_tree();
       if (type_tree == error_mark_node)
        return this->error_type();
-      tree field = build_decl(p->location, FIELD_DECL, name_tree, type_tree);
+      tree field = build_decl(p->location.gcc_location(), FIELD_DECL, name_tree,
+                              type_tree);
       DECL_CONTEXT(field) = fill_tree;
       *pp = field;
       pp = &DECL_CHAIN(field);
@@ -587,12 +588,12 @@ Gcc_backend::fill_in_array(Btype* fill, Btype* element_type,
 
 Btype*
 Gcc_backend::placeholder_pointer_type(const std::string& name,
-                                     source_location location, bool)
+                                     Location location, bool)
 {
   tree ret = build_variant_type_copy(ptr_type_node);
   if (!name.empty())
     {
-      tree decl = build_decl(location, TYPE_DECL,
+      tree decl = build_decl(location.gcc_location(), TYPE_DECL,
                             get_identifier_from_string(name),
                             ret);
       TYPE_NAME(ret) = decl;
@@ -633,10 +634,10 @@ Gcc_backend::set_placeholder_function_type(Btype* placeholder, Btype* ft)
 
 Btype*
 Gcc_backend::placeholder_struct_type(const std::string& name,
-                                    source_location location)
+                                    Location location)
 {
   tree ret = make_node(RECORD_TYPE);
-  tree decl = build_decl(location, TYPE_DECL,
+  tree decl = build_decl(location.gcc_location(), TYPE_DECL,
                         get_identifier_from_string(name),
                         ret);
   TYPE_NAME(ret) = decl;
@@ -660,10 +661,10 @@ Gcc_backend::set_placeholder_struct_type(
 
 Btype*
 Gcc_backend::placeholder_array_type(const std::string& name,
-                                   source_location location)
+                                   Location location)
 {
   tree ret = make_node(ARRAY_TYPE);
-  tree decl = build_decl(location, TYPE_DECL,
+  tree decl = build_decl(location.gcc_location(), TYPE_DECL,
                         get_identifier_from_string(name),
                         ret);
   TYPE_NAME(ret) = decl;
@@ -687,13 +688,13 @@ Gcc_backend::set_placeholder_array_type(Btype* placeholder,
 
 Btype*
 Gcc_backend::named_type(const std::string& name, Btype* btype,
-                       source_location location)
+                       Location location)
 {
   tree type = btype->get_tree();
   if (type == error_mark_node)
     return this->error_type();
   type = build_variant_type_copy(type);
-  tree decl = build_decl(location, TYPE_DECL,
+  tree decl = build_decl(location.gcc_location(), TYPE_DECL,
                         get_identifier_from_string(name),
                         type);
   TYPE_NAME(type) = decl;
@@ -757,13 +758,14 @@ Gcc_backend::init_statement(Bvariable* var, Bexpression* init)
 
 Bstatement*
 Gcc_backend::assignment_statement(Bexpression* lhs, Bexpression* rhs,
-                                 source_location location)
+                                 Location location)
 {
   tree lhs_tree = lhs->get_tree();
   tree rhs_tree = rhs->get_tree();
   if (lhs_tree == error_mark_node || rhs_tree == error_mark_node)
     return this->error_statement();
-  return this->make_statement(fold_build2_loc(location, MODIFY_EXPR,
+  return this->make_statement(fold_build2_loc(location.gcc_location(),
+                                              MODIFY_EXPR,
                                              void_type_node,
                                              lhs_tree, rhs_tree));
 }
@@ -773,7 +775,7 @@ Gcc_backend::assignment_statement(Bexpression* lhs, Bexpression* rhs,
 Bstatement*
 Gcc_backend::return_statement(Bfunction* bfunction,
                              const std::vector<Bexpression*>& vals,
-                             source_location location)
+                             Location location)
 {
   tree fntree = bfunction->get_tree();
   if (fntree == error_mark_node)
@@ -783,15 +785,18 @@ Gcc_backend::return_statement(Bfunction* bfunction,
     return this->error_statement();
   tree ret;
   if (vals.empty())
-    ret = fold_build1_loc(location, RETURN_EXPR, void_type_node, NULL_TREE);
+    ret = fold_build1_loc(location.gcc_location(), RETURN_EXPR, void_type_node,
+                          NULL_TREE);
   else if (vals.size() == 1)
     {
       tree val = vals.front()->get_tree();
       if (val == error_mark_node)
        return this->error_statement();
-      tree set = fold_build2_loc(location, MODIFY_EXPR, void_type_node,
-                                result, vals.front()->get_tree());
-      ret = fold_build1_loc(location, RETURN_EXPR, void_type_node, set);
+      tree set = fold_build2_loc(location.gcc_location(), MODIFY_EXPR,
+                                 void_type_node, result,
+                                 vals.front()->get_tree());
+      ret = fold_build1_loc(location.gcc_location(), RETURN_EXPR,
+                            void_type_node, set);
     }
   else
     {
@@ -808,20 +813,23 @@ Gcc_backend::return_statement(Bfunction* bfunction,
           p++, field = DECL_CHAIN(field))
        {
          gcc_assert(field != NULL_TREE);
-         tree ref = fold_build3_loc(location, COMPONENT_REF, TREE_TYPE(field),
-                                    rettmp, field, NULL_TREE);
+         tree ref = fold_build3_loc(location.gcc_location(), COMPONENT_REF,
+                                     TREE_TYPE(field), rettmp, field,
+                                     NULL_TREE);
          tree val = (*p)->get_tree();
          if (val == error_mark_node)
            return this->error_statement();
-         tree set = fold_build2_loc(location, MODIFY_EXPR, void_type_node,
+         tree set = fold_build2_loc(location.gcc_location(), MODIFY_EXPR,
+                                     void_type_node,
                                     ref, (*p)->get_tree());
          append_to_statement_list(set, &stmt_list);
        }
       gcc_assert(field == NULL_TREE);
-      tree set = fold_build2_loc(location, MODIFY_EXPR, void_type_node,
+      tree set = fold_build2_loc(location.gcc_location(), MODIFY_EXPR,
+                                 void_type_node,
                                 result, rettmp);
-      tree ret_expr = fold_build1_loc(location, RETURN_EXPR, void_type_node,
-                                     set);
+      tree ret_expr = fold_build1_loc(location.gcc_location(), RETURN_EXPR,
+                                      void_type_node, set);
       append_to_statement_list(ret_expr, &stmt_list);
       ret = stmt_list;
     }
@@ -832,7 +840,7 @@ Gcc_backend::return_statement(Bfunction* bfunction,
 
 Bstatement*
 Gcc_backend::if_statement(Bexpression* condition, Bblock* then_block,
-                         Bblock* else_block, source_location location)
+                         Bblock* else_block, Location location)
 {
   tree cond_tree = condition->get_tree();
   tree then_tree = then_block->get_tree();
@@ -841,8 +849,8 @@ Gcc_backend::if_statement(Bexpression* condition, Bblock* then_block,
       || then_tree == error_mark_node
       || else_tree == error_mark_node)
     return this->error_statement();
-  tree ret = build3_loc(location, COND_EXPR, void_type_node, cond_tree,
-                       then_tree, else_tree);
+  tree ret = build3_loc(location.gcc_location(), COND_EXPR, void_type_node,
+                        cond_tree, then_tree, else_tree);
   return this->make_statement(ret);
 }
 
@@ -853,7 +861,7 @@ Gcc_backend::switch_statement(
     Bexpression* value,
     const std::vector<std::vector<Bexpression*> >& cases,
     const std::vector<Bstatement*>& statements,
-    source_location switch_location)
+    Location switch_location)
 {
   gcc_assert(cases.size() == statements.size());
 
@@ -866,8 +874,8 @@ Gcc_backend::switch_statement(
       if (pc->empty())
        {
          source_location loc = (*ps != NULL
-                                ? EXPR_LOCATION((*ps)->get_tree())
-                                : UNKNOWN_LOCATION);
+                                 ? EXPR_LOCATION((*ps)->get_tree())
+                                 : UNKNOWN_LOCATION);
          tree label = create_artificial_label(loc);
          tree c = build_case_label(NULL_TREE, NULL_TREE, label);
          append_to_statement_list(c, &stmt_list);
@@ -900,8 +908,8 @@ Gcc_backend::switch_statement(
   tree tv = value->get_tree();
   if (tv == error_mark_node)
     return this->error_statement();
-  tree t = build3_loc(switch_location, SWITCH_EXPR, void_type_node,
-                     tv, stmt_list, NULL_TREE);
+  tree t = build3_loc(switch_location.gcc_location(), SWITCH_EXPR,
+                      void_type_node, tv, stmt_list, NULL_TREE);
   return this->make_statement(t);
 }
 
@@ -948,8 +956,8 @@ Gcc_backend::statement_list(const std::vector<Bstatement*>& statements)
 Bblock*
 Gcc_backend::block(Bfunction* function, Bblock* enclosing,
                   const std::vector<Bvariable*>& vars,
-                  source_location start_location,
-                  source_location)
+                  Location start_location,
+                  Location)
 {
   tree block_tree = make_node(BLOCK);
   if (enclosing == NULL)
@@ -1010,8 +1018,9 @@ Gcc_backend::block(Bfunction* function, Bblock* enclosing,
 
   TREE_USED(block_tree) = 1;
 
-  tree bind_tree = build3_loc(start_location, BIND_EXPR, void_type_node,
-                             BLOCK_VARS(block_tree), NULL_TREE, block_tree);
+  tree bind_tree = build3_loc(start_location.gcc_location(), BIND_EXPR,
+                              void_type_node, BLOCK_VARS(block_tree),
+                              NULL_TREE, block_tree);
   TREE_SIDE_EFFECTS(bind_tree) = 1;
 
   return new Bblock(bind_tree);
@@ -1057,7 +1066,7 @@ Gcc_backend::global_variable(const std::string& package_name,
                             Btype* btype,
                             bool is_external,
                             bool is_hidden,
-                            source_location location)
+                            Location location)
 {
   tree type_tree = btype->get_tree();
   if (type_tree == error_mark_node)
@@ -1066,7 +1075,7 @@ Gcc_backend::global_variable(const std::string& package_name,
   std::string var_name(package_name);
   var_name.push_back('.');
   var_name.append(name);
-  tree decl = build_decl(location, VAR_DECL,
+  tree decl = build_decl(location.gcc_location(), VAR_DECL,
                         get_identifier_from_string(var_name),
                         type_tree);
   if (is_external)
@@ -1109,12 +1118,12 @@ Gcc_backend::global_variable_set_init(Bvariable* var, Bexpression* expr)
 Bvariable*
 Gcc_backend::local_variable(Bfunction* function, const std::string& name,
                            Btype* btype, bool is_address_taken,
-                           source_location location)
+                           Location location)
 {
   tree type_tree = btype->get_tree();
   if (type_tree == error_mark_node)
     return this->error_variable();
-  tree decl = build_decl(location, VAR_DECL,
+  tree decl = build_decl(location.gcc_location(), VAR_DECL,
                         get_identifier_from_string(name),
                         type_tree);
   DECL_CONTEXT(decl) = function->get_tree();
@@ -1130,12 +1139,12 @@ Gcc_backend::local_variable(Bfunction* function, const std::string& name,
 Bvariable*
 Gcc_backend::parameter_variable(Bfunction* function, const std::string& name,
                                Btype* btype, bool is_address_taken,
-                               source_location location)
+                               Location location)
 {
   tree type_tree = btype->get_tree();
   if (type_tree == error_mark_node)
     return this->error_variable();
-  tree decl = build_decl(location, PARM_DECL,
+  tree decl = build_decl(location.gcc_location(), PARM_DECL,
                         get_identifier_from_string(name),
                         type_tree);
   DECL_CONTEXT(decl) = function->get_tree();
@@ -1153,7 +1162,7 @@ Bvariable*
 Gcc_backend::temporary_variable(Bfunction* function, Bblock* bblock,
                                Btype* btype, Bexpression* binit,
                                bool is_address_taken,
-                               source_location location,
+                               Location location,
                                Bstatement** pstatement)
 {
   tree type_tree = btype->get_tree();
@@ -1171,7 +1180,7 @@ Gcc_backend::temporary_variable(Bfunction* function, Bblock* bblock,
   else
     {
       gcc_assert(bblock != NULL);
-      var = build_decl(location, VAR_DECL,
+      var = build_decl(location.gcc_location(), VAR_DECL,
                       create_tmp_var_name("GOTMP"),
                       type_tree);
       DECL_ARTIFICIAL(var) = 1;
@@ -1199,12 +1208,14 @@ Gcc_backend::temporary_variable(Bfunction* function, Bblock* bblock,
     }
 
   if (init_tree != NULL_TREE)
-    DECL_INITIAL(var) = fold_convert_loc(location, type_tree, init_tree);
+    DECL_INITIAL(var) = fold_convert_loc(location.gcc_location(), type_tree,
+                                         init_tree);
 
   if (is_address_taken)
     TREE_ADDRESSABLE(var) = 1;
 
-  *pstatement = this->make_statement(build1_loc(location, DECL_EXPR,
+  *pstatement = this->make_statement(build1_loc(location.gcc_location(),
+                                                DECL_EXPR,
                                                void_type_node, var));
   return new Bvariable(var);
 }
@@ -1213,13 +1224,13 @@ Gcc_backend::temporary_variable(Bfunction* function, Bblock* bblock,
 
 Bvariable*
 Gcc_backend::immutable_struct(const std::string& name, bool, Btype* btype,
-                             source_location location)
+                             Location location)
 {
   tree type_tree = btype->get_tree();
   if (type_tree == error_mark_node)
     return this->error_variable();
   gcc_assert(TREE_CODE(type_tree) == RECORD_TYPE);
-  tree decl = build_decl(location, VAR_DECL,
+  tree decl = build_decl(location.gcc_location(), VAR_DECL,
                         get_identifier_from_string(name),
                         build_qualified_type(type_tree, TYPE_QUAL_CONST));
   TREE_STATIC(decl) = 1;
@@ -1241,7 +1252,7 @@ Gcc_backend::immutable_struct(const std::string& name, bool, Btype* btype,
 void
 Gcc_backend::immutable_struct_set_init(Bvariable* var, const std::string&,
                                       bool is_common, Btype*,
-                                      source_location,
+                                      Location,
                                       Bexpression* initializer)
 {
   tree decl = var->get_tree();
@@ -1268,13 +1279,13 @@ Gcc_backend::immutable_struct_set_init(Bvariable* var, const std::string&,
 
 Bvariable*
 Gcc_backend::immutable_struct_reference(const std::string& name, Btype* btype,
-                                       source_location location)
+                                       Location location)
 {
   tree type_tree = btype->get_tree();
   if (type_tree == error_mark_node)
     return this->error_variable();
   gcc_assert(TREE_CODE(type_tree) == RECORD_TYPE);
-  tree decl = build_decl(location, VAR_DECL,
+  tree decl = build_decl(location.gcc_location(), VAR_DECL,
                         get_identifier_from_string(name),
                         build_qualified_type(type_tree, TYPE_QUAL_CONST));
   TREE_READONLY(decl) = 1;
@@ -1290,15 +1301,16 @@ Gcc_backend::immutable_struct_reference(const std::string& name, Btype* btype,
 
 Blabel*
 Gcc_backend::label(Bfunction* function, const std::string& name,
-                  source_location location)
+                  Location location)
 {
   tree decl;
   if (name.empty())
-    decl = create_artificial_label(location);
+    decl = create_artificial_label(location.gcc_location());
   else
     {
       tree id = get_identifier_from_string(name);
-      decl = build_decl(location, LABEL_DECL, id, void_type_node);
+      decl = build_decl(location.gcc_location(), LABEL_DECL, id,
+                        void_type_node);
       DECL_CONTEXT(decl) = function->get_tree();
     }
   return new Blabel(decl);
@@ -1318,23 +1330,25 @@ Gcc_backend::label_definition_statement(Blabel* label)
 // Make a goto statement.
 
 Bstatement*
-Gcc_backend::goto_statement(Blabel* label, source_location location)
+Gcc_backend::goto_statement(Blabel* label, Location location)
 {
   tree lab = label->get_tree();
-  tree ret = fold_build1_loc(location, GOTO_EXPR, void_type_node, lab);
+  tree ret = fold_build1_loc(location.gcc_location(), GOTO_EXPR, void_type_node,
+                             lab);
   return this->make_statement(ret);
 }
 
 // Get the address of a label.
 
 Bexpression*
-Gcc_backend::label_address(Blabel* label, source_location location)
+Gcc_backend::label_address(Blabel* label, Location location)
 {
   tree lab = label->get_tree();
   TREE_USED(lab) = 1;
   TREE_ADDRESSABLE(lab) = 1;
-  tree ret = fold_convert_loc(location, ptr_type_node,
-                             build_fold_addr_expr_loc(location, lab));
+  tree ret = fold_convert_loc(location.gcc_location(), ptr_type_node,
+                             build_fold_addr_expr_loc(location.gcc_location(),
+                                                       lab));
   return this->make_expression(ret);
 }
 
diff --git a/gcc/go/go-linemap.cc b/gcc/go/go-linemap.cc
new file mode 100644 (file)
index 0000000..b41559e
--- /dev/null
@@ -0,0 +1,126 @@
+// go-linemap.cc -- GCC implementation of Linemap.
+
+// Copyright 2011 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-linemap.h"
+
+// This class implements the Linemap interface defined by the
+// frontend.
+
+class Gcc_linemap : public Linemap
+{
+ public:
+  Gcc_linemap()
+    : Linemap(),
+      in_file_(false)
+  { }
+
+  void
+  start_file(const char* file_name, unsigned int line_begin);
+
+  void
+  start_line(unsigned int line_number, unsigned int line_size);
+
+  Location
+  get_location(unsigned int column);
+
+  void
+  stop();
+
+ protected:
+  Location
+  get_predeclared_location();
+
+  Location
+  get_unknown_location();
+
+  bool
+  is_predeclared(Location);
+
+  bool
+  is_unknown(Location);
+
+ private:
+  // Whether we are currently reading a file.
+  bool in_file_;
+};
+
+Linemap* Linemap::instance_ = NULL;
+
+// Start getting locations from a new file.
+
+void
+Gcc_linemap::start_file(const char *file_name, unsigned line_begin)
+{
+  if (this->in_file_)
+    linemap_add(line_table, LC_LEAVE, 0, NULL, 0);
+  linemap_add(line_table, LC_ENTER, 0, file_name, line_begin);
+  this->in_file_ = true;
+}
+
+// Stop getting locations.
+
+void
+Gcc_linemap::stop()
+{
+  linemap_add(line_table, LC_LEAVE, 0, NULL, 0);
+  this->in_file_ = false;
+}
+
+// Start a new line.
+
+void
+Gcc_linemap::start_line(unsigned lineno, unsigned linesize)
+{
+  linemap_line_start(line_table, lineno, linesize);
+}
+
+// Get a location.
+
+Location
+Gcc_linemap::get_location(unsigned column)
+{
+  return Location(linemap_position_for_column(line_table, column));
+}
+
+// Get the unknown location.
+
+Location
+Gcc_linemap::get_unknown_location()
+{
+  return Location(UNKNOWN_LOCATION);
+}
+
+// Get the predeclared location.
+
+Location
+Gcc_linemap::get_predeclared_location()
+{
+  return Location(BUILTINS_LOCATION);
+}
+
+// Return whether a location is the predeclared location.
+
+bool
+Gcc_linemap::is_predeclared(Location loc)
+{
+  return loc.gcc_location() == BUILTINS_LOCATION;
+}
+
+// Return whether a location is the unknown location.
+
+bool
+Gcc_linemap::is_unknown(Location loc)
+{
+  return loc.gcc_location() == UNKNOWN_LOCATION;
+}
+
+// Return the Linemap to use for the gcc backend.
+
+Linemap*
+go_get_linemap()
+{
+  return new Gcc_linemap;
+}
diff --git a/gcc/go/go-location.h b/gcc/go/go-location.h
new file mode 100644 (file)
index 0000000..f2731d9
--- /dev/null
@@ -0,0 +1,45 @@
+// go-location.h -- GCC specific Location declaration.   -*- C++ -*-
+
+// Copyright 2011 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_LOCATION_H
+#define GO_LOCATION_H
+
+#include "go-system.h"
+
+// A location in an input source file.
+
+class Location
+{
+ public:
+  Location()
+    : gcc_loc_(UNKNOWN_LOCATION)
+  { }
+
+  explicit Location(source_location loc)
+    : gcc_loc_(loc)
+  { }
+
+  source_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_;
+};
+
+// The Go frontend requires the ability to compare Locations.
+
+inline bool
+operator<(Location loca, Location locb)
+{
+  return loca.gcc_location() < locb.gcc_location();
+}
+
+#endif // !defined(GO_LOCATION_H)
index b18c18c..24a0132 100644 (file)
@@ -46,14 +46,14 @@ class Backend
   {
     std::string name;
     Btype* btype;
-    source_location location;
+    Location location;
 
     Btyped_identifier()
       : name(), btype(NULL), location(UNKNOWN_LOCATION)
     { }
 
     Btyped_identifier(const std::string& a_name, Btype* a_btype,
-                    source_location a_location)
+                    Location a_location)
       : name(a_name), btype(a_btype), location(a_location)
     { }
   };
@@ -100,7 +100,7 @@ class Backend
   function_type(const Btyped_identifier& receiver,
                const std::vector<Btyped_identifier>& parameters,
                const std::vector<Btyped_identifier>& results,
-               source_location location) = 0;
+               Location location) = 0;
 
   // Get a struct type.
   virtual Btype*
@@ -121,7 +121,7 @@ class Backend
   // parameter to set_placeholder_pointer_type or
   // set_placeholder_function_type.
   virtual Btype*
-  placeholder_pointer_type(const std::string& name, source_location,
+  placeholder_pointer_type(const std::string& name, Location,
                           bool for_function) = 0;
 
   // Fill in a placeholder pointer type as a pointer.  This takes a
@@ -141,7 +141,7 @@ class Backend
   // Create a placeholder struct type.  This is used for a named
   // struct type, as with placeholder_pointer_type.
   virtual Btype*
-  placeholder_struct_type(const std::string& name, source_location) = 0;
+  placeholder_struct_type(const std::string& name, Location) = 0;
 
   // Fill in a placeholder struct type.  This takes a type returned by
   // placeholder_struct_type and arranges for it to become a real
@@ -156,7 +156,7 @@ class Backend
   // type, as with placeholder_pointer_type, to handle cases like
   // type A []*A.
   virtual Btype*
-  placeholder_array_type(const std::string& name, source_location) = 0;
+  placeholder_array_type(const std::string& name, Location) = 0;
 
   // Fill in a placeholder array type.  This takes a type returned by
   // placeholder_array_type and arranges for it to become a real array
@@ -172,7 +172,7 @@ class Backend
   // placeholder_array_type..  (It may be called for a pointer,
   // struct, or array type in a case like "type P *byte; type Q P".)
   virtual Btype*
-  named_type(const std::string& name, Btype*, source_location) = 0;
+  named_type(const std::string& name, Btype*, Location) = 0;
 
   // Create a marker for a circular pointer type.  Go pointer and
   // function types can refer to themselves in ways that are not
@@ -227,18 +227,18 @@ class Backend
   // Create an assignment statement.
   virtual Bstatement*
   assignment_statement(Bexpression* lhs, Bexpression* rhs,
-                      source_location) = 0;
+                      Location) = 0;
 
   // Create a return statement, passing the representation of the
   // function and the list of values to return.
   virtual Bstatement*
   return_statement(Bfunction*, const std::vector<Bexpression*>&,
-                  source_location) = 0;
+                  Location) = 0;
 
   // Create an if statement.  ELSE_BLOCK may be NULL.
   virtual Bstatement*
   if_statement(Bexpression* condition, Bblock* then_block, Bblock* else_block,
-              source_location) = 0;
+              Location) = 0;
 
   // Create a switch statement where the case values are constants.
   // CASES and STATEMENTS must have the same number of entries.  If
@@ -251,7 +251,7 @@ class Backend
   switch_statement(Bexpression* value,
                   const std::vector<std::vector<Bexpression*> >& cases,
                   const std::vector<Bstatement*>& statements,
-                  source_location) = 0;
+                  Location) = 0;
 
   // Create a single statement from two statements.
   virtual Bstatement*
@@ -276,7 +276,7 @@ class Backend
   virtual Bblock*
   block(Bfunction* function, Bblock* enclosing,
        const std::vector<Bvariable*>& vars,
-       source_location start_location, source_location end_location) = 0;
+       Location start_location, Location end_location) = 0;
 
   // Add the statements to a block.  The block is created first.  Then
   // the statements are created.  Then the statements are added to the
@@ -313,7 +313,7 @@ class Backend
                  Btype* btype,
                  bool is_external,
                  bool is_hidden,
-                 source_location location) = 0;
+                 Location location) = 0;
 
   // A global variable will 1) be initialized to zero, or 2) be
   // initialized to a constant value, or 3) be initialized in the init
@@ -335,7 +335,7 @@ class Backend
   // init_statement to set the initial value.
   virtual Bvariable*
   local_variable(Bfunction* function, const std::string& name, Btype* type,
-                bool is_address_taken, source_location location) = 0;
+                bool is_address_taken, Location location) = 0;
 
   // Create a function parameter.  This is an incoming parameter, not
   // a result parameter (result parameters are treated as local
@@ -343,7 +343,7 @@ class Backend
   virtual Bvariable*
   parameter_variable(Bfunction* function, const std::string& name,
                     Btype* type, bool is_address_taken,
-                    source_location location) = 0;
+                    Location location) = 0;
 
   // Create a temporary variable.  A temporary variable has no name,
   // just a type.  We pass in FUNCTION and BLOCK in case they are
@@ -358,7 +358,7 @@ class Backend
   // *PSTATEMENT to a statement which initializes the variable.
   virtual Bvariable*
   temporary_variable(Bfunction*, Bblock*, Btype*, Bexpression* init,
-                    bool address_is_taken, source_location location,
+                    bool address_is_taken, Location location,
                     Bstatement** pstatement) = 0;
 
   // Create a named immutable initialized data structure.  This is
@@ -384,7 +384,7 @@ class Backend
   // set_immutable_struct_initializer.
   virtual Bvariable*
   immutable_struct(const std::string& name, bool is_common, Btype* type,
-                  source_location) = 0;
+                  Location) = 0;
 
   // Set the initial value of a variable created by immutable_struct.
   // The NAME, IS_COMMON, TYPE, and location parameters are the same
@@ -395,7 +395,7 @@ class Backend
   // immutable_struct.
   virtual void
   immutable_struct_set_init(Bvariable*, const std::string& name,
-                           bool is_common, Btype* type, source_location,
+                           bool is_common, Btype* type, Location,
                            Bexpression* initializer) = 0;
 
   // Create a reference to a named immutable initialized data
@@ -405,7 +405,7 @@ class Backend
   // corresponds to an extern const global variable in C.
   virtual Bvariable*
   immutable_struct_reference(const std::string& name, Btype* type,
-                            source_location) = 0;
+                            Location) = 0;
 
   // Labels.
   
@@ -413,7 +413,7 @@ class Backend
   // created by the frontend for a loop construct.  The location is
   // where the the label is defined.
   virtual Blabel*
-  label(Bfunction*, const std::string& name, source_location) = 0;
+  label(Bfunction*, const std::string& name, Location) = 0;
 
   // Create a statement which defines a label.  This statement will be
   // put into the codestream at the point where the label should be
@@ -423,13 +423,13 @@ class Backend
 
   // Create a goto statement to a label.
   virtual Bstatement*
-  goto_statement(Blabel*, source_location) = 0;
+  goto_statement(Blabel*, Location) = 0;
 
   // Create an expression for the address of a label.  This is used to
   // get the return address of a deferred function which may call
   // recover.
   virtual Bexpression*
-  label_address(Blabel*, source_location) = 0;
+  label_address(Blabel*, Location) = 0;
 };
 
 // The backend interface has to define this function.
index a4661b7..572ab36 100644 (file)
@@ -189,8 +189,8 @@ Dataflow::Compare_vars::operator()(const Named_object* no1,
     return false;
 
   // We can have two different variables with the same name.
-  source_location loc1 = no1->location();
-  source_location loc2 = no2->location();
+  Location loc1 = no1->location();
+  Location loc2 = no2->location();
   if (loc1 < loc2)
     return false;
   if (loc1 > loc2)
index 48088ad..0832055 100644 (file)
@@ -279,7 +279,7 @@ Export::write_type(const Type* type)
       if (named_type != NULL)
        {
          // The builtin types should have been predefined.
-         go_assert(named_type->location() != BUILTINS_LOCATION
+         go_assert(!Linemap::is_predeclared_location(named_type->location())
                     || (named_type->named_object()->package()->name()
                         == "unsafe"));
          named_object = named_type->named_object();
index e308b9a..a2cf33e 100644 (file)
@@ -41,7 +41,7 @@ extern "C"
 // Class Expression.
 
 Expression::Expression(Expression_classification classification,
-                      source_location location)
+                      Location location)
   : classification_(classification), location_(location)
 {
 }
@@ -203,7 +203,7 @@ Expression::determine_type_no_context()
 tree
 Expression::convert_for_assignment(Translate_context* context, Type* lhs_type,
                                   Type* rhs_type, tree rhs_tree,
-                                  source_location location)
+                                  Location location)
 {
   if (lhs_type == rhs_type)
     return rhs_tree;
@@ -283,7 +283,7 @@ Expression::convert_for_assignment(Translate_context* context, Type* lhs_type,
           || INTEGRAL_TYPE_P(lhs_type_tree)
           || SCALAR_FLOAT_TYPE_P(lhs_type_tree)
           || COMPLEX_FLOAT_TYPE_P(lhs_type_tree))
-    return fold_convert_loc(location, lhs_type_tree, rhs_tree);
+    return fold_convert_loc(location.gcc_location(), lhs_type_tree, rhs_tree);
   else if (TREE_CODE(lhs_type_tree) == RECORD_TYPE
           && TREE_CODE(TREE_TYPE(rhs_tree)) == RECORD_TYPE)
     {
@@ -291,8 +291,8 @@ Expression::convert_for_assignment(Translate_context* context, Type* lhs_type,
       // gotten here.
       go_assert(int_size_in_bytes(lhs_type_tree)
                 == int_size_in_bytes(TREE_TYPE(rhs_tree)));
-      return fold_build1_loc(location, VIEW_CONVERT_EXPR, lhs_type_tree,
-                            rhs_tree);
+      return fold_build1_loc(location.gcc_location(), VIEW_CONVERT_EXPR,
+                             lhs_type_tree, rhs_tree);
     }
   else
     {
@@ -307,7 +307,7 @@ Expression::convert_for_assignment(Translate_context* context, Type* lhs_type,
 tree
 Expression::convert_type_to_interface(Translate_context* context,
                                      Type* lhs_type, Type* rhs_type,
-                                     tree rhs_tree, source_location location)
+                                     tree rhs_tree, Location location)
 {
   Gogo* gogo = context->gogo();
   Interface_type* lhs_interface_type = lhs_type->interface_type();
@@ -356,8 +356,8 @@ Expression::convert_type_to_interface(Translate_context* context,
        method_table =
          rhs_named_type->interface_method_table(gogo, lhs_interface_type,
                                                 is_pointer);
-      first_field_value = fold_convert_loc(location, const_ptr_type_node,
-                                          method_table);
+      first_field_value = fold_convert_loc(location.gcc_location(),
+                                           const_ptr_type_node, method_table);
     }
   if (first_field_value == error_mark_node)
     return error_mark_node;
@@ -371,7 +371,8 @@ Expression::convert_type_to_interface(Translate_context* context,
   go_assert(strcmp(IDENTIFIER_POINTER(DECL_NAME(field)),
                    (lhs_is_empty ? "__type_descriptor" : "__methods")) == 0);
   elt->index = field;
-  elt->value = fold_convert_loc(location, TREE_TYPE(field), first_field_value);
+  elt->value = fold_convert_loc(location.gcc_location(), TREE_TYPE(field),
+                                first_field_value);
 
   elt = VEC_quick_push(constructor_elt, init, NULL);
   field = DECL_CHAIN(field);
@@ -392,16 +393,17 @@ Expression::convert_type_to_interface(Translate_context* context,
   tree object_size = TYPE_SIZE_UNIT(TREE_TYPE(rhs_tree));
 
   tree space = gogo->allocate_memory(rhs_type, object_size, location);
-  space = fold_convert_loc(location, build_pointer_type(TREE_TYPE(rhs_tree)),
-                          space);
+  space = fold_convert_loc(location.gcc_location(),
+                           build_pointer_type(TREE_TYPE(rhs_tree)), space);
   space = save_expr(space);
 
-  tree ref = build_fold_indirect_ref_loc(location, space);
+  tree ref = build_fold_indirect_ref_loc(location.gcc_location(), space);
   TREE_THIS_NOTRAP(ref) = 1;
-  tree set = fold_build2_loc(location, MODIFY_EXPR, void_type_node,
-                            ref, rhs_tree);
+  tree set = fold_build2_loc(location.gcc_location(), MODIFY_EXPR,
+                             void_type_node, ref, rhs_tree);
 
-  elt->value = fold_convert_loc(location, TREE_TYPE(field), space);
+  elt->value = fold_convert_loc(location.gcc_location(), TREE_TYPE(field),
+                                space);
 
   return build2(COMPOUND_EXPR, lhs_type_tree, set,
                build_constructor(lhs_type_tree, init));
@@ -414,7 +416,7 @@ Expression::convert_type_to_interface(Translate_context* context,
 tree
 Expression::get_interface_type_descriptor(Translate_context*,
                                          Type* rhs_type, tree rhs_tree,
-                                         source_location location)
+                                         Location location)
 {
   tree rhs_type_tree = TREE_TYPE(rhs_tree);
   go_assert(TREE_CODE(rhs_type_tree) == RECORD_TYPE);
@@ -432,18 +434,20 @@ Expression::get_interface_type_descriptor(Translate_context*,
             == 0);
   go_assert(POINTER_TYPE_P(TREE_TYPE(v)));
   v = save_expr(v);
-  tree v1 = build_fold_indirect_ref_loc(location, v);
+  tree v1 = build_fold_indirect_ref_loc(location.gcc_location(), v);
   go_assert(TREE_CODE(TREE_TYPE(v1)) == RECORD_TYPE);
   tree f = TYPE_FIELDS(TREE_TYPE(v1));
   go_assert(strcmp(IDENTIFIER_POINTER(DECL_NAME(f)), "__type_descriptor")
             == 0);
   v1 = build3(COMPONENT_REF, TREE_TYPE(f), v1, f, NULL_TREE);
 
-  tree eq = fold_build2_loc(location, EQ_EXPR, boolean_type_node, v,
-                           fold_convert_loc(location, TREE_TYPE(v),
-                                            null_pointer_node));
-  tree n = fold_convert_loc(location, TREE_TYPE(v1), null_pointer_node);
-  return fold_build3_loc(location, COND_EXPR, TREE_TYPE(v1),
+  tree eq = fold_build2_loc(location.gcc_location(), EQ_EXPR, boolean_type_node,
+                            v, fold_convert_loc(location.gcc_location(),
+                                                TREE_TYPE(v),
+                                                null_pointer_node));
+  tree n = fold_convert_loc(location.gcc_location(), TREE_TYPE(v1),
+                            null_pointer_node);
+  return fold_build3_loc(location.gcc_location(), COND_EXPR, TREE_TYPE(v1),
                         eq, n, v1);
 }
 
@@ -454,7 +458,7 @@ tree
 Expression::convert_interface_to_interface(Translate_context* context,
                                           Type *lhs_type, Type *rhs_type,
                                           tree rhs_tree, bool for_type_guard,
-                                          source_location location)
+                                          Location location)
 {
   Gogo* gogo = context->gogo();
   Interface_type* lhs_interface_type = lhs_type->interface_type();
@@ -509,7 +513,8 @@ Expression::convert_interface_to_interface(Translate_context* context,
        return error_mark_node;
       // This will panic if the interface conversion fails.
       TREE_NOTHROW(assert_interface_decl) = 0;
-      elt->value = fold_convert_loc(location, TREE_TYPE(field), call);
+      elt->value = fold_convert_loc(location.gcc_location(), TREE_TYPE(field),
+                                    call);
     }
   else if (lhs_is_empty)
     {
@@ -542,7 +547,8 @@ Expression::convert_interface_to_interface(Translate_context* context,
        return error_mark_node;
       // This will panic if the interface conversion fails.
       TREE_NOTHROW(convert_interface_decl) = 0;
-      elt->value = fold_convert_loc(location, TREE_TYPE(field), call);
+      elt->value = fold_convert_loc(location.gcc_location(), TREE_TYPE(field),
+                                    call);
     }
 
   // The second field is simply the object pointer.
@@ -568,7 +574,7 @@ Expression::convert_interface_to_interface(Translate_context* context,
 tree
 Expression::convert_interface_to_type(Translate_context* context,
                                      Type *lhs_type, Type* rhs_type,
-                                     tree rhs_tree, source_location location)
+                                     tree rhs_tree, Location location)
 {
   Gogo* gogo = context->gogo();
   tree rhs_type_tree = TREE_TYPE(rhs_tree);
@@ -621,12 +627,13 @@ Expression::convert_interface_to_type(Translate_context* context,
   // Otherwise it points to the value.
   if (lhs_type->points_to() == NULL)
     {
-      val = fold_convert_loc(location, build_pointer_type(lhs_type_tree), val);
-      val = build_fold_indirect_ref_loc(location, val);
+      val = fold_convert_loc(location.gcc_location(),
+                             build_pointer_type(lhs_type_tree), val);
+      val = build_fold_indirect_ref_loc(location.gcc_location(), val);
     }
 
   return build2(COMPOUND_EXPR, lhs_type_tree, call,
-               fold_convert_loc(location, lhs_type_tree, val));
+               fold_convert_loc(location.gcc_location(), lhs_type_tree, val));
 }
 
 // Convert an expression to a tree.  This is implemented by the child
@@ -748,14 +755,14 @@ Expression::complex_constant_tree(mpfr_t real, mpfr_t imag, tree type)
 
 tree
 Expression::check_bounds(tree val, tree bound_type, tree sofar,
-                        source_location loc)
+                        Location loc)
 {
   tree val_type = TREE_TYPE(val);
   tree ret = NULL_TREE;
 
   if (!TYPE_UNSIGNED(val_type))
     {
-      ret = fold_build2_loc(loc, LT_EXPR, boolean_type_node, val,
+      ret = fold_build2_loc(loc.gcc_location(), LT_EXPR, boolean_type_node, val,
                            build_int_cst(val_type, 0));
       if (ret == boolean_false_node)
        ret = NULL_TREE;
@@ -770,15 +777,16 @@ Expression::check_bounds(tree val, tree bound_type, tree sofar,
          && !TYPE_UNSIGNED(bound_type)))
     {
       tree max = TYPE_MAX_VALUE(bound_type);
-      tree big = fold_build2_loc(loc, GT_EXPR, boolean_type_node, val,
-                                fold_convert_loc(loc, val_type, max));
+      tree big = fold_build2_loc(loc.gcc_location(), GT_EXPR, boolean_type_node,
+                                 val, fold_convert_loc(loc.gcc_location(),
+                                                       val_type, max));
       if (big == boolean_false_node)
        ;
       else if (ret == NULL_TREE)
        ret = big;
       else
-       ret = fold_build2_loc(loc, TRUTH_OR_EXPR, boolean_type_node,
-                             ret, big);
+       ret = fold_build2_loc(loc.gcc_location(), TRUTH_OR_EXPR,
+                              boolean_type_node, ret, big);
     }
 
   if (ret == NULL_TREE)
@@ -786,7 +794,7 @@ Expression::check_bounds(tree val, tree bound_type, tree sofar,
   else if (sofar == NULL_TREE)
     return ret;
   else
-    return fold_build2_loc(loc, TRUTH_OR_EXPR, boolean_type_node,
+    return fold_build2_loc(loc.gcc_location(), TRUTH_OR_EXPR, boolean_type_node,
                           sofar, ret);
 }
 
@@ -801,7 +809,7 @@ Expression::dump_expression(Ast_dump_context* ast_dump_context) const
 class Error_expression : public Expression
 {
  public:
-  Error_expression(source_location location)
+  Error_expression(Location location)
     : Expression(EXPRESSION_ERROR, location)
   { }
 
@@ -869,7 +877,7 @@ Error_expression::do_dump_expression(Ast_dump_context* ast_dump_context) const
 }
 
 Expression*
-Expression::make_error(source_location location)
+Expression::make_error(Location location)
 {
   return new Error_expression(location);
 }
@@ -881,7 +889,7 @@ class
 Type_expression : public Expression
 {
  public:
-  Type_expression(Type* type, source_location location)
+  Type_expression(Type* type, Location location)
     : Expression(EXPRESSION_TYPE, location),
       type_(type)
   { }
@@ -925,7 +933,7 @@ Type_expression::do_dump_expression(Ast_dump_context* ast_dump_context) const
 }
 
 Expression*
-Expression::make_type(Type* type, source_location location)
+Expression::make_type(Type* type, Location location)
 {
   return new Type_expression(type, location);
 }
@@ -1037,7 +1045,7 @@ Var_expression::do_get_tree(Translate_context* context)
     go_unreachable();
   if (is_in_heap)
     {
-      ret = build_fold_indirect_ref_loc(this->location(), ret);
+      ret = build_fold_indirect_ref_loc(this->location().gcc_location(), ret);
       TREE_THIS_NOTRAP(ret) = 1;
     }
   return ret;
@@ -1054,7 +1062,7 @@ Var_expression::do_dump_expression(Ast_dump_context* ast_dump_context) const
 // Make a reference to a variable in an expression.
 
 Expression*
-Expression::make_var_reference(Named_object* var, source_location location)
+Expression::make_var_reference(Named_object* var, Location location)
 {
   if (var->is_sink())
     return Expression::make_sink(location);
@@ -1104,7 +1112,7 @@ Temporary_reference_expression::do_get_tree(Translate_context* context)
     {
       Btype* type_btype = this->type()->base()->get_backend(context->gogo());
       tree type_tree = type_to_tree(type_btype);
-      ret = fold_convert_loc(this->location(), type_tree, ret);
+      ret = fold_convert_loc(this->location().gcc_location(), type_tree, ret);
     }
   return ret;
 }
@@ -1122,7 +1130,7 @@ Temporary_reference_expression::do_dump_expression(
 
 Temporary_reference_expression*
 Expression::make_temporary_reference(Temporary_statement* statement,
-                                    source_location location)
+                                    Location location)
 {
   return new Temporary_reference_expression(statement, location);
 }
@@ -1132,7 +1140,7 @@ Expression::make_temporary_reference(Temporary_statement* statement,
 class Sink_expression : public Expression
 {
  public:
-  Sink_expression(source_location location)
+  Sink_expression(Location location)
     : Expression(EXPRESSION_SINK, location),
       type_(NULL), var_(NULL_TREE)
   { }
@@ -1210,7 +1218,7 @@ Sink_expression::do_dump_expression(Ast_dump_context* ast_dump_context) const
 // Make a sink expression.
 
 Expression*
-Expression::make_sink(source_location location)
+Expression::make_sink(Location location)
 {
   return new Sink_expression(location);
 }
@@ -1285,7 +1293,7 @@ Func_expression::get_tree_without_closure(Gogo* gogo)
   if (fndecl == error_mark_node)
     return error_mark_node;
 
-  return build_fold_addr_expr_loc(this->location(), fndecl);
+  return build_fold_addr_expr_loc(this->location().gcc_location(), fndecl);
 }
 
 // Get the tree for a function expression.  This is used when we take
@@ -1357,7 +1365,7 @@ Func_expression::do_dump_expression(Ast_dump_context* ast_dump_context) const
 
 Expression*
 Expression::make_func_reference(Named_object* function, Expression* closure,
-                               source_location location)
+                               Location location)
 {
   return new Func_expression(function, closure, location);
 }
@@ -1377,7 +1385,7 @@ Unknown_expression::name() const
 Expression*
 Unknown_expression::do_lower(Gogo*, Named_object*, Statement_inserter*, int)
 {
-  source_location location = this->location();
+  Location location = this->location();
   Named_object* no = this->named_object_;
   Named_object* real;
   if (!no->is_unknown())
@@ -1433,7 +1441,7 @@ Unknown_expression::do_dump_expression(Ast_dump_context* ast_dump_context) const
 // Make a reference to an unknown name.
 
 Expression*
-Expression::make_unknown_reference(Named_object* no, source_location location)
+Expression::make_unknown_reference(Named_object* no, Location location)
 {
   return new Unknown_expression(no, location);
 }
@@ -1443,7 +1451,7 @@ Expression::make_unknown_reference(Named_object* no, source_location location)
 class Boolean_expression : public Expression
 {
  public:
-  Boolean_expression(bool val, source_location location)
+  Boolean_expression(bool val, Location location)
     : Expression(EXPRESSION_BOOLEAN, location),
       val_(val), type_(NULL)
   { }
@@ -1528,7 +1536,7 @@ Boolean_expression::do_import(Import* imp)
 // Make a boolean expression.
 
 Expression*
-Expression::make_boolean(bool val, source_location location)
+Expression::make_boolean(bool val, Location location)
 {
   return new Boolean_expression(val, location);
 }
@@ -1665,7 +1673,7 @@ String_expression::do_dump_expression(Ast_dump_context* ast_dump_context) const
 // Make a string expression.
 
 Expression*
-Expression::make_string(const std::string& val, source_location location)
+Expression::make_string(const std::string& val, Location location)
 {
   return new String_expression(val, location);
 }
@@ -1675,7 +1683,7 @@ Expression::make_string(const std::string& val, source_location location)
 class Integer_expression : public Expression
 {
  public:
-  Integer_expression(const mpz_t* val, Type* type, source_location location)
+  Integer_expression(const mpz_t* val, Type* type, Location location)
     : Expression(EXPRESSION_INTEGER, location),
       type_(type)
   { mpz_init_set(this->val_, *val); }
@@ -1685,7 +1693,7 @@ class Integer_expression : public Expression
 
   // Return whether VAL fits in the type.
   static bool
-  check_constant(mpz_t val, Type*, source_location);
+  check_constant(mpz_t val, Type*, Location);
 
   // Write VAL to string dump.
   static void
@@ -1778,7 +1786,7 @@ Integer_expression::do_determine_type(const Type_context* context)
 
 bool
 Integer_expression::check_constant(mpz_t val, Type* type,
-                                  source_location location)
+                                  Location location)
 {
   if (type == NULL)
     return true;
@@ -1985,7 +1993,7 @@ Integer_expression::do_dump_expression(Ast_dump_context* ast_dump_context) const
 
 Expression*
 Expression::make_integer(const mpz_t* val, Type* type,
-                        source_location location)
+                        Location location)
 {
   return new Integer_expression(val, type, location);
 }
@@ -1995,7 +2003,7 @@ Expression::make_integer(const mpz_t* val, Type* type,
 class Float_expression : public Expression
 {
  public:
-  Float_expression(const mpfr_t* val, Type* type, source_location location)
+  Float_expression(const mpfr_t* val, Type* type, Location location)
     : Expression(EXPRESSION_FLOAT, location),
       type_(type)
   {
@@ -2008,7 +2016,7 @@ class Float_expression : public Expression
 
   // Return whether VAL fits in the type.
   static bool
-  check_constant(mpfr_t val, Type*, source_location);
+  check_constant(mpfr_t val, Type*, Location);
 
   // Write VAL to export data.
   static void
@@ -2111,7 +2119,7 @@ Float_expression::do_determine_type(const Type_context* context)
 
 bool
 Float_expression::check_constant(mpfr_t val, Type* type,
-                                source_location location)
+                                Location location)
 {
   if (type == NULL)
     return true;
@@ -2237,7 +2245,7 @@ Float_expression::do_dump_expression(Ast_dump_context* ast_dump_context) const
 // Make a float expression.
 
 Expression*
-Expression::make_float(const mpfr_t* val, Type* type, source_location location)
+Expression::make_float(const mpfr_t* val, Type* type, Location location)
 {
   return new Float_expression(val, type, location);
 }
@@ -2248,7 +2256,7 @@ class Complex_expression : public Expression
 {
  public:
   Complex_expression(const mpfr_t* real, const mpfr_t* imag, Type* type,
-                    source_location location)
+                    Location location)
     : Expression(EXPRESSION_COMPLEX, location),
       type_(type)
   {
@@ -2262,7 +2270,7 @@ class Complex_expression : public Expression
 
   // Return whether REAL/IMAG fits in the type.
   static bool
-  check_constant(mpfr_t real, mpfr_t imag, Type*, source_location);
+  check_constant(mpfr_t real, mpfr_t imag, Type*, Location);
 
   // Write REAL/IMAG to string dump.
   static void
@@ -2373,7 +2381,7 @@ Complex_expression::do_determine_type(const Type_context* context)
 
 bool
 Complex_expression::check_constant(mpfr_t real, mpfr_t imag, Type* type,
-                                  source_location location)
+                                  Location location)
 {
   if (type == NULL)
     return true;
@@ -2489,7 +2497,7 @@ Complex_expression::do_dump_expression(Ast_dump_context* ast_dump_context) const
 
 Expression*
 Expression::make_complex(const mpfr_t* real, const mpfr_t* imag, Type* type,
-                        source_location location)
+                        Location location)
 {
   return new Complex_expression(real, imag, type, location);
 }
@@ -2525,7 +2533,7 @@ class Find_named_object : public Traverse
 class Const_expression : public Expression
 {
  public:
-  Const_expression(Named_object* constant, source_location location)
+  Const_expression(Named_object* constant, Location location)
     : Expression(EXPRESSION_CONST_REFERENCE, location),
       constant_(constant), type_(NULL), seen_(false)
   { }
@@ -2982,7 +2990,7 @@ Const_expression::do_dump_expression(Ast_dump_context* ast_dump_context) const
 
 Expression*
 Expression::make_const_reference(Named_object* constant,
-                                source_location location)
+                                Location location)
 {
   return new Const_expression(constant, location);
 }
@@ -3028,7 +3036,7 @@ Find_named_object::expression(Expression** pexpr)
 class Nil_expression : public Expression
 {
  public:
-  Nil_expression(source_location location)
+  Nil_expression(Location location)
     : Expression(EXPRESSION_NIL, location)
   { }
 
@@ -3077,7 +3085,7 @@ Nil_expression::do_import(Import* imp)
 // Make a nil expression.
 
 Expression*
-Expression::make_nil(source_location location)
+Expression::make_nil(Location location)
 {
   return new Nil_expression(location);
 }
@@ -3090,7 +3098,7 @@ Expression::make_nil(source_location location)
 class Iota_expression : public Parser_expression
 {
  public:
-  Iota_expression(source_location location)
+  Iota_expression(Location location)
     : Parser_expression(EXPRESSION_IOTA, location)
   { }
 
@@ -3115,7 +3123,7 @@ class Iota_expression : public Parser_expression
 Expression*
 Expression::make_iota()
 {
-  static Iota_expression iota_expression(UNKNOWN_LOCATION);
+  static Iota_expression iota_expression(Linemap::unknown_location());
   return &iota_expression;
 }
 
@@ -3125,7 +3133,7 @@ class Type_conversion_expression : public Expression
 {
  public:
   Type_conversion_expression(Type* type, Expression* expr,
-                            source_location location)
+                            Location location)
     : Expression(EXPRESSION_CONVERSION, location),
       type_(type), expr_(expr), may_convert_function_types_(false)
   { }
@@ -3234,7 +3242,7 @@ Type_conversion_expression::do_lower(Gogo*, Named_object*,
 {
   Type* type = this->type_;
   Expression* val = this->expr_;
-  source_location location = this->location();
+  Location location = this->location();
 
   if (type->integer_type() != NULL)
     {
@@ -3632,7 +3640,8 @@ Type_conversion_expression::do_get_tree(Translate_context* context)
       tree valptr = fold_convert(const_ptr_type_node,
                                 a->value_pointer_tree(gogo, expr_tree));
       tree len = a->length_tree(gogo, expr_tree);
-      len = fold_convert_loc(this->location(), integer_type_node, len);
+      len = fold_convert_loc(this->location().gcc_location(), integer_type_node,
+                             len);
       if (e->integer_type()->is_unsigned()
          && e->integer_type()->bits() == 8)
        {
@@ -3702,7 +3711,8 @@ Type_conversion_expression::do_get_tree(Translate_context* context)
   else if (this->may_convert_function_types_
           && type->function_type() != NULL
           && expr_type->function_type() != NULL)
-    ret = fold_convert_loc(this->location(), type_tree, expr_tree);
+    ret = fold_convert_loc(this->location().gcc_location(), type_tree,
+                           expr_tree);
   else
     ret = Expression::convert_for_assignment(context, type, expr_type,
                                             expr_tree, this->location());
@@ -3750,7 +3760,7 @@ Type_conversion_expression::do_dump_expression(
 // Make a type cast expression.
 
 Expression*
-Expression::make_cast(Type* type, Expression* val, source_location location)
+Expression::make_cast(Type* type, Expression* val, Location location)
 {
   if (type->is_error_type() || val->is_error_expression())
     return Expression::make_error(location);
@@ -3763,7 +3773,7 @@ class Unsafe_type_conversion_expression : public Expression
 {
  public:
   Unsafe_type_conversion_expression(Type* type, Expression* expr,
-                                   source_location location)
+                                   Location location)
     : Expression(EXPRESSION_UNSAFE_CONVERSION, location),
       type_(type), expr_(expr)
   { }
@@ -3827,7 +3837,7 @@ Unsafe_type_conversion_expression::do_get_tree(Translate_context* context)
   if (type_tree == error_mark_node || expr_tree == error_mark_node)
     return error_mark_node;
 
-  source_location loc = this->location();
+  Location loc = this->location();
 
   bool use_view_convert = false;
   if (t->is_slice_type())
@@ -3873,9 +3883,10 @@ Unsafe_type_conversion_expression::do_get_tree(Translate_context* context)
     go_unreachable();
 
   if (use_view_convert)
-    return fold_build1_loc(loc, VIEW_CONVERT_EXPR, type_tree, expr_tree);
+    return fold_build1_loc(loc.gcc_location(), VIEW_CONVERT_EXPR, type_tree,
+                           expr_tree);
   else
-    return fold_convert_loc(loc, type_tree, expr_tree);
+    return fold_convert_loc(loc.gcc_location(), type_tree, expr_tree);
 }
 
 // Dump ast representation for an unsafe type conversion expression.
@@ -3894,7 +3905,7 @@ Unsafe_type_conversion_expression::do_dump_expression(
 
 Expression*
 Expression::make_unsafe_cast(Type* type, Expression* expr,
-                            source_location location)
+                            Location location)
 {
   return new Unsafe_type_conversion_expression(type, expr, location);
 }
@@ -3904,7 +3915,7 @@ Expression::make_unsafe_cast(Type* type, Expression* expr,
 class Unary_expression : public Expression
 {
  public:
-  Unary_expression(Operator op, Expression* expr, source_location location)
+  Unary_expression(Operator op, Expression* expr, Location location)
     : Expression(EXPRESSION_UNARY, location),
       op_(op), escapes_(true), create_temp_(false), expr_(expr)
   { }
@@ -3940,7 +3951,7 @@ class Unary_expression : public Expression
   // could be done, false if not.
   static bool
   eval_integer(Operator op, Type* utype, mpz_t uval, mpz_t val,
-              source_location);
+              Location);
 
   // Apply unary opcode OP to UVAL, setting VAL.  Return true if this
   // could be done, false if not.
@@ -4029,7 +4040,7 @@ class Unary_expression : public Expression
 Expression*
 Unary_expression::do_lower(Gogo*, Named_object*, Statement_inserter*, int)
 {
-  source_location loc = this->location();
+  Location loc = this->location();
   Operator op = this->op_;
   Expression* expr = this->expr_;
 
@@ -4170,7 +4181,7 @@ Unary_expression::do_is_constant() const
 
 bool
 Unary_expression::eval_integer(Operator op, Type* utype, mpz_t uval, mpz_t val,
-                              source_location location)
+                              Location location)
 {
   switch (op)
     {
@@ -4470,7 +4481,7 @@ Unary_expression::do_get_tree(Translate_context* context)
   if (expr == error_mark_node)
     return error_mark_node;
 
-  source_location loc = this->location();
+  Location loc = this->location();
   switch (this->op_)
     {
     case OPERATOR_PLUS:
@@ -4482,7 +4493,7 @@ Unary_expression::do_get_tree(Translate_context* context)
        tree compute_type = excess_precision_type(type);
        if (compute_type != NULL_TREE)
          expr = ::convert(compute_type, expr);
-       tree ret = fold_build1_loc(loc, NEGATE_EXPR,
+       tree ret = fold_build1_loc(loc.gcc_location(), NEGATE_EXPR,
                                   (compute_type != NULL_TREE
                                    ? compute_type
                                    : type),
@@ -4494,13 +4505,15 @@ Unary_expression::do_get_tree(Translate_context* context)
 
     case OPERATOR_NOT:
       if (TREE_CODE(TREE_TYPE(expr)) == BOOLEAN_TYPE)
-       return fold_build1_loc(loc, TRUTH_NOT_EXPR, TREE_TYPE(expr), expr);
+       return fold_build1_loc(loc.gcc_location(), TRUTH_NOT_EXPR,
+                               TREE_TYPE(expr), expr);
       else
-       return fold_build2_loc(loc, NE_EXPR, boolean_type_node, expr,
-                              build_int_cst(TREE_TYPE(expr), 0));
+       return fold_build2_loc(loc.gcc_location(), NE_EXPR, boolean_type_node,
+                               expr, build_int_cst(TREE_TYPE(expr), 0));
 
     case OPERATOR_XOR:
-      return fold_build1_loc(loc, BIT_NOT_EXPR, TREE_TYPE(expr), expr);
+      return fold_build1_loc(loc.gcc_location(), BIT_NOT_EXPR, TREE_TYPE(expr),
+                             expr);
 
     case OPERATOR_AND:
       if (!this->create_temp_)
@@ -4516,7 +4529,7 @@ Unary_expression::do_get_tree(Translate_context* context)
       // Build a decl for a constant constructor.
       if (TREE_CODE(expr) == CONSTRUCTOR && TREE_CONSTANT(expr))
        {
-         tree decl = build_decl(this->location(), VAR_DECL,
+         tree decl = build_decl(this->location().gcc_location(), VAR_DECL,
                                 create_tmp_var_name("C"), TREE_TYPE(expr));
          DECL_EXTERNAL(decl) = 0;
          TREE_PUBLIC(decl) = 0;
@@ -4540,13 +4553,14 @@ Unary_expression::do_get_tree(Translate_context* context)
          DECL_IGNORED_P(tmp) = 1;
          DECL_INITIAL(tmp) = expr;
          TREE_ADDRESSABLE(tmp) = 1;
-         return build2_loc(loc, COMPOUND_EXPR,
+         return build2_loc(loc.gcc_location(), COMPOUND_EXPR,
                            build_pointer_type(TREE_TYPE(expr)),
-                           build1_loc(loc, DECL_EXPR, void_type_node, tmp),
-                           build_fold_addr_expr_loc(loc, tmp));
+                           build1_loc(loc.gcc_location(), DECL_EXPR,
+                                       void_type_node, tmp),
+                           build_fold_addr_expr_loc(loc.gcc_location(), tmp));
        }
 
-      return build_fold_addr_expr_loc(loc, expr);
+      return build_fold_addr_expr_loc(loc.gcc_location(), expr);
 
     case OPERATOR_MULT:
       {
@@ -4561,15 +4575,18 @@ Unary_expression::do_get_tree(Translate_context* context)
          {
            if (!DECL_P(expr))
              expr = save_expr(expr);
-           tree compare = fold_build2_loc(loc, EQ_EXPR, boolean_type_node,
+           tree compare = fold_build2_loc(loc.gcc_location(), EQ_EXPR,
+                                           boolean_type_node,
                                           expr,
                                           fold_convert(TREE_TYPE(expr),
                                                        null_pointer_node));
            tree crash = Gogo::runtime_error(RUNTIME_ERROR_NIL_DEREFERENCE,
                                             loc);
-           expr = fold_build2_loc(loc, COMPOUND_EXPR, TREE_TYPE(expr),
-                                  build3(COND_EXPR, void_type_node,
-                                         compare, crash, NULL_TREE),
+           expr = fold_build2_loc(loc.gcc_location(), COMPOUND_EXPR,
+                                   TREE_TYPE(expr), build3(COND_EXPR,
+                                                           void_type_node,
+                                                           compare, crash,
+                                                           NULL_TREE),
                                   expr);
          }
 
@@ -4579,10 +4596,11 @@ Unary_expression::do_get_tree(Translate_context* context)
          {
            Type* pt = this->expr_->type()->points_to();
            tree ind = type_to_tree(pt->get_backend(context->gogo()));
-           expr = fold_convert_loc(loc, build_pointer_type(ind), expr);
+           expr = fold_convert_loc(loc.gcc_location(),
+                                    build_pointer_type(ind), expr);
          }
 
-       return build_fold_indirect_ref_loc(loc, expr);
+       return build_fold_indirect_ref_loc(loc.gcc_location(), expr);
       }
 
     default:
@@ -4659,7 +4677,7 @@ Unary_expression::do_dump_expression(Ast_dump_context* ast_dump_context) const
 // Make a unary expression.
 
 Expression*
-Expression::make_unary(Operator op, Expression* expr, source_location location)
+Expression::make_unary(Operator op, Expression* expr, Location location)
 {
   return new Unary_expression(op, expr, location);
 }
@@ -4807,7 +4825,7 @@ Binary_expression::compare_complex(Operator op, Type* type,
 bool
 Binary_expression::eval_integer(Operator op, Type* left_type, mpz_t left_val,
                                Type* right_type, mpz_t right_val,
-                               source_location location, mpz_t val)
+                               Location location, mpz_t val)
 {
   bool is_shift_op = false;
   switch (op)
@@ -4947,7 +4965,7 @@ Binary_expression::eval_integer(Operator op, Type* left_type, mpz_t left_val,
 bool
 Binary_expression::eval_float(Operator op, Type* left_type, mpfr_t left_val,
                              Type* right_type, mpfr_t right_val,
-                             mpfr_t val, source_location location)
+                             mpfr_t val, Location location)
 {
   switch (op)
     {
@@ -5030,7 +5048,7 @@ Binary_expression::eval_complex(Operator op, Type* left_type,
                                Type *right_type,
                                mpfr_t right_real, mpfr_t right_imag,
                                mpfr_t real, mpfr_t imag,
-                               source_location location)
+                               Location location)
 {
   switch (op)
     {
@@ -5391,7 +5409,7 @@ Binary_expression::eval_complex(Operator op, Type* left_type,
 Expression*
 Binary_expression::do_lower(Gogo*, Named_object*, Statement_inserter*, int)
 {
-  source_location location = this->location();
+  Location location = this->location();
   Operator op = this->op_;
   Expression* left = this->left_;
   Expression* right = this->right_;
@@ -6048,7 +6066,7 @@ Binary_expression::do_determine_type(const Type_context* context)
 
 bool
 Binary_expression::check_operator_type(Operator op, Type* type,
-                                      source_location location)
+                                      Location location)
 {
   switch (op)
     {
@@ -6222,7 +6240,7 @@ Binary_expression::do_check_types(Gogo*)
                {
                  this->report_error(_("negative shift count"));
                  mpz_set_ui(val, 0);
-                 source_location rloc = this->right_->location();
+                 Location rloc = this->right_->location();
                  this->right_ = Expression::make_integer(&val, right_type,
                                                          rloc);
                }
@@ -6354,12 +6372,13 @@ Binary_expression::do_get_tree(Translate_context* context)
          if (eval_saved == NULL_TREE)
            eval_saved = right;
          else
-           eval_saved = fold_build2_loc(this->location(), COMPOUND_EXPR,
+           eval_saved = fold_build2_loc(this->location().gcc_location(),
+                                         COMPOUND_EXPR,
                                         void_type_node, eval_saved, right);
        }
     }
 
-  tree ret = fold_build2_loc(this->location(),
+  tree ret = fold_build2_loc(this->location().gcc_location(),
                             code,
                             compute_type != NULL_TREE ? compute_type : type,
                             left, right);
@@ -6378,35 +6397,38 @@ Binary_expression::do_get_tree(Translate_context* context)
       tree compare = fold_build2(LT_EXPR, boolean_type_node, right,
                                 build_int_cst_type(TREE_TYPE(right), bits));
 
-      tree overflow_result = fold_convert_loc(this->location(),
+      tree overflow_result = fold_convert_loc(this->location().gcc_location(),
                                              TREE_TYPE(left),
                                              integer_zero_node);
       if (this->op_ == OPERATOR_RSHIFT
          && !this->left_->type()->integer_type()->is_unsigned())
        {
-         tree neg = fold_build2_loc(this->location(), LT_EXPR,
-                                    boolean_type_node, left,
-                                    fold_convert_loc(this->location(),
-                                                     TREE_TYPE(left),
-                                                     integer_zero_node));
-         tree neg_one = fold_build2_loc(this->location(),
-                                        MINUS_EXPR, TREE_TYPE(left),
-                                        fold_convert_loc(this->location(),
-                                                         TREE_TYPE(left),
-                                                         integer_zero_node),
-                                        fold_convert_loc(this->location(),
-                                                         TREE_TYPE(left),
-                                                         integer_one_node));
-         overflow_result = fold_build3_loc(this->location(), COND_EXPR,
-                                           TREE_TYPE(left), neg, neg_one,
-                                           overflow_result);
-       }
-
-      ret = fold_build3_loc(this->location(), COND_EXPR, TREE_TYPE(left),
-                           compare, ret, overflow_result);
+         tree neg =
+            fold_build2_loc(this->location().gcc_location(), LT_EXPR,
+                            boolean_type_node, left,
+                            fold_convert_loc(this->location().gcc_location(),
+                                             TREE_TYPE(left),
+                                             integer_zero_node));
+         tree neg_one =
+            fold_build2_loc(this->location().gcc_location(),
+                            MINUS_EXPR, TREE_TYPE(left),
+                            fold_convert_loc(this->location().gcc_location(),
+                                             TREE_TYPE(left),
+                                             integer_zero_node),
+                            fold_convert_loc(this->location().gcc_location(),
+                                             TREE_TYPE(left),
+                                             integer_one_node));
+         overflow_result =
+            fold_build3_loc(this->location().gcc_location(), COND_EXPR,
+                            TREE_TYPE(left), neg, neg_one,
+                            overflow_result);
+       }
+
+      ret = fold_build3_loc(this->location().gcc_location(), COND_EXPR,
+                            TREE_TYPE(left), compare, ret, overflow_result);
 
       if (eval_saved != NULL_TREE)
-       ret = fold_build2_loc(this->location(), COMPOUND_EXPR,
+       ret = fold_build2_loc(this->location().gcc_location(), COMPOUND_EXPR,
                              TREE_TYPE(ret), eval_saved, ret);
     }
 
@@ -6622,7 +6644,7 @@ Binary_expression::do_dump_expression(Ast_dump_context* ast_dump_context) const
 
 Expression*
 Expression::make_binary(Operator op, Expression* left, Expression* right,
-                       source_location location)
+                       Location location)
 {
   return new Binary_expression(op, left, right, location);
 }
@@ -6633,7 +6655,7 @@ tree
 Expression::comparison_tree(Translate_context* context, Operator op,
                            Type* left_type, tree left_tree,
                            Type* right_type, tree right_tree,
-                           source_location location)
+                           Location location)
 {
   enum tree_code code;
   switch (op)
@@ -6702,7 +6724,7 @@ Expression::comparison_tree(Translate_context* context, Operator op,
       else if (TREE_ADDRESSABLE(TREE_TYPE(right_tree)) || DECL_P(right_tree))
        {
          make_tmp = NULL_TREE;
-         arg = build_fold_addr_expr_loc(location, right_tree);
+         arg = build_fold_addr_expr_loc(location.gcc_location(), right_tree);
          if (DECL_P(right_tree))
            TREE_ADDRESSABLE(right_tree) = 1;
        }
@@ -6714,10 +6736,10 @@ Expression::comparison_tree(Translate_context* context, Operator op,
          DECL_INITIAL(tmp) = right_tree;
          TREE_ADDRESSABLE(tmp) = 1;
          make_tmp = build1(DECL_EXPR, void_type_node, tmp);
-         SET_EXPR_LOCATION(make_tmp, location);
-         arg = build_fold_addr_expr_loc(location, tmp);
+         SET_EXPR_LOCATION(make_tmp, location.gcc_location());
+         arg = build_fold_addr_expr_loc(location.gcc_location(), tmp);
        }
-      arg = fold_convert_loc(location, ptr_type_node, arg);
+      arg = fold_convert_loc(location.gcc_location(), ptr_type_node, arg);
 
       tree descriptor = right_type->type_descriptor_pointer(context->gogo(),
                                                            location);
@@ -6872,7 +6894,7 @@ Expression::comparison_tree(Translate_context* context, Operator op,
 
   tree ret = fold_build2(code, boolean_type_node, left_tree, right_tree);
   if (CAN_HAVE_LOCATION_P(ret))
-    SET_EXPR_LOCATION(ret, location);
+    SET_EXPR_LOCATION(ret, location.gcc_location());
   return ret;
 }
 
@@ -6972,7 +6994,7 @@ Bound_method_expression::do_dump_expression(Ast_dump_context* ast_dump_context)
 
 Bound_method_expression*
 Expression::make_bound_method(Expression* expr, Named_object* method,
-                             source_location location)
+                             Location location)
 {
   return new Bound_method_expression(expr, method, location);
 }
@@ -6984,7 +7006,7 @@ class Builtin_call_expression : public Call_expression
 {
  public:
   Builtin_call_expression(Gogo* gogo, Expression* fn, Expression_list* args,
-                         bool is_varargs, source_location location);
+                         bool is_varargs, Location location);
 
  protected:
   // This overrides Call_expression::do_lower.
@@ -7097,7 +7119,7 @@ Builtin_call_expression::Builtin_call_expression(Gogo* gogo,
                                                 Expression* fn,
                                                 Expression_list* args,
                                                 bool is_varargs,
-                                                source_location location)
+                                                Location location)
   : Call_expression(fn, args, is_varargs, location),
     gogo_(gogo), code_(BUILTIN_INVALID), seen_(false)
 {
@@ -7209,7 +7231,7 @@ Builtin_call_expression::do_lower(Gogo* gogo, Named_object* function,
   if (this->classification() == EXPRESSION_ERROR)
     return this;
 
-  source_location loc = this->location();
+  Location loc = this->location();
 
   if (this->is_varargs() && this->code_ != BUILTIN_APPEND)
     {
@@ -7369,7 +7391,7 @@ Builtin_call_expression::do_lower(Gogo* gogo, Named_object* function,
 Expression*
 Builtin_call_expression::lower_make()
 {
-  source_location loc = this->location();
+  Location loc = this->location();
 
   const Expression_list* args = this->args();
   if (args == NULL || args->size() < 1)
@@ -7448,7 +7470,7 @@ Builtin_call_expression::lower_make()
       return Expression::make_error(this->location());
     }
 
-  source_location type_loc = first_arg->location();
+  Location type_loc = first_arg->location();
   Expression* type_arg;
   if (is_slice || is_chan)
     type_arg = Expression::make_type_descriptor(type, type_loc);
@@ -7937,7 +7959,7 @@ Builtin_call_expression::do_type()
       return Type::make_void_type();
 
     case BUILTIN_RECOVER:
-      return Type::make_interface_type(NULL, BUILTINS_LOCATION);
+      return Type::make_interface_type(NULL, Linemap::predeclared_location());
 
     case BUILTIN_APPEND:
       {
@@ -8352,7 +8374,7 @@ tree
 Builtin_call_expression::do_get_tree(Translate_context* context)
 {
   Gogo* gogo = context->gogo();
-  source_location location = this->location();
+  Location location = this->location();
   switch (this->code_)
     {
     case BUILTIN_INVALID:
@@ -8523,7 +8545,8 @@ Builtin_call_expression::do_get_tree(Translate_context* context)
                    fnname = "__go_print_uint64";
                    Type* itype = Type::lookup_integer_type("uint64");
                    Btype* bitype = itype->get_backend(gogo);
-                   arg = fold_convert_loc(location, type_to_tree(bitype), arg);
+                   arg = fold_convert_loc(location.gcc_location(),
+                                           type_to_tree(bitype), arg);
                  }
                else if (type->integer_type() != NULL)
                  {
@@ -8532,22 +8555,24 @@ Builtin_call_expression::do_get_tree(Translate_context* context)
                    fnname = "__go_print_int64";
                    Type* itype = Type::lookup_integer_type("int64");
                    Btype* bitype = itype->get_backend(gogo);
-                   arg = fold_convert_loc(location, type_to_tree(bitype), arg);
+                   arg = fold_convert_loc(location.gcc_location(),
+                                           type_to_tree(bitype), arg);
                  }
                else if (type->float_type() != NULL)
                  {
                    static tree print_double_fndecl;
                    pfndecl = &print_double_fndecl;
                    fnname = "__go_print_double";
-                   arg = fold_convert_loc(location, double_type_node, arg);
+                   arg = fold_convert_loc(location.gcc_location(),
+                                           double_type_node, arg);
                  }
                else if (type->complex_type() != NULL)
                  {
                    static tree print_complex_fndecl;
                    pfndecl = &print_complex_fndecl;
                    fnname = "__go_print_complex";
-                   arg = fold_convert_loc(location, complex_double_type_node,
-                                          arg);
+                   arg = fold_convert_loc(location.gcc_location(),
+                                           complex_double_type_node, arg);
                  }
                else if (type->is_boolean_type())
                  {
@@ -8563,7 +8588,8 @@ Builtin_call_expression::do_get_tree(Translate_context* context)
                    static tree print_pointer_fndecl;
                    pfndecl = &print_pointer_fndecl;
                    fnname = "__go_print_pointer";
-                   arg = fold_convert_loc(location, ptr_type_node, arg);
+                   arg = fold_convert_loc(location.gcc_location(),
+                                           ptr_type_node, arg);
                  }
                else if (type->interface_type() != NULL)
                  {
@@ -8626,7 +8652,8 @@ Builtin_call_expression::do_get_tree(Translate_context* context)
        tree arg_tree = arg->get_tree(context);
        if (arg_tree == error_mark_node)
          return error_mark_node;
-       Type *empty = Type::make_interface_type(NULL, BUILTINS_LOCATION);
+       Type *empty =
+         Type::make_interface_type(NULL, Linemap::predeclared_location());
        arg_tree = Expression::convert_for_assignment(context, empty,
                                                      arg->type(),
                                                      arg_tree, location);
@@ -8658,7 +8685,8 @@ Builtin_call_expression::do_get_tree(Translate_context* context)
        if (arg_tree == error_mark_node)
          return error_mark_node;
 
-       Type *empty = Type::make_interface_type(NULL, BUILTINS_LOCATION);
+       Type *empty =
+         Type::make_interface_type(NULL, Linemap::predeclared_location());
        tree empty_tree = type_to_tree(empty->get_backend(context->gogo()));
 
        Type* nil_type = Type::make_nil_type();
@@ -8694,8 +8722,8 @@ Builtin_call_expression::do_get_tree(Translate_context* context)
          }
        if (call == error_mark_node)
          return error_mark_node;
-       return fold_build3_loc(location, COND_EXPR, empty_tree, arg_tree,
-                              call, empty_nil_tree);
+       return fold_build3_loc(location.gcc_location(), COND_EXPR, empty_tree,
+                               arg_tree, call, empty_nil_tree);
       }
 
     case BUILTIN_CLOSE:
@@ -8777,9 +8805,10 @@ Builtin_call_expression::do_get_tree(Translate_context* context)
 
        arg1_len = save_expr(arg1_len);
        arg2_len = save_expr(arg2_len);
-       tree len = fold_build3_loc(location, COND_EXPR, TREE_TYPE(arg1_len),
-                                  fold_build2_loc(location, LT_EXPR,
-                                                  boolean_type_node,
+       tree len = fold_build3_loc(location.gcc_location(), COND_EXPR,
+                                   TREE_TYPE(arg1_len),
+                                  fold_build2_loc(location.gcc_location(),
+                                                   LT_EXPR, boolean_type_node,
                                                   arg1_len, arg2_len),
                                   arg1_len, arg2_len);
        len = save_expr(len);
@@ -8790,15 +8819,18 @@ Builtin_call_expression::do_get_tree(Translate_context* context)
        if (element_type_tree == error_mark_node)
          return error_mark_node;
        tree element_size = TYPE_SIZE_UNIT(element_type_tree);
-       tree bytecount = fold_convert_loc(location, TREE_TYPE(element_size),
-                                         len);
-       bytecount = fold_build2_loc(location, MULT_EXPR,
+       tree bytecount = fold_convert_loc(location.gcc_location(),
+                                          TREE_TYPE(element_size), len);
+       bytecount = fold_build2_loc(location.gcc_location(), MULT_EXPR,
                                    TREE_TYPE(element_size),
                                    bytecount, element_size);
-       bytecount = fold_convert_loc(location, size_type_node, bytecount);
+       bytecount = fold_convert_loc(location.gcc_location(), size_type_node,
+                                     bytecount);
 
-       arg1_val = fold_convert_loc(location, ptr_type_node, arg1_val);
-       arg2_val = fold_convert_loc(location, ptr_type_node, arg2_val);
+       arg1_val = fold_convert_loc(location.gcc_location(), ptr_type_node,
+                                    arg1_val);
+       arg2_val = fold_convert_loc(location.gcc_location(), ptr_type_node,
+                                    arg2_val);
 
        static tree copy_fndecl;
        tree call = Gogo::call_builtin(&copy_fndecl,
@@ -8815,8 +8847,8 @@ Builtin_call_expression::do_get_tree(Translate_context* context)
        if (call == error_mark_node)
          return error_mark_node;
 
-       return fold_build2_loc(location, COMPOUND_EXPR, TREE_TYPE(len),
-                              call, len);
+       return fold_build2_loc(location.gcc_location(), COMPOUND_EXPR,
+                               TREE_TYPE(len), call, len);
       }
 
     case BUILTIN_APPEND:
@@ -8866,9 +8898,11 @@ Builtin_call_expression::do_get_tree(Translate_context* context)
             element_size = TYPE_SIZE_UNIT(element_type_tree);
          }
 
-       arg2_val = fold_convert_loc(location, ptr_type_node, arg2_val);
-       arg2_len = fold_convert_loc(location, size_type_node, arg2_len);
-       element_size = fold_convert_loc(location, size_type_node,
+       arg2_val = fold_convert_loc(location.gcc_location(), ptr_type_node,
+                                    arg2_val);
+       arg2_len = fold_convert_loc(location.gcc_location(), size_type_node,
+                                    arg2_len);
+       element_size = fold_convert_loc(location.gcc_location(), size_type_node,
                                        element_size);
 
        if (arg2_val == error_mark_node
@@ -8905,11 +8939,11 @@ Builtin_call_expression::do_get_tree(Translate_context* context)
          return error_mark_node;
        go_assert(COMPLEX_FLOAT_TYPE_P(TREE_TYPE(arg_tree)));
        if (this->code_ == BUILTIN_REAL)
-         return fold_build1_loc(location, REALPART_EXPR,
+         return fold_build1_loc(location.gcc_location(), REALPART_EXPR,
                                 TREE_TYPE(TREE_TYPE(arg_tree)),
                                 arg_tree);
        else
-         return fold_build1_loc(location, IMAGPART_EXPR,
+         return fold_build1_loc(location.gcc_location(), IMAGPART_EXPR,
                                 TREE_TYPE(TREE_TYPE(arg_tree)),
                                 arg_tree);
       }
@@ -8925,7 +8959,7 @@ Builtin_call_expression::do_get_tree(Translate_context* context)
        go_assert(TYPE_MAIN_VARIANT(TREE_TYPE(r))
                   == TYPE_MAIN_VARIANT(TREE_TYPE(i)));
        go_assert(SCALAR_FLOAT_TYPE_P(TREE_TYPE(r)));
-       return fold_build2_loc(location, COMPLEX_EXPR,
+       return fold_build2_loc(location.gcc_location(), COMPLEX_EXPR,
                               build_complex_type(TREE_TYPE(r)),
                               r, i);
       }
@@ -9013,7 +9047,7 @@ Expression*
 Call_expression::do_lower(Gogo* gogo, Named_object* function,
                          Statement_inserter* inserter, int)
 {
-  source_location loc = this->location();
+  Location loc = this->location();
 
   // A type cast can look like a function call.
   if (this->fn_->is_type_expression()
@@ -9160,7 +9194,7 @@ Call_expression::lower_varargs(Gogo* gogo, Named_object* function,
   if (this->varargs_are_lowered_)
     return;
 
-  source_location loc = this->location();
+  Location loc = this->location();
 
   go_assert(param_count > 0);
   go_assert(varargs_type->is_slice_type());
@@ -9211,7 +9245,7 @@ Call_expression::lower_varargs(Gogo* gogo, Named_object* function,
            {
              // Check types here so that we get a better message.
              Type* patype = (*pa)->type();
-             source_location paloc = (*pa)->location();
+             Location paloc = (*pa)->location();
              if (!this->check_argument_type(i, element_type, patype,
                                             paloc, issued_error))
                continue;
@@ -9410,7 +9444,7 @@ Call_expression::determining_types()
 bool
 Call_expression::check_argument_type(int i, const Type* parameter_type,
                                     const Type* argument_type,
-                                    source_location argument_location,
+                                    Location argument_location,
                                     bool issued_error)
 {
   std::string reason;
@@ -9559,7 +9593,7 @@ Call_expression::do_get_tree(Translate_context* context)
     return error_mark_node;
 
   Gogo* gogo = context->gogo();
-  source_location location = this->location();
+  Location location = this->location();
 
   Func_expression* func = this->fn_->func_expression();
   Interface_field_reference_expression* interface_method =
@@ -9652,7 +9686,7 @@ Call_expression::do_get_tree(Translate_context* context)
       tree fnt = type_to_tree(fntype->get_backend(gogo));
       if (fnt == error_mark_node)
        return error_mark_node;
-      fn = fold_convert_loc(location, fnt, fn);
+      fn = fold_convert_loc(location.gcc_location(), fnt, fn);
     }
 
   // This is to support builtin math functions when using 80387 math.
@@ -9675,7 +9709,8 @@ Call_expression::do_get_tree(Translate_context* context)
            excess_type = NULL_TREE;
          else
            {
-             fn = build_fold_addr_expr_loc(location, excess_fndecl);
+             fn = build_fold_addr_expr_loc(location.gcc_location(),
+                                            excess_fndecl);
              for (int i = 0; i < nargs; ++i)
                args[i] = ::convert(excess_type, args[i]);
            }
@@ -9686,7 +9721,7 @@ Call_expression::do_get_tree(Translate_context* context)
                              fn, nargs, args);
   delete[] args;
 
-  SET_EXPR_LOCATION(ret, location);
+  SET_EXPR_LOCATION(ret, location.gcc_location());
 
   if (has_closure)
     {
@@ -9702,7 +9737,7 @@ Call_expression::do_get_tree(Translate_context* context)
   if (TREE_TYPE(ret) == ptr_type_node)
     {
       tree t = type_to_tree(this->type()->base()->get_backend(gogo));
-      ret = fold_convert_loc(location, t, ret);
+      ret = fold_convert_loc(location.gcc_location(), t, ret);
     }
 
   if (excess_type != NULL_TREE)
@@ -9735,7 +9770,7 @@ Call_expression::set_results(Translate_context* context, tree call_tree)
       return call_tree;
     }
 
-  source_location loc = this->location();
+  Location loc = this->location();
   tree field = TYPE_FIELDS(TREE_TYPE(call_tree));
   size_t rc = this->result_count();
   for (size_t i = 0; i < rc; ++i, field = DECL_CHAIN(field))
@@ -9750,10 +9785,10 @@ Call_expression::set_results(Translate_context* context, tree call_tree)
       if (temp_tree == error_mark_node)
        continue;
 
-      tree val_tree = build3_loc(loc, COMPONENT_REF, TREE_TYPE(field),
-                                call_tree, field, NULL_TREE);
-      tree set_tree = build2_loc(loc, MODIFY_EXPR, void_type_node, temp_tree,
-                                val_tree);
+      tree val_tree = build3_loc(loc.gcc_location(), COMPONENT_REF,
+                                 TREE_TYPE(field), call_tree, field, NULL_TREE);
+      tree set_tree = build2_loc(loc.gcc_location(), MODIFY_EXPR,
+                                 void_type_node, temp_tree, val_tree);
 
       append_to_statement_list(set_tree, &stmt_list);
     }
@@ -9779,7 +9814,7 @@ Call_expression::do_dump_expression(Ast_dump_context* ast_dump_context) const
 
 Call_expression*
 Expression::make_call(Expression* fn, Expression_list* args, bool is_varargs,
-                     source_location location)
+                     Location location)
 {
   return new Call_expression(fn, args, is_varargs, location);
 }
@@ -9971,7 +10006,7 @@ Index_expression::do_traverse(Traverse* traverse)
 Expression*
 Index_expression::do_lower(Gogo*, Named_object*, Statement_inserter*, int)
 {
-  source_location location = this->location();
+  Location location = this->location();
   Expression* left = this->left_;
   Expression* start = this->start_;
   Expression* end = this->end_;
@@ -10051,7 +10086,7 @@ Index_expression::do_dump_expression(Ast_dump_context* ast_dump_context)
 
 Expression*
 Expression::make_index(Expression* left, Expression* start, Expression* end,
-                      source_location location)
+                      Location location)
 {
   return new Index_expression(left, start, end, location);
 }
@@ -10062,7 +10097,7 @@ class Array_index_expression : public Expression
 {
  public:
   Array_index_expression(Expression* array, Expression* start,
-                        Expression* end, source_location location)
+                        Expression* end, Location location)
     : Expression(EXPRESSION_ARRAY_INDEX, location),
       array_(array), start_(start), end_(end), type_(NULL)
   { }
@@ -10275,7 +10310,7 @@ tree
 Array_index_expression::do_get_tree(Translate_context* context)
 {
   Gogo* gogo = context->gogo();
-  source_location loc = this->location();
+  Location loc = this->location();
 
   Array_type* array_type = this->array_->type()->array_type();
   if (array_type == NULL)
@@ -10313,9 +10348,10 @@ Array_index_expression::do_get_tree(Translate_context* context)
   bad_index = Expression::check_bounds(start_tree, length_type, bad_index,
                                       loc);
 
-  start_tree = fold_convert_loc(loc, length_type, start_tree);
-  bad_index = fold_build2_loc(loc, TRUTH_OR_EXPR, boolean_type_node, bad_index,
-                             fold_build2_loc(loc,
+  start_tree = fold_convert_loc(loc.gcc_location(), length_type, start_tree);
+  bad_index = fold_build2_loc(loc.gcc_location(), TRUTH_OR_EXPR,
+                              boolean_type_node, bad_index,
+                             fold_build2_loc(loc.gcc_location(),
                                              (this->end_ == NULL
                                               ? GE_EXPR
                                               : GT_EXPR),
@@ -10339,7 +10375,7 @@ Array_index_expression::do_get_tree(Translate_context* context)
                          build3(COND_EXPR, void_type_node,
                                 bad_index, crash, NULL_TREE),
                          start_tree);
-      start_tree = fold_convert_loc(loc, sizetype, start_tree);
+      start_tree = fold_convert_loc(loc.gcc_location(), sizetype, start_tree);
 
       if (array_type->length() != NULL)
        {
@@ -10357,9 +10393,9 @@ Array_index_expression::do_get_tree(Translate_context* context)
          if (element_type_tree == error_mark_node)
            return error_mark_node;
          tree element_size = TYPE_SIZE_UNIT(element_type_tree);
-         tree offset = fold_build2_loc(loc, MULT_EXPR, sizetype,
+         tree offset = fold_build2_loc(loc.gcc_location(), MULT_EXPR, sizetype,
                                        start_tree, element_size);
-         tree ptr = fold_build2_loc(loc, POINTER_PLUS_EXPR,
+         tree ptr = fold_build2_loc(loc.gcc_location(), POINTER_PLUS_EXPR,
                                     TREE_TYPE(values), values, offset);
          return build_fold_indirect_ref(ptr);
        }
@@ -10370,7 +10406,8 @@ Array_index_expression::do_get_tree(Translate_context* context)
   tree capacity_tree = array_type->capacity_tree(gogo, array_tree);
   if (capacity_tree == error_mark_node)
     return error_mark_node;
-  capacity_tree = fold_convert_loc(loc, length_type, capacity_tree);
+  capacity_tree = fold_convert_loc(loc.gcc_location(), length_type,
+                                   capacity_tree);
 
   tree end_tree;
   if (this->end_->is_nil_expression())
@@ -10388,18 +10425,19 @@ Array_index_expression::do_get_tree(Translate_context* context)
       bad_index = Expression::check_bounds(end_tree, length_type, bad_index,
                                           loc);
 
-      end_tree = fold_convert_loc(loc, length_type, end_tree);
+      end_tree = fold_convert_loc(loc.gcc_location(), length_type, end_tree);
 
       capacity_tree = save_expr(capacity_tree);
-      tree bad_end = fold_build2_loc(loc, TRUTH_OR_EXPR, boolean_type_node,
-                                    fold_build2_loc(loc, LT_EXPR,
-                                                    boolean_type_node,
+      tree bad_end = fold_build2_loc(loc.gcc_location(), TRUTH_OR_EXPR,
+                                     boolean_type_node,
+                                    fold_build2_loc(loc.gcc_location(),
+                                                     LT_EXPR, boolean_type_node,
                                                     end_tree, start_tree),
-                                    fold_build2_loc(loc, GT_EXPR,
-                                                    boolean_type_node,
+                                    fold_build2_loc(loc.gcc_location(),
+                                                     GT_EXPR, boolean_type_node,
                                                     end_tree, capacity_tree));
-      bad_index = fold_build2_loc(loc, TRUTH_OR_EXPR, boolean_type_node,
-                                 bad_index, bad_end);
+      bad_index = fold_build2_loc(loc.gcc_location(), TRUTH_OR_EXPR,
+                                  boolean_type_node, bad_index, bad_end);
     }
 
   Type* element_type = array_type->element_type();
@@ -10408,23 +10446,25 @@ Array_index_expression::do_get_tree(Translate_context* context)
     return error_mark_node;
   tree element_size = TYPE_SIZE_UNIT(element_type_tree);
 
-  tree offset = fold_build2_loc(loc, MULT_EXPR, sizetype,
-                               fold_convert_loc(loc, sizetype, start_tree),
+  tree offset = fold_build2_loc(loc.gcc_location(), MULT_EXPR, sizetype,
+                               fold_convert_loc(loc.gcc_location(), sizetype,
+                                                 start_tree),
                                element_size);
 
   tree value_pointer = array_type->value_pointer_tree(gogo, array_tree);
   if (value_pointer == error_mark_node)
     return error_mark_node;
 
-  value_pointer = fold_build2_loc(loc, POINTER_PLUS_EXPR,
+  value_pointer = fold_build2_loc(loc.gcc_location(), POINTER_PLUS_EXPR,
                                  TREE_TYPE(value_pointer),
                                  value_pointer, offset);
 
-  tree result_length_tree = fold_build2_loc(loc, MINUS_EXPR, length_type,
-                                           end_tree, start_tree);
+  tree result_length_tree = fold_build2_loc(loc.gcc_location(), MINUS_EXPR,
+                                            length_type, end_tree, start_tree);
 
-  tree result_capacity_tree = fold_build2_loc(loc, MINUS_EXPR, length_type,
-                                             capacity_tree, start_tree);
+  tree result_capacity_tree = fold_build2_loc(loc.gcc_location(), MINUS_EXPR,
+                                              length_type, capacity_tree,
+                                              start_tree);
 
   tree struct_tree = type_to_tree(this->type()->get_backend(gogo));
   go_assert(TREE_CODE(struct_tree) == RECORD_TYPE);
@@ -10441,13 +10481,15 @@ Array_index_expression::do_get_tree(Translate_context* context)
   field = DECL_CHAIN(field);
   go_assert(strcmp(IDENTIFIER_POINTER(DECL_NAME(field)), "__count") == 0);
   elt->index = field;
-  elt->value = fold_convert_loc(loc, TREE_TYPE(field), result_length_tree);
+  elt->value = fold_convert_loc(loc.gcc_location(), TREE_TYPE(field),
+                                result_length_tree);
 
   elt = VEC_quick_push(constructor_elt, init, NULL);
   field = DECL_CHAIN(field);
   go_assert(strcmp(IDENTIFIER_POINTER(DECL_NAME(field)), "__capacity") == 0);
   elt->index = field;
-  elt->value = fold_convert_loc(loc, TREE_TYPE(field), result_capacity_tree);
+  elt->value = fold_convert_loc(loc.gcc_location(), TREE_TYPE(field),
+                                result_capacity_tree);
 
   tree constructor = build_constructor(struct_tree, init);
 
@@ -10456,7 +10498,8 @@ Array_index_expression::do_get_tree(Translate_context* context)
       && TREE_CONSTANT(result_capacity_tree))
     TREE_CONSTANT(constructor) = 1;
 
-  return fold_build2_loc(loc, COMPOUND_EXPR, TREE_TYPE(constructor),
+  return fold_build2_loc(loc.gcc_location(), COMPOUND_EXPR,
+                         TREE_TYPE(constructor),
                         build3(COND_EXPR, void_type_node,
                                bad_index, crash, NULL_TREE),
                         constructor);
@@ -10476,7 +10519,7 @@ Array_index_expression::do_dump_expression(Ast_dump_context* ast_dump_context)
 
 Expression*
 Expression::make_array_index(Expression* array, Expression* start,
-                            Expression* end, source_location location)
+                            Expression* end, Location location)
 {
   // Taking a slice of a composite literal requires moving the literal
   // onto the heap.
@@ -10494,7 +10537,7 @@ class String_index_expression : public Expression
 {
  public:
   String_index_expression(Expression* string, Expression* start,
-                         Expression* end, source_location location)
+                         Expression* end, Location location)
     : Expression(EXPRESSION_STRING_INDEX, location),
       string_(string), start_(start), end_(end)
   { }
@@ -10632,7 +10675,7 @@ String_index_expression::do_check_types(Gogo*)
 tree
 String_index_expression::do_get_tree(Translate_context* context)
 {
-  source_location loc = this->location();
+  Location loc = this->location();
 
   tree string_tree = this->string_->get_tree(context);
   if (string_tree == error_mark_node)
@@ -10661,7 +10704,7 @@ String_index_expression::do_get_tree(Translate_context* context)
   bad_index = Expression::check_bounds(start_tree, length_type, bad_index,
                                       loc);
 
-  start_tree = fold_convert_loc(loc, length_type, start_tree);
+  start_tree = fold_convert_loc(loc.gcc_location(), length_type, start_tree);
 
   int code = (this->end_ == NULL
              ? RUNTIME_ERROR_STRING_INDEX_OUT_OF_BOUNDS
@@ -10670,17 +10713,19 @@ String_index_expression::do_get_tree(Translate_context* context)
 
   if (this->end_ == NULL)
     {
-      bad_index = fold_build2_loc(loc, TRUTH_OR_EXPR, boolean_type_node,
-                                 bad_index,
-                                 fold_build2_loc(loc, GE_EXPR,
+      bad_index = fold_build2_loc(loc.gcc_location(), TRUTH_OR_EXPR,
+                                  boolean_type_node, bad_index,
+                                 fold_build2_loc(loc.gcc_location(), GE_EXPR,
                                                  boolean_type_node,
                                                  start_tree, length_tree));
 
       tree bytes_tree = String_type::bytes_tree(context->gogo(), string_tree);
-      tree ptr = fold_build2_loc(loc, POINTER_PLUS_EXPR, TREE_TYPE(bytes_tree),
+      tree ptr = fold_build2_loc(loc.gcc_location(), POINTER_PLUS_EXPR,
+                                 TREE_TYPE(bytes_tree),
                                 bytes_tree,
-                                fold_convert_loc(loc, sizetype, start_tree));
-      tree index = build_fold_indirect_ref_loc(loc, ptr);
+                                fold_convert_loc(loc.gcc_location(), sizetype,
+                                                  start_tree));
+      tree index = build_fold_indirect_ref_loc(loc.gcc_location(), ptr);
 
       return build2(COMPOUND_EXPR, TREE_TYPE(index),
                    build3(COND_EXPR, void_type_node,
@@ -10705,7 +10750,8 @@ String_index_expression::do_get_tree(Translate_context* context)
          bad_index = Expression::check_bounds(end_tree, length_type,
                                               bad_index, loc);
 
-         end_tree = fold_convert_loc(loc, length_type, end_tree);
+         end_tree = fold_convert_loc(loc.gcc_location(), length_type,
+                                      end_tree);
        }
 
       static tree strslice_fndecl;
@@ -10750,7 +10796,7 @@ String_index_expression::do_dump_expression(Ast_dump_context* ast_dump_context)
 
 Expression*
 Expression::make_string_index(Expression* string, Expression* start,
-                             Expression* end, source_location location)
+                             Expression* end, Location location)
 {
   return new String_index_expression(string, start, end, location);
 }
@@ -10906,14 +10952,16 @@ Map_index_expression::get_value_pointer(Translate_context* context,
     }
   else
     {
-      tmp = build_decl(this->location(), VAR_DECL, create_tmp_var_name("M"),
+      tmp = build_decl(this->location().gcc_location(), VAR_DECL,
+                       create_tmp_var_name("M"),
                       TREE_TYPE(index_tree));
       DECL_EXTERNAL(tmp) = 0;
       TREE_PUBLIC(tmp) = 0;
       TREE_STATIC(tmp) = 1;
       DECL_ARTIFICIAL(tmp) = 1;
       if (!TREE_CONSTANT(index_tree))
-       make_tmp = fold_build2_loc(this->location(), INIT_EXPR, void_type_node,
+       make_tmp = fold_build2_loc(this->location().gcc_location(),
+                                   INIT_EXPR, void_type_node,
                                   tmp, index_tree);
       else
        {
@@ -10924,9 +10972,10 @@ Map_index_expression::get_value_pointer(Translate_context* context,
        }
       rest_of_decl_compilation(tmp, 1, 0);
     }
-  tree tmpref = fold_convert_loc(this->location(), const_ptr_type_node,
-                                build_fold_addr_expr_loc(this->location(),
-                                                         tmp));
+  tree tmpref =
+    fold_convert_loc(this->location().gcc_location(), const_ptr_type_node,
+                     build_fold_addr_expr_loc(this->location().gcc_location(),
+                                              tmp));
 
   static tree map_index_fndecl;
   tree call = Gogo::call_builtin(&map_index_fndecl,
@@ -10954,7 +11003,8 @@ Map_index_expression::get_value_pointer(Translate_context* context,
     return error_mark_node;
   tree ptr_val_type_tree = build_pointer_type(val_type_tree);
 
-  tree ret = fold_convert_loc(this->location(), ptr_val_type_tree, call);
+  tree ret = fold_convert_loc(this->location().gcc_location(),
+                              ptr_val_type_tree, call);
   if (make_tmp != NULL_TREE)
     ret = build2(COMPOUND_EXPR, ptr_val_type_tree, make_tmp, ret);
   return ret;
@@ -10974,7 +11024,7 @@ Map_index_expression::do_dump_expression(Ast_dump_context* ast_dump_context)
 
 Map_index_expression*
 Expression::make_map_index(Expression* map, Expression* index,
-                          source_location location)
+                          Location location)
 {
   return new Map_index_expression(map, index, location);
 }
@@ -11050,7 +11100,7 @@ Field_reference_expression::do_dump_expression(
 
 Field_reference_expression*
 Expression::make_field_reference(Expression* expr, unsigned int field_index,
-                                source_location location)
+                                Location location)
 {
   return new Field_reference_expression(expr, field_index, location);
 }
@@ -11207,7 +11257,7 @@ Interface_field_reference_expression::do_dump_expression(
 Expression*
 Expression::make_interface_field_reference(Expression* expr,
                                           const std::string& field,
-                                          source_location location)
+                                          Location location)
 {
   return new Interface_field_reference_expression(expr, field, location);
 }
@@ -11219,7 +11269,7 @@ class Selector_expression : public Parser_expression
 {
  public:
   Selector_expression(Expression* left, const std::string& name,
-                     source_location location)
+                     Location location)
     : Parser_expression(EXPRESSION_SELECTOR, location),
       left_(left), name_(name)
   { }
@@ -11272,7 +11322,7 @@ Selector_expression::do_lower(Gogo* gogo, Named_object*, Statement_inserter*,
 Expression*
 Selector_expression::lower_method_expression(Gogo* gogo)
 {
-  source_location location = this->location();
+  Location location = this->location();
   Type* type = this->left_->type();
   const std::string& name(this->name_);
 
@@ -11477,7 +11527,7 @@ Selector_expression::do_dump_expression(Ast_dump_context* ast_dump_context)
 
 Expression*
 Expression::make_selector(Expression* left, const std::string& name,
-                         source_location location)
+                         Location location)
 {
   return new Selector_expression(left, name, location);
 }
@@ -11487,7 +11537,7 @@ Expression::make_selector(Expression* left, const std::string& name,
 class Allocation_expression : public Expression
 {
  public:
-  Allocation_expression(Type* type, source_location location)
+  Allocation_expression(Type* type, Location location)
     : Expression(EXPRESSION_ALLOCATION, location),
       type_(type)
   { }
@@ -11550,7 +11600,7 @@ Allocation_expression::do_dump_expression(Ast_dump_context* ast_dump_context)
 // Make an allocation expression.
 
 Expression*
-Expression::make_allocation(Type* type, source_location location)
+Expression::make_allocation(Type* type, Location location)
 {
   return new Allocation_expression(type, location);
 }
@@ -11561,7 +11611,7 @@ class Struct_construction_expression : public Expression
 {
  public:
   Struct_construction_expression(Type* type, Expression_list* vals,
-                                source_location location)
+                                Location location)
     : Expression(EXPRESSION_STRUCT_CONSTRUCTION, location),
       type_(type), vals_(vals)
   { }
@@ -11832,7 +11882,7 @@ Struct_construction_expression::do_dump_expression(
 
 Expression*
 Expression::make_struct_composite_literal(Type* type, Expression_list* vals,
-                                         source_location location)
+                                         Location location)
 {
   go_assert(type->struct_type() != NULL);
   return new Struct_construction_expression(type, vals, location);
@@ -11847,7 +11897,7 @@ class Array_construction_expression : public Expression
  protected:
   Array_construction_expression(Expression_classification classification,
                                Type* type, Expression_list* vals,
-                               source_location location)
+                               Location location)
     : Expression(classification, location),
       type_(type), vals_(vals)
   { }
@@ -12097,7 +12147,7 @@ class Fixed_array_construction_expression :
 {
  public:
   Fixed_array_construction_expression(Type* type, Expression_list* vals,
-                                     source_location location)
+                                     Location location)
     : Array_construction_expression(EXPRESSION_FIXED_ARRAY_CONSTRUCTION,
                                    type, vals, location)
   {
@@ -12155,7 +12205,7 @@ class Open_array_construction_expression : public Array_construction_expression
 {
  public:
   Open_array_construction_expression(Type* type, Expression_list* vals,
-                                    source_location location)
+                                    Location location)
     : Array_construction_expression(EXPRESSION_OPEN_ARRAY_CONSTRUCTION,
                                    type, vals, location)
   {
@@ -12246,7 +12296,7 @@ Open_array_construction_expression::do_get_tree(Translate_context* context)
 
   if (is_constant_initializer)
     {
-      tree tmp = build_decl(this->location(), VAR_DECL,
+      tree tmp = build_decl(this->location().gcc_location(), VAR_DECL,
                            create_tmp_var_name("C"), TREE_TYPE(values));
       DECL_EXTERNAL(tmp) = 0;
       TREE_PUBLIC(tmp) = 0;
@@ -12282,7 +12332,8 @@ Open_array_construction_expression::do_get_tree(Translate_context* context)
       space = save_expr(space);
 
       tree s = fold_convert(build_pointer_type(TREE_TYPE(values)), space);
-      tree ref = build_fold_indirect_ref_loc(this->location(), s);
+      tree ref = build_fold_indirect_ref_loc(this->location().gcc_location(),
+                                             s);
       TREE_THIS_NOTRAP(ref) = 1;
       set = build2(MODIFY_EXPR, void_type_node, ref, values);
     }
@@ -12331,7 +12382,7 @@ Open_array_construction_expression::do_get_tree(Translate_context* context)
 
 Expression*
 Expression::make_slice_composite_literal(Type* type, Expression_list* vals,
-                                        source_location location)
+                                        Location location)
 {
   go_assert(type->is_slice_type());
   return new Open_array_construction_expression(type, vals, location);
@@ -12343,7 +12394,7 @@ class Map_construction_expression : public Expression
 {
  public:
   Map_construction_expression(Type* type, Expression_list* vals,
-                             source_location location)
+                             Location location)
     : Expression(EXPRESSION_MAP_CONSTRUCTION, location),
       type_(type), vals_(vals)
   { go_assert(vals == NULL || vals->size() % 2 == 0); }
@@ -12460,7 +12511,7 @@ tree
 Map_construction_expression::do_get_tree(Translate_context* context)
 {
   Gogo* gogo = context->gogo();
-  source_location loc = this->location();
+  Location loc = this->location();
 
   Map_type* mt = this->type_->map_type();
 
@@ -12472,7 +12523,8 @@ Map_construction_expression::do_get_tree(Translate_context* context)
   tree key_type_tree = type_to_tree(key_type->get_backend(gogo));
   if (key_type_tree == error_mark_node)
     return error_mark_node;
-  tree key_field = build_decl(loc, FIELD_DECL, id, key_type_tree);
+  tree key_field = build_decl(loc.gcc_location(), FIELD_DECL, id,
+                              key_type_tree);
   DECL_CONTEXT(key_field) = struct_type;
   TYPE_FIELDS(struct_type) = key_field;
 
@@ -12481,7 +12533,8 @@ Map_construction_expression::do_get_tree(Translate_context* context)
   tree val_type_tree = type_to_tree(val_type->get_backend(gogo));
   if (val_type_tree == error_mark_node)
     return error_mark_node;
-  tree val_field = build_decl(loc, FIELD_DECL, id, val_type_tree);
+  tree val_field = build_decl(loc.gcc_location(), FIELD_DECL, id,
+                              val_type_tree);
   DECL_CONTEXT(val_field) = struct_type;
   DECL_CHAIN(key_field) = val_field;
 
@@ -12553,19 +12606,21 @@ Map_construction_expression::do_get_tree(Translate_context* context)
        {
          tmp = create_tmp_var(array_type, get_name(array_type));
          DECL_INITIAL(tmp) = init;
-         make_tmp = fold_build1_loc(loc, DECL_EXPR, void_type_node, tmp);
+         make_tmp = fold_build1_loc(loc.gcc_location(), DECL_EXPR,
+                                     void_type_node, tmp);
          TREE_ADDRESSABLE(tmp) = 1;
        }
       else
        {
-         tmp = build_decl(loc, VAR_DECL, create_tmp_var_name("M"), array_type);
+         tmp = build_decl(loc.gcc_location(), VAR_DECL,
+                           create_tmp_var_name("M"), array_type);
          DECL_EXTERNAL(tmp) = 0;
          TREE_PUBLIC(tmp) = 0;
          TREE_STATIC(tmp) = 1;
          DECL_ARTIFICIAL(tmp) = 1;
          if (!TREE_CONSTANT(init))
-           make_tmp = fold_build2_loc(loc, INIT_EXPR, void_type_node, tmp,
-                                      init);
+           make_tmp = fold_build2_loc(loc.gcc_location(), INIT_EXPR,
+                                       void_type_node, tmp, init);
          else
            {
              TREE_READONLY(tmp) = 1;
@@ -12610,7 +12665,8 @@ Map_construction_expression::do_get_tree(Translate_context* context)
   if (make_tmp == NULL)
     ret = call;
   else
-    ret = fold_build2_loc(loc, COMPOUND_EXPR, type_tree, make_tmp, call);
+    ret = fold_build2_loc(loc.gcc_location(), COMPOUND_EXPR, type_tree,
+                          make_tmp, call);
   return ret;
 }
 
@@ -12649,7 +12705,7 @@ class Composite_literal_expression : public Parser_expression
 {
  public:
   Composite_literal_expression(Type* type, int depth, bool has_keys,
-                              Expression_list* vals, source_location location)
+                              Expression_list* vals, Location location)
     : Parser_expression(EXPRESSION_COMPOSITE_LITERAL, location),
       type_(type), depth_(depth), vals_(vals), has_keys_(has_keys)
   { }
@@ -12758,7 +12814,7 @@ Composite_literal_expression::do_lower(Gogo* gogo, Named_object* function,
 Expression*
 Composite_literal_expression::lower_struct(Gogo* gogo, Type* type)
 {
-  source_location location = this->location();
+  Location location = this->location();
   Struct_type* st = type->struct_type();
   if (this->vals_ == NULL || !this->has_keys_)
     return new Struct_construction_expression(type, this->vals_, location);
@@ -12924,7 +12980,7 @@ Composite_literal_expression::lower_struct(Gogo* gogo, Type* type)
 Expression*
 Composite_literal_expression::lower_array(Type* type)
 {
-  source_location location = this->location();
+  Location location = this->location();
   if (this->vals_ == NULL || !this->has_keys_)
     return this->make_array(type, this->vals_);
 
@@ -13035,7 +13091,7 @@ Composite_literal_expression::lower_array(Type* type)
 Expression*
 Composite_literal_expression::make_array(Type* type, Expression_list* vals)
 {
-  source_location location = this->location();
+  Location location = this->location();
   Array_type* at = type->array_type();
   if (at->length() != NULL && at->length()->is_nil_expression())
     {
@@ -13060,7 +13116,7 @@ Composite_literal_expression::lower_map(Gogo* gogo, Named_object* function,
                                        Statement_inserter* inserter,
                                        Type* type)
 {
-  source_location location = this->location();
+  Location location = this->location();
   if (this->vals_ != NULL)
     {
       if (!this->has_keys_)
@@ -13114,7 +13170,7 @@ Composite_literal_expression::do_dump_expression(
 Expression*
 Expression::make_composite_literal(Type* type, int depth, bool has_keys,
                                   Expression_list* vals,
-                                  source_location location)
+                                  Location location)
 {
   return new Composite_literal_expression(type, depth, has_keys, vals,
                                          location);
@@ -13298,7 +13354,7 @@ Type_guard_expression::do_dump_expression(Ast_dump_context* ast_dump_context)
 
 Expression*
 Expression::make_type_guard(Expression* expr, Type* type,
-                           source_location location)
+                           Location location)
 {
   return new Type_guard_expression(expr, type, location);
 }
@@ -13311,7 +13367,7 @@ Expression::make_type_guard(Expression* expr, Type* type,
 class Heap_composite_expression : public Expression
 {
  public:
-  Heap_composite_expression(Expression* expr, source_location location)
+  Heap_composite_expression(Expression* expr, Location location)
     : Expression(EXPRESSION_HEAP_COMPOSITE, location),
       expr_(expr)
   { }
@@ -13367,12 +13423,13 @@ Heap_composite_expression::do_get_tree(Translate_context* context)
                                                expr_size, this->location());
   space = fold_convert(build_pointer_type(TREE_TYPE(expr_tree)), space);
   space = save_expr(space);
-  tree ref = build_fold_indirect_ref_loc(this->location(), space);
+  tree ref = build_fold_indirect_ref_loc(this->location().gcc_location(),
+                                         space);
   TREE_THIS_NOTRAP(ref) = 1;
   tree ret = build2(COMPOUND_EXPR, TREE_TYPE(space),
                    build2(MODIFY_EXPR, void_type_node, ref, expr_tree),
                    space);
-  SET_EXPR_LOCATION(ret, this->location());
+  SET_EXPR_LOCATION(ret, this->location().gcc_location());
   return ret;
 }
 
@@ -13390,7 +13447,7 @@ Heap_composite_expression::do_dump_expression(
 // Allocate a composite literal on the heap.
 
 Expression*
-Expression::make_heap_composite(Expression* expr, source_location location)
+Expression::make_heap_composite(Expression* expr, Location location)
 {
   return new Heap_composite_expression(expr, location);
 }
@@ -13466,7 +13523,7 @@ Receive_expression::do_dump_expression(Ast_dump_context* ast_dump_context) const
 // Make a receive expression.
 
 Receive_expression*
-Expression::make_receive(Expression* channel, source_location location)
+Expression::make_receive(Expression* channel, Location location)
 {
   return new Receive_expression(channel, location);
 }
@@ -13477,7 +13534,7 @@ Expression::make_receive(Expression* channel, source_location location)
 class Type_descriptor_expression : public Expression
 {
  public:
-  Type_descriptor_expression(Type* type, source_location location)
+  Type_descriptor_expression(Type* type, Location location)
     : Expression(EXPRESSION_TYPE_DESCRIPTOR, location),
       type_(type)
   { }
@@ -13522,7 +13579,7 @@ Type_descriptor_expression::do_dump_expression(
 // Make a type descriptor expression.
 
 Expression*
-Expression::make_type_descriptor(Type* type, source_location location)
+Expression::make_type_descriptor(Type* type, Location location)
 {
   return new Type_descriptor_expression(type, location);
 }
@@ -13537,7 +13594,7 @@ class Type_info_expression : public Expression
 {
  public:
   Type_info_expression(Type* type, Type_info type_info)
-    : Expression(EXPRESSION_TYPE_INFO, BUILTINS_LOCATION),
+    : Expression(EXPRESSION_TYPE_INFO, Linemap::predeclared_location()),
       type_(type), type_info_(type_info)
   { }
 
@@ -13643,7 +13700,8 @@ class Struct_field_offset_expression : public Expression
 {
  public:
   Struct_field_offset_expression(Struct_type* type, const Struct_field* field)
-    : Expression(EXPRESSION_STRUCT_FIELD_OFFSET, BUILTINS_LOCATION),
+    : Expression(EXPRESSION_STRUCT_FIELD_OFFSET,
+                Linemap::predeclared_location()),
       type_(type), field_(field)
   { }
 
@@ -13731,7 +13789,7 @@ Expression::make_struct_field_offset(Struct_type* type,
 class Map_descriptor_expression : public Expression
 {
  public:
-  Map_descriptor_expression(Map_type* type, source_location location)
+  Map_descriptor_expression(Map_type* type, Location location)
     : Expression(EXPRESSION_MAP_DESCRIPTOR, location),
       type_(type)
   { }
@@ -13778,7 +13836,7 @@ Map_descriptor_expression::do_dump_expression(
 // Make a map descriptor expression.
 
 Expression*
-Expression::make_map_descriptor(Map_type* type, source_location location)
+Expression::make_map_descriptor(Map_type* type, Location location)
 {
   return new Map_descriptor_expression(type, location);
 }
@@ -13788,7 +13846,7 @@ Expression::make_map_descriptor(Map_type* type, source_location location)
 class Label_addr_expression : public Expression
 {
  public:
-  Label_addr_expression(Label* label, source_location location)
+  Label_addr_expression(Label* label, Location location)
     : Expression(EXPRESSION_LABEL_ADDR, location),
       label_(label)
   { }
@@ -13824,7 +13882,7 @@ class Label_addr_expression : public Expression
 // Make an expression for the address of an unnamed label.
 
 Expression*
-Expression::make_label_addr(Label* label, source_location location)
+Expression::make_label_addr(Label* label, Location location)
 {
   return new Label_addr_expression(label, location);
 }
index a1f03c4..74d1281 100644 (file)
@@ -98,81 +98,81 @@ class Expression
     EXPRESSION_LABEL_ADDR
   };
 
-  Expression(Expression_classification, source_location);
+  Expression(Expression_classification, Location);
 
   virtual ~Expression();
 
   // Make an error expression.  This is used when a parse error occurs
   // to prevent cascading errors.
   static Expression*
-  make_error(source_location);
+  make_error(Location);
 
   // Make an expression which is really a type.  This is used during
   // parsing.
   static Expression*
-  make_type(Type*, source_location);
+  make_type(Type*, Location);
 
   // Make a unary expression.
   static Expression*
-  make_unary(Operator, Expression*, source_location);
+  make_unary(Operator, Expression*, Location);
 
   // Make a binary expression.
   static Expression*
-  make_binary(Operator, Expression*, Expression*, source_location);
+  make_binary(Operator, Expression*, Expression*, Location);
 
   // Make a reference to a constant in an expression.
   static Expression*
-  make_const_reference(Named_object*, source_location);
+  make_const_reference(Named_object*, Location);
 
   // Make a reference to a variable in an expression.
   static Expression*
-  make_var_reference(Named_object*, source_location);
+  make_var_reference(Named_object*, Location);
 
   // Make a reference to a temporary variable.  Temporary variables
   // are always created by a single statement, which is what we use to
   // refer to them.
   static Temporary_reference_expression*
-  make_temporary_reference(Temporary_statement*, source_location);
+  make_temporary_reference(Temporary_statement*, Location);
 
   // Make a sink expression--a reference to the blank identifier _.
   static Expression*
-  make_sink(source_location);
+  make_sink(Location);
 
   // Make a reference to a function in an expression.
   static Expression*
-  make_func_reference(Named_object*, Expression* closure, source_location);
+  make_func_reference(Named_object*, Expression* closure, Location);
 
   // Make a reference to an unknown name.  In a correct program this
   // will always be lowered to a real const/var/func reference.
   static Expression*
-  make_unknown_reference(Named_object*, source_location);
+  make_unknown_reference(Named_object*, Location);
 
   // Make a constant bool expression.
   static Expression*
-  make_boolean(bool val, source_location);
+  make_boolean(bool val, Location);
 
   // Make a constant string expression.
   static Expression*
-  make_string(const std::string&, source_location);
+  make_string(const std::string&, Location);
 
   // Make a constant integer expression.  TYPE should be NULL for an
   // abstract type.
   static Expression*
-  make_integer(const mpz_t*, Type*, source_location);
+  make_integer(const mpz_t*, Type*, Location);
 
   // Make a constant float expression.  TYPE should be NULL for an
   // abstract type.
   static Expression*
-  make_float(const mpfr_t*, Type*, source_location);
+  make_float(const mpfr_t*, Type*, Location);
 
   // Make a constant complex expression.  TYPE should be NULL for an
   // abstract type.
   static Expression*
-  make_complex(const mpfr_t* real, const mpfr_t* imag, Type*, source_location);
+  make_complex(const mpfr_t* real, const mpfr_t* imag, Type*, Location);
 
   // Make a nil expression.
   static Expression*
-  make_nil(source_location);
+  make_nil(Location);
 
   // Make an iota expression.  This is used for the predeclared
   // constant iota.
@@ -182,7 +182,7 @@ class Expression
   // Make a call expression.
   static Call_expression*
   make_call(Expression* func, Expression_list* args, bool is_varargs,
-           source_location);
+           Location);
 
   // Make a reference to a specific result of a call expression which
   // returns a tuple.
@@ -192,7 +192,7 @@ class Expression
   // Make an expression which is a method bound to its first
   // parameter.
   static Bound_method_expression*
-  make_bound_method(Expression* object, Named_object* method, source_location);
+  make_bound_method(Expression* object, Named_object* method, Location);
 
   // Make an index or slice expression.  This is a parser expression
   // which represents LEFT[START:END].  END may be NULL, meaning an
@@ -201,84 +201,84 @@ class Expression
   // string index, or a map index.
   static Expression*
   make_index(Expression* left, Expression* start, Expression* end,
-            source_location);
+            Location);
 
   // Make an array index expression.  END may be NULL, in which case
   // this is an lvalue.
   static Expression*
   make_array_index(Expression* array, Expression* start, Expression* end,
-                  source_location);
+                  Location);
 
   // Make a string index expression.  END may be NULL.  This is never
   // an lvalue.
   static Expression*
   make_string_index(Expression* string, Expression* start, Expression* end,
-                   source_location);
+                   Location);
 
   // Make a map index expression.  This is an lvalue.
   static Map_index_expression*
-  make_map_index(Expression* map, Expression* val, source_location);
+  make_map_index(Expression* map, Expression* val, Location);
 
   // Make a selector.  This is a parser expression which represents
   // LEFT.NAME.  At parse time we may not know the type of the left
   // hand side.
   static Expression*
-  make_selector(Expression* left, const std::string& name, source_location);
+  make_selector(Expression* left, const std::string& name, Location);
 
   // Make a reference to a field in a struct.
   static Field_reference_expression*
-  make_field_reference(Expression*, unsigned int field_index, source_location);
+  make_field_reference(Expression*, unsigned int field_index, Location);
 
   // Make a reference to a field of an interface, with an associated
   // object.
   static Expression*
   make_interface_field_reference(Expression*, const std::string&,
-                                source_location);
+                                Location);
 
   // Make an allocation expression.
   static Expression*
-  make_allocation(Type*, source_location);
+  make_allocation(Type*, Location);
 
   // Make a type guard expression.
   static Expression*
-  make_type_guard(Expression*, Type*, source_location);
+  make_type_guard(Expression*, Type*, Location);
 
   // Make a type cast expression.
   static Expression*
-  make_cast(Type*, Expression*, source_location);
+  make_cast(Type*, Expression*, Location);
 
   // Make an unsafe type cast expression.  This is only used when
   // passing parameter to builtin functions that are part of the Go
   // runtime.
   static Expression*
-  make_unsafe_cast(Type*, Expression*, source_location);
+  make_unsafe_cast(Type*, Expression*, Location);
 
   // Make a composite literal.  The DEPTH parameter is how far down we
   // are in a list of composite literals with omitted types.
   static Expression*
   make_composite_literal(Type*, int depth, bool has_keys, Expression_list*,
-                        source_location);
+                        Location);
 
   // Make a struct composite literal.
   static Expression*
-  make_struct_composite_literal(Type*, Expression_list*, source_location);
+  make_struct_composite_literal(Type*, Expression_list*, Location);
 
   // Make a slice composite literal.
   static Expression*
-  make_slice_composite_literal(Type*, Expression_list*, source_location);
+  make_slice_composite_literal(Type*, Expression_list*, Location);
 
   // Take a composite literal and allocate it on the heap.
   static Expression*
-  make_heap_composite(Expression*, source_location);
+  make_heap_composite(Expression*, Location);
 
   // Make a receive expression.  VAL is NULL for a unary receive.
   static Receive_expression*
-  make_receive(Expression* channel, source_location);
+  make_receive(Expression* channel, Location);
 
   // Make an expression which evaluates to the address of the type
   // descriptor for TYPE.
   static Expression*
-  make_type_descriptor(Type* type, source_location);
+  make_type_descriptor(Type* type, Location);
 
   // Make an expression which evaluates to some characteristic of a
   // type.  These are only used for type descriptors, so there is no
@@ -306,12 +306,12 @@ class Expression
   // Make an expression which evaluates to the address of the map
   // descriptor for TYPE.
   static Expression*
-  make_map_descriptor(Map_type* type, source_location);
+  make_map_descriptor(Map_type* type, Location);
 
   // Make an expression which evaluates to the address of an unnamed
   // label.
   static Expression*
-  make_label_addr(Label*, source_location);
+  make_label_addr(Label*, Location);
 
   // Return the expression classification.
   Expression_classification
@@ -319,7 +319,7 @@ class Expression
   { return this->classification_; }
 
   // Return the location of the expression.
-  source_location
+  Location
   location() const
   { return this->location_; }
 
@@ -602,7 +602,7 @@ class Expression
   // assignment.
   static tree
   convert_for_assignment(Translate_context*, Type* lhs_type, Type* rhs_type,
-                        tree rhs_tree, source_location location);
+                        tree rhs_tree, Location location);
 
   // Return a tree converting a value of one interface type to another
   // interface type.  If FOR_TYPE_GUARD is true this is for a type
@@ -610,14 +610,14 @@ class Expression
   static tree
   convert_interface_to_interface(Translate_context*, Type* lhs_type,
                                 Type* rhs_type, tree rhs_tree,
-                                bool for_type_guard, source_location);
+                                bool for_type_guard, Location);
 
   // Return a tree implementing the comparison LHS_TREE OP RHS_TREE.
   // TYPE is the type of both sides.
   static tree
   comparison_tree(Translate_context*, Operator op, Type* left_type,
                  tree left_tree, Type* right_type, tree right_tree,
-                 source_location);
+                 Location);
 
   // Return a tree for the multi-precision integer VAL in TYPE.
   static tree
@@ -647,7 +647,7 @@ class Expression
   // BOUND_TYPE.  If SOFAR is not NULL, it is or'red into the result.
   // The return value may be NULL if SOFAR is NULL.
   static tree
-  check_bounds(tree val, tree bound_type, tree sofar, source_location);
+  check_bounds(tree val, tree bound_type, tree sofar, Location);
 
   // Dump an expression to a dump constext.
   void
@@ -785,20 +785,20 @@ class Expression
 
   static tree
   convert_type_to_interface(Translate_context*, Type*, Type*, tree,
-                           source_location);
+                           Location);
 
   static tree
   get_interface_type_descriptor(Translate_context*, Type*, tree,
-                               source_location);
+                               Location);
 
   static tree
   convert_interface_to_type(Translate_context*, Type*, Type*, tree,
-                           source_location);
+                           Location);
 
   // The expression classification.
   Expression_classification classification_;
   // The location in the input file.
-  source_location location_;
+  Location location_;
 };
 
 // A list of Expressions.
@@ -900,7 +900,7 @@ class Parser_expression : public Expression
 {
  public:
   Parser_expression(Expression_classification classification,
-                   source_location location)
+                   Location location)
     : Expression(classification, location)
   { }
 
@@ -929,7 +929,7 @@ class Parser_expression : public Expression
 class Var_expression : public Expression
 {
  public:
-  Var_expression(Named_object* variable, source_location location)
+  Var_expression(Named_object* variable, Location location)
     : Expression(EXPRESSION_VAR_REFERENCE, location),
       variable_(variable)
   { }
@@ -977,7 +977,7 @@ class Temporary_reference_expression : public Expression
 {
  public:
   Temporary_reference_expression(Temporary_statement* statement,
-                                source_location location)
+                                Location location)
     : Expression(EXPRESSION_TEMPORARY_REFERENCE, location),
       statement_(statement), is_lvalue_(false)
   { }
@@ -1026,7 +1026,7 @@ class Temporary_reference_expression : public Expression
 class String_expression : public Expression
 {
  public:
-  String_expression(const std::string& val, source_location location)
+  String_expression(const std::string& val, Location location)
     : Expression(EXPRESSION_STRING, location),
       val_(val), type_(NULL)
   { }
@@ -1086,7 +1086,7 @@ class Binary_expression : public Expression
 {
  public:
   Binary_expression(Operator op, Expression* left, Expression* right,
-                   source_location location)
+                   Location location)
     : Expression(EXPRESSION_BINARY, location),
       op_(op), left_(left), right_(right)
   { }
@@ -1112,7 +1112,7 @@ class Binary_expression : public Expression
   // if this could be done, false if not.
   static bool
   eval_integer(Operator op, Type* left_type, mpz_t left_val,
-              Type* right_type, mpz_t right_val, source_location,
+              Type* right_type, mpz_t right_val, Location,
               mpz_t val);
 
   // Apply binary opcode OP to LEFT_VAL and RIGHT_VAL, setting VAL.
@@ -1120,7 +1120,7 @@ class Binary_expression : public Expression
   static bool
   eval_float(Operator op, Type* left_type, mpfr_t left_val,
             Type* right_type, mpfr_t right_val, mpfr_t val,
-            source_location);
+            Location);
 
   // Apply binary opcode OP to LEFT_REAL/LEFT_IMAG and
   // RIGHT_REAL/RIGHT_IMAG, setting REAL/IMAG.  Return true if this
@@ -1128,7 +1128,7 @@ class Binary_expression : public Expression
   static bool
   eval_complex(Operator op, Type* left_type, mpfr_t left_real,
               mpfr_t left_imag, Type* right_type, mpfr_t right_real,
-              mpfr_t right_imag, mpfr_t real, mpfr_t imag, source_location);
+              mpfr_t right_imag, mpfr_t real, mpfr_t imag, Location);
 
   // Compare integer constants according to OP.
   static bool
@@ -1149,7 +1149,7 @@ class Binary_expression : public Expression
   // Report an error if OP can not be applied to TYPE.  Return whether
   // it can.
   static bool
-  check_operator_type(Operator op, Type* type, source_location);
+  check_operator_type(Operator op, Type* type, Location);
 
  protected:
   int
@@ -1214,7 +1214,7 @@ class Call_expression : public Expression
 {
  public:
   Call_expression(Expression* fn, Expression_list* args, bool is_varargs,
-                 source_location location)
+                 Location location)
     : Expression(EXPRESSION_CALL, location),
       fn_(fn), args_(args), type_(NULL), results_(NULL), tree_(NULL),
       is_varargs_(is_varargs), are_hidden_fields_ok_(false),
@@ -1352,7 +1352,7 @@ class Call_expression : public Expression
 
  private:
   bool
-  check_argument_type(int, const Type*, const Type*, source_location, bool);
+  check_argument_type(int, const Type*, const Type*, Location, bool);
 
   tree
   interface_method_function(Translate_context*,
@@ -1397,7 +1397,7 @@ class Func_expression : public Expression
 {
  public:
   Func_expression(Named_object* function, Expression* closure,
-                 source_location location)
+                 Location location)
     : Expression(EXPRESSION_FUNC_REFERENCE, location),
       function_(function), closure_(closure)
   { }
@@ -1461,7 +1461,7 @@ class Func_expression : public Expression
 class Unknown_expression : public Parser_expression
 {
  public:
-  Unknown_expression(Named_object* named_object, source_location location)
+  Unknown_expression(Named_object* named_object, Location location)
     : Parser_expression(EXPRESSION_UNKNOWN_REFERENCE, location),
       named_object_(named_object), is_composite_literal_key_(false)
   { }
@@ -1512,7 +1512,7 @@ class Index_expression : public Parser_expression
 {
  public:
   Index_expression(Expression* left, Expression* start, Expression* end,
-                  source_location location)
+                  Location location)
     : Parser_expression(EXPRESSION_INDEX, location),
       left_(left), start_(start), end_(end), is_lvalue_(false)
   { }
@@ -1574,7 +1574,7 @@ class Map_index_expression : public Expression
 {
  public:
   Map_index_expression(Expression* map, Expression* index,
-                      source_location location)
+                      Location location)
     : Expression(EXPRESSION_MAP_INDEX, location),
       map_(map), index_(index), is_lvalue_(false),
       is_in_tuple_assignment_(false)
@@ -1682,7 +1682,7 @@ class Bound_method_expression : public Expression
 {
  public:
   Bound_method_expression(Expression* expr, Named_object* method,
-                         source_location location)
+                         Location location)
     : Expression(EXPRESSION_BOUND_METHOD, location),
       expr_(expr), expr_type_(NULL), method_(method)
   { }
@@ -1753,7 +1753,7 @@ class Field_reference_expression : public Expression
 {
  public:
   Field_reference_expression(Expression* expr, unsigned int field_index,
-                            source_location location)
+                            Location location)
     : Expression(EXPRESSION_FIELD_REFERENCE, location),
       expr_(expr), field_index_(field_index)
   { }
@@ -1824,7 +1824,7 @@ class Interface_field_reference_expression : public Expression
  public:
   Interface_field_reference_expression(Expression* expr,
                                       const std::string& name,
-                                      source_location location)
+                                      Location location)
     : Expression(EXPRESSION_INTERFACE_FIELD_REFERENCE, location),
       expr_(expr), name_(name)
   { }
@@ -1890,7 +1890,7 @@ class Interface_field_reference_expression : public Expression
 class Type_guard_expression : public Expression
 {
  public:
-  Type_guard_expression(Expression* expr, Type* type, source_location location)
+  Type_guard_expression(Expression* expr, Type* type, Location location)
     : Expression(EXPRESSION_TYPE_GUARD, location),
       expr_(expr), type_(type)
   { }
@@ -1945,7 +1945,7 @@ class Type_guard_expression : public Expression
 class Receive_expression : public Expression
 {
  public:
-  Receive_expression(Expression* channel, source_location location)
+  Receive_expression(Expression* channel, Location location)
     : Expression(EXPRESSION_RECEIVE, location),
       channel_(channel), for_select_(false)
   { }
diff --git a/gcc/go/gofrontend/go-linemap.h b/gcc/go/gofrontend/go-linemap.h
new file mode 100644 (file)
index 0000000..ffbcbe7
--- /dev/null
@@ -0,0 +1,131 @@
+// go-linemap.h -- interface to location tracking   -*- C++ -*-
+
+// Copyright 2011 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_LINEMAP_H
+#define GO_LINEMAP_H
+
+#include "go-system.h"
+
+// The backend must define a type named Location which holds
+// information about a location in a source file.  The only thing the
+// frontend does with instances of Location is pass them back to the
+// backend interface.  The Location type must be assignable, and it
+// must be comparable: i.e., it must support operator= and operator<.
+// The type is normally passed by value rather than by reference, and
+// it should support that efficiently.  The type should be defined in
+// "go-location.h".
+
+#include "go-location.h"
+
+// The Linemap class is a pure abstract interface, plus some static
+// convenience functions.  The backend must implement the interface.
+
+class Linemap
+{
+ public:
+  Linemap()
+  {
+    // Only one instance of Linemap is allowed to exist.
+    go_assert(Linemap::instance_ == NULL);
+    Linemap::instance_ = this;
+  }
+
+  virtual
+  ~Linemap() { Linemap::instance_ = NULL; }
+
+  // Subsequent Location values will come from the file named
+  // FILE_NAME, starting at LINE_BEGIN.  Normally LINE_BEGIN will be
+  // 0, but it will be non-zero if the Go source has a //line comment.
+  virtual void
+  start_file(const char* file_name, unsigned int line_begin) = 0;
+
+  // Subsequent Location values will come from the line LINE_NUMBER,
+  // in the current file.  LINE_SIZE is the size of the line in bytes.
+  // This will normally be called for every line in a source file.
+  virtual void
+  start_line(unsigned int line_number, unsigned int line_size) = 0;
+
+  // Get a Location representing column position COLUMN on the current
+  // line in the current file.
+  virtual Location
+  get_location(unsigned int column) = 0;
+
+  // Stop generating Location values.  This will be called after all
+  // input files have been read, in case any cleanup is required.
+  virtual void
+  stop() = 0;
+
+ protected:
+  // Return a special Location used for predeclared identifiers.  This
+  // Location should be different from that for any actual source
+  // file.  This location will be used for various different types,
+  // functions, and objects created by the frontend.
+  virtual Location
+  get_predeclared_location() = 0;
+
+  // Return a special Location which indicates that no actual location
+  // is known.  This is used for undefined objects and for errors.
+  virtual Location
+  get_unknown_location() = 0;
+
+  // Return whether the argument is the Location returned by
+  // get_predeclared_location.
+  virtual bool
+  is_predeclared(Location) = 0;
+
+  // Return whether the argument is the Location returned by
+  // get_unknown_location.
+  virtual bool
+  is_unknown(Location) = 0;
+
+  // The single existing instance of Linemap.
+  static Linemap *instance_;
+
+ public:
+  // Following are convenience static functions, which allow us to
+  // access some virtual functions without explicitly passing around
+  // an instance of Linemap.
+
+  // Return the special Location used for predeclared identifiers.
+  static Location
+  predeclared_location()
+  {
+    go_assert(Linemap::instance_ != NULL);
+    return Linemap::instance_->get_predeclared_location();
+  }
+
+  // Return the special Location used when no location is known.
+  static Location
+  unknown_location()
+  {
+    go_assert(Linemap::instance_ != NULL);
+    return Linemap::instance_->get_unknown_location();
+  }
+
+  // Return whether the argument is the special location used for
+  // predeclared identifiers.
+  static bool
+  is_predeclared_location(Location loc)
+  {
+    go_assert(Linemap::instance_ != NULL);
+    return Linemap::instance_->is_predeclared(loc);
+  }
+
+  // Return whether the argument is the special location used when no
+  // location is known.
+  static bool
+  is_unknown_location(Location loc)
+  {
+    go_assert(Linemap::instance_ != NULL);
+    return Linemap::instance_->is_unknown(loc);
+  }
+};
+
+// The backend interface must define this function.  It should return
+// a fully implemented instance of Linemap.
+extern Linemap* go_get_linemap();
+
+#endif // !defined(GO_LINEMAP_H)
index 4ab0f8e..39af549 100644 (file)
@@ -28,7 +28,8 @@ void
 go_create_gogo(int int_type_size, int pointer_size)
 {
   go_assert(::gogo == NULL);
-  ::gogo = new Gogo(go_get_backend(), int_type_size, pointer_size);
+  Linemap* linemap = go_get_linemap();
+  ::gogo = new Gogo(go_get_backend(), linemap, int_type_size, pointer_size);
   if (!unique_prefix.empty())
     ::gogo->set_unique_prefix(unique_prefix);
 
@@ -64,6 +65,7 @@ go_parse_input_files(const char** filenames, unsigned int filename_count,
                     bool only_check_syntax, bool require_return_statement)
 {
   go_assert(filename_count > 0);
+
   for (unsigned int i = 0; i < filename_count; ++i)
     {
       if (i > 0)
@@ -80,7 +82,7 @@ go_parse_input_files(const char** filenames, unsigned int filename_count,
            fatal_error("cannot open %s: %m", filename);
        }
 
-      Lex lexer(filename, file);
+      Lex lexer(filename, file, ::gogo->linemap());
 
       Parse parse(&lexer, ::gogo);
       parse.program();
@@ -89,6 +91,8 @@ go_parse_input_files(const char** filenames, unsigned int filename_count,
        fclose(file);
     }
 
+  ::gogo->linemap()->stop();
+
   ::gogo->clear_file_scope();
 
   // If the global predeclared names are referenced but not defined,
index 349ee25..0e77f5d 100644 (file)
@@ -336,8 +336,9 @@ Gogo::register_gc_vars(const std::vector<Named_object*>& var_gc,
   rest_of_decl_compilation(decl, 1, 0);
 
   static tree register_gc_fndecl;
-  tree call = Gogo::call_builtin(&register_gc_fndecl, BUILTINS_LOCATION,
-                                "__go_register_gc_roots",
+  tree call = Gogo::call_builtin(&register_gc_fndecl,
+                                 Linemap::predeclared_location(),
+                                 "__go_register_gc_roots",
                                 1,
                                 void_type_node,
                                 build_pointer_type(root_list_type),
@@ -746,8 +747,9 @@ Gogo::write_globals()
              else if (is_sink)
                var_init_tree = init;
              else
-               var_init_tree = fold_build2_loc(no->location(), MODIFY_EXPR,
-                                               void_type_node, vec[i], init);
+               var_init_tree = fold_build2_loc(no->location().gcc_location(),
+                                                MODIFY_EXPR, void_type_node,
+                                                vec[i], init);
            }
          else
            {
@@ -843,7 +845,7 @@ Named_object::get_id(Gogo* gogo)
       && !this->func_declaration_value()->asm_name().empty())
     decl_name = this->func_declaration_value()->asm_name();
   else if (this->is_type()
-          && this->type_value()->location() == BUILTINS_LOCATION)
+          && Linemap::is_predeclared_location(this->type_value()->location()))
     {
       // We don't need the package name for builtin types.
       decl_name = Gogo::unpack_hidden_name(this->name_);
@@ -920,8 +922,8 @@ Named_object::get_tree(Gogo* gogo, Named_object* function)
              decl = error_mark_node;
            else if (INTEGRAL_TYPE_P(TREE_TYPE(expr_tree)))
              {
-               decl = build_decl(named_constant->location(), CONST_DECL,
-                                 name, TREE_TYPE(expr_tree));
+               decl = build_decl(named_constant->location().gcc_location(),
+                                  CONST_DECL, name, TREE_TYPE(expr_tree));
                DECL_INITIAL(decl) = expr_tree;
                TREE_CONSTANT(decl) = 1;
                TREE_READONLY(decl) = 1;
@@ -958,9 +960,12 @@ Named_object::get_tree(Gogo* gogo, Named_object* function)
            // descriptor, even though we don't do anything with it.
            if (this->package_ == NULL)
              {
-               named_type->type_descriptor_pointer(gogo, BUILTINS_LOCATION);
+               named_type->
+                  type_descriptor_pointer(gogo,
+                                         Linemap::predeclared_location());
                Type* pn = Type::make_pointer_type(named_type);
-               pn->type_descriptor_pointer(gogo, BUILTINS_LOCATION);
+               pn->type_descriptor_pointer(gogo,
+                                           Linemap::predeclared_location());
              }
          }
       }
@@ -989,7 +994,8 @@ Named_object::get_tree(Gogo* gogo, Named_object* function)
                else
                  push_cfun(DECL_STRUCT_FUNCTION(decl));
 
-               cfun->function_end_locus = func->block()->end_location();
+               cfun->function_end_locus =
+                  func->block()->end_location().gcc_location();
 
                current_function_decl = decl;
 
@@ -1091,8 +1097,9 @@ Variable::get_init_block(Gogo* gogo, Named_object* function, tree var_decl)
                                                        this->location());
          if (val == error_mark_node)
            return error_mark_node;
-         tree set = fold_build2_loc(this->location(), MODIFY_EXPR,
-                                    void_type_node, var_decl, val);
+         tree set = fold_build2_loc(this->location().gcc_location(),
+                                     MODIFY_EXPR, void_type_node, var_decl,
+                                     val);
          append_to_statement_list(set, &statements);
        }
     }
@@ -1116,7 +1123,8 @@ Function::get_or_make_decl(Gogo* gogo, Named_object* no, tree id)
          // want the real function type for a function declaration.
          go_assert(POINTER_TYPE_P(functype));
          functype = TREE_TYPE(functype);
-         tree decl = build_decl(this->location(), FUNCTION_DECL, id, functype);
+         tree decl = build_decl(this->location().gcc_location(), FUNCTION_DECL,
+                                 id, functype);
 
          this->fndecl_ = decl;
 
@@ -1146,8 +1154,9 @@ Function::get_or_make_decl(Gogo* gogo, Named_object* no, tree id)
 
          // Why do we have to do this in the frontend?
          tree restype = TREE_TYPE(functype);
-         tree resdecl = build_decl(this->location(), RESULT_DECL, NULL_TREE,
-                                   restype);
+         tree resdecl =
+            build_decl(this->location().gcc_location(), RESULT_DECL, NULL_TREE,
+                       restype);
          DECL_ARTIFICIAL(resdecl) = 1;
          DECL_IGNORED_P(resdecl) = 1;
          DECL_CONTEXT(resdecl) = decl;
@@ -1233,7 +1242,8 @@ Function_declaration::get_or_make_decl(Gogo* gogo, Named_object* no, tree id)
          // want the real function type for a function declaration.
          go_assert(POINTER_TYPE_P(functype));
          functype = TREE_TYPE(functype);
-         decl = build_decl(this->location(), FUNCTION_DECL, id, functype);
+         decl = build_decl(this->location().gcc_location(), FUNCTION_DECL, id,
+                            functype);
          TREE_PUBLIC(decl) = 1;
          DECL_EXTERNAL(decl) = 1;
 
@@ -1292,7 +1302,8 @@ Function::make_receiver_parm_decl(Gogo* gogo, Named_object* no, tree var_decl)
                                         no->location());
       space = save_expr(space);
       space = fold_convert(build_pointer_type(val_type), space);
-      tree spaceref = build_fold_indirect_ref_loc(no->location(), space);
+      tree spaceref = build_fold_indirect_ref_loc(no->location().gcc_location(),
+                                                  space);
       TREE_THIS_NOTRAP(spaceref) = 1;
       tree set = fold_build2_loc(loc, MODIFY_EXPR, void_type_node,
                                 spaceref, init);
@@ -1314,7 +1325,7 @@ Function::copy_parm_to_heap(Gogo* gogo, Named_object* no, tree var_decl)
   if (var_decl == error_mark_node)
     return error_mark_node;
   go_assert(TREE_CODE(var_decl) == VAR_DECL);
-  source_location loc = DECL_SOURCE_LOCATION(var_decl);
+  Location loc(DECL_SOURCE_LOCATION(var_decl));
 
   std::string name = IDENTIFIER_POINTER(DECL_NAME(var_decl));
   name += ".param";
@@ -1324,7 +1335,7 @@ Function::copy_parm_to_heap(Gogo* gogo, Named_object* no, tree var_decl)
   go_assert(POINTER_TYPE_P(type));
   type = TREE_TYPE(type);
 
-  tree parm_decl = build_decl(loc, PARM_DECL, id, type);
+  tree parm_decl = build_decl(loc.gcc_location(), PARM_DECL, id, type);
   DECL_CONTEXT(parm_decl) = current_function_decl;
   DECL_ARG_TYPE(parm_decl) = type;
 
@@ -1332,7 +1343,7 @@ Function::copy_parm_to_heap(Gogo* gogo, Named_object* no, tree var_decl)
   tree space = gogo->allocate_memory(no->var_value()->type(), size, loc);
   space = save_expr(space);
   space = fold_convert(TREE_TYPE(var_decl), space);
-  tree spaceref = build_fold_indirect_ref_loc(loc, space);
+  tree spaceref = build_fold_indirect_ref_loc(loc.gcc_location(), space);
   TREE_THIS_NOTRAP(spaceref) = 1;
   tree init = build2(COMPOUND_EXPR, TREE_TYPE(space),
                     build2(MODIFY_EXPR, void_type_node, spaceref, parm_decl),
@@ -1415,13 +1426,13 @@ Function::build_tree(Gogo* gogo, Named_object* named_function)
            }
          else
            {
-             source_location loc = (*p)->location();
+             Location loc = (*p)->location();
              tree type_tree = type_to_tree(type->get_backend(gogo));
              tree space = gogo->allocate_memory(type,
                                                 TYPE_SIZE_UNIT(type_tree),
                                                 loc);
              tree ptr_type_tree = build_pointer_type(type_tree);
-             init = fold_convert_loc(loc, ptr_type_tree, space);
+             init = fold_convert_loc(loc.gcc_location(), ptr_type_tree, space);
            }
 
          if (var_decl != error_mark_node)
@@ -1486,7 +1497,8 @@ Function::build_tree(Gogo* gogo, Named_object* named_function)
       // function.
       if (defer_init != NULL_TREE && defer_init != error_mark_node)
        {
-         SET_EXPR_LOCATION(defer_init, this->block_->start_location());
+         SET_EXPR_LOCATION(defer_init,
+                            this->block_->start_location().gcc_location());
          append_to_statement_list(defer_init, &init);
 
          // Clean up the defer stack when we leave the function.
@@ -1524,7 +1536,7 @@ void
 Function::build_defer_wrapper(Gogo* gogo, Named_object* named_function,
                              tree *except, tree *fini)
 {
-  source_location end_loc = this->block_->end_location();
+  Location end_loc = this->block_->end_location();
 
   // Add an exception handler.  This is used if a panic occurs.  Its
   // purpose is to stop the stack unwinding if a deferred function
@@ -1545,9 +1557,10 @@ Function::build_defer_wrapper(Gogo* gogo, Named_object* named_function,
   if (retval == NULL_TREE)
     set = NULL_TREE;
   else
-    set = fold_build2_loc(end_loc, MODIFY_EXPR, void_type_node,
+    set = fold_build2_loc(end_loc.gcc_location(), MODIFY_EXPR, void_type_node,
                          DECL_RESULT(this->fndecl_), retval);
-  tree ret_stmt = fold_build1_loc(end_loc, RETURN_EXPR, void_type_node, set);
+  tree ret_stmt = fold_build1_loc(end_loc.gcc_location(), RETURN_EXPR,
+                                  void_type_node, set);
   append_to_statement_list(ret_stmt, &stmt_list);
 
   go_assert(*except == NULL_TREE);
@@ -1564,9 +1577,9 @@ Function::build_defer_wrapper(Gogo* gogo, Named_object* named_function,
 
   stmt_list = NULL;
 
-  tree label = create_artificial_label(end_loc);
-  tree define_label = fold_build1_loc(end_loc, LABEL_EXPR, void_type_node,
-                                     label);
+  tree label = create_artificial_label(end_loc.gcc_location());
+  tree define_label = fold_build1_loc(end_loc.gcc_location(), LABEL_EXPR,
+                                      void_type_node, label);
   append_to_statement_list(define_label, &stmt_list);
 
   call = Runtime::make_call(Runtime::UNDEFER, end_loc, 1,
@@ -1580,7 +1593,8 @@ Function::build_defer_wrapper(Gogo* gogo, Named_object* named_function,
   if (undefer == error_mark_node || defer == error_mark_node)
     return;
 
-  tree jump = fold_build1_loc(end_loc, GOTO_EXPR, void_type_node, label);
+  tree jump = fold_build1_loc(end_loc.gcc_location(), GOTO_EXPR, void_type_node,
+                              label);
   tree catch_body = build2(COMPOUND_EXPR, void_type_node, defer, jump);
   catch_body = build2(CATCH_EXPR, void_type_node, NULL, catch_body);
   tree try_catch = build2(TRY_CATCH_EXPR, void_type_node, undefer, catch_body);
@@ -1598,15 +1612,16 @@ Function::build_defer_wrapper(Gogo* gogo, Named_object* named_function,
       // variable to true if we are returning from this function.
       retval = this->return_value(gogo, named_function, end_loc,
                                  &stmt_list);
-      set = fold_build2_loc(end_loc, MODIFY_EXPR, void_type_node,
+      set = fold_build2_loc(end_loc.gcc_location(), MODIFY_EXPR, void_type_node,
                            DECL_RESULT(this->fndecl_), retval);
-      ret_stmt = fold_build1_loc(end_loc, RETURN_EXPR, void_type_node, set);
+      ret_stmt = fold_build1_loc(end_loc.gcc_location(), RETURN_EXPR,
+                                 void_type_node, set);
 
       Expression* ref =
        Expression::make_temporary_reference(this->defer_stack_, end_loc);
       tree tref = ref->get_tree(&context);
-      tree s = build3_loc(end_loc, COND_EXPR, void_type_node, tref,
-                         ret_stmt, NULL_TREE);
+      tree s = build3_loc(end_loc.gcc_location(), COND_EXPR, void_type_node,
+                          tref, ret_stmt, NULL_TREE);
 
       append_to_statement_list(s, &stmt_list);
 
@@ -1623,7 +1638,7 @@ Function::build_defer_wrapper(Gogo* gogo, Named_object* named_function,
 
 tree
 Function::return_value(Gogo* gogo, Named_object* named_function,
-                      source_location location, tree* stmt_list) const
+                      Location location, tree* stmt_list) const
 {
   const Typed_identifier_list* results = this->type_->results();
   if (results == NULL || results->empty())
@@ -1644,7 +1659,7 @@ Function::return_value(Gogo* gogo, Named_object* named_function,
                                                      named_function);
       tree ret = var_to_tree(bvar);
       if (this->results_->front()->result_var_value()->is_in_heap())
-       ret = build_fold_indirect_ref_loc(location, ret);
+       ret = build_fold_indirect_ref_loc(location.gcc_location(), ret);
       return ret;
     }
   else
@@ -1662,8 +1677,9 @@ Function::return_value(Gogo* gogo, Named_object* named_function,
          Bvariable* bvar = no->get_backend_variable(gogo, named_function);
          tree val = var_to_tree(bvar);
          if (no->result_var_value()->is_in_heap())
-           val = build_fold_indirect_ref_loc(location, val);
-         tree set = fold_build2_loc(location, MODIFY_EXPR, void_type_node,
+           val = build_fold_indirect_ref_loc(location.gcc_location(), val);
+         tree set = fold_build2_loc(location.gcc_location(), MODIFY_EXPR,
+                                     void_type_node,
                                     build3(COMPONENT_REF, TREE_TYPE(field),
                                            retval, field, NULL_TREE),
                                     val);
@@ -1762,7 +1778,7 @@ go_type_for_mode(enum machine_mode mode, int unsignedp)
 // type TYPE.
 
 tree
-Gogo::allocate_memory(Type* type, tree size, source_location location)
+Gogo::allocate_memory(Type* type, tree size, Location location)
 {
   // If the package imports unsafe, then it may play games with
   // pointers that look like integers.
@@ -2028,7 +2044,8 @@ Gogo::interface_method_table_for_type(const Interface_type* interface,
     td_type = type;
   else
     td_type = Type::make_pointer_type(type);
-  tree tdp = td_type->type_descriptor_pointer(this, BUILTINS_LOCATION);
+  tree tdp = td_type->type_descriptor_pointer(this,
+                                              Linemap::predeclared_location());
   elt->value = fold_convert(const_ptr_type_node, tdp);
 
   size_t i = 1;
@@ -2105,7 +2122,7 @@ Gogo::mark_fndecl_as_builtin_library(tree fndecl)
 // Build a call to a builtin function.
 
 tree
-Gogo::call_builtin(tree* pdecl, source_location location, const char* name,
+Gogo::call_builtin(tree* pdecl, Location location, const char* name,
                   int nargs, tree rettype, ...)
 {
   if (rettype == error_mark_node)
@@ -2151,10 +2168,10 @@ Gogo::call_builtin(tree* pdecl, source_location location, const char* name,
 
   tree fnptr = build_fold_addr_expr(*pdecl);
   if (CAN_HAVE_LOCATION_P(fnptr))
-    SET_EXPR_LOCATION(fnptr, location);
+    SET_EXPR_LOCATION(fnptr, location.gcc_location());
 
   tree ret = build_call_array(rettype, fnptr, nargs, args);
-  SET_EXPR_LOCATION(ret, location);
+  SET_EXPR_LOCATION(ret, location.gcc_location());
 
   delete[] types;
   delete[] args;
@@ -2165,7 +2182,7 @@ Gogo::call_builtin(tree* pdecl, source_location location, const char* name,
 // Build a call to the runtime error function.
 
 tree
-Gogo::runtime_error(int code, source_location location)
+Gogo::runtime_error(int code, Location location)
 {
   static tree runtime_error_fndecl;
   tree ret = Gogo::call_builtin(&runtime_error_fndecl,
@@ -2190,7 +2207,7 @@ Gogo::runtime_error(int code, source_location location)
 
 tree
 Gogo::receive_from_channel(tree type_tree, tree channel, bool for_select,
-                          source_location location)
+                          Location location)
 {
   if (type_tree == error_mark_node || channel == error_mark_node)
     return error_mark_node;
@@ -2218,9 +2235,9 @@ Gogo::receive_from_channel(tree type_tree, tree channel, bool for_select,
       TREE_NOTHROW(receive_small_fndecl) = 0;
       int bitsize = GET_MODE_BITSIZE(TYPE_MODE(type_tree));
       tree int_type_tree = go_type_for_size(bitsize, 1);
-      return fold_convert_loc(location, type_tree,
-                             fold_convert_loc(location, int_type_tree,
-                                              call));
+      return fold_convert_loc(location.gcc_location(), type_tree,
+                             fold_convert_loc(location.gcc_location(),
+                                               int_type_tree, call));
     }
   else
     {
@@ -2228,7 +2245,7 @@ Gogo::receive_from_channel(tree type_tree, tree channel, bool for_select,
       DECL_IGNORED_P(tmp) = 0;
       TREE_ADDRESSABLE(tmp) = 1;
       tree make_tmp = build1(DECL_EXPR, void_type_node, tmp);
-      SET_EXPR_LOCATION(make_tmp, location);
+      SET_EXPR_LOCATION(make_tmp, location.gcc_location());
       tree tmpaddr = build_fold_addr_expr(tmp);
       tmpaddr = fold_convert(ptr_type_node, tmpaddr);
       static tree receive_big_fndecl;
@@ -2284,7 +2301,7 @@ Gogo::trampoline_type_tree()
 // Make a trampoline which calls FNADDR passing CLOSURE.
 
 tree
-Gogo::make_trampoline(tree fnaddr, tree closure, source_location location)
+Gogo::make_trampoline(tree fnaddr, tree closure, Location location)
 {
   tree trampoline_type = Gogo::trampoline_type_tree();
   tree trampoline_size = TYPE_SIZE_UNIT(trampoline_type);
@@ -2302,8 +2319,8 @@ Gogo::make_trampoline(tree fnaddr, tree closure, source_location location)
                              size_type_node,
                              trampoline_size,
                              ptr_type_node,
-                             fold_convert_loc(location, ptr_type_node,
-                                              closure));
+                             fold_convert_loc(location.gcc_location(),
+                                               ptr_type_node, closure));
   if (x == error_mark_node)
     return error_mark_node;
 
index 45fb938..dc5ac75 100644 (file)
 
 // Class Gogo.
 
-Gogo::Gogo(Backend* backend, int int_type_size, int pointer_size)
+Gogo::Gogo(Backend* backend, Linemap* linemap, int int_type_size,
+           int pointer_size)
   : backend_(backend),
+    linemap_(linemap),
     package_(NULL),
     functions_(),
     globals_(new Bindings(NULL)),
@@ -38,7 +40,7 @@ Gogo::Gogo(Backend* backend, int int_type_size, int pointer_size)
     interface_types_(),
     named_types_are_converted_(false)
 {
-  const source_location loc = BUILTINS_LOCATION;
+  const Location loc = Linemap::predeclared_location();
 
   Named_type* uint8_type = Type::make_integer_type("uint8", true, 8,
                                                   RUNTIME_TYPE_KIND_UINT8);
@@ -245,7 +247,7 @@ Gogo::package_name() const
 
 void
 Gogo::set_package_name(const std::string& package_name,
-                      source_location location)
+                      Location location)
 {
   if (this->package_ != NULL && this->package_->name() != package_name)
     {
@@ -270,10 +272,10 @@ Gogo::set_package_name(const std::string& package_name,
     {
       // Declare "main" as a function which takes no parameters and
       // returns no value.
+      Location uloc = Linemap::unknown_location();
       this->declare_function("main",
-                            Type::make_function_type(NULL, NULL, NULL,
-                                                     BUILTINS_LOCATION),
-                            BUILTINS_LOCATION);
+                            Type::make_function_type (NULL, NULL, NULL, uloc),
+                            uloc);
     }
 }
 
@@ -292,7 +294,7 @@ void
 Gogo::import_package(const std::string& filename,
                     const std::string& local_name,
                     bool is_local_name_exported,
-                    source_location location)
+                    Location location)
 {
   if (filename == "unsafe")
     {
@@ -502,7 +504,7 @@ Gogo::add_imported_package(const std::string& real_name,
                           const std::string& alias_arg,
                           bool is_alias_exported,
                           const std::string& unique_prefix,
-                          source_location location,
+                          Location location,
                           bool* padd_to_globals)
 {
   // FIXME: Now that we compile packages as a whole, should we permit
@@ -552,7 +554,7 @@ Gogo::add_imported_package(const std::string& real_name,
 
 Named_object*
 Gogo::add_package(const std::string& real_name, const std::string& alias,
-                 const std::string& unique_prefix, source_location location)
+                 const std::string& unique_prefix, Location location)
 {
   go_assert(this->in_global_scope());
 
@@ -570,7 +572,7 @@ Gogo::add_package(const std::string& real_name, const std::string& alias,
 Package*
 Gogo::register_package(const std::string& package_name,
                       const std::string& unique_prefix,
-                      source_location location)
+                      Location location)
 {
   go_assert(!unique_prefix.empty() && !package_name.empty());
   std::string name = unique_prefix + '.' + package_name;
@@ -584,7 +586,7 @@ Gogo::register_package(const std::string& package_name,
       go_assert(package != NULL);
       go_assert(package->name() == package_name
                 && package->unique_prefix() == unique_prefix);
-      if (package->location() == UNKNOWN_LOCATION)
+      if (Linemap::is_unknown_location(package->location()))
        package->set_location(location);
     }
   else
@@ -602,7 +604,7 @@ Gogo::register_package(const std::string& package_name,
 
 Named_object*
 Gogo::start_function(const std::string& name, Function_type* type,
-                    bool add_method_to_type, source_location location)
+                    bool add_method_to_type, Location location)
 {
   bool at_top_level = this->functions_.empty();
 
@@ -787,7 +789,7 @@ Gogo::start_function(const std::string& name, Function_type* type,
 // Finish compiling a function.
 
 void
-Gogo::finish_function(source_location location)
+Gogo::finish_function(Location location)
 {
   this->finish_block(location);
   go_assert(this->functions_.back().blocks.empty());
@@ -806,7 +808,7 @@ Gogo::current_function() const
 // Start a new block.
 
 void
-Gogo::start_block(source_location location)
+Gogo::start_block(Location location)
 {
   go_assert(!this->functions_.empty());
   Block* block = new Block(this->current_block(), location);
@@ -816,7 +818,7 @@ Gogo::start_block(source_location location)
 // Finish a block.
 
 Block*
-Gogo::finish_block(source_location location)
+Gogo::finish_block(Location location)
 {
   go_assert(!this->functions_.empty());
   go_assert(!this->functions_.back().blocks.empty());
@@ -829,7 +831,7 @@ Gogo::finish_block(source_location location)
 // Add an unknown name.
 
 Named_object*
-Gogo::add_unknown_name(const std::string& name, source_location location)
+Gogo::add_unknown_name(const std::string& name, Location location)
 {
   return this->package_->bindings()->add_unknown_name(name, location);
 }
@@ -838,7 +840,7 @@ Gogo::add_unknown_name(const std::string& name, source_location location)
 
 Named_object*
 Gogo::declare_function(const std::string& name, Function_type* type,
-                      source_location location)
+                      Location location)
 {
   if (!type->is_method())
     return this->current_bindings()->add_function_declaration(name, NULL, type,
@@ -874,7 +876,7 @@ Gogo::declare_function(const std::string& name, Function_type* type,
 
 Label*
 Gogo::add_label_definition(const std::string& label_name,
-                          source_location location)
+                          Location location)
 {
   go_assert(!this->functions_.empty());
   Function* func = this->functions_.back().function->func_value();
@@ -887,7 +889,7 @@ Gogo::add_label_definition(const std::string& label_name,
 
 Label*
 Gogo::add_label_reference(const std::string& label_name,
-                         source_location location, bool issue_goto_errors)
+                         Location location, bool issue_goto_errors)
 {
   go_assert(!this->functions_.empty());
   Function* func = this->functions_.back().function->func_value();
@@ -898,7 +900,7 @@ Gogo::add_label_reference(const std::string& label_name,
 // Return the current binding state.
 
 Bindings_snapshot*
-Gogo::bindings_snapshot(source_location location)
+Gogo::bindings_snapshot(Location location)
 {
   return new Bindings_snapshot(this->current_block(), location);
 }
@@ -916,7 +918,7 @@ Gogo::add_statement(Statement* statement)
 // Add a block.
 
 void
-Gogo::add_block(Block* block, source_location location)
+Gogo::add_block(Block* block, Location location)
 {
   go_assert(!this->functions_.empty()
             && !this->functions_.back().blocks.empty());
@@ -936,7 +938,7 @@ Gogo::add_constant(const Typed_identifier& tid, Expression* expr,
 // Add a type.
 
 void
-Gogo::add_type(const std::string& name, Type* type, source_location location)
+Gogo::add_type(const std::string& name, Type* type, Location location)
 {
   Named_object* no = this->current_bindings()->add_type(name, NULL, type,
                                                        location);
@@ -956,7 +958,7 @@ Gogo::add_named_type(Named_type* type)
 // Declare a type.
 
 Named_object*
-Gogo::declare_type(const std::string& name, source_location location)
+Gogo::declare_type(const std::string& name, Location location)
 {
   Bindings* bindings = this->current_bindings();
   Named_object* no = bindings->add_type_declaration(name, NULL, location);
@@ -971,7 +973,7 @@ Gogo::declare_type(const std::string& name, source_location location)
 // Declare a type at the package level.
 
 Named_object*
-Gogo::declare_package_type(const std::string& name, source_location location)
+Gogo::declare_package_type(const std::string& name, Location location)
 {
   return this->package_->bindings()->add_type_declaration(name, NULL, location);
 }
@@ -1077,9 +1079,9 @@ Gogo::define_global_names()
            {
              error_at(no->location(), "expected type");
              Type* errtype = Type::make_error_type();
-             Named_object* err = Named_object::make_type("error", NULL,
-                                                         errtype,
-                                                         BUILTINS_LOCATION);
+             Named_object* err =
+                Named_object::make_type("erroneous_type", NULL, errtype,
+                                        Linemap::predeclared_location());
              no->set_type_value(err->type_value());
            }
        }
@@ -1839,7 +1841,7 @@ Shortcuts::convert_shortcut(Block* enclosing, Expression** pshortcut)
   Binary_expression* shortcut = (*pshortcut)->binary_expression();
   Expression* left = shortcut->left();
   Expression* right = shortcut->right();
-  source_location loc = shortcut->location();
+  Location loc = shortcut->location();
 
   Block* retblock = new Block(enclosing, loc);
   retblock->set_end_location(loc);
@@ -2032,7 +2034,7 @@ Order_eval::statement(Block* block, size_t* pindex, Statement* s)
       if (is_thunk && p + 1 == find_eval_ordering.end())
        break;
 
-      source_location loc = (*pexpr)->location();
+      Location loc = (*pexpr)->location();
       Statement* s;
       if ((*pexpr)->call_expression() == NULL
          || (*pexpr)->call_expression()->result_count() < 2)
@@ -2091,7 +2093,7 @@ Order_eval::variable(Named_object* no)
        ++p)
     {
       Expression** pexpr = *p;
-      source_location loc = (*pexpr)->location();
+      Location loc = (*pexpr)->location();
       Statement* s;
       if ((*pexpr)->call_expression() == NULL
          || (*pexpr)->call_expression()->result_count() < 2)
@@ -2173,7 +2175,7 @@ class Build_recover_thunks : public Traverse
 
  private:
   Expression*
-  can_recover_arg(source_location);
+  can_recover_arg(Location);
 
   // General IR.
   Gogo* gogo_;
@@ -2191,7 +2193,7 @@ Build_recover_thunks::function(Named_object* orig_no)
     return TRAVERSE_CONTINUE;
 
   Gogo* gogo = this->gogo_;
-  source_location location = orig_func->location();
+  Location location = orig_func->location();
 
   static int count;
   char buf[50];
@@ -2389,12 +2391,12 @@ Build_recover_thunks::function(Named_object* orig_no)
 // __go_can_recover(__builtin_return_address()).
 
 Expression*
-Build_recover_thunks::can_recover_arg(source_location location)
+Build_recover_thunks::can_recover_arg(Location location)
 {
   static Named_object* builtin_return_address;
   if (builtin_return_address == NULL)
     {
-      const source_location bloc = BUILTINS_LOCATION;
+      const Location bloc = Linemap::predeclared_location();
 
       Typed_identifier_list* param_types = new Typed_identifier_list();
       Type* uint_type = Type::lookup_integer_type("uint");
@@ -2416,7 +2418,7 @@ Build_recover_thunks::can_recover_arg(source_location location)
   static Named_object* can_recover;
   if (can_recover == NULL)
     {
-      const source_location bloc = BUILTINS_LOCATION;
+      const Location bloc = Linemap::predeclared_location();
       Typed_identifier_list* param_types = new Typed_identifier_list();
       Type* voidptr_type = Type::make_pointer_type(Type::make_void_type());
       param_types->push_back(Typed_identifier("a", voidptr_type, bloc));
@@ -2748,7 +2750,7 @@ Gogo::convert_named_types_in_bindings(Bindings* bindings)
 // Class Function.
 
 Function::Function(Function_type* type, Function* enclosing, Block* block,
-                  source_location location)
+                  Location location)
   : type_(type), enclosing_(enclosing), results_(NULL),
     closure_var_(NULL), block_(block), location_(location), fndecl_(NULL),
     defer_stack_(NULL), results_are_named_(false), calls_recover_(false),
@@ -2829,7 +2831,7 @@ Function::closure_var()
     {
       // We don't know the type of the variable yet.  We add fields as
       // we find them.
-      source_location loc = this->type_->location();
+      Location loc = this->type_->location();
       Struct_field_list* sfl = new Struct_field_list;
       Type* struct_type = Type::make_struct_type(sfl, loc);
       Variable* var = new Variable(Type::make_pointer_type(struct_type),
@@ -2880,7 +2882,7 @@ Function::is_method() const
 
 Label*
 Function::add_label_definition(Gogo* gogo, const std::string& label_name,
-                              source_location location)
+                              Location location)
 {
   Label* lnull = NULL;
   std::pair<Labels::iterator, bool> ins =
@@ -2924,7 +2926,7 @@ Function::add_label_definition(Gogo* gogo, const std::string& label_name,
 
 Label*
 Function::add_label_reference(Gogo* gogo, const std::string& label_name,
-                             source_location location, bool issue_goto_errors)
+                             Location location, bool issue_goto_errors)
 {
   Label* lnull = NULL;
   std::pair<Labels::iterator, bool> ins =
@@ -3039,7 +3041,7 @@ Function::determine_types()
 // function which uses defer.
 
 Expression*
-Function::defer_stack(source_location location)
+Function::defer_stack(Location location)
 {
   if (this->defer_stack_ == NULL)
     {
@@ -3218,7 +3220,7 @@ Function::import_func(Import* imp, std::string* pname,
 
 // Class Block.
 
-Block::Block(Block* enclosing, source_location location)
+Block::Block(Block* enclosing, Location location)
   : enclosing_(enclosing), statements_(),
     bindings_(new Bindings(enclosing == NULL
                           ? NULL
@@ -3463,7 +3465,7 @@ Block::get_backend(Translate_context* context)
 
 // Class Bindings_snapshot.
 
-Bindings_snapshot::Bindings_snapshot(const Block* b, source_location location)
+Bindings_snapshot::Bindings_snapshot(const Block* b, Location location)
   : block_(b), counts_(), location_(location)
 {
   while (b != NULL)
@@ -3476,7 +3478,7 @@ Bindings_snapshot::Bindings_snapshot(const Block* b, source_location location)
 // Report errors appropriate for a goto from B to this.
 
 void
-Bindings_snapshot::check_goto_from(const Block* b, source_location loc)
+Bindings_snapshot::check_goto_from(const Block* b, Location loc)
 {
   size_t dummy;
   if (!this->check_goto_block(loc, b, this->block_, &dummy))
@@ -3504,7 +3506,7 @@ Bindings_snapshot::check_goto_to(const Block* b)
 // BFROM.
 
 bool
-Bindings_snapshot::check_goto_block(source_location loc, const Block* bfrom,
+Bindings_snapshot::check_goto_block(Location loc, const Block* bfrom,
                                    const Block* bto, size_t* pindex)
 {
   // It is an error if BTO is not either BFROM or above BFROM.
@@ -3527,7 +3529,7 @@ Bindings_snapshot::check_goto_block(source_location loc, const Block* bfrom,
 // CTO is the number of names defined at the point of the label.
 
 void
-Bindings_snapshot::check_goto_defs(source_location loc, const Block* block,
+Bindings_snapshot::check_goto_defs(Location loc, const Block* block,
                                   size_t cfrom, size_t cto)
 {
   if (cfrom < cto)
@@ -3551,7 +3553,7 @@ Bindings_snapshot::check_goto_defs(source_location loc, const Block* block,
 
 Variable::Variable(Type* type, Expression* init, bool is_global,
                   bool is_parameter, bool is_receiver,
-                  source_location location)
+                  Location location)
   : type_(type), init_(init), preinit_(NULL), location_(location),
     backend_(NULL), is_global_(is_global), is_parameter_(is_parameter),
     is_receiver_(is_receiver), is_varargs_parameter_(false),
@@ -4098,7 +4100,7 @@ Type_declaration::add_method(const std::string& name, Function* function)
 Named_object*
 Type_declaration::add_method_declaration(const std::string&  name,
                                         Function_type* type,
-                                        source_location location)
+                                        Location location)
 {
   Named_object* ret = Named_object::make_function_declaration(name, NULL, type,
                                                              location);
@@ -4165,7 +4167,7 @@ Named_object::Named_object(const std::string& name,
 
 Named_object*
 Named_object::make_unknown_name(const std::string& name,
-                               source_location location)
+                               Location location)
 {
   Named_object* named_object = new Named_object(name, NULL,
                                                NAMED_OBJECT_UNKNOWN);
@@ -4194,7 +4196,7 @@ Named_object::make_constant(const Typed_identifier& tid,
 
 Named_object*
 Named_object::make_type(const std::string& name, const Package* package,
-                       Type* type, source_location location)
+                       Type* type, Location location)
 {
   Named_object* named_object = new Named_object(name, package,
                                                NAMED_OBJECT_TYPE);
@@ -4208,7 +4210,7 @@ Named_object::make_type(const std::string& name, const Package* package,
 Named_object*
 Named_object::make_type_declaration(const std::string& name,
                                    const Package* package,
-                                   source_location location)
+                                   Location location)
 {
   Named_object* named_object = new Named_object(name, package,
                                                NAMED_OBJECT_TYPE_DECLARATION);
@@ -4267,7 +4269,7 @@ Named_object*
 Named_object::make_function_declaration(const std::string& name,
                                        const Package* package,
                                        Function_type* fntype,
-                                       source_location location)
+                                       Location location)
 {
   Named_object* named_object = new Named_object(name, package,
                                                NAMED_OBJECT_FUNC_DECLARATION);
@@ -4341,7 +4343,7 @@ Named_object::declare_as_type()
 
 // Return the location of a named object.
 
-source_location
+Location
 Named_object::location() const
 {
   switch (this->classification_)
@@ -4717,7 +4719,7 @@ Named_object*
 Bindings::add_function_declaration(const std::string& name,
                                   const Package* package,
                                   Function_type* type,
-                                  source_location location)
+                                  Location location)
 {
   Named_object* no = Named_object::make_function_declaration(name, package,
                                                             type, location);
@@ -4869,7 +4871,7 @@ Label::get_backend_label(Translate_context* context)
 // Return an expression for the address of this label.
 
 Bexpression*
-Label::get_addr(Translate_context* context, source_location location)
+Label::get_addr(Translate_context* context, Location location)
 {
   Blabel* label = this->get_backend_label(context);
   return context->backend()->label_address(label, location);
@@ -4905,7 +4907,7 @@ Unnamed_label::get_definition(Translate_context* context)
 // Return a goto statement to this unnamed label.
 
 Bstatement*
-Unnamed_label::get_goto(Translate_context* context, source_location location)
+Unnamed_label::get_goto(Translate_context* context, Location location)
 {
   Blabel* blabel = this->get_blabel(context);
   return context->backend()->goto_statement(blabel, location);
@@ -4914,7 +4916,7 @@ Unnamed_label::get_goto(Translate_context* context, source_location location)
 // Class Package.
 
 Package::Package(const std::string& name, const std::string& unique_prefix,
-                source_location location)
+                Location location)
   : name_(name), unique_prefix_(unique_prefix), bindings_(new Bindings(NULL)),
     priority_(0), location_(location), used_(false), is_imported_(false),
     uses_sink_alias_(false)
index 91e814c..9d3b37a 100644 (file)
@@ -7,6 +7,8 @@
 #ifndef GO_GOGO_H
 #define GO_GOGO_H
 
+#include "go-linemap.h"
+
 class Traverse;
 class Statement_inserter;
 class Type;
@@ -111,20 +113,25 @@ class Gogo
  public:
   // Create the IR, passing in the sizes of the types "int" and
   // "uintptr" in bits.
-  Gogo(Backend* backend, int int_type_size, int pointer_size);
+  Gogo(Backend* backend, Linemap *linemap, int int_type_size, int pointer_size);
 
   // Get the backend generator.
   Backend*
   backend()
   { return this->backend_; }
 
+  // Get the Location generator.
+  Linemap*
+  linemap()
+  { return this->linemap_; }
+
   // Get the package name.
   const std::string&
   package_name() const;
 
   // Set the package name.
   void
-  set_package_name(const std::string&, source_location);
+  set_package_name(const std::string&, Location);
 
   // Return whether this is the "main" package.
   bool
@@ -195,7 +202,7 @@ class Gogo
   // the declarations are added to the global scope.
   void
   import_package(const std::string& filename, const std::string& local_name,
-                bool is_local_name_exported, source_location);
+                bool is_local_name_exported, Location);
 
   // Whether we are the global binding level.
   bool
@@ -223,7 +230,7 @@ class Gogo
   add_imported_package(const std::string& real_name, const std::string& alias,
                       bool is_alias_exported,
                       const std::string& unique_prefix,
-                      source_location location,
+                      Location location,
                       bool* padd_to_globals);
 
   // Register a package.  This package may or may not be imported.
@@ -231,17 +238,17 @@ class Gogo
   // it necessary.
   Package*
   register_package(const std::string& name, const std::string& unique_prefix,
-                  source_location);
+                  Location);
 
   // Start compiling a function.  ADD_METHOD_TO_TYPE is true if a
   // method function should be added to the type of its receiver.
   Named_object*
   start_function(const std::string& name, Function_type* type,
-                bool add_method_to_type, source_location);
+                bool add_method_to_type, Location);
 
   // Finish compiling a function.
   void
-  finish_function(source_location);
+  finish_function(Location);
 
   // Return the current function.
   Named_object*
@@ -254,36 +261,36 @@ class Gogo
   // Start a new block.  This is not initially associated with a
   // function.
   void
-  start_block(source_location);
+  start_block(Location);
 
   // Finish the current block and return it.
   Block*
-  finish_block(source_location);
+  finish_block(Location);
 
   // Declare an unknown name.  This is used while parsing.  The name
   // must be resolved by the end of the parse.  Unknown names are
   // always added at the package level.
   Named_object*
-  add_unknown_name(const std::string& name, source_location);
+  add_unknown_name(const std::string& name, Location);
 
   // Declare a function.
   Named_object*
-  declare_function(const std::string&, Function_type*, source_location);
+  declare_function(const std::string&, Function_type*, Location);
 
   // Add a label.
   Label*
-  add_label_definition(const std::string&, source_location);
+  add_label_definition(const std::string&, Location);
 
   // Add a label reference.  ISSUE_GOTO_ERRORS is true if we should
   // report errors for a goto from the current location to the label
   // location.
   Label*
-  add_label_reference(const std::string&, source_location,
+  add_label_reference(const std::string&, Location,
                      bool issue_goto_errors);
 
   // Return a snapshot of the current binding state.
   Bindings_snapshot*
-  bindings_snapshot(source_location);
+  bindings_snapshot(Location);
 
   // Add a statement to the current block.
   void
@@ -291,7 +298,7 @@ class Gogo
 
   // Add a block to the current block.
   void
-  add_block(Block*, source_location);
+  add_block(Block*, Location);
 
   // Add a constant.
   Named_object*
@@ -299,7 +306,7 @@ class Gogo
 
   // Add a type.
   void
-  add_type(const std::string&, Type*, source_location);
+  add_type(const std::string&, Type*, Location);
 
   // Add a named type.  This is used for builtin types, and to add an
   // imported type to the global scope.
@@ -308,12 +315,12 @@ class Gogo
 
   // Declare a type.
   Named_object*
-  declare_type(const std::string&, source_location);
+  declare_type(const std::string&, Location);
 
   // Declare a type at the package level.  This is used when the
   // parser sees an unknown name where a type name is required.
   Named_object*
-  declare_package_type(const std::string&, source_location);
+  declare_package_type(const std::string&, Location);
 
   // Define a type which was already declared.
   void
@@ -466,12 +473,12 @@ class Gogo
   // RETTYPE is the return type.  It is followed by NARGS pairs of
   // type and argument (both trees).
   static tree
-  call_builtin(tree* pdecl, source_location, const char* name, int nargs,
+  call_builtin(tree* pdecl, Location, const char* name, int nargs,
               tree rettype, ...);
 
   // Build a call to the runtime error function.
   static tree
-  runtime_error(int code, source_location);
+  runtime_error(int code, Location);
 
   // Build a builtin struct with a list of fields.
   static tree
@@ -503,7 +510,7 @@ class Gogo
   // Return a tree which allocate SIZE bytes to hold values of type
   // TYPE.
   tree
-  allocate_memory(Type *type, tree size, source_location);
+  allocate_memory(Type *type, tree size, Location);
 
   // Return a type to use for pointer to const char.
   static tree
@@ -521,7 +528,7 @@ class Gogo
   // Receive a value from a channel.
   static tree
   receive_from_channel(tree type_tree, tree channel, bool for_select,
-                      source_location);
+                      Location);
 
   // Return a tree for receiving an integer on a channel.
   static tree
@@ -530,7 +537,7 @@ class Gogo
 
   // Make a trampoline which calls FNADDR passing CLOSURE.
   tree
-  make_trampoline(tree fnaddr, tree closure, source_location);
+  make_trampoline(tree fnaddr, tree closure, Location);
 
  private:
   // During parsing, we keep a stack of functions.  Each function on
@@ -549,12 +556,12 @@ class Gogo
 
   // Set up the built-in unsafe package.
   void
-  import_unsafe(const std::string&, bool is_exported, source_location);
+  import_unsafe(const std::string&, bool is_exported, Location);
 
   // Add a new imported package.
   Named_object*
   add_package(const std::string& real_name, const std::string& alias,
-             const std::string& unique_prefix, source_location location);
+             const std::string& unique_prefix, Location location);
 
   // Return the current binding contour.
   Bindings*
@@ -603,6 +610,8 @@ class Gogo
 
   // The backend generator.
   Backend* backend_;
+  // The object used to keep track of file names and line numbers.
+  Linemap* linemap_;
   // The package we are compiling.
   Package* package_;
   // The list of currently open functions during parsing.
@@ -640,7 +649,7 @@ class Gogo
 class Block
 {
  public:
-  Block(Block* enclosing, source_location);
+  Block(Block* enclosing, Location);
 
   // Return the enclosing block.
   const Block*
@@ -663,13 +672,13 @@ class Block
 
   // Return the start location.  This is normally the location of the
   // left curly brace which starts the block.
-  source_location
+  Location
   start_location() const
   { return this->start_location_; }
 
   // Return the end location.  This is normally the location of the
   // right curly brace which ends the block.
-  source_location
+  Location
   end_location() const
   { return this->end_location_; }
 
@@ -695,7 +704,7 @@ class Block
 
   // Set the end location of the block.
   void
-  set_end_location(source_location location)
+  set_end_location(Location location)
   { this->end_location_ = location; }
 
   // Traverse the tree.
@@ -735,9 +744,9 @@ class Block
   // Binding contour.
   Bindings* bindings_;
   // Location of start of block.
-  source_location start_location_;
+  Location start_location_;
   // Location of end of block.
-  source_location end_location_;
+  Location end_location_;
 };
 
 // A function.
@@ -745,7 +754,7 @@ class Block
 class Function
 {
  public:
-  Function(Function_type* type, Function*, Block*, source_location);
+  Function(Function_type* type, Function*, Block*, Location);
 
   // Return the function's type.
   Function_type*
@@ -790,7 +799,7 @@ class Function
 
   // Add a new field to the closure variable.
   void
-  add_closure_field(Named_object* var, source_location loc)
+  add_closure_field(Named_object* var, Location loc)
   { this->closure_fields_.push_back(std::make_pair(var, loc)); }
 
   // Whether this function needs a closure.
@@ -831,7 +840,7 @@ class Function
   { return this->block_; }
 
   // Get the location of the start of the function.
-  source_location
+  Location
   location() const
   { return this->location_; }
 
@@ -841,14 +850,14 @@ class Function
 
   // Add a label definition to the function.
   Label*
-  add_label_definition(Gogo*, const std::string& label_name, source_location);
+  add_label_definition(Gogo*, const std::string& label_name, Location);
 
   // Add a label reference to a function.  ISSUE_GOTO_ERRORS is true
   // if we should report errors for a goto from the current location
   // to the label location.
   Label*
   add_label_reference(Gogo*, const std::string& label_name,
-                     source_location, bool issue_goto_errors);
+                     Location, bool issue_goto_errors);
 
   // Warn about labels that are defined but not used.
   void
@@ -918,11 +927,11 @@ class Function
   // Get the value to return when not explicitly specified.  May also
   // add statements to execute first to STMT_LIST.
   tree
-  return_value(Gogo*, Named_object*, source_location, tree* stmt_list) const;
+  return_value(Gogo*, Named_object*, Location, tree* stmt_list) const;
 
   // Get a tree for the variable holding the defer stack.
   Expression*
-  defer_stack(source_location);
+  defer_stack(Location);
 
   // Export the function.
   void
@@ -953,7 +962,7 @@ class Function
   build_defer_wrapper(Gogo*, Named_object*, tree*, tree*);
 
   typedef std::vector<std::pair<Named_object*,
-                               source_location> > Closure_fields;
+                               Location> > Closure_fields;
 
   // The function's type.
   Function_type* type_;
@@ -972,7 +981,7 @@ class Function
   // The outer block of statements in the function.
   Block* block_;
   // The source location of the start of the function.
-  source_location location_;
+  Location location_;
   // Labels defined or referenced in the function.
   Labels labels_;
   // The function decl.
@@ -996,12 +1005,12 @@ class Function
 class Bindings_snapshot
 {
  public:
-  Bindings_snapshot(const Block*, source_location);
+  Bindings_snapshot(const Block*, Location);
 
   // Report any errors appropriate for a goto from the current binding
   // state of B to this one.
   void
-  check_goto_from(const Block* b, source_location);
+  check_goto_from(const Block* b, Location);
 
   // Report any errors appropriate for a goto from this binding state
   // to the current state of B.
@@ -1010,10 +1019,10 @@ class Bindings_snapshot
 
  private:
   bool
-  check_goto_block(source_location, const Block*, const Block*, size_t*);
+  check_goto_block(Location, const Block*, const Block*, size_t*);
 
   void
-  check_goto_defs(source_location, const Block*, size_t, size_t);
+  check_goto_defs(Location, const Block*, size_t, size_t);
 
   // The current block.
   const Block* block_;
@@ -1022,7 +1031,7 @@ class Bindings_snapshot
   // this->block_->enclosing(), etc.
   std::vector<size_t> counts_;
   // The location where this snapshot was taken.
-  source_location location_;
+  Location location_;
 };
 
 // A function declaration.
@@ -1030,7 +1039,7 @@ class Bindings_snapshot
 class Function_declaration
 {
  public:
-  Function_declaration(Function_type* fntype, source_location location)
+  Function_declaration(Function_type* fntype, Location location)
     : fntype_(fntype), location_(location), asm_name_(), fndecl_(NULL)
   { }
 
@@ -1038,7 +1047,7 @@ class Function_declaration
   type() const
   { return this->fntype_; }
 
-  source_location
+  Location
   location() const
   { return this->location_; }
 
@@ -1064,7 +1073,7 @@ class Function_declaration
   // The type of the function.
   Function_type* fntype_;
   // The location of the declaration.
-  source_location location_;
+  Location location_;
   // The assembler name: this is the name to use in references to the
   // function.  This is normally empty.
   std::string asm_name_;
@@ -1078,7 +1087,7 @@ class Variable
 {
  public:
   Variable(Type*, Expression*, bool is_global, bool is_parameter,
-          bool is_receiver, source_location);
+          bool is_receiver, Location);
 
   // Get the type of the variable.
   Type*
@@ -1172,7 +1181,7 @@ class Variable
   { this->is_non_escaping_address_taken_ = true; }
 
   // Get the source location of the variable's declaration.
-  source_location
+  Location
   location() const
   { return this->location_; }
 
@@ -1309,7 +1318,7 @@ class Variable
   // Statements to run before the init statement.
   Block* preinit_;
   // Location of variable definition.
-  source_location location_;
+  Location location_;
   // Backend representation.
   Bvariable* backend_;
   // Whether this is a global variable.
@@ -1352,7 +1361,7 @@ class Result_variable
 {
  public:
   Result_variable(Type* type, Function* function, int index,
-                 source_location location)
+                 Location location)
     : type_(type), function_(function), index_(index), location_(location),
       backend_(NULL), is_address_taken_(false),
       is_non_escaping_address_taken_(false)
@@ -1374,7 +1383,7 @@ class Result_variable
   { return this->index_; }
 
   // The location of the variable definition.
-  source_location
+  Location
   location() const
   { return this->location_; }
 
@@ -1422,7 +1431,7 @@ class Result_variable
   // Index in list of results.
   int index_;
   // Where the result variable is defined.
-  source_location location_;
+  Location location_;
   // Backend representation.
   Bvariable* backend_;
   // Whether something takes the address of this variable.
@@ -1439,7 +1448,7 @@ class Named_constant
 {
  public:
   Named_constant(Type* type, Expression* expr, int iota_value,
-                source_location location)
+                Location location)
     : type_(type), expr_(expr), iota_value_(iota_value), location_(location),
       lowering_(false)
   { }
@@ -1456,7 +1465,7 @@ class Named_constant
   iota_value() const
   { return this->iota_value_; }
 
-  source_location
+  Location
   location() const
   { return this->location_; }
 
@@ -1507,7 +1516,7 @@ class Named_constant
   // we lower.
   int iota_value_;
   // The location of the definition.
-  source_location location_;
+  Location location_;
   // Whether we are currently lowering this constant.
   bool lowering_;
 };
@@ -1517,13 +1526,13 @@ class Named_constant
 class Type_declaration
 {
  public:
-  Type_declaration(source_location location)
+  Type_declaration(Location location)
     : location_(location), in_function_(NULL), methods_(),
       issued_warning_(false)
   { }
 
   // Return the location.
-  source_location
+  Location
   location() const
   { return this->location_; }
 
@@ -1546,7 +1555,7 @@ class Type_declaration
   // Add a method declaration to this type.
   Named_object*
   add_method_declaration(const std::string& name, Function_type* type,
-                        source_location location);
+                        Location location);
 
   // Return whether any methods were defined.
   bool
@@ -1565,7 +1574,7 @@ class Type_declaration
   typedef std::vector<Named_object*> Methods;
 
   // The location of the type declaration.
-  source_location location_;
+  Location location_;
   // If this type is declared in a function, a pointer back to the
   // function in which it is defined.
   Named_object* in_function_;
@@ -1585,12 +1594,12 @@ class Type_declaration
 class Unknown_name
 {
  public:
-  Unknown_name(source_location location)
+  Unknown_name(Location location)
     : location_(location), real_named_object_(NULL)
   { }
 
   // Return the location where this name was first seen.
-  source_location
+  Location
   location() const
   { return this->location_; }
 
@@ -1606,7 +1615,7 @@ class Unknown_name
 
  private:
   // The location where this name was first seen.
-  source_location location_;
+  Location location_;
   // The real named object when it is known.
   Named_object*
   real_named_object_;
@@ -1697,17 +1706,17 @@ class Named_object
   // Creators.
 
   static Named_object*
-  make_unknown_name(const std::string& name, source_location);
+  make_unknown_name(const std::string& name, Location);
 
   static Named_object*
   make_constant(const Typed_identifier&, const Package*, Expression*,
                int iota_value);
 
   static Named_object*
-  make_type(const std::string&, const Package*, Type*, source_location);
+  make_type(const std::string&, const Package*, Type*, Location);
 
   static Named_object*
-  make_type_declaration(const std::string&, const Package*, source_location);
+  make_type_declaration(const std::string&, const Package*, Location);
 
   static Named_object*
   make_variable(const std::string&, const Package*, Variable*);
@@ -1723,7 +1732,7 @@ class Named_object
 
   static Named_object*
   make_function_declaration(const std::string&, const Package*, Function_type*,
-                           source_location);
+                           Location);
 
   static Named_object*
   make_package(const std::string& alias, Package* package);
@@ -1899,7 +1908,7 @@ class Named_object
   }
 
   // The location where this object was defined or referenced.
-  source_location
+  Location
   location() const;
 
   // Convert a variable to the backend representation.
@@ -1969,7 +1978,7 @@ class Bindings
 
   // Add an unknown name.
   Named_object*
-  add_unknown_name(const std::string& name, source_location location)
+  add_unknown_name(const std::string& name, Location location)
   {
     return this->add_named_object(Named_object::make_unknown_name(name,
                                                                  location));
@@ -1988,7 +1997,7 @@ class Bindings
   // Add a type.
   Named_object*
   add_type(const std::string& name, const Package* package, Type* type,
-          source_location location)
+          Location location)
   {
     return this->add_named_object(Named_object::make_type(name, package, type,
                                                          location));
@@ -2002,7 +2011,7 @@ class Bindings
   // Add a type declaration.
   Named_object*
   add_type_declaration(const std::string& name, const Package* package,
-                      source_location location)
+                      Location location)
   {
     Named_object* no = Named_object::make_type_declaration(name, package,
                                                           location);
@@ -2033,7 +2042,7 @@ class Bindings
   // Add a function declaration.
   Named_object*
   add_function_declaration(const std::string& name, const Package* package,
-                          Function_type* type, source_location location);
+                          Function_type* type, Location location);
 
   // Add a package.  The location is the location of the import
   // statement.
@@ -2153,8 +2162,8 @@ class Label
 {
  public:
   Label(const std::string& name)
-    : name_(name), location_(0), snapshot_(NULL), refs_(), is_used_(false),
-      blabel_(NULL)
+    : name_(name), location_(Linemap::unknown_location()), snapshot_(NULL),
+      refs_(), is_used_(false), blabel_(NULL)
   { }
 
   // Return the label's name.
@@ -2165,7 +2174,7 @@ class Label
   // Return whether the label has been defined.
   bool
   is_defined() const
-  { return this->location_ != 0; }
+  { return !Linemap::is_unknown_location(this->location_); }
 
   // Return whether the label has been used.
   bool
@@ -2178,7 +2187,7 @@ class Label
   { this->is_used_ = true; }
 
   // Return the location of the definition.
-  source_location
+  Location
   location() const
   { return this->location_; }
 
@@ -2191,7 +2200,7 @@ class Label
   void
   add_snapshot_ref(Bindings_snapshot* snapshot)
   {
-    go_assert(this->location_ == 0);
+    go_assert(Linemap::is_unknown_location(this->location_));
     this->refs_.push_back(snapshot);
   }
 
@@ -2207,9 +2216,10 @@ class Label
 
   // Define the label at LOCATION with the given bindings snapshot.
   void
-  define(source_location location, Bindings_snapshot* snapshot)
+  define(Location location, Bindings_snapshot* snapshot)
   {
-    go_assert(this->location_ == 0 && this->snapshot_ == NULL);
+    go_assert(Linemap::is_unknown_location(this->location_)
+              && this->snapshot_ == NULL);
     this->location_ = location;
     this->snapshot_ = snapshot;
   }
@@ -2222,14 +2232,14 @@ class Label
   // to get the return address of a deferred function to see whether
   // the function may call recover.
   Bexpression*
-  get_addr(Translate_context*, source_location location);
+  get_addr(Translate_context*, Location location);
 
  private:
   // The name of the label.
   std::string name_;
   // The location of the definition.  This is 0 if the label has not
   // yet been defined.
-  source_location location_;
+  Location location_;
   // A snapshot of the set of bindings defined at this label, used to
   // issue errors about invalid goto statements.
   Bindings_snapshot* snapshot_;
@@ -2246,18 +2256,18 @@ class Label
 class Unnamed_label
 {
  public:
-  Unnamed_label(source_location location)
+  Unnamed_label(Location location)
     : location_(location), blabel_(NULL)
   { }
 
   // Get the location where the label is defined.
-  source_location
+  Location
   location() const
   { return this->location_; }
 
   // Set the location where the label is defined.
   void
-  set_location(source_location location)
+  set_location(Location location)
   { this->location_ = location; }
 
   // Return a statement which defines this label.
@@ -2266,7 +2276,7 @@ class Unnamed_label
 
   // Return a goto to this label from LOCATION.
   Bstatement*
-  get_goto(Translate_context*, source_location location);
+  get_goto(Translate_context*, Location location);
 
  private:
   // Return the backend representation.
@@ -2274,7 +2284,7 @@ class Unnamed_label
   get_blabel(Translate_context*);
 
   // The location where the label is defined.
-  source_location location_;
+  Location location_;
   // The backend representation of this label.
   Blabel* blabel_;
 };
@@ -2285,7 +2295,7 @@ class Package
 {
  public:
   Package(const std::string& name, const std::string& unique_prefix,
-         source_location location);
+         Location location);
 
   // The real name of this package.  This may be different from the
   // name in the associated Named_object if the import statement used
@@ -2295,7 +2305,7 @@ class Package
   { return this->name_; }
 
   // Return the location of the import statement.
-  source_location
+  Location
   location() const
   { return this->location_; }
 
@@ -2378,7 +2388,7 @@ class Package
   // Set the location of the package.  This is used if it is seen in a
   // different import before it is really imported.
   void
-  set_location(source_location location)
+  set_location(Location location)
   { this->location_ = location; }
 
   // Add a constant to the package.
@@ -2388,12 +2398,12 @@ class Package
 
   // Add a type to the package.
   Named_object*
-  add_type(const std::string& name, Type* type, source_location location)
+  add_type(const std::string& name, Type* type, Location location)
   { return this->bindings_->add_type(name, this, type, location); }
 
   // Add a type declaration to the package.
   Named_object*
-  add_type_declaration(const std::string& name, source_location location)
+  add_type_declaration(const std::string& name, Location location)
   { return this->bindings_->add_type_declaration(name, this, location); }
 
   // Add a variable to the package.
@@ -2404,7 +2414,7 @@ class Package
   // Add a function declaration to the package.
   Named_object*
   add_function_declaration(const std::string& name, Function_type* type,
-                          source_location loc)
+                          Location loc)
   { return this->bindings_->add_function_declaration(name, this, type, loc); }
 
   // Determine types of constants.
@@ -2423,7 +2433,7 @@ class Package
   // is used to run init functions in the right order.
   int priority_;
   // The location of the import statement.
-  source_location location_;
+  Location location_;
   // True if some name from this package was used.  This is mutable
   // because we can use a package even if we have a const pointer to
   // it.
index 07ac01a..032c6a0 100644 (file)
@@ -66,7 +66,7 @@ Import::is_archive_magic(const char* bytes)
 class Archive_file
 {
  public:
-  Archive_file(const std::string& filename, int fd, source_location location)
+  Archive_file(const std::string& filename, int fd, Location location)
     : filename_(filename), fd_(fd), filesize_(-1), extended_names_(),
       is_thin_archive_(false), location_(location), nested_archives_()
   { }
@@ -91,7 +91,7 @@ class Archive_file
   { return this->is_thin_archive_; }
 
   // Return the location of the import statement.
-  source_location
+  Location
   location() const
   { return this->location_; }
 
@@ -133,7 +133,7 @@ class Archive_file
   // Whether this is a thin archive.
   bool is_thin_archive_;
   // The location of the import statements.
-  source_location location_;
+  Location location_;
   // Table of nested archives.
   Nested_archive_table nested_archives_;
 };
@@ -613,7 +613,7 @@ Stream_concatenate::do_advance(size_t skip)
 
 Import::Stream*
 Import::find_archive_export_data(const std::string& filename, int fd,
-                                source_location location)
+                                Location location)
 {
   Archive_file afile(filename, fd, location);
   if (!afile.initialize())
index 4aca1a3..d3405c1 100644 (file)
@@ -59,7 +59,7 @@ const char* const Import::import_marker = "*imported*";
 // later in the search path.
 
 Import::Stream*
-Import::open_package(const std::string& filename, source_location location)
+Import::open_package(const std::string& filename, Location location)
 {
   if (!IS_ABSOLUTE_PATH(filename))
     {
@@ -88,7 +88,7 @@ Import::open_package(const std::string& filename, source_location location)
 
 Import::Stream*
 Import::try_package_in_directory(const std::string& filename,
-                                source_location location)
+                                Location location)
 {
   std::string found_filename = filename;
   int fd = open(found_filename.c_str(), O_RDONLY | O_BINARY);
@@ -175,7 +175,7 @@ Import::try_suffixes(std::string* pfilename)
 
 Import::Stream*
 Import::find_export_data(const std::string& filename, int fd,
-                        source_location location)
+                        Location location)
 {
   // See if we can read this as an object file.
   Import::Stream* stream = Import::find_object_export_data(filename, fd, 0,
@@ -213,7 +213,7 @@ Import::Stream*
 Import::find_object_export_data(const std::string& filename,
                                int fd,
                                off_t offset,
-                               source_location location)
+                               Location location)
 {
   const char* errmsg;
   int err;
@@ -262,7 +262,7 @@ Import::find_object_export_data(const std::string& filename,
 // Construct an Import object.  We make the builtin_types_ vector
 // large enough to hold all the builtin types.
 
-Import::Import(Stream* stream, source_location location)
+Import::Import(Stream* stream, Location location)
   : gogo_(NULL), stream_(stream), location_(location), package_(NULL),
     add_to_globals_(false),
     builtin_types_((- SMALLEST_BUILTIN_CODE) + 1),
@@ -448,7 +448,7 @@ Import::import_func(Package* package)
   if (is_varargs)
     fntype->set_is_varargs();
 
-  source_location loc = this->location_;
+  Location loc = this->location_;
   Named_object* no;
   if (fntype->is_method())
     {
@@ -603,7 +603,7 @@ Import::read_type()
     package = this->package_;
   else
     package = this->gogo_->register_package(package_name, unique_prefix,
-                                           UNKNOWN_LOCATION);
+                                           Linemap::unknown_location());
 
   Named_object* no = package->bindings()->lookup(type_name);
   if (no == NULL)
@@ -798,7 +798,7 @@ Import::Stream::match_bytes(const char* bytes, size_t length)
 // Require that the next LENGTH bytes from the stream match BYTES.
 
 void
-Import::Stream::require_bytes(source_location location, const char* bytes,
+Import::Stream::require_bytes(Location location, const char* bytes,
                              size_t length)
 {
   const char* read;
index 0101a40..f5b4b3d 100644 (file)
@@ -8,6 +8,7 @@
 #define GO_IMPORT_H
 
 #include "export.h"
+#include "go-linemap.h"
 
 class Gogo;
 class Package;
@@ -78,13 +79,13 @@ class Import
     // Give an error if the next bytes do not match STR.  Advance the
     // read position by the length of STR.
     void
-    require_c_string(source_location location, const char* str)
+    require_c_string(Location location, const char* str)
     { this->require_bytes(location, str, strlen(str)); }
 
     // Given an error if the next LENGTH bytes do not match BYTES.
     // Advance the read position by LENGTH.
     void
-    require_bytes(source_location, const char* bytes, size_t length);
+    require_bytes(Location, const char* bytes, size_t length);
 
     // Advance the read position by SKIP bytes.
     void
@@ -124,10 +125,10 @@ class Import
   // returns a pointer to a Stream object to read the data that it
   // exports.  LOCATION is the location of the import statement.
   static Stream*
-  open_package(const std::string& filename, source_location location);
+  open_package(const std::string& filename, Location location);
 
   // Constructor.
-  Import(Stream*, source_location);
+  Import(Stream*, Location);
 
   // Register the builtin types.
   void
@@ -142,7 +143,7 @@ class Import
   import(Gogo*, const std::string& local_name, bool is_local_name_exported);
 
   // The location of the import statement.
-  source_location
+  Location
   location() const
   { return this->location_; }
 
@@ -190,17 +191,17 @@ class Import
 
  private:
   static Stream*
-  try_package_in_directory(const std::string&, source_location);
+  try_package_in_directory(const std::string&, Location);
 
   static int
   try_suffixes(std::string*);
 
   static Stream*
-  find_export_data(const std::string& filename, int fd, source_location);
+  find_export_data(const std::string& filename, int fd, Location);
 
   static Stream*
   find_object_export_data(const std::string& filename, int fd,
-                         off_t offset, source_location);
+                         off_t offset, Location);
 
   static const int archive_magic_len = 8;
 
@@ -209,7 +210,7 @@ class Import
 
   static Stream*
   find_archive_export_data(const std::string& filename, int fd,
-                          source_location);
+                          Location);
 
   // Read the import control functions.
   void
@@ -244,7 +245,7 @@ class Import
   // The stream from which to read import data.
   Stream* stream_;
   // The location of the import statement we are processing.
-  source_location location_;
+  Location location_;
   // The package we are importing.
   Package* package_;
   // Whether to add new objects to the global scope, rather than to a
index 167c7dd..effa087 100644 (file)
@@ -146,7 +146,7 @@ static Keywords keywords;
 
 // Make a general token.
 
-Token::Token(Classification classification, source_location location)
+Token::Token(Classification classification, Location location)
   : classification_(classification), location_(location)
 {
 }
@@ -432,19 +432,18 @@ Token::print(FILE* file) const
 
 // Class Lex.
 
-Lex::Lex(const char* input_file_name, FILE* input_file)
+Lex::Lex(const char* input_file_name, FILE* input_file, Linemap* linemap)
   : input_file_name_(input_file_name), input_file_(input_file),
-    linebuf_(NULL), linebufsize_(120), linesize_(0), lineoff_(0),
-    lineno_(0), add_semi_at_eol_(false)
+    linemap_(linemap), linebuf_(NULL), linebufsize_(120), linesize_(0),
+    lineoff_(0), lineno_(0), add_semi_at_eol_(false)
 {
   this->linebuf_ = new char[this->linebufsize_];
-  linemap_add(line_table, LC_ENTER, 0, input_file_name, 1);
+  this->linemap_->start_file(input_file_name, 0);
 }
 
 Lex::~Lex()
 {
   delete[] this->linebuf_;
-  linemap_add(line_table, LC_LEAVE, 0, NULL, 0);
 }
 
 // Read a new line from the file.
@@ -508,26 +507,26 @@ Lex::require_line()
   this->linesize_= got;
   this->lineoff_ = 0;
 
-  linemap_line_start(line_table, this->lineno_, this->linesize_);
+  this->linemap_->start_line(this->lineno_, this->linesize_);
 
   return true;
 }
 
 // Get the current location.
 
-source_location
+Location
 Lex::location() const
 {
-  return linemap_position_for_column (line_table, this->lineoff_ + 1);
+  return this->linemap_->get_location(this->lineoff_ + 1);
 }
 
 // Get a location slightly before the current one.  This is used for
 // slightly more efficient handling of operator tokens.
 
-source_location
+Location
 Lex::earlier_location(int chars) const
 {
-  return linemap_position_for_column (line_table, this->lineoff_ + 1 - chars);
+  return this->linemap_->get_location(this->lineoff_ + 1 - chars);
 }
 
 // Get the next token.
@@ -586,7 +585,7 @@ Lex::next_token()
              else if (p[1] == '*')
                {
                  this->lineoff_ = p - this->linebuf_;
-                 source_location location = this->location();
+                 Location location = this->location();
                  if (!this->skip_c_comment())
                    return Token::make_invalid_token(location);
                  p = this->linebuf_ + this->lineoff_;
@@ -889,7 +888,7 @@ Lex::gather_identifier()
          buf.append(ubuf);
        }
     }
-  source_location location = this->location();
+  Location location = this->location();
   this->add_semi_at_eol_ = true;
   this->lineoff_ = p - this->linebuf_;
   if (has_non_ascii_char)
@@ -956,7 +955,7 @@ Lex::gather_number()
   const char* p = pstart;
   const char* pend = this->linebuf_ + this->linesize_;
 
-  source_location location = this->location();
+  Location location = this->location();
 
   bool neg = false;
   if (*p == '+')
@@ -1253,7 +1252,7 @@ Lex::advance_one_char(const char* p, bool is_single_quote, unsigned int* value,
 
 void
 Lex::append_char(unsigned int v, bool is_character, std::string* str,
-                source_location location)
+                Location location)
 {
   char buf[4];
   size_t len;
@@ -1319,7 +1318,7 @@ Lex::gather_character()
   mpz_t val;
   mpz_init_set_ui(val, value);
 
-  source_location location = this->location();
+  Location location = this->location();
   this->lineoff_ = p + 1 - this->linebuf_;
   Token ret = Token::make_integer_token(val, location);
   mpz_clear(val);
@@ -1338,7 +1337,7 @@ Lex::gather_string()
   std::string value;
   while (*p != '"')
     {
-      source_location loc = this->location();
+      Location loc = this->location();
       unsigned int c;
       bool is_character;
       this->lineoff_ = p - this->linebuf_;
@@ -1352,7 +1351,7 @@ Lex::gather_string()
       Lex::append_char(c, is_character, &value, loc);
     }
 
-  source_location location = this->location();
+  Location location = this->location();
   this->lineoff_ = p + 1 - this->linebuf_;
   return Token::make_string_token(value, location);
 }
@@ -1364,7 +1363,7 @@ Lex::gather_raw_string()
 {
   const char* p = this->linebuf_ + this->lineoff_ + 1;
   const char* pend = this->linebuf_ + this->linesize_;
-  source_location location = this->location();
+  Location location = this->location();
 
   std::string value;
   while (true)
@@ -1376,7 +1375,7 @@ Lex::gather_raw_string()
              this->lineoff_ = p + 1 - this->linebuf_;
              return Token::make_string_token(value, location);
            }
-         source_location loc = this->location();
+         Location loc = this->location();
          unsigned int c;
          bool issued_error;
          this->lineoff_ = p - this->linebuf_;
@@ -1630,8 +1629,7 @@ Lex::skip_cpp_comment()
              memcpy(file, p, filelen);
              file[filelen] = '\0';
 
-             linemap_add(line_table, LC_LEAVE, 0, NULL, 0);
-             linemap_add(line_table, LC_ENTER, 0, file, lineno);
+              this->linemap_->start_file(file, lineno);
              this->lineno_ = lineno - 1;
 
              p = plend;
index bda07f1..6341e1e 100644 (file)
@@ -11,6 +11,7 @@
 #include <mpfr.h>
 
 #include "operator.h"
+#include "go-linemap.h"
 
 struct Unicode_range;
 
@@ -88,17 +89,17 @@ class Token
 
   // Make a token for an invalid value.
   static Token
-  make_invalid_token(source_location location)
+  make_invalid_token(Location location)
   { return Token(TOKEN_INVALID, location); }
 
   // Make a token representing end of file.
   static Token
-  make_eof_token(source_location location)
+  make_eof_token(Location location)
   { return Token(TOKEN_EOF, location); }
 
   // Make a keyword token.
   static Token
-  make_keyword_token(Keyword keyword, source_location location)
+  make_keyword_token(Keyword keyword, Location location)
   {
     Token tok(TOKEN_KEYWORD, location);
     tok.u_.keyword = keyword;
@@ -108,7 +109,7 @@ class Token
   // Make an identifier token.
   static Token
   make_identifier_token(const std::string& value, bool is_exported,
-                       source_location location)
+                       Location location)
   {
     Token tok(TOKEN_IDENTIFIER, location);
     tok.u_.identifier_value.name = new std::string(value);
@@ -118,7 +119,7 @@ class Token
 
   // Make a quoted string token.
   static Token
-  make_string_token(const std::string& value, source_location location)
+  make_string_token(const std::string& value, Location location)
   {
     Token tok(TOKEN_STRING, location);
     tok.u_.string_value = new std::string(value);
@@ -127,7 +128,7 @@ class Token
 
   // Make an operator token.
   static Token
-  make_operator_token(Operator op, source_location location)
+  make_operator_token(Operator op, Location location)
   {
     Token tok(TOKEN_OPERATOR, location);
     tok.u_.op = op;
@@ -136,7 +137,7 @@ class Token
 
   // Make an integer token.
   static Token
-  make_integer_token(mpz_t val, source_location location)
+  make_integer_token(mpz_t val, Location location)
   {
     Token tok(TOKEN_INTEGER, location);
     mpz_init(tok.u_.integer_value);
@@ -146,7 +147,7 @@ class Token
 
   // Make a float token.
   static Token
-  make_float_token(mpfr_t val, source_location location)
+  make_float_token(mpfr_t val, Location location)
   {
     Token tok(TOKEN_FLOAT, location);
     mpfr_init(tok.u_.float_value);
@@ -156,7 +157,7 @@ class Token
 
   // Make a token for an imaginary number.
   static Token
-  make_imaginary_token(mpfr_t val, source_location location)
+  make_imaginary_token(mpfr_t val, Location location)
   {
     Token tok(TOKEN_IMAGINARY, location);
     mpfr_init(tok.u_.float_value);
@@ -165,7 +166,7 @@ class Token
   }
 
   // Get the location of the token.
-  source_location
+  Location
   location() const
   { return this->location_; }
 
@@ -275,7 +276,7 @@ class Token
 
  private:
   // Private constructor used by make_..._token functions above.
-  Token(Classification, source_location);
+  Token(Classification, Location);
 
   // Clear the token.
   void
@@ -307,7 +308,7 @@ class Token
     Operator op;
   } u_;
   // The source location.
-  source_location location_;
+  Location location_;
 };
 
 // The lexer itself.
@@ -315,7 +316,7 @@ class Token
 class Lex
 {
  public:
-  Lex(const char* input_file_name, FILE* input_file);
+  Lex(const char* input_file_name, FILE* input_file, Linemap *linemap);
 
   ~Lex();
 
@@ -334,7 +335,7 @@ class Lex
   // location is used to warn about an out of range character.
   static void
   append_char(unsigned int v, bool is_charater, std::string* str,
-             source_location);
+             Location);
 
   // A helper function.  Fetch a UTF-8 character from STR and store it
   // in *VALUE.  Return the number of bytes read from STR.  Return 0
@@ -350,11 +351,11 @@ class Lex
   require_line();
 
   // The current location.
-  source_location
+  Location
   location() const;
 
   // A position CHARS column positions before the current location.
-  source_location
+  Location
   earlier_location(int chars) const;
 
   static bool
@@ -432,6 +433,8 @@ class Lex
   const char* input_file_name_;
   // The input file.
   FILE* input_file_;
+  // The object used to keep track of file names and line numbers.
+  Linemap* linemap_;
   // The line buffer.  This holds the current line.
   char* linebuf_;
   // The size of the line buffer.
index 6f7b8f2..6228868 100644 (file)
@@ -42,8 +42,8 @@ Parse::Enclosing_var_comparison::operator()(const Enclosing_var& v1,
 
 Parse::Parse(Lex* lex, Gogo* gogo)
   : lex_(lex),
-    token_(Token::make_invalid_token(0)),
-    unget_token_(Token::make_invalid_token(0)),
+    token_(Token::make_invalid_token(Linemap::unknown_location())),
+    unget_token_(Token::make_invalid_token(Linemap::unknown_location())),
     unget_token_valid_(false),
     gogo_(gogo),
     break_stack_(NULL),
@@ -92,7 +92,7 @@ Parse::unget_token(const Token& token)
 
 // The location of the current token.
 
-source_location
+Location
 Parse::location()
 {
   return this->peek_token()->location();
@@ -142,7 +142,7 @@ Parse::expression_list(Expression* first, bool may_be_sink)
        return ret;
 
       // Most expression lists permit a trailing comma.
-      source_location location = token->location();
+      Location location = token->location();
       this->advance_token();
       if (!this->expression_may_start_here())
        {
@@ -242,7 +242,7 @@ Parse::type()
     return this->interface_type();
   else if (token->is_keyword(KEYWORD_FUNC))
     {
-      source_location location = token->location();
+      Location location = token->location();
       this->advance_token();
       Type* type = this->signature(NULL, location);
       if (type == NULL)
@@ -299,7 +299,7 @@ Parse::type_may_start_here()
 Type*
 Parse::type_name(bool issue_error)
 {
-  source_location location = this->location();
+  Location location = this->location();
 
   std::string name;
   Named_object* package;
@@ -425,7 +425,7 @@ Parse::array_type(bool may_use_ellipsis)
 Type*
 Parse::map_type()
 {
-  source_location location = this->location();
+  Location location = this->location();
   go_assert(this->peek_token()->is_keyword(KEYWORD_MAP));
   if (!this->advance_token()->is_op(OPERATOR_LSQUARE))
     {
@@ -457,10 +457,10 @@ Type*
 Parse::struct_type()
 {
   go_assert(this->peek_token()->is_keyword(KEYWORD_STRUCT));
-  source_location location = this->location();
+  Location location = this->location();
   if (!this->advance_token()->is_op(OPERATOR_LCURLY))
     {
-      source_location token_loc = this->location();
+      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 %<{%>");
@@ -514,7 +514,7 @@ void
 Parse::field_decl(Struct_field_list* sfl)
 {
   const Token* token = this->peek_token();
-  source_location location = token->location();
+  Location location = token->location();
   bool is_anonymous;
   bool is_anonymous_pointer;
   if (token->is_op(OPERATOR_MULT))
@@ -526,7 +526,7 @@ Parse::field_decl(Struct_field_list* sfl)
     {
       std::string id = token->identifier();
       bool is_id_exported = token->is_identifier_exported();
-      source_location id_location = token->location();
+      Location id_location = token->location();
       token = this->advance_token();
       is_anonymous = (token->is_op(OPERATOR_SEMICOLON)
                      || token->is_op(OPERATOR_RCURLY)
@@ -718,7 +718,7 @@ Parse::check_signature_names(const Typed_identifier_list* params,
 // This returns NULL on a parse error.
 
 Function_type*
-Parse::signature(Typed_identifier* receiver, source_location location)
+Parse::signature(Typed_identifier* receiver, Location location)
 {
   bool is_varargs = false;
   Typed_identifier_list* params;
@@ -801,7 +801,7 @@ Parse::parameters(Typed_identifier_list** pparams, bool* is_varargs)
 Typed_identifier_list*
 Parse::parameter_list(bool* is_varargs)
 {
-  source_location location = this->location();
+  Location location = this->location();
   Typed_identifier_list* ret = new Typed_identifier_list();
 
   bool saw_error = false;
@@ -822,7 +822,7 @@ Parse::parameter_list(bool* is_varargs)
     {
       std::string name = token->identifier();
       bool is_exported = token->is_identifier_exported();
-      source_location location = token->location();
+      Location location = token->location();
       token = this->advance_token();
       if (!token->is_op(OPERATOR_COMMA))
        {
@@ -1000,7 +1000,7 @@ Parse::parameter_decl(bool parameters_have_names,
   if (!parameters_have_names)
     {
       Type* type;
-      source_location location = this->location();
+      Location location = this->location();
       if (!this->peek_token()->is_identifier())
        {
          if (!this->peek_token()->is_op(OPERATOR_ELLIPSIS))
@@ -1078,7 +1078,7 @@ Parse::result(Typed_identifier_list** presults)
     return this->parameters(presults, NULL);
   else
     {
-      source_location location = this->location();
+      Location location = this->location();
       Type* type = this->type();
       if (type->is_error_type())
        {
@@ -1096,19 +1096,19 @@ Parse::result(Typed_identifier_list** presults)
 
 // Returns the location of the closing brace.
 
-source_location
+Location
 Parse::block()
 {
   if (!this->peek_token()->is_op(OPERATOR_LCURLY))
     {
-      source_location loc = this->location();
+      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 %<{%>");
       else
        {
          error_at(this->location(), "expected %<{%>");
-         return UNKNOWN_LOCATION;
+         return Linemap::unknown_location();
        }
     }
 
@@ -1125,7 +1125,7 @@ Parse::block()
 
          // Skip ahead to the end of the block, in hopes of avoiding
          // lots of meaningless errors.
-         source_location ret = token->location();
+         Location ret = token->location();
          int nest = 0;
          while (!token->is_eof())
            {
@@ -1147,7 +1147,7 @@ Parse::block()
        }
     }
 
-  source_location ret = token->location();
+  Location ret = token->location();
   this->advance_token();
   return ret;
 }
@@ -1159,11 +1159,11 @@ Type*
 Parse::interface_type()
 {
   go_assert(this->peek_token()->is_keyword(KEYWORD_INTERFACE));
-  source_location location = this->location();
+  Location location = this->location();
 
   if (!this->advance_token()->is_op(OPERATOR_LCURLY))
     {
-      source_location token_loc = this->location();
+      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 %<{%>");
@@ -1224,7 +1224,7 @@ Parse::method_spec(Typed_identifier_list* methods)
 
   std::string name = token->identifier();
   bool is_exported = token->is_identifier_exported();
-  source_location location = token->location();
+  Location location = token->location();
 
   if (this->advance_token()->is_op(OPERATOR_LPAREN))
     {
@@ -1472,7 +1472,7 @@ Parse::type_spec(void*)
     }
   std::string name = token->identifier();
   bool is_exported = token->is_identifier_exported();
-  source_location location = token->location();
+  Location location = token->location();
   token = this->advance_token();
 
   // The scope of the type name starts at the point where the
@@ -1549,7 +1549,7 @@ Parse::var_spec(void*)
   Typed_identifier_list til;
   this->identifier_list(&til);
 
-  source_location location = this->location();
+  Location location = this->location();
 
   Type* type = NULL;
   Expression_list* init = NULL;
@@ -1588,7 +1588,7 @@ Parse::var_spec(void*)
 void
 Parse::init_vars(const Typed_identifier_list* til, Type* type,
                 Expression_list* init, bool is_coloneq,
-                source_location location)
+                Location location)
 {
   // Check for an initialization which can yield multiple values.
   if (init != NULL && init->size() == 1 && til->size() > 1)
@@ -1648,7 +1648,7 @@ Parse::init_vars(const Typed_identifier_list* til, Type* type,
 bool
 Parse::init_vars_from_call(const Typed_identifier_list* vars, Type* type,
                           Expression* expr, bool is_coloneq,
-                          source_location location)
+                          Location location)
 {
   Call_expression* call = expr->call_expression();
   if (call == NULL)
@@ -1681,7 +1681,7 @@ Parse::init_vars_from_call(const Typed_identifier_list* vars, Type* type,
 bool
 Parse::init_vars_from_map(const Typed_identifier_list* vars, Type* type,
                          Expression* expr, bool is_coloneq,
-                         source_location location)
+                         Location location)
 {
   Index_expression* index = expr->index_expression();
   if (index == NULL)
@@ -1746,7 +1746,7 @@ Parse::init_vars_from_map(const Typed_identifier_list* vars, Type* type,
 bool
 Parse::init_vars_from_receive(const Typed_identifier_list* vars, Type* type,
                              Expression* expr, bool is_coloneq,
-                             source_location location)
+                             Location location)
 {
   Receive_expression* receive = expr->receive_expression();
   if (receive == NULL)
@@ -1812,7 +1812,7 @@ Parse::init_vars_from_receive(const Typed_identifier_list* vars, Type* type,
 bool
 Parse::init_vars_from_type_guard(const Typed_identifier_list* vars,
                                 Type* type, Expression* expr,
-                                bool is_coloneq, source_location location)
+                                bool is_coloneq, Location location)
 {
   Type_guard_expression* type_guard = expr->type_guard_expression();
   if (type_guard == NULL)
@@ -1878,7 +1878,7 @@ Named_object*
 Parse::init_var(const Typed_identifier& tid, Type* type, Expression* init,
                bool is_coloneq, bool type_from_init, bool* is_new)
 {
-  source_location location = tid.location();
+  Location location = tid.location();
 
   if (Gogo::is_sink_name(tid.name()))
     {
@@ -1927,7 +1927,7 @@ Parse::init_var(const Typed_identifier& tid, Type* type, Expression* init,
 
 Named_object*
 Parse::create_dummy_global(Type* type, Expression* init,
-                          source_location location)
+                          Location location)
 {
   if (type == NULL && init == NULL)
     type = Type::lookup_bool_type();
@@ -1956,7 +1956,7 @@ Parse::create_dummy_global(Type* type, Expression* init,
 
 void
 Parse::simple_var_decl_or_assignment(const std::string& name,
-                                    source_location location,
+                                    Location location,
                                     Range_clause* p_range_clause,
                                     Type_switch* p_type_switch)
 {
@@ -1976,7 +1976,7 @@ Parse::simple_var_decl_or_assignment(const std::string& name,
 
          std::string id = token->identifier();
          bool is_id_exported = token->is_identifier_exported();
-         source_location id_location = token->location();
+         Location id_location = token->location();
 
          token = this->advance_token();
          if (!token->is_op(OPERATOR_COMMA))
@@ -2079,7 +2079,7 @@ void
 Parse::function_decl()
 {
   go_assert(this->peek_token()->is_keyword(KEYWORD_FUNC));
-  source_location location = this->location();
+  Location location = this->location();
   const Token* token = this->advance_token();
 
   Typed_identifier* rec = NULL;
@@ -2138,7 +2138,7 @@ Parse::function_decl()
   // Check for the easy error of a newline before the opening brace.
   if (this->peek_token()->is_op(OPERATOR_SEMICOLON))
     {
-      source_location semi_loc = this->location();
+      Location semi_loc = this->location();
       if (this->advance_token()->is_op(OPERATOR_LCURLY))
        error_at(this->location(),
                 "unexpected semicolon or newline before %<{%>");
@@ -2155,7 +2155,7 @@ Parse::function_decl()
   else
     {
       this->gogo_->start_function(name, fntype, true, location);
-      source_location end_loc = this->block();
+      Location end_loc = this->block();
       this->gogo_->finish_function(end_loc);
     }
 }
@@ -2170,7 +2170,7 @@ Parse::receiver()
 
   std::string name;
   const Token* token = this->advance_token();
-  source_location location = token->location();
+  Location location = token->location();
   if (!token->is_op(OPERATOR_MULT))
     {
       if (!token->is_identifier())
@@ -2271,7 +2271,7 @@ Parse::operand(bool may_be_sink)
     {
     case Token::TOKEN_IDENTIFIER:
       {
-       source_location location = token->location();
+       Location location = token->location();
        std::string id = token->identifier();
        bool is_exported = token->is_identifier_exported();
        std::string packed = this->gogo_->pack_hidden_name(id, is_exported);
@@ -2412,7 +2412,7 @@ Parse::operand(bool may_be_sink)
        case KEYWORD_MAP:
        case KEYWORD_STRUCT:
          {
-           source_location location = token->location();
+           Location location = token->location();
            return Expression::make_type(this->type(), location);
          }
        default:
@@ -2435,7 +2435,7 @@ Parse::operand(bool may_be_sink)
        {
          // Here we call array_type directly, as this is the only
          // case where an ellipsis is permitted for an array type.
-         source_location location = token->location();
+         Location location = token->location();
          return Expression::make_type(this->array_type(true), location);
        }
       break;
@@ -2455,7 +2455,7 @@ Parse::operand(bool may_be_sink)
 
 Expression*
 Parse::enclosing_var_reference(Named_object* in_function, Named_object* var,
-                              source_location location)
+                              Location location)
 {
   go_assert(var->is_variable() || var->is_result_variable());
 
@@ -2505,7 +2505,7 @@ Parse::enclosing_var_reference(Named_object* in_function, Named_object* var,
 // 1.  In [][][]int{{{1}}} it will be 2.
 
 Expression*
-Parse::composite_lit(Type* type, int depth, source_location location)
+Parse::composite_lit(Type* type, int depth, Location location)
 {
   go_assert(this->peek_token()->is_op(OPERATOR_LCURLY));
   this->advance_token();
@@ -2530,7 +2530,7 @@ Parse::composite_lit(Type* type, int depth, source_location location)
        {
          std::string identifier = token->identifier();
          bool is_exported = token->is_identifier_exported();
-         source_location location = token->location();
+         Location location = token->location();
 
          if (this->advance_token()->is_op(OPERATOR_COLON))
            {
@@ -2656,7 +2656,7 @@ Parse::composite_lit(Type* type, int depth, source_location location)
 Expression*
 Parse::function_lit()
 {
-  source_location location = this->location();
+  Location location = this->location();
   go_assert(this->peek_token()->is_keyword(KEYWORD_FUNC));
   this->advance_token();
 
@@ -2679,7 +2679,7 @@ Parse::function_lit()
 
   Named_object* no = this->gogo_->start_function("", type, true, location);
 
-  source_location end_loc = this->block();
+  Location end_loc = this->block();
 
   this->gogo_->finish_function(end_loc);
 
@@ -2706,7 +2706,7 @@ Parse::function_lit()
 
 Expression*
 Parse::create_closure(Named_object* function, Enclosing_vars* enclosing_vars,
-                     source_location location)
+                     Location location)
 {
   if (enclosing_vars->empty())
     return NULL;
@@ -2761,7 +2761,7 @@ Expression*
 Parse::primary_expr(bool may_be_sink, bool may_be_composite_lit,
                    bool* is_type_switch)
 {
-  source_location start_loc = this->location();
+  Location start_loc = this->location();
   bool is_parenthesized = this->peek_token()->is_op(OPERATOR_LPAREN);
 
   Expression* ret = this->operand(may_be_sink);
@@ -2792,7 +2792,7 @@ Parse::primary_expr(bool may_be_sink, bool may_be_composite_lit,
        }
       else if (this->peek_token()->is_op(OPERATOR_LPAREN))
        {
-         source_location loc = this->location();
+         Location loc = this->location();
          this->advance_token();
          Expression* expr = this->expression(PRECEDENCE_NORMAL, false, true,
                                              NULL);
@@ -2859,7 +2859,7 @@ Expression*
 Parse::selector(Expression* left, bool* is_type_switch)
 {
   go_assert(this->peek_token()->is_op(OPERATOR_DOT));
-  source_location location = this->location();
+  Location location = this->location();
 
   const Token* token = this->advance_token();
   if (token->is_identifier())
@@ -2917,7 +2917,7 @@ Parse::selector(Expression* left, bool* is_type_switch)
 Expression*
 Parse::index(Expression* expr)
 {
-  source_location location = this->location();
+  Location location = this->location();
   go_assert(this->peek_token()->is_op(OPERATOR_LSQUARE));
   this->advance_token();
 
@@ -2982,7 +2982,7 @@ Parse::call(Expression* func)
 // Return an expression for a single unqualified identifier.
 
 Expression*
-Parse::id_to_expression(const std::string& name, source_location location)
+Parse::id_to_expression(const std::string& name, Location location)
 {
   Named_object* in_function;
   Named_object* named_object = this->gogo_->lookup(name, &in_function);
@@ -3096,7 +3096,7 @@ Parse::expression(Precedence precedence, bool may_be_sink,
        }
 
       Operator op = token->op();
-      source_location binop_location = token->location();
+      Location binop_location = token->location();
 
       if (precedence >= right_precedence)
        {
@@ -3188,7 +3188,7 @@ Parse::unary_expr(bool may_be_sink, bool may_be_composite_lit,
       || token->is_op(OPERATOR_MULT)
       || token->is_op(OPERATOR_AND))
     {
-      source_location location = token->location();
+      Location location = token->location();
       Operator op = token->op();
       this->advance_token();
 
@@ -3288,7 +3288,7 @@ Parse::statement(Label* label)
       {
        std::string identifier = token->identifier();
        bool is_exported = token->is_identifier_exported();
-       source_location location = token->location();
+       Location location = token->location();
        if (this->advance_token()->is_op(OPERATOR_COLON))
          {
            this->advance_token();
@@ -3307,9 +3307,9 @@ Parse::statement(Label* label)
     case Token::TOKEN_OPERATOR:
       if (token->is_op(OPERATOR_LCURLY))
        {
-         source_location location = token->location();
+         Location location = token->location();
          this->gogo_->start_block(location);
-         source_location end_loc = this->block();
+         Location end_loc = this->block();
          this->gogo_->add_block(this->gogo_->finish_block(end_loc),
                                 location);
        }
@@ -3391,7 +3391,7 @@ Parse::statement_may_start_here()
 // Label       = identifier .
 
 void
-Parse::labeled_stmt(const std::string& label_name, source_location location)
+Parse::labeled_stmt(const std::string& label_name, Location location)
 {
   Label* label = this->gogo_->add_label_definition(label_name, location);
 
@@ -3447,7 +3447,7 @@ Parse::simple_stat(bool may_be_composite_lit, bool* return_exp,
     {
       std::string identifier = token->identifier();
       bool is_exported = token->is_identifier_exported();
-      source_location location = token->location();
+      Location location = token->location();
 
       token = this->advance_token();
       if (token->is_op(OPERATOR_COLONEQ)
@@ -3576,7 +3576,7 @@ void
 Parse::send_stmt(Expression* channel)
 {
   go_assert(this->peek_token()->is_op(OPERATOR_CHANOP));
-  source_location loc = this->location();
+  Location loc = this->location();
   this->advance_token();
   Expression* val = this->expression(PRECEDENCE_NORMAL, false, true, NULL);
   Statement* s = Statement::make_send_statement(channel, val, loc);
@@ -3655,7 +3655,7 @@ Parse::tuple_assignment(Expression_list* lhs, Range_clause* p_range_clause)
       return;
     }
   Operator op = token->op();
-  source_location location = token->location();
+  Location location = token->location();
 
   token = this->advance_token();
 
@@ -3803,9 +3803,9 @@ Parse::go_or_defer_stat()
   go_assert(this->peek_token()->is_keyword(KEYWORD_GO)
             || this->peek_token()->is_keyword(KEYWORD_DEFER));
   bool is_go = this->peek_token()->is_keyword(KEYWORD_GO);
-  source_location stat_location = this->location();
+  Location stat_location = this->location();
   this->advance_token();
-  source_location expr_location = this->location();
+  Location expr_location = this->location();
   Expression* expr = this->expression(PRECEDENCE_NORMAL, false, true, NULL);
   Call_expression* call_expr = expr->call_expression();
   if (call_expr == NULL)
@@ -3833,7 +3833,7 @@ void
 Parse::return_stat()
 {
   go_assert(this->peek_token()->is_keyword(KEYWORD_RETURN));
-  source_location location = this->location();
+  Location location = this->location();
   this->advance_token();
   Expression_list* vals = NULL;
   if (this->expression_may_start_here())
@@ -3865,7 +3865,7 @@ void
 Parse::if_stat()
 {
   go_assert(this->peek_token()->is_keyword(KEYWORD_IF));
-  source_location location = this->location();
+  Location location = this->location();
   this->advance_token();
 
   this->gogo_->start_block(location);
@@ -3911,13 +3911,13 @@ Parse::if_stat()
     }
 
   this->gogo_->start_block(this->location());
-  source_location end_loc = this->block();
+  Location end_loc = this->block();
   Block* then_block = this->gogo_->finish_block(end_loc);
 
   // Check for the easy error of a newline before "else".
   if (this->peek_token()->is_op(OPERATOR_SEMICOLON))
     {
-      source_location semi_loc = this->location();
+      Location semi_loc = this->location();
       if (this->advance_token()->is_keyword(KEYWORD_ELSE))
        error_at(this->location(),
                 "unexpected semicolon or newline before %<else%>");
@@ -3962,7 +3962,7 @@ void
 Parse::switch_stat(Label* label)
 {
   go_assert(this->peek_token()->is_keyword(KEYWORD_SWITCH));
-  source_location location = this->location();
+  Location location = this->location();
   this->advance_token();
 
   this->gogo_->start_block(location);
@@ -4004,7 +4004,7 @@ Parse::switch_stat(Label* label)
              const Token* token = this->peek_token();
              std::string identifier = token->identifier();
              bool is_exported = token->is_identifier_exported();
-             source_location id_loc = token->location();
+             Location id_loc = token->location();
 
              token = this->advance_token();
              bool is_coloneq = token->is_op(OPERATOR_COLONEQ);
@@ -4043,7 +4043,7 @@ Parse::switch_stat(Label* label)
 
   if (!this->peek_token()->is_op(OPERATOR_LCURLY))
     {
-      source_location token_loc = this->location();
+      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 %<{%>");
@@ -4088,7 +4088,7 @@ Parse::switch_stat(Label* label)
 
 Statement*
 Parse::expr_switch_body(Label* label, Expression* switch_val,
-                       source_location location)
+                       Location location)
 {
   Switch_statement* statement = Statement::make_switch_statement(switch_val,
                                                                 location);
@@ -4122,7 +4122,7 @@ Parse::expr_switch_body(Label* label, Expression* switch_val,
 void
 Parse::expr_case_clause(Case_clauses* clauses, bool* saw_default)
 {
-  source_location location = this->location();
+  Location location = this->location();
 
   bool is_default = false;
   Expression_list* vals = this->expr_switch_case(&is_default);
@@ -4198,7 +4198,7 @@ Parse::expr_switch_case(bool* is_default)
 
 Statement*
 Parse::type_switch_body(Label* label, const Type_switch& type_switch,
-                       source_location location)
+                       Location location)
 {
   Named_object* switch_no = NULL;
   if (!type_switch.name.empty())
@@ -4243,7 +4243,7 @@ void
 Parse::type_case_clause(Named_object* switch_no, Type_case_clauses* clauses,
                        bool* saw_default)
 {
-  source_location location = this->location();
+  Location location = this->location();
 
   std::vector<Type*> types;
   bool is_default = false;
@@ -4355,12 +4355,12 @@ void
 Parse::select_stat(Label* label)
 {
   go_assert(this->peek_token()->is_keyword(KEYWORD_SELECT));
-  source_location location = this->location();
+  Location location = this->location();
   const Token* token = this->advance_token();
 
   if (!token->is_op(OPERATOR_LCURLY))
     {
-      source_location token_loc = token->location();
+      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 %<{%>");
@@ -4402,7 +4402,7 @@ Parse::select_stat(Label* label)
 void
 Parse::comm_clause(Select_clauses* clauses, bool* saw_default)
 {
-  source_location location = this->location();
+  Location location = this->location();
   bool is_send = false;
   Expression* channel = NULL;
   Expression* val = NULL;
@@ -4518,7 +4518,7 @@ Parse::send_or_recv_stmt(bool* is_send, Expression** channel, Expression** val,
       Gogo* gogo = this->gogo_;
       std::string recv_var = token->identifier();
       bool is_rv_exported = token->is_identifier_exported();
-      source_location recv_var_loc = token->location();
+      Location recv_var_loc = token->location();
       token = this->advance_token();
       if (token->is_op(OPERATOR_COLONEQ))
        {
@@ -4547,7 +4547,7 @@ Parse::send_or_recv_stmt(bool* is_send, Expression** channel, Expression** val,
            {
              std::string recv_closed = token->identifier();
              bool is_rc_exported = token->is_identifier_exported();
-             source_location recv_closed_loc = token->location();
+             Location recv_closed_loc = token->location();
              closed_is_id = true;
 
              token = this->advance_token();
@@ -4673,7 +4673,7 @@ void
 Parse::for_stat(Label* label)
 {
   go_assert(this->peek_token()->is_keyword(KEYWORD_FOR));
-  source_location location = this->location();
+  Location location = this->location();
   const Token* token = this->advance_token();
 
   // Open a block to hold any variables defined in the init statement
@@ -4761,7 +4761,7 @@ Parse::for_stat(Label* label)
   // For_statement.
 
   this->gogo_->start_block(this->location());
-  source_location end_loc = this->block();
+  Location end_loc = this->block();
   Block* statements = this->gogo_->finish_block(end_loc);
 
   if (sfor != NULL)
@@ -4830,7 +4830,7 @@ Parse::range_clause_decl(const Typed_identifier_list* til,
                         Range_clause* p_range_clause)
 {
   go_assert(this->peek_token()->is_keyword(KEYWORD_RANGE));
-  source_location location = this->location();
+  Location location = this->location();
 
   p_range_clause->found = true;
 
@@ -4956,7 +4956,7 @@ void
 Parse::break_stat()
 {
   go_assert(this->peek_token()->is_keyword(KEYWORD_BREAK));
-  source_location location = this->location();
+  Location location = this->location();
 
   const Token* token = this->advance_token();
   Statement* enclosing;
@@ -4978,7 +4978,8 @@ Parse::break_stat()
        {
          // If there is a label with this name, mark it as used to
          // avoid a useless error about an unused label.
-         this->gogo_->add_label_reference(token->identifier(), 0, false);
+         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());
@@ -5012,7 +5013,7 @@ void
 Parse::continue_stat()
 {
   go_assert(this->peek_token()->is_keyword(KEYWORD_CONTINUE));
-  source_location location = this->location();
+  Location location = this->location();
 
   const Token* token = this->advance_token();
   Statement* enclosing;
@@ -5033,7 +5034,8 @@ Parse::continue_stat()
        {
          // If there is a label with this name, mark it as used to
          // avoid a useless error about an unused label.
-         this->gogo_->add_label_reference(token->identifier(), 0, false);
+         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());
@@ -5061,7 +5063,7 @@ void
 Parse::goto_stat()
 {
   go_assert(this->peek_token()->is_keyword(KEYWORD_GOTO));
-  source_location location = this->location();
+  Location location = this->location();
   const Token* token = this->advance_token();
   if (!token->is_identifier())
     error_at(this->location(), "expected label for goto");
@@ -5081,7 +5083,7 @@ void
 Parse::package_clause()
 {
   const Token* token = this->peek_token();
-  source_location location = token->location();
+  Location location = token->location();
   std::string name;
   if (!token->is_keyword(KEYWORD_PACKAGE))
     {
@@ -5126,7 +5128,7 @@ void
 Parse::import_spec(void*)
 {
   const Token* token = this->peek_token();
-  source_location location = token->location();
+  Location location = token->location();
 
   std::string local_name;
   bool is_local_name_exported = false;
index 0da86fb..0a3fe64 100644 (file)
@@ -75,7 +75,7 @@ class Parse
     // The variable name.
     std::string name;
     // The location of the variable.
-    source_location location;
+    Location location;
     // The expression.
     Expression* expr;
 
@@ -147,7 +147,7 @@ class Parse
   unget_token(const Token&);
 
   // The location of the current token.
-  source_location
+  Location
   location();
 
   // For break and continue we keep a stack of statements with
@@ -169,12 +169,12 @@ class Parse
   Type* pointer_type();
   Type* channel_type();
   void check_signature_names(const Typed_identifier_list*, Names*);
-  Function_type* signature(Typed_identifier*, source_location);
+  Function_type* signature(Typed_identifier*, Location);
   bool parameters(Typed_identifier_list**, bool* is_varargs);
   Typed_identifier_list* parameter_list(bool* is_varargs);
   void parameter_decl(bool, Typed_identifier_list*, bool*, bool*);
   bool result(Typed_identifier_list**);
-  source_location block();
+  Location block();
   Type* interface_type();
   void method_spec(Typed_identifier_list*);
   void declaration();
@@ -188,30 +188,30 @@ class Parse
   void var_decl();
   void var_spec(void*);
   void init_vars(const Typed_identifier_list*, Type*, Expression_list*,
-                bool is_coloneq, source_location);
+                bool is_coloneq, Location);
   bool init_vars_from_call(const Typed_identifier_list*, Type*, Expression*,
-                          bool is_coloneq, source_location);
+                          bool is_coloneq, Location);
   bool init_vars_from_map(const Typed_identifier_list*, Type*, Expression*,
-                         bool is_coloneq, source_location);
+                         bool is_coloneq, Location);
   bool init_vars_from_receive(const Typed_identifier_list*, Type*,
-                             Expression*, bool is_coloneq, source_location);
+                             Expression*, bool is_coloneq, Location);
   bool init_vars_from_type_guard(const Typed_identifier_list*, Type*,
                                 Expression*, bool is_coloneq,
-                                source_location);
+                                Location);
   Named_object* init_var(const Typed_identifier&, Type*, Expression*,
                         bool is_coloneq, bool type_from_init, bool* is_new);
-  Named_object* create_dummy_global(Type*, Expression*, source_location);
-  void simple_var_decl_or_assignment(const std::string&, source_location,
+  Named_object* create_dummy_global(Type*, Expression*, Location);
+  void simple_var_decl_or_assignment(const std::string&, Location,
                                     Range_clause*, Type_switch*);
   void function_decl();
   Typed_identifier* receiver();
   Expression* operand(bool may_be_sink);
   Expression* enclosing_var_reference(Named_object*, Named_object*,
-                                     source_location);
-  Expression* composite_lit(Type*, int depth, source_location);
+                                     Location);
+  Expression* composite_lit(Type*, int depth, Location);
   Expression* function_lit();
   Expression* create_closure(Named_object* function, Enclosing_vars*,
-                            source_location);
+                            Location);
   Expression* primary_expr(bool may_be_sink, bool may_be_composite_lit,
                           bool* is_type_switch);
   Expression* selector(Expression*, bool* is_type_switch);
@@ -222,11 +222,11 @@ class Parse
   bool expression_may_start_here();
   Expression* unary_expr(bool may_be_sink, bool may_be_composite_lit,
                         bool* is_type_switch);
-  Expression* qualified_expr(Expression*, source_location);
-  Expression* id_to_expression(const std::string&, source_location);
+  Expression* qualified_expr(Expression*, Location);
+  Expression* id_to_expression(const std::string&, Location);
   void statement(Label*);
   bool statement_may_start_here();
-  void labeled_stmt(const std::string&, source_location);
+  void labeled_stmt(const std::string&, Location);
   Expression* simple_stat(bool, bool*, Range_clause*, Type_switch*);
   bool simple_stat_may_start_here();
   void statement_list();
@@ -241,10 +241,10 @@ class Parse
   void return_stat();
   void if_stat();
   void switch_stat(Label*);
-  Statement* expr_switch_body(Label*, Expression*, source_location);
+  Statement* expr_switch_body(Label*, Expression*, Location);
   void expr_case_clause(Case_clauses*, bool* saw_default);
   Expression_list* expr_switch_case(bool*);
-  Statement* type_switch_body(Label*, const Type_switch&, source_location);
+  Statement* type_switch_body(Label*, const Type_switch&, Location);
   void type_case_clause(Named_object*, Type_case_clauses*, bool* saw_default);
   void type_switch_case(std::vector<Type*>*, bool*);
   void select_stat(Label*);
index 2ecfbf5..42f1e78 100644 (file)
@@ -82,7 +82,7 @@ runtime_function_type(Runtime_function_type bft)
   go_assert(bft < NUMBER_OF_RUNTIME_FUNCTION_TYPES);
   if (runtime_function_types[bft] == NULL)
     {
-      const source_location bloc = BUILTINS_LOCATION;
+      const Location bloc = Linemap::predeclared_location();
       Type* t;
       switch (bft)
        {
@@ -193,7 +193,7 @@ runtime_function_type(Runtime_function_type bft)
 
 static Expression*
 convert_to_runtime_function_type(Runtime_function_type bft, Expression* e,
-                                source_location loc)
+                                Location loc)
 {
   switch (bft)
     {
@@ -295,7 +295,7 @@ Runtime::runtime_declaration(Function code)
     {
       const Runtime_function* pb = &runtime_functions[code];
 
-      source_location bloc = BUILTINS_LOCATION;
+      Location bloc = Linemap::predeclared_location();
 
       Typed_identifier_list* param_types = NULL;
       if (pb->parameter_types[0] != RFT_VOID)
@@ -347,7 +347,7 @@ Runtime::runtime_declaration(Function code)
 // Make a call to a runtime function.
 
 Call_expression*
-Runtime::make_call(Runtime::Function code, source_location loc,
+Runtime::make_call(Runtime::Function code, Location loc,
                   int param_count, ...)
 {
   go_assert(code < Runtime::NUMBER_OF_FUNCTIONS);
@@ -387,7 +387,8 @@ Runtime::map_iteration_type()
 
   mpz_t ival;
   mpz_init_set_ui(ival, map_iteration_size);
-  Expression* iexpr = Expression::make_integer(&ival, NULL, BUILTINS_LOCATION);
+  Expression* iexpr = Expression::make_integer(&ival, NULL,
+                                               Linemap::predeclared_location());
   mpz_clear(ival);
 
   return Type::make_array_type(runtime_function_type(RFT_POINTER), iexpr);
index f7c878e..3cd4034 100644 (file)
@@ -32,7 +32,7 @@ class Runtime
 
   // Make a call to a runtime function.
   static Call_expression*
-  make_call(Function, source_location, int, ...);
+  make_call(Function, Location, int, ...);
 
   // Convert all the types used by runtime functions to the backend
   // representation.
index 156977d..835a0cc 100644 (file)
@@ -20,7 +20,7 @@
 // Class Statement.
 
 Statement::Statement(Statement_classification classification,
-                    source_location location)
+                    Location location)
   : classification_(classification), location_(location)
 {
 }
@@ -175,7 +175,7 @@ Statement::report_error(const char* msg)
 class Error_statement : public Statement
 {
  public:
-  Error_statement(source_location location)
+  Error_statement(Location location)
     : Statement(STATEMENT_ERROR, location)
   { }
 
@@ -204,7 +204,7 @@ Error_statement::do_dump_statement(Ast_dump_context* ast_dump_context) const
 // Make an error statement.
 
 Statement*
-Statement::make_error_statement(source_location location)
+Statement::make_error_statement(Location location)
 {
   return new Error_statement(location);
 }
@@ -268,7 +268,7 @@ Variable_declaration_statement::do_get_backend(Translate_context* context)
   // Something takes the address of this variable, so the value is
   // stored in the heap.  Initialize it to newly allocated memory
   // space, and assign the initial value to the new space.
-  source_location loc = this->location();
+  Location loc = this->location();
   Named_object* newfn = context->gogo()->lookup_global("new");
   go_assert(newfn != NULL && newfn->is_function_declaration());
   Expression* func = Expression::make_func_reference(newfn, NULL, loc);
@@ -497,7 +497,7 @@ Temporary_statement::do_dump_statement(Ast_dump_context* ast_dump_context) const
 
 Temporary_statement*
 Statement::make_temporary(Type* type, Expression* init,
-                         source_location location)
+                         Location location)
 {
   return new Temporary_statement(type, init, location);
 }
@@ -508,7 +508,7 @@ class Assignment_statement : public Statement
 {
  public:
   Assignment_statement(Expression* lhs, Expression* rhs,
-                      source_location location)
+                      Location location)
     : Statement(STATEMENT_ASSIGNMENT, location),
       lhs_(lhs), rhs_(rhs), are_hidden_fields_ok_(false)
   { }
@@ -647,7 +647,7 @@ Assignment_statement::do_dump_statement(Ast_dump_context* ast_dump_context)
 
 Statement*
 Statement::make_assignment(Expression* lhs, Expression* rhs,
-                          source_location location)
+                          Location location)
 {
   return new Assignment_statement(lhs, rhs, location);
 }
@@ -684,7 +684,7 @@ Move_subexpressions::expression(Expression** pexpr)
     --this->skip_;
   else if ((*pexpr)->temporary_reference_expression() == NULL)
     {
-      source_location loc = (*pexpr)->location();
+      Location loc = (*pexpr)->location();
       Temporary_statement* temp = Statement::make_temporary(NULL, *pexpr, loc);
       this->block_->add_statement(temp);
       *pexpr = Expression::make_temporary_reference(temp, loc);
@@ -731,7 +731,7 @@ Move_ordered_evals::expression(Expression** pexpr)
 
   if ((*pexpr)->must_eval_in_order())
     {
-      source_location loc = (*pexpr)->location();
+      Location loc = (*pexpr)->location();
       Temporary_statement* temp = Statement::make_temporary(NULL, *pexpr, loc);
       this->block_->add_statement(temp);
       *pexpr = Expression::make_temporary_reference(temp, loc);
@@ -745,7 +745,7 @@ class Assignment_operation_statement : public Statement
 {
  public:
   Assignment_operation_statement(Operator op, Expression* lhs, Expression* rhs,
-                                source_location location)
+                                Location location)
     : Statement(STATEMENT_ASSIGNMENT_OPERATION, location),
       op_(op), lhs_(lhs), rhs_(rhs)
   { }
@@ -794,7 +794,7 @@ Statement*
 Assignment_operation_statement::do_lower(Gogo*, Named_object*,
                                         Block* enclosing, Statement_inserter*)
 {
-  source_location loc = this->location();
+  Location loc = this->location();
 
   // We have to evaluate the left hand side expression only once.  We
   // do this by moving out any expression with side effects.
@@ -875,7 +875,7 @@ Assignment_operation_statement::do_dump_statement(
 
 Statement*
 Statement::make_assignment_operation(Operator op, Expression* lhs,
-                                    Expression* rhs, source_location location)
+                                    Expression* rhs, Location location)
 {
   return new Assignment_operation_statement(op, lhs, rhs, location);
 }
@@ -888,7 +888,7 @@ class Tuple_assignment_statement : public Statement
 {
  public:
   Tuple_assignment_statement(Expression_list* lhs, Expression_list* rhs,
-                            source_location location)
+                            Location location)
     : Statement(STATEMENT_TUPLE_ASSIGNMENT, location),
       lhs_(lhs), rhs_(rhs), are_hidden_fields_ok_(false)
   { }
@@ -944,7 +944,7 @@ Statement*
 Tuple_assignment_statement::do_lower(Gogo*, Named_object*, Block* enclosing,
                                     Statement_inserter*)
 {
-  source_location loc = this->location();
+  Location loc = this->location();
 
   Block* b = new Block(enclosing, loc);
 
@@ -1035,7 +1035,7 @@ Tuple_assignment_statement::do_dump_statement(
 
 Statement*
 Statement::make_tuple_assignment(Expression_list* lhs, Expression_list* rhs,
-                                source_location location)
+                                Location location)
 {
   return new Tuple_assignment_statement(lhs, rhs, location);
 }
@@ -1048,7 +1048,7 @@ class Tuple_map_assignment_statement : public Statement
 public:
   Tuple_map_assignment_statement(Expression* val, Expression* present,
                                 Expression* map_index,
-                                source_location location)
+                                Location location)
     : Statement(STATEMENT_TUPLE_MAP_ASSIGNMENT, location),
       val_(val), present_(present), map_index_(map_index)
   { }
@@ -1097,7 +1097,7 @@ Statement*
 Tuple_map_assignment_statement::do_lower(Gogo*, Named_object*,
                                         Block* enclosing, Statement_inserter*)
 {
-  source_location loc = this->location();
+  Location loc = this->location();
 
   Map_index_expression* map_index = this->map_index_->map_index_expression();
   if (map_index == NULL)
@@ -1184,7 +1184,7 @@ Tuple_map_assignment_statement::do_dump_statement(
 Statement*
 Statement::make_tuple_map_assignment(Expression* val, Expression* present,
                                     Expression* map_index,
-                                    source_location location)
+                                    Location location)
 {
   return new Tuple_map_assignment_statement(val, present, map_index, location);
 }
@@ -1197,7 +1197,7 @@ class Map_assignment_statement : public Statement
  public:
   Map_assignment_statement(Expression* map_index,
                           Expression* val, Expression* should_set,
-                          source_location location)
+                          Location location)
     : Statement(STATEMENT_MAP_ASSIGNMENT, location),
       map_index_(map_index), val_(val), should_set_(should_set)
   { }
@@ -1246,7 +1246,7 @@ Statement*
 Map_assignment_statement::do_lower(Gogo*, Named_object*, Block* enclosing,
                                   Statement_inserter*)
 {
-  source_location loc = this->location();
+  Location loc = this->location();
 
   Map_index_expression* map_index = this->map_index_->map_index_expression();
   if (map_index == NULL)
@@ -1318,7 +1318,7 @@ Map_assignment_statement::do_dump_statement(
 Statement*
 Statement::make_map_assignment(Expression* map_index,
                               Expression* val, Expression* should_set,
-                              source_location location)
+                              Location location)
 {
   return new Map_assignment_statement(map_index, val, should_set, location);
 }
@@ -1330,7 +1330,7 @@ class Tuple_receive_assignment_statement : public Statement
  public:
   Tuple_receive_assignment_statement(Expression* val, Expression* closed,
                                     Expression* channel, bool for_select,
-                                    source_location location)
+                                    Location location)
     : Statement(STATEMENT_TUPLE_RECEIVE_ASSIGNMENT, location),
       val_(val), closed_(closed), channel_(channel), for_select_(for_select)
   { }
@@ -1382,7 +1382,7 @@ Tuple_receive_assignment_statement::do_lower(Gogo*, Named_object*,
                                             Block* enclosing,
                                             Statement_inserter*)
 {
-  source_location loc = this->location();
+  Location loc = this->location();
 
   Channel_type* channel_type = this->channel_->type()->channel_type();
   if (channel_type == NULL)
@@ -1461,7 +1461,7 @@ Statement*
 Statement::make_tuple_receive_assignment(Expression* val, Expression* closed,
                                         Expression* channel,
                                         bool for_select,
-                                        source_location location)
+                                        Location location)
 {
   return new Tuple_receive_assignment_statement(val, closed, channel,
                                                for_select, location);
@@ -1475,7 +1475,7 @@ class Tuple_type_guard_assignment_statement : public Statement
  public:
   Tuple_type_guard_assignment_statement(Expression* val, Expression* ok,
                                        Expression* expr, Type* type,
-                                       source_location location)
+                                       Location location)
     : Statement(STATEMENT_TUPLE_TYPE_GUARD_ASSIGNMENT, location),
       val_(val), ok_(ok), expr_(expr), type_(type)
   { }
@@ -1534,7 +1534,7 @@ Tuple_type_guard_assignment_statement::do_lower(Gogo*, Named_object*,
                                                Block* enclosing,
                                                Statement_inserter*)
 {
-  source_location loc = this->location();
+  Location loc = this->location();
 
   Type* expr_type = this->expr_->type();
   if (expr_type->interface_type() == NULL)
@@ -1599,7 +1599,7 @@ Tuple_type_guard_assignment_statement::do_lower(Gogo*, Named_object*,
 Call_expression*
 Tuple_type_guard_assignment_statement::lower_to_type(Runtime::Function code)
 {
-  source_location loc = this->location();
+  Location loc = this->location();
   return Runtime::make_call(code, loc, 2,
                            Expression::make_type_descriptor(this->type_, loc),
                            this->expr_);
@@ -1612,7 +1612,7 @@ Tuple_type_guard_assignment_statement::lower_to_object_type(
     Block* b,
     Runtime::Function code)
 {
-  source_location loc = this->location();
+  Location loc = this->location();
 
   // var val_temp TYPE
   Temporary_statement* val_temp = Statement::make_temporary(this->type_,
@@ -1655,7 +1655,7 @@ Tuple_type_guard_assignment_statement::do_dump_statement(
 Statement*
 Statement::make_tuple_type_guard_assignment(Expression* val, Expression* ok,
                                            Expression* expr, Type* type,
-                                           source_location location)
+                                           Location location)
 {
   return new Tuple_type_guard_assignment_statement(val, ok, expr, type,
                                                   location);
@@ -1778,7 +1778,7 @@ Statement::make_statement(Expression* expr, bool is_ignored)
 class Block_statement : public Statement
 {
  public:
-  Block_statement(Block* block, source_location location)
+  Block_statement(Block* block, Location location)
     : Statement(STATEMENT_BLOCK, location),
       block_(block)
   { }
@@ -1826,7 +1826,7 @@ Block_statement::do_dump_statement(Ast_dump_context*) const
 // Make a block statement.
 
 Statement*
-Statement::make_block_statement(Block* block, source_location location)
+Statement::make_block_statement(Block* block, Location location)
 {
   return new Block_statement(block, location);
 }
@@ -1872,7 +1872,7 @@ class Inc_dec_statement : public Statement
 Statement*
 Inc_dec_statement::do_lower(Gogo*, Named_object*, Block*, Statement_inserter*)
 {
-  source_location loc = this->location();
+  Location loc = this->location();
 
   mpz_t oval;
   mpz_init_set_ui(oval, 1UL);
@@ -1916,7 +1916,7 @@ Statement::make_dec_statement(Expression* expr)
 
 Thunk_statement::Thunk_statement(Statement_classification classification,
                                 Call_expression* call,
-                                source_location location)
+                                Location location)
     : Statement(classification, location),
       call_(call), struct_type_(NULL)
 {
@@ -2145,7 +2145,7 @@ Thunk_statement::simplify_statement(Gogo* gogo, Named_object* function,
   Interface_field_reference_expression* interface_method =
     fn->interface_field_reference_expression();
 
-  source_location location = this->location();
+  Location location = this->location();
 
   std::string thunk_name = Gogo::thunk_name();
 
@@ -2230,7 +2230,7 @@ Thunk_statement::thunk_field_param(int n, char* buf, size_t buflen)
 Struct_type*
 Thunk_statement::build_struct(Function_type* fntype)
 {
-  source_location location = this->location();
+  Location location = this->location();
 
   Struct_field_list* fields = new Struct_field_list();
 
@@ -2288,7 +2288,7 @@ Thunk_statement::build_struct(Function_type* fntype)
 void
 Thunk_statement::build_thunk(Gogo* gogo, const std::string& thunk_name)
 {
-  source_location location = this->location();
+  Location location = this->location();
 
   Call_expression* ce = this->call_->call_expression();
 
@@ -2541,7 +2541,7 @@ Go_statement::do_dump_statement(Ast_dump_context* ast_dump_context) const
 // Make a go statement.
 
 Statement*
-Statement::make_go_statement(Call_expression* call, source_location location)
+Statement::make_go_statement(Call_expression* call, Location location)
 {
   return new Go_statement(call, location);
 }
@@ -2556,7 +2556,7 @@ Defer_statement::do_get_backend(Translate_context* context)
   if (!this->get_fn_and_arg(&fn, &arg))
     return context->backend()->error_statement();
 
-  source_location loc = this->location();
+  Location loc = this->location();
   Expression* ds = context->function()->func_value()->defer_stack(loc);
 
   Expression* call = Runtime::make_call(Runtime::DEFER, loc, 3,
@@ -2581,7 +2581,7 @@ Defer_statement::do_dump_statement(Ast_dump_context* ast_dump_context) const
 
 Statement*
 Statement::make_defer_statement(Call_expression* call,
-                               source_location location)
+                               Location location)
 {
   return new Defer_statement(call, location);
 }
@@ -2623,7 +2623,7 @@ Return_statement::do_lower(Gogo*, Named_object* function, Block* enclosing,
   this->vals_ = NULL;
   this->is_lowered_ = true;
 
-  source_location loc = this->location();
+  Location loc = this->location();
 
   size_t vals_count = vals == NULL ? 0 : vals->size();
   Function::Results* results = function->func_value()->result_variables();
@@ -2757,7 +2757,7 @@ Return_statement::do_lower(Gogo*, Named_object* function, Block* enclosing,
 Bstatement*
 Return_statement::do_get_backend(Translate_context* context)
 {
-  source_location loc = this->location();
+  Location loc = this->location();
 
   Function* function = context->function()->func_value();
   tree fndecl = function->get_decl();
@@ -2795,7 +2795,7 @@ Return_statement::do_dump_statement(Ast_dump_context* ast_dump_context) const
 
 Return_statement*
 Statement::make_return_statement(Expression_list* vals,
-                                source_location location)
+                                Location location)
 {
   return new Return_statement(vals, location);
 }
@@ -2805,7 +2805,7 @@ Statement::make_return_statement(Expression_list* vals,
 class Bc_statement : public Statement
 {
  public:
-  Bc_statement(bool is_break, Unnamed_label* label, source_location location)
+  Bc_statement(bool is_break, Unnamed_label* label, Location location)
     : Statement(STATEMENT_BREAK_OR_CONTINUE, location),
       label_(label), is_break_(is_break)
   { }
@@ -2855,7 +2855,7 @@ Bc_statement::do_dump_statement(Ast_dump_context* ast_dump_context) const
 // Make a break statement.
 
 Statement*
-Statement::make_break_statement(Unnamed_label* label, source_location location)
+Statement::make_break_statement(Unnamed_label* label, Location location)
 {
   return new Bc_statement(true, label, location);
 }
@@ -2864,7 +2864,7 @@ Statement::make_break_statement(Unnamed_label* label, source_location location)
 
 Statement*
 Statement::make_continue_statement(Unnamed_label* label,
-                                  source_location location)
+                                  Location location)
 {
   return new Bc_statement(false, label, location);
 }
@@ -2874,7 +2874,7 @@ Statement::make_continue_statement(Unnamed_label* label,
 class Goto_statement : public Statement
 {
  public:
-  Goto_statement(Label* label, source_location location)
+  Goto_statement(Label* label, Location location)
     : Statement(STATEMENT_GOTO, location),
       label_(label)
   { }
@@ -2936,7 +2936,7 @@ Goto_statement::do_dump_statement(Ast_dump_context* ast_dump_context) const
 // Make a goto statement.
 
 Statement*
-Statement::make_goto_statement(Label* label, source_location location)
+Statement::make_goto_statement(Label* label, Location location)
 {
   return new Goto_statement(label, location);
 }
@@ -2946,7 +2946,7 @@ Statement::make_goto_statement(Label* label, source_location location)
 class Goto_unnamed_statement : public Statement
 {
  public:
-  Goto_unnamed_statement(Unnamed_label* label, source_location location)
+  Goto_unnamed_statement(Unnamed_label* label, Location location)
     : Statement(STATEMENT_GOTO_UNNAMED, location),
       label_(label)
   { }
@@ -2987,7 +2987,7 @@ Goto_unnamed_statement::do_dump_statement(
 
 Statement*
 Statement::make_goto_unnamed_statement(Unnamed_label* label,
-                                      source_location location)
+                                      Location location)
 {
   return new Goto_unnamed_statement(label, location);
 }
@@ -3024,7 +3024,7 @@ Label_statement::do_dump_statement(Ast_dump_context* ast_dump_context) const
 // Make a label statement.
 
 Statement*
-Statement::make_label_statement(Label* label, source_location location)
+Statement::make_label_statement(Label* label, Location location)
 {
   return new Label_statement(label, location);
 }
@@ -3081,7 +3081,7 @@ class If_statement : public Statement
 {
  public:
   If_statement(Expression* cond, Block* then_block, Block* else_block,
-              source_location location)
+              Location location)
     : Statement(STATEMENT_IF, location),
       cond_(cond), then_block_(then_block), else_block_(else_block)
   { }
@@ -3201,7 +3201,7 @@ If_statement::do_dump_statement(Ast_dump_context* ast_dump_context) const
 
 Statement*
 Statement::make_if_statement(Expression* cond, Block* then_block,
-                            Block* else_block, source_location location)
+                            Block* else_block, Location location)
 {
   return new If_statement(cond, then_block, else_block, location);
 }
@@ -3303,7 +3303,7 @@ Case_clauses::Case_clause::lower(Block* b, Temporary_statement* val_temp,
                                 Unnamed_label* start_label,
                                 Unnamed_label* finish_label) const
 {
-  source_location loc = this->location_;
+  Location loc = this->location_;
   Unnamed_label* next_case_label;
   if (this->cases_ == NULL || this->cases_->empty())
     {
@@ -3335,7 +3335,7 @@ Case_clauses::Case_clause::lower(Block* b, Temporary_statement* val_temp,
        }
 
       Block* then_block = new Block(b, loc);
-      next_case_label = new Unnamed_label(UNKNOWN_LOCATION);
+      next_case_label = new Unnamed_label(Linemap::unknown_location());
       Statement* s = Statement::make_goto_unnamed_statement(next_case_label,
                                                            loc);
       then_block->add_statement(s);
@@ -3693,7 +3693,7 @@ class Constant_switch_statement : public Statement
  public:
   Constant_switch_statement(Expression* val, Case_clauses* clauses,
                            Unnamed_label* break_label,
-                           source_location location)
+                           Location location)
     : Statement(STATEMENT_CONSTANT_SWITCH, location),
       val_(val), clauses_(clauses), break_label_(break_label)
   { }
@@ -3838,7 +3838,7 @@ Statement*
 Switch_statement::do_lower(Gogo*, Named_object*, Block* enclosing,
                           Statement_inserter*)
 {
-  source_location loc = this->location();
+  Location loc = this->location();
 
   if (this->val_ != NULL
       && (this->val_->is_error_expression()
@@ -3915,7 +3915,7 @@ Switch_statement::do_dump_statement(Ast_dump_context* ast_dump_context) const
 // Make a switch statement.
 
 Switch_statement*
-Statement::make_switch_statement(Expression* val, source_location location)
+Statement::make_switch_statement(Expression* val, Location location)
 {
   return new Switch_statement(val, location);
 }
@@ -3949,7 +3949,7 @@ Type_case_clauses::Type_case_clause::lower(Block* b,
                                           Unnamed_label* break_label,
                                           Unnamed_label** stmts_label) const
 {
-  source_location loc = this->location_;
+  Location loc = this->location_;
 
   Unnamed_label* next_case_label = NULL;
   if (!this->is_default_)
@@ -3979,7 +3979,7 @@ Type_case_clauses::Type_case_clause::lower(Block* b,
       if (!this->is_fallthrough_)
        {
          // if !COND { goto NEXT_CASE_LABEL }
-         next_case_label = new Unnamed_label(UNKNOWN_LOCATION);
+         next_case_label = new Unnamed_label(Linemap::unknown_location());
          dest = next_case_label;
          cond = Expression::make_unary(OPERATOR_NOT, cond, loc);
        }
@@ -3988,7 +3988,7 @@ Type_case_clauses::Type_case_clause::lower(Block* b,
          // if COND { goto STMTS_LABEL }
          go_assert(stmts_label != NULL);
          if (*stmts_label == NULL)
-           *stmts_label = new Unnamed_label(UNKNOWN_LOCATION);
+           *stmts_label = new Unnamed_label(Linemap::unknown_location());
          dest = *stmts_label;
        }
       Block* then_block = new Block(b, loc);
@@ -4022,7 +4022,7 @@ Type_case_clauses::Type_case_clause::lower(Block* b,
     go_assert(next_case_label == NULL);
   else
     {
-      source_location gloc = (this->statements_ == NULL
+      Location gloc = (this->statements_ == NULL
                              ? loc
                              : this->statements_->end_location());
       b->add_statement(Statement::make_goto_unnamed_statement(break_label,
@@ -4169,7 +4169,7 @@ Statement*
 Type_switch_statement::do_lower(Gogo*, Named_object*, Block* enclosing,
                                Statement_inserter*)
 {
-  const source_location loc = this->location();
+  const Location loc = this->location();
 
   if (this->clauses_ != NULL)
     this->clauses_->check_duplicates();
@@ -4268,7 +4268,7 @@ Type_switch_statement::do_dump_statement(Ast_dump_context* ast_dump_context)
 
 Type_switch_statement*
 Statement::make_type_switch_statement(Named_object* var, Expression* expr,
-                                     source_location location)
+                                     Location location)
 {
   return new Type_switch_statement(var, expr, location);
 }
@@ -4334,7 +4334,7 @@ Send_statement::do_check_types(Gogo*)
 Bstatement*
 Send_statement::do_get_backend(Translate_context* context)
 {
-  source_location loc = this->location();
+  Location loc = this->location();
 
   Channel_type* channel_type = this->channel_->type()->channel_type();
   Type* element_type = channel_type->element_type();
@@ -4450,7 +4450,7 @@ Send_statement::do_dump_statement(Ast_dump_context* ast_dump_context) const
 
 Send_statement*
 Statement::make_send_statement(Expression* channel, Expression* val,
-                              source_location location)
+                              Location location)
 {
   return new Send_statement(channel, val, location);
 }
@@ -4505,7 +4505,7 @@ Select_clauses::Select_clause::lower(Gogo* gogo, Named_object* function,
       return;
     }
 
-  source_location loc = this->location_;
+  Location loc = this->location_;
 
   // Evaluate the channel before the select statement.
   Temporary_statement* channel_temp = Statement::make_temporary(NULL,
@@ -4767,7 +4767,7 @@ Select_clauses::may_fall_through() const
 Bstatement*
 Select_clauses::get_backend(Translate_context* context,
                            Unnamed_label *break_label,
-                           source_location location)
+                           Location location)
 {
   size_t count = this->clauses_.size();
 
@@ -4941,7 +4941,7 @@ Select_clauses::get_backend(Translate_context* context,
 void
 Select_clauses::add_clause_backend(
     Translate_context* context,
-    source_location location,
+    Location location,
     int index,
     int case_value,
     Select_clause* clause,
@@ -4957,7 +4957,7 @@ Select_clauses::add_clause_backend(
 
   Bstatement* s = clause->get_statements_backend(context);
 
-  source_location gloc = (clause->statements() == NULL
+  Location gloc = (clause->statements() == NULL
                          ? clause->location()
                          : clause->statements()->end_location());
   Bstatement* g = bottom_label->get_goto(context, gloc);
@@ -5038,7 +5038,7 @@ Select_statement::do_dump_statement(Ast_dump_context* ast_dump_context) const
 // Make a select statement.
 
 Select_statement*
-Statement::make_select_statement(source_location location)
+Statement::make_select_statement(Location location)
 {
   return new Select_statement(location);
 }
@@ -5076,7 +5076,7 @@ For_statement::do_lower(Gogo*, Named_object*, Block* enclosing,
                        Statement_inserter*)
 {
   Statement* s;
-  source_location loc = this->location();
+  Location loc = this->location();
 
   Block* b = new Block(enclosing, this->location());
   if (this->init_ != NULL)
@@ -5100,7 +5100,7 @@ For_statement::do_lower(Gogo*, Named_object*, Block* enclosing,
                                      this->statements_->start_location());
   b->add_statement(s);
 
-  source_location end_loc = this->statements_->end_location();
+  Location end_loc = this->statements_->end_location();
 
   Unnamed_label* cont = this->continue_label_;
   if (cont != NULL)
@@ -5120,7 +5120,7 @@ For_statement::do_lower(Gogo*, Named_object*, Block* enclosing,
     {
       b->add_statement(Statement::make_unnamed_label_statement(entry));
 
-      source_location cond_loc = this->cond_->location();
+      Location cond_loc = this->cond_->location();
       Block* then_block = new Block(b, cond_loc);
       s = Statement::make_goto_unnamed_statement(top, cond_loc);
       then_block->add_statement(s);
@@ -5211,7 +5211,7 @@ For_statement::do_dump_statement(Ast_dump_context* ast_dump_context) const
 
 For_statement*
 Statement::make_for_statement(Block* init, Expression* cond, Block* post,
-                             source_location location)
+                             Location location)
 {
   return new For_statement(init, cond, post, location);
 }
@@ -5285,7 +5285,7 @@ For_range_statement::do_lower(Gogo* gogo, Named_object*, Block* enclosing,
       return Statement::make_error_statement(this->location());
     }
 
-  source_location loc = this->location();
+  Location loc = this->location();
   Block* temp_block = new Block(enclosing, loc);
 
   Named_object* range_object = NULL;
@@ -5388,7 +5388,7 @@ For_range_statement::do_lower(Gogo* gogo, Named_object*, Block* enclosing,
 Expression*
 For_range_statement::make_range_ref(Named_object* range_object,
                                    Temporary_statement* range_temp,
-                                   source_location loc)
+                                   Location loc)
 {
   if (range_object != NULL)
     return Expression::make_var_reference(range_object, loc);
@@ -5402,7 +5402,7 @@ For_range_statement::make_range_ref(Named_object* range_object,
 Expression*
 For_range_statement::call_builtin(Gogo* gogo, const char* funcname,
                                  Expression* arg,
-                                 source_location loc)
+                                 Location loc)
 {
   Named_object* no = gogo->lookup_global(funcname);
   go_assert(no != NULL && no->is_function_declaration());
@@ -5427,7 +5427,7 @@ For_range_statement::lower_range_array(Gogo* gogo,
                                       Block** piter_init,
                                       Block** ppost)
 {
-  source_location loc = this->location();
+  Location loc = this->location();
 
   // The loop we generate:
   //   len_temp := len(range)
@@ -5519,7 +5519,7 @@ For_range_statement::lower_range_string(Gogo*,
                                        Block** piter_init,
                                        Block** ppost)
 {
-  source_location loc = this->location();
+  Location loc = this->location();
 
   // The loop we generate:
   //   var next_index_temp int
@@ -5647,7 +5647,7 @@ For_range_statement::lower_range_map(Gogo*,
                                     Block** piter_init,
                                     Block** ppost)
 {
-  source_location loc = this->location();
+  Location loc = this->location();
 
   // The runtime uses a struct to handle ranges over a map.  The
   // struct is four pointers long.  The first pointer is NULL when we
@@ -5752,7 +5752,7 @@ For_range_statement::lower_range_channel(Gogo*,
 {
   go_assert(value_temp == NULL);
 
-  source_location loc = this->location();
+  Location loc = this->location();
 
   // The loop we generate:
   //   for {
@@ -5863,7 +5863,7 @@ For_range_statement*
 Statement::make_for_range_statement(Expression* index_var,
                                    Expression* value_var,
                                    Expression* range,
-                                   source_location location)
+                                   Location location)
 {
   return new For_range_statement(index_var, value_var, range, location);
 }
index 86b0f30..16914f1 100644 (file)
@@ -123,7 +123,7 @@ class Statement
     STATEMENT_TYPE_SWITCH
   };
 
-  Statement(Statement_classification, source_location);
+  Statement(Statement_classification, Location);
 
   virtual ~Statement();
 
@@ -139,30 +139,30 @@ class Statement
   // Either the type or the initialization expression may be NULL, but
   // not both.
   static Temporary_statement*
-  make_temporary(Type*, Expression*, source_location);
+  make_temporary(Type*, Expression*, Location);
 
   // Make an assignment statement.
   static Statement*
-  make_assignment(Expression*, Expression*, source_location);
+  make_assignment(Expression*, Expression*, Location);
 
   // Make an assignment operation (+=, etc.).
   static Statement*
   make_assignment_operation(Operator, Expression*, Expression*,
-                           source_location);
+                           Location);
 
   // Make a tuple assignment statement.
   static Statement*
-  make_tuple_assignment(Expression_list*, Expression_list*, source_location);
+  make_tuple_assignment(Expression_list*, Expression_list*, Location);
 
   // Make an assignment from a map index to a pair of variables.
   static Statement*
   make_tuple_map_assignment(Expression* val, Expression* present,
-                           Expression*, source_location);
+                           Expression*, Location);
 
   // Make a statement which assigns a pair of values to a map.
   static Statement*
   make_map_assignment(Expression*, Expression* val,
-                     Expression* should_set, source_location);
+                     Expression* should_set, Location);
 
   // Make an assignment from a nonblocking receive to a pair of
   // variables.  FOR_SELECT is true is this is being created for a
@@ -170,13 +170,13 @@ class Statement
   static Statement*
   make_tuple_receive_assignment(Expression* val, Expression* closed,
                                Expression* channel, bool for_select,
-                               source_location);
+                               Location);
 
   // Make an assignment from a type guard to a pair of variables.
   static Statement*
   make_tuple_type_guard_assignment(Expression* val, Expression* ok,
                                   Expression* expr, Type* type,
-                                  source_location);
+                                  Location);
 
   // Make an expression statement from an Expression.  IS_IGNORED is
   // true if the value is being explicitly ignored, as in an
@@ -187,7 +187,7 @@ class Statement
   // Make a block statement from a Block.  This is an embedded list of
   // statements which may also include variable definitions.
   static Statement*
-  make_block_statement(Block*, source_location);
+  make_block_statement(Block*, Location);
 
   // Make an increment statement.
   static Statement*
@@ -199,35 +199,35 @@ class Statement
 
   // Make a go statement.
   static Statement*
-  make_go_statement(Call_expression* call, source_location);
+  make_go_statement(Call_expression* call, Location);
 
   // Make a defer statement.
   static Statement*
-  make_defer_statement(Call_expression* call, source_location);
+  make_defer_statement(Call_expression* call, Location);
 
   // Make a return statement.
   static Return_statement*
-  make_return_statement(Expression_list*, source_location);
+  make_return_statement(Expression_list*, Location);
 
   // Make a break statement.
   static Statement*
-  make_break_statement(Unnamed_label* label, source_location);
+  make_break_statement(Unnamed_label* label, Location);
 
   // Make a continue statement.
   static Statement*
-  make_continue_statement(Unnamed_label* label, source_location);
+  make_continue_statement(Unnamed_label* label, Location);
 
   // Make a goto statement.
   static Statement*
-  make_goto_statement(Label* label, source_location);
+  make_goto_statement(Label* label, Location);
 
   // Make a goto statement to an unnamed label.
   static Statement*
-  make_goto_unnamed_statement(Unnamed_label* label, source_location);
+  make_goto_unnamed_statement(Unnamed_label* label, Location);
 
   // Make a label statement--where the label is defined.
   static Statement*
-  make_label_statement(Label* label, source_location);
+  make_label_statement(Label* label, Location);
 
   // Make an unnamed label statement--where the label is defined.
   static Statement*
@@ -236,33 +236,33 @@ class Statement
   // Make an if statement.
   static Statement*
   make_if_statement(Expression* cond, Block* then_block, Block* else_block,
-                   source_location);
+                   Location);
 
   // Make a switch statement.
   static Switch_statement*
-  make_switch_statement(Expression* switch_val, source_location);
+  make_switch_statement(Expression* switch_val, Location);
 
   // Make a type switch statement.
   static Type_switch_statement*
-  make_type_switch_statement(Named_object* var, Expression*, source_location);
+  make_type_switch_statement(Named_object* var, Expression*, Location);
 
   // Make a send statement.
   static Send_statement*
-  make_send_statement(Expression* channel, Expression* val, source_location);
+  make_send_statement(Expression* channel, Expression* val, Location);
 
   // Make a select statement.
   static Select_statement*
-  make_select_statement(source_location);
+  make_select_statement(Location);
 
   // Make a for statement.
   static For_statement*
   make_for_statement(Block* init, Expression* cond, Block* post,
-                    source_location location);
+                    Location location);
 
   // Make a for statement with a range clause.
   static For_range_statement*
   make_for_range_statement(Expression* index_var, Expression* value_var,
-                          Expression* range, source_location);
+                          Expression* range, Location);
 
   // Return the statement classification.
   Statement_classification
@@ -270,7 +270,7 @@ class Statement
   { return this->classification_; }
 
   // Get the statement location.
-  source_location
+  Location
   location() const
   { return this->location_; }
 
@@ -448,7 +448,7 @@ class Statement
 
   // For children to return an error statement from lower().
   static Statement*
-  make_error_statement(source_location);
+  make_error_statement(Location);
 
  private:
   // Convert to the desired statement classification, or return NULL.
@@ -474,7 +474,7 @@ class Statement
   // The statement classification.
   Statement_classification classification_;
   // The location in the input file of the start of this statement.
-  source_location location_;
+  Location location_;
 };
 
 // A statement which creates and initializes a temporary variable.
@@ -482,7 +482,7 @@ class Statement
 class Temporary_statement : public Statement
 {
  public:
-  Temporary_statement(Type* type, Expression* init, source_location location)
+  Temporary_statement(Type* type, Expression* init, Location location)
     : Statement(STATEMENT_TEMPORARY, location),
       type_(type), init_(init), bvariable_(NULL), are_hidden_fields_ok_(false),
       is_address_taken_(false)
@@ -579,7 +579,7 @@ class Variable_declaration_statement : public Statement
 class Return_statement : public Statement
 {
  public:
-  Return_statement(Expression_list* vals, source_location location)
+  Return_statement(Expression_list* vals, Location location)
     : Statement(STATEMENT_RETURN, location),
       vals_(vals), are_hidden_fields_ok_(false), is_lowered_(false)
   { }
@@ -632,7 +632,7 @@ class Send_statement : public Statement
 {
  public:
   Send_statement(Expression* channel, Expression* val,
-                source_location location)
+                Location location)
     : Statement(STATEMENT_SEND, location),
       channel_(channel), val_(val), for_select_(false)
   { }
@@ -691,7 +691,7 @@ class Select_clauses
   void
   add(bool is_send, Expression* channel, Expression* val, Expression* closed,
       Named_object* var, Named_object* closedvar, bool is_default,
-      Block* statements, source_location location)
+      Block* statements, Location location)
   {
     this->clauses_.push_back(Select_clause(is_send, channel, val, closed, var,
                                           closedvar, is_default, statements,
@@ -717,7 +717,7 @@ class Select_clauses
 
   // Convert to the backend representation.
   Bstatement*
-  get_backend(Translate_context*, Unnamed_label* break_label, source_location);
+  get_backend(Translate_context*, Unnamed_label* break_label, Location);
 
   // Dump AST representation.
   void
@@ -737,7 +737,7 @@ class Select_clauses
     Select_clause(bool is_send, Expression* channel, Expression* val,
                  Expression* closed, Named_object* var,
                  Named_object* closedvar, bool is_default, Block* statements,
-                 source_location location)
+                 Location location)
       : channel_(channel), val_(val), closed_(closed), var_(var),
        closedvar_(closedvar), statements_(statements), location_(location),
        is_send_(is_send), is_default_(is_default), is_lowered_(false)
@@ -780,7 +780,7 @@ class Select_clauses
     { return this->statements_; }
 
     // Return the location.
-    source_location
+    Location
     location() const
     { return this->location_; }
 
@@ -813,7 +813,7 @@ class Select_clauses
     // The statements to execute.
     Block* statements_;
     // The location of this clause.
-    source_location location_;
+    Location location_;
     // Whether this is a send or a receive.
     bool is_send_;
     // Whether this is the default.
@@ -823,7 +823,7 @@ class Select_clauses
   };
 
   void
-  add_clause_backend(Translate_context*, source_location, int index,
+  add_clause_backend(Translate_context*, Location, int index,
                     int case_value, Select_clause*, Unnamed_label*,
                     std::vector<std::vector<Bexpression*> >* cases,
                     std::vector<Bstatement*>* clauses);
@@ -838,7 +838,7 @@ class Select_clauses
 class Select_statement : public Statement
 {
  public:
-  Select_statement(source_location location)
+  Select_statement(Location location)
     : Statement(STATEMENT_SELECT, location),
       clauses_(NULL), break_label_(NULL), is_lowered_(false)
   { }
@@ -892,7 +892,7 @@ class Thunk_statement : public Statement
 {
  public:
   Thunk_statement(Statement_classification, Call_expression*,
-                 source_location);
+                 Location);
 
   // Return the call expression.
   Expression*
@@ -955,7 +955,7 @@ class Thunk_statement : public Statement
 class Go_statement : public Thunk_statement
 {
  public:
-  Go_statement(Call_expression* call, source_location location)
+  Go_statement(Call_expression* call, Location location)
     : Thunk_statement(STATEMENT_GO, call, location)
   { }
 
@@ -972,7 +972,7 @@ class Go_statement : public Thunk_statement
 class Defer_statement : public Thunk_statement
 {
  public:
-  Defer_statement(Call_expression* call, source_location location)
+  Defer_statement(Call_expression* call, Location location)
     : Thunk_statement(STATEMENT_DEFER, call, location)
   { }
 
@@ -989,7 +989,7 @@ class Defer_statement : public Thunk_statement
 class Label_statement : public Statement
 {
  public:
-  Label_statement(Label* label, source_location location)
+  Label_statement(Label* label, Location location)
     : Statement(STATEMENT_LABEL, location),
       label_(label)
   { }
@@ -1020,7 +1020,7 @@ class For_statement : public Statement
 {
  public:
   For_statement(Block* init, Expression* cond, Block* post,
-               source_location location)
+               Location location)
     : Statement(STATEMENT_FOR, location),
       init_(init), cond_(cond), post_(post), statements_(NULL),
       break_label_(NULL), continue_label_(NULL)
@@ -1086,7 +1086,7 @@ class For_range_statement : public Statement
 {
  public:
   For_range_statement(Expression* index_var, Expression* value_var,
-                     Expression* range, source_location location)
+                     Expression* range, Location location)
     : Statement(STATEMENT_FOR_RANGE, location),
       index_var_(index_var), value_var_(value_var), range_(range),
       statements_(NULL), break_label_(NULL), continue_label_(NULL)
@@ -1128,10 +1128,10 @@ class For_range_statement : public Statement
 
  private:
   Expression*
-  make_range_ref(Named_object*, Temporary_statement*, source_location);
+  make_range_ref(Named_object*, Temporary_statement*, Location);
 
   Expression*
-  call_builtin(Gogo*, const char* funcname, Expression* arg, source_location);
+  call_builtin(Gogo*, const char* funcname, Expression* arg, Location);
 
   void
   lower_range_array(Gogo*, Block*, Block*, Named_object*, Temporary_statement*,
@@ -1186,7 +1186,7 @@ class Case_clauses
   // next clause.
   void
   add(Expression_list* cases, bool is_default, Block* statements,
-      bool is_fallthrough, source_location location)
+      bool is_fallthrough, Location location)
   {
     this->clauses_.push_back(Case_clause(cases, is_default, statements,
                                         is_fallthrough, location));
@@ -1252,7 +1252,7 @@ class Case_clauses
     { }
 
     Case_clause(Expression_list* cases, bool is_default, Block* statements,
-               bool is_fallthrough, source_location location)
+               bool is_fallthrough, Location location)
       : cases_(cases), statements_(statements), is_default_(is_default),
        is_fallthrough_(is_fallthrough), location_(location)
     { }
@@ -1268,7 +1268,7 @@ class Case_clauses
     { return this->is_default_; }
 
     // The location of this clause.
-    source_location
+    Location
     location() const
     { return this->location_; }
 
@@ -1318,7 +1318,7 @@ class Case_clauses
     // Whether this falls through after the statements.
     bool is_fallthrough_;
     // The location of this case clause.
-    source_location location_;
+    Location location_;
   };
 
   friend class Case_clause;
@@ -1335,7 +1335,7 @@ class Case_clauses
 class Switch_statement : public Statement
 {
  public:
-  Switch_statement(Expression* val, source_location location)
+  Switch_statement(Expression* val, Location location)
     : Statement(STATEMENT_SWITCH, location),
       val_(val), clauses_(NULL), break_label_(NULL)
   { }
@@ -1392,7 +1392,7 @@ class Type_case_clauses
   // statements; it may be NULL.
   void
   add(Type* type, bool is_fallthrough, bool is_default, Block* statements,
-      source_location location)
+      Location location)
   {
     this->clauses_.push_back(Type_case_clause(type, is_fallthrough, is_default,
                                              statements, location));
@@ -1431,7 +1431,7 @@ class Type_case_clauses
     { }
 
     Type_case_clause(Type* type, bool is_fallthrough, bool is_default,
-                    Block* statements, source_location location)
+                    Block* statements, Location location)
       : type_(type), statements_(statements), is_fallthrough_(is_fallthrough),
        is_default_(is_default), location_(location)
     { }
@@ -1447,7 +1447,7 @@ class Type_case_clauses
     { return this->is_default_; }
 
     // The location of this type clause.
-    source_location
+    Location
     location() const
     { return this->location_; }
 
@@ -1474,7 +1474,7 @@ class Type_case_clauses
     // Whether this is the default case.
     bool is_default_;
     // The location of this type case clause.
-    source_location location_;
+    Location location_;
   };
 
   friend class Type_case_clause;
@@ -1492,7 +1492,7 @@ class Type_switch_statement : public Statement
 {
  public:
   Type_switch_statement(Named_object* var, Expression* expr,
-                       source_location location)
+                       Location location)
     : Statement(STATEMENT_TYPE_SWITCH, location),
       var_(var), expr_(expr), clauses_(NULL), break_label_(NULL)
   { go_assert(var == NULL || expr == NULL); }
index c596de9..74d9765 100644 (file)
@@ -853,7 +853,7 @@ Type::get_btype_without_hash(Gogo* gogo)
 // Return a pointer to the type descriptor for this type.
 
 tree
-Type::type_descriptor_pointer(Gogo* gogo, source_location location)
+Type::type_descriptor_pointer(Gogo* gogo, Location location)
 {
   Type* t = this->forwarded();
   if (t->type_descriptor_var_ == NULL)
@@ -864,7 +864,7 @@ Type::type_descriptor_pointer(Gogo* gogo, source_location location)
   tree var_tree = var_to_tree(t->type_descriptor_var_);
   if (var_tree == error_mark_node)
     return error_mark_node;
-  return build_fold_addr_expr_loc(location, var_tree);
+  return build_fold_addr_expr_loc(location.gcc_location(), var_tree);
 }
 
 // A mapping from unnamed types to type descriptor variables.
@@ -934,7 +934,7 @@ Type::make_type_descriptor_var(Gogo* gogo)
        }
     }
 
-  source_location loc = nt == NULL ? BUILTINS_LOCATION : nt->location();
+  Location loc = nt == NULL ? Linemap::predeclared_location() : nt->location();
 
   if (is_defined_elsewhere)
     {
@@ -1054,7 +1054,7 @@ Type::make_builtin_struct_type(int nfields, ...)
   va_list ap;
   va_start(ap, nfields);
 
-  source_location bloc = BUILTINS_LOCATION;
+  Location bloc = Linemap::predeclared_location();
   Struct_field_list* sfl = new Struct_field_list();
   for (int i = 0; i < nfields; i++)
     {
@@ -1077,7 +1077,7 @@ std::vector<Named_type*> Type::named_builtin_types;
 Named_type*
 Type::make_builtin_named_type(const char* name, Type* type)
 {
-  source_location bloc = BUILTINS_LOCATION;
+  Location bloc = Linemap::predeclared_location();
   Named_object* no = Named_object::make_type(name, NULL, type, bloc);
   Named_type* ret = no->type_value();
   Type::named_builtin_types.push_back(ret);
@@ -1110,7 +1110,7 @@ Type::make_type_descriptor_type()
   static Type* ret;
   if (ret == NULL)
     {
-      source_location bloc = BUILTINS_LOCATION;
+      Location bloc = Linemap::predeclared_location();
 
       Type* uint8_type = Type::lookup_integer_type("uint8");
       Type* uint32_type = Type::lookup_integer_type("uint32");
@@ -1286,7 +1286,7 @@ Type::type_descriptor_constructor(Gogo* gogo, int runtime_type_kind,
                                  Named_type* name, const Methods* methods,
                                  bool only_value_methods)
 {
-  source_location bloc = BUILTINS_LOCATION;
+  Location bloc = Linemap::predeclared_location();
 
   Type* td_type = Type::make_type_descriptor_type();
   const Struct_field_list* fields = td_type->struct_type()->fields();
@@ -1394,7 +1394,7 @@ Type::uncommon_type_constructor(Gogo* gogo, Type* uncommon_type,
                                Named_type* name, const Methods* methods,
                                bool only_value_methods) const
 {
-  source_location bloc = BUILTINS_LOCATION;
+  Location bloc = Linemap::predeclared_location();
 
   const Struct_field_list* fields = uncommon_type->struct_type()->fields();
 
@@ -1477,7 +1477,7 @@ Type::methods_constructor(Gogo* gogo, Type* methods_type,
                          const Methods* methods,
                          bool only_value_methods) const
 {
-  source_location bloc = BUILTINS_LOCATION;
+  Location bloc = Linemap::predeclared_location();
 
   std::vector<std::pair<std::string, const Method*> > smethods;
   if (methods != NULL)
@@ -1524,7 +1524,7 @@ Type::method_constructor(Gogo*, Type* method_type,
                         const Method* m,
                         bool only_value_methods) const
 {
-  source_location bloc = BUILTINS_LOCATION;
+  Location bloc = Linemap::predeclared_location();
 
   const Struct_field_list* fields = method_type->struct_type()->fields();
 
@@ -1688,7 +1688,7 @@ class Error_type : public Type
 
   Expression*
   do_type_descriptor(Gogo*, Named_type*)
-  { return Expression::make_error(BUILTINS_LOCATION); }
+  { return Expression::make_error(Linemap::predeclared_location()); }
 
   void
   do_reflection(Gogo*, std::string*) const
@@ -1807,9 +1807,9 @@ Named_type*
 Type::make_named_bool_type()
 {
   Type* bool_type = Type::make_boolean_type();
-  Named_object* named_object = Named_object::make_type("bool", NULL,
-                                                      bool_type,
-                                                      BUILTINS_LOCATION);
+  Named_object* named_object =
+    Named_object::make_type("bool", NULL, bool_type,
+                            Linemap::predeclared_location());
   Named_type* named_type = named_object->type_value();
   named_bool_type = named_type;
   return named_type;
@@ -1829,9 +1829,9 @@ Integer_type::create_integer_type(const char* name, bool is_unsigned,
   Integer_type* integer_type = new Integer_type(false, is_unsigned, bits,
                                                runtime_type_kind);
   std::string sname(name);
-  Named_object* named_object = Named_object::make_type(sname, NULL,
-                                                      integer_type,
-                                                      BUILTINS_LOCATION);
+  Named_object* named_object =
+    Named_object::make_type(sname, NULL, integer_type,
+                            Linemap::predeclared_location());
   Named_type* named_type = named_object->type_value();
   std::pair<Named_integer_types::iterator, bool> ins =
     Integer_type::named_integer_types.insert(std::make_pair(sname, named_type));
@@ -1965,8 +1965,9 @@ Float_type::create_float_type(const char* name, int bits,
 {
   Float_type* float_type = new Float_type(false, bits, runtime_type_kind);
   std::string sname(name);
-  Named_object* named_object = Named_object::make_type(sname, NULL, float_type,
-                                                      BUILTINS_LOCATION);
+  Named_object* named_object =
+    Named_object::make_type(sname, NULL, float_type,
+                            Linemap::predeclared_location());
   Named_type* named_type = named_object->type_value();
   std::pair<Named_float_types::iterator, bool> ins =
     Float_type::named_float_types.insert(std::make_pair(sname, named_type));
@@ -2089,9 +2090,9 @@ Complex_type::create_complex_type(const char* name, int bits,
   Complex_type* complex_type = new Complex_type(false, bits,
                                                runtime_type_kind);
   std::string sname(name);
-  Named_object* named_object = Named_object::make_type(sname, NULL,
-                                                      complex_type,
-                                                      BUILTINS_LOCATION);
+  Named_object* named_object =
+    Named_object::make_type(sname, NULL, complex_type,
+                            Linemap::predeclared_location());
   Named_type* named_type = named_object->type_value();
   std::pair<Named_complex_types::iterator, bool> ins =
     Complex_type::named_complex_types.insert(std::make_pair(sname,
@@ -2219,12 +2220,12 @@ String_type::do_get_backend(Gogo* gogo)
       Type* pb = Type::make_pointer_type(b);
       fields[0].name = "__data";
       fields[0].btype = pb->get_backend(gogo);
-      fields[0].location = UNKNOWN_LOCATION;
+      fields[0].location = Linemap::predeclared_location();
 
       Type* int_type = Type::lookup_integer_type("int");
       fields[1].name = "__length";
       fields[1].btype = int_type->get_backend(gogo);
-      fields[1].location = UNKNOWN_LOCATION;
+      fields[1].location = fields[0].location;
 
       backend_string_type = gogo->backend()->struct_type(fields);
     }
@@ -2317,9 +2318,9 @@ Named_type*
 Type::make_named_string_type()
 {
   Type* string_type = Type::make_string_type();
-  Named_object* named_object = Named_object::make_type("string", NULL,
-                                                      string_type,
-                                                      BUILTINS_LOCATION);
+  Named_object* named_object =
+    Named_object::make_type("string", NULL, string_type,
+                            Linemap::predeclared_location());
   Named_type* named_type = named_object->type_value();
   named_string_type = named_type;
   return named_type;
@@ -2742,7 +2743,7 @@ Function_type::make_function_type_descriptor_type()
 Expression*
 Function_type::do_type_descriptor(Gogo* gogo, Named_type* name)
 {
-  source_location bloc = BUILTINS_LOCATION;
+  Location bloc = Linemap::predeclared_location();
 
   Type* ftdt = Function_type::make_function_type_descriptor_type();
 
@@ -2785,7 +2786,7 @@ Function_type::type_descriptor_params(Type* params_type,
                                      const Typed_identifier* receiver,
                                      const Typed_identifier_list* params)
 {
-  source_location bloc = BUILTINS_LOCATION;
+  Location bloc = Linemap::predeclared_location();
 
   if (receiver == NULL && params == NULL)
     return Expression::make_slice_composite_literal(params_type, NULL, bloc);
@@ -3073,7 +3074,7 @@ Function_type*
 Type::make_function_type(Typed_identifier* receiver,
                         Typed_identifier_list* parameters,
                         Typed_identifier_list* results,
-                        source_location location)
+                        Location location)
 {
   return new Function_type(receiver, parameters, results, location);
 }
@@ -3140,7 +3141,7 @@ Pointer_type::do_type_descriptor(Gogo* gogo, Named_type* name)
     }
   else
     {
-      source_location bloc = BUILTINS_LOCATION;
+      Location bloc = Linemap::predeclared_location();
 
       const Methods* methods;
       Type* deref = this->points_to();
@@ -3302,7 +3303,7 @@ class Call_multiple_result_type : public Type
   do_type_descriptor(Gogo*, Named_type*)
   {
     go_assert(saw_errors());
-    return Expression::make_error(UNKNOWN_LOCATION);
+    return Expression::make_error(Linemap::unknown_location());
   }
 
   void
@@ -3609,7 +3610,7 @@ Struct_type::find_local_field(const std::string& name,
 
 Field_reference_expression*
 Struct_type::field_reference(Expression* struct_expr, const std::string& name,
-                            source_location location) const
+                            Location location) const
 {
   unsigned int depth;
   return this->field_reference_depth(struct_expr, name, location, NULL,
@@ -3622,7 +3623,7 @@ Struct_type::field_reference(Expression* struct_expr, const std::string& name,
 Field_reference_expression*
 Struct_type::field_reference_depth(Expression* struct_expr,
                                   const std::string& name,
-                                  source_location location,
+                                  Location location,
                                   Saw_named_type* saw,
                                   unsigned int* depth) const
 {
@@ -3867,7 +3868,7 @@ Struct_type::make_struct_type_descriptor_type()
 Expression*
 Struct_type::do_type_descriptor(Gogo* gogo, Named_type* name)
 {
-  source_location bloc = BUILTINS_LOCATION;
+  Location bloc = Linemap::predeclared_location();
 
   Type* stdt = Struct_type::make_struct_type_descriptor_type();
 
@@ -4081,8 +4082,8 @@ Struct_type::do_export(Export* exp) const
       if (p->has_tag())
        {
          exp->write_c_string(" ");
-         Expression* expr = Expression::make_string(p->tag(),
-                                                    BUILTINS_LOCATION);
+         Expression* expr =
+            Expression::make_string(p->tag(), Linemap::predeclared_location());
          expr->export_expression(exp);
          delete expr;
        }
@@ -4140,7 +4141,7 @@ Struct_type::do_import(Import* imp)
 
 Struct_type*
 Type::make_struct_type(Struct_field_list* fields,
-                      source_location location)
+                      Location location)
 {
   return new Struct_type(fields, location);
 }
@@ -4356,23 +4357,24 @@ get_backend_slice_fields(Gogo* gogo, Array_type* type,
 
   Type* pet = Type::make_pointer_type(type->element_type());
   Btype* pbet = pet->get_backend(gogo);
+  Location ploc = Linemap::predeclared_location();
 
   Backend::Btyped_identifier* p = &(*bfields)[0];
   p->name = "__values";
   p->btype = pbet;
-  p->location = UNKNOWN_LOCATION;
+  p->location = ploc;
 
   Type* int_type = Type::lookup_integer_type("int");
 
   p = &(*bfields)[1];
   p->name = "__count";
   p->btype = int_type->get_backend(gogo);
-  p->location = UNKNOWN_LOCATION;
+  p->location = ploc;
 
   p = &(*bfields)[2];
   p->name = "__capacity";
   p->btype = int_type->get_backend(gogo);
-  p->location = UNKNOWN_LOCATION;
+  p->location = ploc;
 }
 
 // Get a tree for the type of this array.  A fixed array is simply
@@ -4579,7 +4581,7 @@ Array_type::do_type_descriptor(Gogo* gogo, Named_type* name)
 Expression*
 Array_type::array_type_descriptor(Gogo* gogo, Named_type* name)
 {
-  source_location bloc = BUILTINS_LOCATION;
+  Location bloc = Linemap::predeclared_location();
 
   Type* atdt = Array_type::make_array_type_descriptor_type();
 
@@ -4618,7 +4620,7 @@ Array_type::array_type_descriptor(Gogo* gogo, Named_type* name)
 Expression*
 Array_type::slice_type_descriptor(Gogo* gogo, Named_type* name)
 {
-  source_location bloc = BUILTINS_LOCATION;
+  Location bloc = Linemap::predeclared_location();
 
   Type* stdt = Array_type::make_slice_type_descriptor_type();
 
@@ -4772,29 +4774,31 @@ Map_type::do_get_backend(Gogo* gogo)
     {
       std::vector<Backend::Btyped_identifier> bfields(4);
 
+      Location bloc = Linemap::predeclared_location();
+
       Type* pdt = Type::make_type_descriptor_ptr_type();
       bfields[0].name = "__descriptor";
       bfields[0].btype = pdt->get_backend(gogo);
-      bfields[0].location = BUILTINS_LOCATION;
+      bfields[0].location = bloc;
 
       Type* uintptr_type = Type::lookup_integer_type("uintptr");
       bfields[1].name = "__element_count";
       bfields[1].btype = uintptr_type->get_backend(gogo);
-      bfields[1].location = BUILTINS_LOCATION;
+      bfields[1].location = bloc;
 
       bfields[2].name = "__bucket_count";
       bfields[2].btype = bfields[1].btype;
-      bfields[2].location = BUILTINS_LOCATION;
+      bfields[2].location = bloc;
 
       Btype* bvt = gogo->backend()->void_type();
       Btype* bpvt = gogo->backend()->pointer_type(bvt);
       Btype* bppvt = gogo->backend()->pointer_type(bpvt);
       bfields[3].name = "__buckets";
       bfields[3].btype = bppvt;
-      bfields[3].location = BUILTINS_LOCATION;
+      bfields[3].location = bloc;
 
       Btype *bt = gogo->backend()->struct_type(bfields);
-      bt = gogo->backend()->named_type("__go_map", bt, BUILTINS_LOCATION);
+      bt = gogo->backend()->named_type("__go_map", bt, bloc);
       backend_map_type = gogo->backend()->pointer_type(bt);
     }
   return backend_map_type;
@@ -4828,7 +4832,7 @@ Map_type::make_map_type_descriptor_type()
 Expression*
 Map_type::do_type_descriptor(Gogo* gogo, Named_type* name)
 {
-  source_location bloc = BUILTINS_LOCATION;
+  Location bloc = Linemap::predeclared_location();
 
   Type* mtdt = Map_type::make_map_type_descriptor_type();
 
@@ -4864,13 +4868,13 @@ Map_type::Map_descriptors Map_type::map_descriptors;
 // Build a map descriptor for this type.  Return a pointer to it.
 
 tree
-Map_type::map_descriptor_pointer(Gogo* gogo, source_location location)
+Map_type::map_descriptor_pointer(Gogo* gogo, Location location)
 {
   Bvariable* bvar = this->map_descriptor(gogo);
   tree var_tree = var_to_tree(bvar);
   if (var_tree == error_mark_node)
     return error_mark_node;
-  return build_fold_addr_expr_loc(location, var_tree);
+  return build_fold_addr_expr_loc(location.gcc_location(), var_tree);
 }
 
 // Build a map descriptor for this type.
@@ -4907,7 +4911,7 @@ Map_type::map_descriptor(Gogo* gogo)
   Expression_list* vals = new Expression_list();
   vals->reserve(4);
 
-  source_location bloc = BUILTINS_LOCATION;
+  Location bloc = Linemap::predeclared_location();
 
   Struct_field_list::const_iterator p = fields->begin();
 
@@ -5028,7 +5032,7 @@ Map_type::do_import(Import* imp)
 // Make a map type.
 
 Map_type*
-Type::make_map_type(Type* key_type, Type* val_type, source_location location)
+Type::make_map_type(Type* key_type, Type* val_type, Location location)
 {
   return new Map_type(key_type, val_type, location);
 }
@@ -5075,7 +5079,8 @@ Channel_type::do_get_backend(Gogo* gogo)
     {
       std::vector<Backend::Btyped_identifier> bfields;
       Btype* bt = gogo->backend()->struct_type(bfields);
-      bt = gogo->backend()->named_type("__go_channel", bt, BUILTINS_LOCATION);
+      bt = gogo->backend()->named_type("__go_channel", bt,
+                                       Linemap::predeclared_location());
       backend_channel_type = gogo->backend()->pointer_type(bt);
     }
   return backend_channel_type;
@@ -5111,7 +5116,7 @@ Channel_type::make_chan_type_descriptor_type()
 Expression*
 Channel_type::do_type_descriptor(Gogo* gogo, Named_type* name)
 {
-  source_location bloc = BUILTINS_LOCATION;
+  Location bloc = Linemap::predeclared_location();
 
   Type* ctdt = Channel_type::make_chan_type_descriptor_type();
 
@@ -5670,15 +5675,17 @@ Interface_type::get_backend_empty_interface_type(Gogo* gogo)
     {
       std::vector<Backend::Btyped_identifier> bfields(2);
 
+      Location bloc = Linemap::predeclared_location();
+
       Type* pdt = Type::make_type_descriptor_ptr_type();
       bfields[0].name = "__type_descriptor";
       bfields[0].btype = pdt->get_backend(gogo);
-      bfields[0].location = UNKNOWN_LOCATION;
+      bfields[0].location = bloc;
 
       Type* vt = Type::make_pointer_type(Type::make_void_type());
       bfields[1].name = "__object";
       bfields[1].btype = vt->get_backend(gogo);
-      bfields[1].location = UNKNOWN_LOCATION;
+      bfields[1].location = bloc;
 
       empty_interface_type = gogo->backend()->struct_type(bfields);
     }
@@ -5693,7 +5700,7 @@ static void
 get_backend_interface_fields(Gogo* gogo, Interface_type* type,
                             std::vector<Backend::Btyped_identifier>* bfields)
 {
-  source_location loc = type->location();
+  Location loc = type->location();
 
   std::vector<Backend::Btyped_identifier> mfields(type->methods()->size() + 1);
 
@@ -5727,7 +5734,7 @@ get_backend_interface_fields(Gogo* gogo, Interface_type* type,
   Type* vt = Type::make_pointer_type(Type::make_void_type());
   (*bfields)[1].name = "__object";
   (*bfields)[1].btype = vt->get_backend(gogo);
-  (*bfields)[1].location = UNKNOWN_LOCATION;
+  (*bfields)[1].location = Linemap::predeclared_location();
 }
 
 // Return a tree for an interface type.  An interface is a pointer to
@@ -5789,7 +5796,7 @@ Interface_type::make_interface_type_descriptor_type()
 Expression*
 Interface_type::do_type_descriptor(Gogo* gogo, Named_type* name)
 {
-  source_location bloc = BUILTINS_LOCATION;
+  Location bloc = Linemap::predeclared_location();
 
   Type* itdt = Interface_type::make_interface_type_descriptor_type();
 
@@ -5800,9 +5807,9 @@ Interface_type::do_type_descriptor(Gogo* gogo, Named_type* name)
 
   Struct_field_list::const_iterator pif = ifields->begin();
   go_assert(pif->is_field_name("commonType"));
-  ivals->push_back(this->type_descriptor_constructor(gogo,
-                                                    RUNTIME_TYPE_KIND_INTERFACE,
-                                                    name, NULL, true));
+  const int rt = RUNTIME_TYPE_KIND_INTERFACE;
+  ivals->push_back(this->type_descriptor_constructor(gogo, rt, name, NULL,
+                                                    true));
 
   ++pif;
   go_assert(pif->is_field_name("methods"));
@@ -6095,7 +6102,7 @@ Interface_type::do_import(Import* imp)
 
 Interface_type*
 Type::make_interface_type(Typed_identifier_list* methods,
-                         source_location location)
+                         Location location)
 {
   return new Interface_type(methods, location);
 }
@@ -6105,7 +6112,7 @@ Type::make_interface_type(Typed_identifier_list* methods,
 // Bind a method to an object.
 
 Expression*
-Method::bind_method(Expression* expr, source_location location) const
+Method::bind_method(Expression* expr, Location location) const
 {
   if (this->stub_ == NULL)
     {
@@ -6144,7 +6151,7 @@ Named_method::do_type() const
 
 // Return the location of the method receiver.
 
-source_location
+Location
 Named_method::do_receiver_location() const
 {
   return this->do_type()->receiver()->location();
@@ -6153,7 +6160,7 @@ Named_method::do_receiver_location() const
 // Bind a method to an object.
 
 Expression*
-Named_method::do_bind_method(Expression* expr, source_location location) const
+Named_method::do_bind_method(Expression* expr, Location location) const
 {
   Named_object* no = this->named_object_;
   Bound_method_expression* bme = Expression::make_bound_method(expr, no,
@@ -6177,7 +6184,7 @@ Named_method::do_bind_method(Expression* expr, source_location location) const
 
 Expression*
 Interface_method::do_bind_method(Expression* expr,
-                                source_location location) const
+                                Location location) const
 {
   return Expression::make_interface_field_reference(expr, this->name_,
                                                    location);
@@ -6299,7 +6306,7 @@ Named_type::add_method(const std::string& name, Function* function)
 Named_object*
 Named_type::add_method_declaration(const std::string& name, Package* package,
                                   Function_type* type,
-                                  source_location location)
+                                  Location location)
 {
   if (this->local_methods_ == NULL)
     this->local_methods_ = new Bindings(NULL);
@@ -6967,7 +6974,7 @@ Named_type::do_type_descriptor(Gogo* gogo, Named_type* name)
 void
 Named_type::do_reflection(Gogo* gogo, std::string* ret) const
 {
-  if (this->location() != BUILTINS_LOCATION)
+  if (!Linemap::is_predeclared_location(this->location()))
     {
       const Package* package = this->named_object_->package();
       if (package != NULL)
@@ -6991,7 +6998,7 @@ Named_type::do_mangled_name(Gogo* gogo, std::string* ret) const
 {
   Named_object* no = this->named_object_;
   std::string name;
-  if (this->location() == BUILTINS_LOCATION)
+  if (Linemap::is_predeclared_location(this->location()))
     go_assert(this->in_function_ == NULL);
   else
     {
@@ -7081,7 +7088,7 @@ Named_type::do_export(Export* exp) const
 
 Named_type*
 Type::make_named_type(Named_object* named_object, Type* type,
-                     source_location location)
+                     Location location)
 {
   return new Named_type(named_object, type, location);
 }
@@ -7091,7 +7098,7 @@ Type::make_named_type(Named_object* named_object, Type* type,
 // all required stubs.
 
 void
-Type::finalize_methods(Gogo* gogo, const Type* type, source_location location,
+Type::finalize_methods(Gogo* gogo, const Type* type, Location location,
                       Methods** all_methods)
 {
   *all_methods = NULL;
@@ -7291,7 +7298,7 @@ Type::add_interface_methods_for_type(const Type* type,
 
 void
 Type::build_stub_methods(Gogo* gogo, const Type* type, const Methods* methods,
-                        source_location location)
+                        Location location)
 {
   if (methods == NULL)
     return;
@@ -7317,7 +7324,7 @@ Type::build_stub_methods(Gogo* gogo, const Type* type, const Methods* methods,
       Type* receiver_type = const_cast<Type*>(type);
       if (!m->is_value_method())
        receiver_type = Type::make_pointer_type(receiver_type);
-      source_location receiver_location = m->receiver_location();
+      Location receiver_location = m->receiver_location();
       Typed_identifier* receiver = new Typed_identifier(buf, receiver_type,
                                                        receiver_location);
 
@@ -7397,7 +7404,7 @@ Type::build_one_stub_method(Gogo* gogo, Method* method,
                            const char* receiver_name,
                            const Typed_identifier_list* params,
                            bool is_varargs,
-                           source_location location)
+                           Location location)
 {
   Named_object* receiver_object = gogo->lookup(receiver_name, NULL);
   go_assert(receiver_object != NULL);
@@ -7460,7 +7467,7 @@ Type::build_one_stub_method(Gogo* gogo, Method* method,
 Expression*
 Type::apply_field_indexes(Expression* expr,
                          const Method::Field_indexes* field_indexes,
-                         source_location location)
+                         Location location)
 {
   if (field_indexes == NULL)
     return expr;
@@ -7526,7 +7533,7 @@ Type::method_function(const Methods* methods, const std::string& name,
 Expression*
 Type::bind_field_or_method(Gogo* gogo, const Type* type, Expression* expr,
                           const std::string& name,
-                          source_location location)
+                          Location location)
 {
   if (type->deref()->is_error_type())
     return Expression::make_error(location);
@@ -8040,7 +8047,7 @@ Forward_declaration_type::add_method(const std::string& name,
 Named_object*
 Forward_declaration_type::add_method_declaration(const std::string& name,
                                                 Function_type* type,
-                                                source_location location)
+                                                Location location)
 {
   Named_object* no = this->named_object();
   if (no->is_unknown())
@@ -8085,15 +8092,16 @@ Forward_declaration_type::do_get_backend(Gogo* gogo)
 Expression*
 Forward_declaration_type::do_type_descriptor(Gogo* gogo, Named_type* name)
 {
+  Location ploc = Linemap::predeclared_location();
   if (!this->is_defined())
-    return Expression::make_nil(BUILTINS_LOCATION);
+    return Expression::make_nil(ploc);
   else
     {
       Type* t = this->real_type();
       if (name != NULL)
        return this->named_type_descriptor(gogo, t, name);
       else
-       return Expression::make_type_descriptor(t, BUILTINS_LOCATION);
+       return Expression::make_type_descriptor(t, ploc);
     }
 }
 
index 2ec828f..035444f 100644 (file)
@@ -7,6 +7,8 @@
 #ifndef GO_TYPES_H
 #define GO_TYPES_H
 
+#include "go-linemap.h"
+
 class Gogo;
 class Package;
 class Traverse;
@@ -147,14 +149,14 @@ class Method
   { return this->do_type(); }
 
   // Return the location of the method receiver.
-  source_location
+  Location
   receiver_location() const
   { return this->do_receiver_location(); }
 
   // Return an expression which binds this method to EXPR.  This is
   // something which can be used with a function call.
   Expression*
-  bind_method(Expression* expr, source_location location) const;
+  bind_method(Expression* expr, Location location) const;
 
   // Return the named object for this method.  This may only be called
   // after methods are finalized.
@@ -195,12 +197,12 @@ class Method
   do_type() const = 0;
 
   // Return the location of the method receiver.
-  virtual source_location
+  virtual Location
   do_receiver_location() const = 0;
 
   // Bind a method to an object.
   virtual Expression*
-  do_bind_method(Expression* expr, source_location location) const = 0;
+  do_bind_method(Expression* expr, Location location) const = 0;
 
  private:
   // The sequence of field indexes used for this method.  If this is
@@ -245,12 +247,12 @@ class Named_method : public Method
   do_type() const;
 
   // Return the location of the method receiver.
-  source_location
+  Location
   do_receiver_location() const;
 
   // Bind a method to an object.
   Expression*
-  do_bind_method(Expression* expr, source_location location) const;
+  do_bind_method(Expression* expr, Location location) const;
 
  private:
   // The method itself.  For a method which needs a stub, this starts
@@ -265,7 +267,7 @@ class Named_method : public Method
 class Interface_method : public Method
 {
  public:
-  Interface_method(const std::string& name, source_location location,
+  Interface_method(const std::string& name, Location location,
                   Function_type* fntype, const Field_indexes* field_indexes,
                   unsigned int depth)
     : Method(field_indexes, depth, true, true),
@@ -285,19 +287,19 @@ class Interface_method : public Method
   { return this->fntype_; }
 
   // Return the location of the method receiver.
-  source_location
+  Location
   do_receiver_location() const
   { return this->location_; }
 
   // Bind a method to an object.
   Expression*
-  do_bind_method(Expression* expr, source_location location) const;
+  do_bind_method(Expression* expr, Location location) const;
 
  private:
   // The name of the interface method to call.
   std::string name_;
   // The location of the definition of the interface method.
-  source_location location_;
+  Location location_;
   // The type of the interface method.
   Function_type* fntype_;
 };
@@ -457,7 +459,7 @@ class Type
   make_function_type(Typed_identifier* receiver,
                     Typed_identifier_list* parameters,
                     Typed_identifier_list* results,
-                    source_location);
+                    Location);
 
   static Pointer_type*
   make_pointer_type(Type*);
@@ -469,19 +471,19 @@ class Type
   make_call_multiple_result_type(Call_expression*);
 
   static Struct_type*
-  make_struct_type(Struct_field_list* fields, source_location);
+  make_struct_type(Struct_field_list* fields, Location);
 
   static Array_type*
   make_array_type(Type* element_type, Expression* length);
 
   static Map_type*
-  make_map_type(Type* key_type, Type* value_type, source_location);
+  make_map_type(Type* key_type, Type* value_type, Location);
 
   static Channel_type*
   make_channel_type(bool send, bool receive, Type*);
 
   static Interface_type*
-  make_interface_type(Typed_identifier_list* methods, source_location);
+  make_interface_type(Typed_identifier_list* methods, Location);
 
   static Type*
   make_type_descriptor_type();
@@ -490,7 +492,7 @@ class Type
   make_type_descriptor_ptr_type();
 
   static Named_type*
-  make_named_type(Named_object*, Type*, source_location);
+  make_named_type(Named_object*, Type*, Location);
 
   static Type*
   make_forward_declaration(Named_object*);
@@ -806,7 +808,7 @@ class Type
   // it, bound to EXPR.
   static Expression*
   bind_field_or_method(Gogo*, const Type* type, Expression* expr,
-                      const std::string& name, source_location);
+                      const std::string& name, Location);
 
   // Return true if NAME is an unexported field or method of TYPE.
   static bool
@@ -825,7 +827,7 @@ class Type
   // it.  The location is the location which causes us to need the
   // entry.
   tree
-  type_descriptor_pointer(Gogo* gogo, source_location);
+  type_descriptor_pointer(Gogo* gogo, Location);
 
   // Return the type reflection string for this type.
   std::string
@@ -889,7 +891,7 @@ class Type
 
   // Finalize the methods for a type.
   static void
-  finalize_methods(Gogo*, const Type*, source_location, Methods**);
+  finalize_methods(Gogo*, const Type*, Location, Methods**);
 
   // Return a method from a set of methods.
   static Method*
@@ -1061,16 +1063,16 @@ class Type
   // Build stub methods for a type.
   static void
   build_stub_methods(Gogo*, const Type* type, const Methods* methods,
-                    source_location);
+                    Location);
 
   static void
   build_one_stub_method(Gogo*, Method*, const char* receiver_name,
                        const Typed_identifier_list*, bool is_varargs,
-                       source_location);
+                       Location);
 
   static Expression*
   apply_field_indexes(Expression*, const Method::Field_indexes*,
-                     source_location);
+                     Location);
 
   // Look for a field or method named NAME in TYPE.
   static bool
@@ -1129,7 +1131,7 @@ class Typed_identifier
 {
  public:
   Typed_identifier(const std::string& name, Type* type,
-                  source_location location)
+                  Location location)
     : name_(name), type_(type), location_(location)
   { }
 
@@ -1145,7 +1147,7 @@ class Typed_identifier
 
   // Return the location where the name was seen.  This is not always
   // meaningful.
-  source_location
+  Location
   location() const
   { return this->location_; }
 
@@ -1163,7 +1165,7 @@ class Typed_identifier
   // Type.
   Type* type_;
   // The location where the name was seen.
-  source_location location_;
+  Location location_;
 };
 
 // A list of Typed_identifiers.
@@ -1240,7 +1242,8 @@ class Typed_identifier_list
   resize(size_t c)
   {
     go_assert(c <= this->entries_.size());
-    this->entries_.resize(c, Typed_identifier("", NULL, UNKNOWN_LOCATION));
+    this->entries_.resize(c, Typed_identifier("", NULL,
+                                              Linemap::unknown_location()));
   }
 
   // Iterators.
@@ -1524,7 +1527,7 @@ class Function_type : public Type
 {
  public:
   Function_type(Typed_identifier* receiver, Typed_identifier_list* parameters,
-               Typed_identifier_list* results, source_location location)
+               Typed_identifier_list* results, Location location)
     : Type(TYPE_FUNCTION),
       receiver_(receiver), parameters_(parameters), results_(results),
       location_(location), is_varargs_(false), is_builtin_(false)
@@ -1556,7 +1559,7 @@ class Function_type : public Type
   { return this->is_builtin_; }
 
   // The location where this type was defined.
-  source_location
+  Location
   location() const
   { return this->location_; }
 
@@ -1659,7 +1662,7 @@ class Function_type : public Type
   // The location where this type was defined.  This exists solely to
   // give a location for the fields of the struct if this function
   // returns multiple values.
-  source_location location_;
+  Location location_;
   // Whether this function takes a variable number of arguments.
   bool is_varargs_;
   // Whether this is a special builtin function which can not simply
@@ -1742,7 +1745,7 @@ class Struct_field
   { return this->typed_identifier_.type(); }
 
   // The field location.
-  source_location
+  Location
   location() const
   { return this->typed_identifier_.location(); }
 
@@ -1845,7 +1848,7 @@ class Struct_field_list
 class Struct_type : public Type
 {
  public:
-  Struct_type(Struct_field_list* fields, source_location location)
+  Struct_type(Struct_field_list* fields, Location location)
     : Type(TYPE_STRUCT),
       fields_(fields), location_(location), all_methods_(NULL)
   { }
@@ -1882,7 +1885,7 @@ class Struct_type : public Type
   // NULL if there is no field with that name.
   Field_reference_expression*
   field_reference(Expression* struct_expr, const std::string& name,
-                 source_location) const;
+                 Location) const;
 
   // Return the total number of fields, including embedded fields.
   // This is the number of values which can appear in a conversion to
@@ -1979,13 +1982,13 @@ class Struct_type : public Type
 
   Field_reference_expression*
   field_reference_depth(Expression* struct_expr, const std::string& name,
-                       source_location, Saw_named_type*,
+                       Location, Saw_named_type*,
                        unsigned int* depth) const;
 
   // The fields of the struct.
   Struct_field_list* fields_;
   // The place where the struct was declared.
-  source_location location_;
+  Location location_;
   // If this struct is unnamed, a list of methods.
   Methods* all_methods_;
 };
@@ -2106,7 +2109,7 @@ class Array_type : public Type
 class Map_type : public Type
 {
  public:
-  Map_type(Type* key_type, Type* val_type, source_location location)
+  Map_type(Type* key_type, Type* val_type, Location location)
     : Type(TYPE_MAP),
       key_type_(key_type), val_type_(val_type), location_(location)
   { }
@@ -2139,7 +2142,7 @@ class Map_type : public Type
   // The location is the location which causes us to need the
   // descriptor.
   tree
-  map_descriptor_pointer(Gogo* gogo, source_location);
+  map_descriptor_pointer(Gogo* gogo, Location);
 
  protected:
   int
@@ -2184,7 +2187,7 @@ class Map_type : public Type
   // The value type.
   Type* val_type_;
   // Where the type was defined.
-  source_location location_;
+  Location location_;
 };
 
 // The type of a channel.
@@ -2267,13 +2270,13 @@ class Channel_type : public Type
 class Interface_type : public Type
 {
  public:
-  Interface_type(Typed_identifier_list* methods, source_location location)
+  Interface_type(Typed_identifier_list* methods, Location location)
     : Type(TYPE_INTERFACE),
       methods_(methods), location_(location)
   { go_assert(methods == NULL || !methods->empty()); }
 
   // The location where the interface type was defined.
-  source_location
+  Location
   location() const
   { return this->location_; }
 
@@ -2368,7 +2371,7 @@ class Interface_type : public Type
   // NULL for the empty interface.
   Typed_identifier_list* methods_;
   // The location where the interface was defined.
-  source_location location_;
+  Location location_;
 };
 
 // The value we keep for a named type.  This lets us get the right
@@ -2380,7 +2383,7 @@ class Interface_type : public Type
 class Named_type : public Type
 {
  public:
-  Named_type(Named_object* named_object, Type* type, source_location location)
+  Named_type(Named_object* named_object, Type* type, Location location)
     : Type(TYPE_NAMED),
       named_object_(named_object), in_function_(NULL), type_(type),
       local_methods_(NULL), all_methods_(NULL),
@@ -2436,7 +2439,7 @@ class Named_type : public Type
   { return this->type_; }
 
   // Return the location.
-  source_location
+  Location
   location() const
   { return this->location_; }
 
@@ -2458,7 +2461,7 @@ class Named_type : public Type
   // Whether this is a builtin type.
   bool
   is_builtin() const
-  { return this->location_ == BUILTINS_LOCATION; }
+  { return Linemap::is_predeclared_location(this->location_); }
 
   // Whether this is a circular type: a pointer or function type that
   // refers to itself, which is not possible in C.
@@ -2484,7 +2487,7 @@ class Named_type : public Type
   // Add a method declaration to this type.
   Named_object*
   add_method_declaration(const std::string& name, Package* package,
-                        Function_type* type, source_location location);
+                        Function_type* type, Location location);
 
   // Add an existing method--one defined before the type itself was
   // defined--to a type.
@@ -2617,7 +2620,7 @@ class Named_type : public Type
   // tables for pointers to this type.
   Interface_method_tables* pointer_interface_method_tables_;
   // The location where this type was defined.
-  source_location location_;
+  Location location_;
   // The backend representation of this type during backend
   // conversion.  This is used to avoid endless recursion when a named
   // type refers to itself.
@@ -2691,7 +2694,7 @@ class Forward_declaration_type : public Type
   // Add a method declaration to this type.
   Named_object*
   add_method_declaration(const std::string& name, Function_type*,
-                        source_location);
+                        Location);
 
  protected:
   int
index 434932b..eb9462e 100644 (file)
@@ -15,9 +15,9 @@
 
 void
 Gogo::import_unsafe(const std::string& local_name, bool is_local_name_exported,
-                   source_location location)
+                   Location location)
 {
-  location_t bloc = BUILTINS_LOCATION;
+  Location bloc = Linemap::predeclared_location();
 
   bool add_to_globals;
   Package* package = this->add_imported_package("unsafe", local_name,
@@ -41,7 +41,8 @@ Gogo::import_unsafe(const std::string& local_name, bool is_local_name_exported,
   if (no == NULL)
     {
       Type* type = Type::make_pointer_type(Type::make_void_type());
-      no = bindings->add_type("Pointer", package, type, UNKNOWN_LOCATION);
+      no = bindings->add_type("Pointer", package, type,
+                             Linemap::unknown_location());
     }
   else
     {