Commit 8afa2bfb by Sanjoy Das Committed by Ian Lance Taylor

compiler: Define and use backend-independent Location class.

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
parent 09ad58e6
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> 2011-11-02 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
* Make-lang.in (gospec.o): Pass SHLIB instead of SHLIB_LINK. * Make-lang.in (gospec.o): Pass SHLIB instead of SHLIB_LINK.
......
...@@ -54,6 +54,7 @@ GO_OBJS = \ ...@@ -54,6 +54,7 @@ GO_OBJS = \
go/go-dump.o \ go/go-dump.o \
go/go-gcc.o \ go/go-gcc.o \
go/go-lang.o \ go/go-lang.o \
go/go-linemap.o \
go/go-optimize.o \ go/go-optimize.o \
go/go.o \ go/go.o \
go/gogo-tree.o \ go/gogo-tree.o \
...@@ -217,14 +218,15 @@ GO_SYSTEM_H = go/go-system.h $(CONFIG_H) $(SYSTEM_H) coretypes.h \ ...@@ -217,14 +218,15 @@ GO_SYSTEM_H = go/go-system.h $(CONFIG_H) $(SYSTEM_H) coretypes.h \
$(DIAGNOSTIC_CORE_H) $(INPUT_H) intl.h $(DIAGNOSTIC_CORE_H) $(INPUT_H) intl.h
GO_C_H = go/go-c.h $(MACHMODE_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_PARSE_H = go/gofrontend/parse.h
GO_GOGO_H = go/gofrontend/gogo.h GO_GOGO_H = go/gofrontend/gogo.h $(GO_LINEMAP_H)
GO_TYPES_H = go/gofrontend/types.h GO_TYPES_H = go/gofrontend/types.h $(GO_LINEMAP_H)
GO_STATEMENTS_H = go/gofrontend/statements.h go/gofrontend/operator.h GO_STATEMENTS_H = go/gofrontend/statements.h go/gofrontend/operator.h
GO_EXPRESSIONS_H = go/gofrontend/expressions.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_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_RUNTIME_H = go/gofrontend/runtime.h go/gofrontend/runtime.def
GO_AST_DUMP_H = go/gofrontend/ast-dump.h go/gofrontend/string-dump.h 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 \ ...@@ -247,6 +249,9 @@ go/go-gcc.o: go/go-gcc.cc $(GO_SYSTEM_H) $(TREE_H) tree-iterator.h \
go/gofrontend/backend.h go/gofrontend/backend.h
$(CXX) -c $(GOINCLUDES) $(ALL_CPPFLAGS) $(ALL_CXXFLAGS) $< $(OUTPUT_OPTION) $(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 go/%.o: go/gofrontend/%.cc
$(CXX) -c $(GOINCLUDES) $(ALL_CPPFLAGS) $(ALL_CXXFLAGS) $< $(OUTPUT_OPTION) $(CXX) -c $(GOINCLUDES) $(ALL_CPPFLAGS) $(ALL_CXXFLAGS) $< $(OUTPUT_OPTION)
......
// 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;
}
// 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)
...@@ -46,14 +46,14 @@ class Backend ...@@ -46,14 +46,14 @@ class Backend
{ {
std::string name; std::string name;
Btype* btype; Btype* btype;
source_location location; Location location;
Btyped_identifier() Btyped_identifier()
: name(), btype(NULL), location(UNKNOWN_LOCATION) : name(), btype(NULL), location(UNKNOWN_LOCATION)
{ } { }
Btyped_identifier(const std::string& a_name, Btype* a_btype, 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) : name(a_name), btype(a_btype), location(a_location)
{ } { }
}; };
...@@ -100,7 +100,7 @@ class Backend ...@@ -100,7 +100,7 @@ class Backend
function_type(const Btyped_identifier& receiver, function_type(const Btyped_identifier& receiver,
const std::vector<Btyped_identifier>& parameters, const std::vector<Btyped_identifier>& parameters,
const std::vector<Btyped_identifier>& results, const std::vector<Btyped_identifier>& results,
source_location location) = 0; Location location) = 0;
// Get a struct type. // Get a struct type.
virtual Btype* virtual Btype*
...@@ -121,7 +121,7 @@ class Backend ...@@ -121,7 +121,7 @@ class Backend
// parameter to set_placeholder_pointer_type or // parameter to set_placeholder_pointer_type or
// set_placeholder_function_type. // set_placeholder_function_type.
virtual Btype* virtual Btype*
placeholder_pointer_type(const std::string& name, source_location, placeholder_pointer_type(const std::string& name, Location,
bool for_function) = 0; bool for_function) = 0;
// Fill in a placeholder pointer type as a pointer. This takes a // Fill in a placeholder pointer type as a pointer. This takes a
...@@ -141,7 +141,7 @@ class Backend ...@@ -141,7 +141,7 @@ class Backend
// Create a placeholder struct type. This is used for a named // Create a placeholder struct type. This is used for a named
// struct type, as with placeholder_pointer_type. // struct type, as with placeholder_pointer_type.
virtual Btype* 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 // Fill in a placeholder struct type. This takes a type returned by
// placeholder_struct_type and arranges for it to become a real // placeholder_struct_type and arranges for it to become a real
...@@ -156,7 +156,7 @@ class Backend ...@@ -156,7 +156,7 @@ class Backend
// type, as with placeholder_pointer_type, to handle cases like // type, as with placeholder_pointer_type, to handle cases like
// type A []*A. // type A []*A.
virtual Btype* 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 // Fill in a placeholder array type. This takes a type returned by
// placeholder_array_type and arranges for it to become a real array // placeholder_array_type and arranges for it to become a real array
...@@ -172,7 +172,7 @@ class Backend ...@@ -172,7 +172,7 @@ class Backend
// placeholder_array_type.. (It may be called for a pointer, // placeholder_array_type.. (It may be called for a pointer,
// struct, or array type in a case like "type P *byte; type Q P".) // struct, or array type in a case like "type P *byte; type Q P".)
virtual Btype* 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 // Create a marker for a circular pointer type. Go pointer and
// function types can refer to themselves in ways that are not // function types can refer to themselves in ways that are not
...@@ -227,18 +227,18 @@ class Backend ...@@ -227,18 +227,18 @@ class Backend
// Create an assignment statement. // Create an assignment statement.
virtual Bstatement* virtual Bstatement*
assignment_statement(Bexpression* lhs, Bexpression* rhs, assignment_statement(Bexpression* lhs, Bexpression* rhs,
source_location) = 0; Location) = 0;
// Create a return statement, passing the representation of the // Create a return statement, passing the representation of the
// function and the list of values to return. // function and the list of values to return.
virtual Bstatement* virtual Bstatement*
return_statement(Bfunction*, const std::vector<Bexpression*>&, return_statement(Bfunction*, const std::vector<Bexpression*>&,
source_location) = 0; Location) = 0;
// Create an if statement. ELSE_BLOCK may be NULL. // Create an if statement. ELSE_BLOCK may be NULL.
virtual Bstatement* virtual Bstatement*
if_statement(Bexpression* condition, Bblock* then_block, Bblock* else_block, 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. // Create a switch statement where the case values are constants.
// CASES and STATEMENTS must have the same number of entries. If // CASES and STATEMENTS must have the same number of entries. If
...@@ -251,7 +251,7 @@ class Backend ...@@ -251,7 +251,7 @@ class Backend
switch_statement(Bexpression* value, switch_statement(Bexpression* value,
const std::vector<std::vector<Bexpression*> >& cases, const std::vector<std::vector<Bexpression*> >& cases,
const std::vector<Bstatement*>& statements, const std::vector<Bstatement*>& statements,
source_location) = 0; Location) = 0;
// Create a single statement from two statements. // Create a single statement from two statements.
virtual Bstatement* virtual Bstatement*
...@@ -276,7 +276,7 @@ class Backend ...@@ -276,7 +276,7 @@ class Backend
virtual Bblock* virtual Bblock*
block(Bfunction* function, Bblock* enclosing, block(Bfunction* function, Bblock* enclosing,
const std::vector<Bvariable*>& vars, 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 // Add the statements to a block. The block is created first. Then
// the statements are created. Then the statements are added to the // the statements are created. Then the statements are added to the
...@@ -313,7 +313,7 @@ class Backend ...@@ -313,7 +313,7 @@ class Backend
Btype* btype, Btype* btype,
bool is_external, bool is_external,
bool is_hidden, bool is_hidden,
source_location location) = 0; Location location) = 0;
// A global variable will 1) be initialized to zero, or 2) be // A global variable will 1) be initialized to zero, or 2) be
// initialized to a constant value, or 3) be initialized in the init // initialized to a constant value, or 3) be initialized in the init
...@@ -335,7 +335,7 @@ class Backend ...@@ -335,7 +335,7 @@ class Backend
// init_statement to set the initial value. // init_statement to set the initial value.
virtual Bvariable* virtual Bvariable*
local_variable(Bfunction* function, const std::string& name, Btype* type, 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 // Create a function parameter. This is an incoming parameter, not
// a result parameter (result parameters are treated as local // a result parameter (result parameters are treated as local
...@@ -343,7 +343,7 @@ class Backend ...@@ -343,7 +343,7 @@ class Backend
virtual Bvariable* virtual Bvariable*
parameter_variable(Bfunction* function, const std::string& name, parameter_variable(Bfunction* function, const std::string& name,
Btype* type, bool is_address_taken, Btype* type, bool is_address_taken,
source_location location) = 0; Location location) = 0;
// Create a temporary variable. A temporary variable has no name, // Create a temporary variable. A temporary variable has no name,
// just a type. We pass in FUNCTION and BLOCK in case they are // just a type. We pass in FUNCTION and BLOCK in case they are
...@@ -358,7 +358,7 @@ class Backend ...@@ -358,7 +358,7 @@ class Backend
// *PSTATEMENT to a statement which initializes the variable. // *PSTATEMENT to a statement which initializes the variable.
virtual Bvariable* virtual Bvariable*
temporary_variable(Bfunction*, Bblock*, Btype*, Bexpression* init, temporary_variable(Bfunction*, Bblock*, Btype*, Bexpression* init,
bool address_is_taken, source_location location, bool address_is_taken, Location location,
Bstatement** pstatement) = 0; Bstatement** pstatement) = 0;
// Create a named immutable initialized data structure. This is // Create a named immutable initialized data structure. This is
...@@ -384,7 +384,7 @@ class Backend ...@@ -384,7 +384,7 @@ class Backend
// set_immutable_struct_initializer. // set_immutable_struct_initializer.
virtual Bvariable* virtual Bvariable*
immutable_struct(const std::string& name, bool is_common, Btype* type, 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. // Set the initial value of a variable created by immutable_struct.
// The NAME, IS_COMMON, TYPE, and location parameters are the same // The NAME, IS_COMMON, TYPE, and location parameters are the same
...@@ -395,7 +395,7 @@ class Backend ...@@ -395,7 +395,7 @@ class Backend
// immutable_struct. // immutable_struct.
virtual void virtual void
immutable_struct_set_init(Bvariable*, const std::string& name, 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; Bexpression* initializer) = 0;
// Create a reference to a named immutable initialized data // Create a reference to a named immutable initialized data
...@@ -405,7 +405,7 @@ class Backend ...@@ -405,7 +405,7 @@ class Backend
// corresponds to an extern const global variable in C. // corresponds to an extern const global variable in C.
virtual Bvariable* virtual Bvariable*
immutable_struct_reference(const std::string& name, Btype* type, immutable_struct_reference(const std::string& name, Btype* type,
source_location) = 0; Location) = 0;
// Labels. // Labels.
...@@ -413,7 +413,7 @@ class Backend ...@@ -413,7 +413,7 @@ class Backend
// created by the frontend for a loop construct. The location is // created by the frontend for a loop construct. The location is
// where the the label is defined. // where the the label is defined.
virtual Blabel* 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 // Create a statement which defines a label. This statement will be
// put into the codestream at the point where the label should be // put into the codestream at the point where the label should be
...@@ -423,13 +423,13 @@ class Backend ...@@ -423,13 +423,13 @@ class Backend
// Create a goto statement to a label. // Create a goto statement to a label.
virtual Bstatement* 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 // Create an expression for the address of a label. This is used to
// get the return address of a deferred function which may call // get the return address of a deferred function which may call
// recover. // recover.
virtual Bexpression* virtual Bexpression*
label_address(Blabel*, source_location) = 0; label_address(Blabel*, Location) = 0;
}; };
// The backend interface has to define this function. // The backend interface has to define this function.
......
...@@ -189,8 +189,8 @@ Dataflow::Compare_vars::operator()(const Named_object* no1, ...@@ -189,8 +189,8 @@ Dataflow::Compare_vars::operator()(const Named_object* no1,
return false; return false;
// We can have two different variables with the same name. // We can have two different variables with the same name.
source_location loc1 = no1->location(); Location loc1 = no1->location();
source_location loc2 = no2->location(); Location loc2 = no2->location();
if (loc1 < loc2) if (loc1 < loc2)
return false; return false;
if (loc1 > loc2) if (loc1 > loc2)
......
...@@ -279,7 +279,7 @@ Export::write_type(const Type* type) ...@@ -279,7 +279,7 @@ Export::write_type(const Type* type)
if (named_type != NULL) if (named_type != NULL)
{ {
// The builtin types should have been predefined. // 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() || (named_type->named_object()->package()->name()
== "unsafe")); == "unsafe"));
named_object = named_type->named_object(); named_object = named_type->named_object();
......
// 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)
...@@ -28,7 +28,8 @@ void ...@@ -28,7 +28,8 @@ void
go_create_gogo(int int_type_size, int pointer_size) go_create_gogo(int int_type_size, int pointer_size)
{ {
go_assert(::gogo == NULL); 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()) if (!unique_prefix.empty())
::gogo->set_unique_prefix(unique_prefix); ::gogo->set_unique_prefix(unique_prefix);
...@@ -64,6 +65,7 @@ go_parse_input_files(const char** filenames, unsigned int filename_count, ...@@ -64,6 +65,7 @@ go_parse_input_files(const char** filenames, unsigned int filename_count,
bool only_check_syntax, bool require_return_statement) bool only_check_syntax, bool require_return_statement)
{ {
go_assert(filename_count > 0); go_assert(filename_count > 0);
for (unsigned int i = 0; i < filename_count; ++i) for (unsigned int i = 0; i < filename_count; ++i)
{ {
if (i > 0) if (i > 0)
...@@ -80,7 +82,7 @@ go_parse_input_files(const char** filenames, unsigned int filename_count, ...@@ -80,7 +82,7 @@ go_parse_input_files(const char** filenames, unsigned int filename_count,
fatal_error("cannot open %s: %m", filename); fatal_error("cannot open %s: %m", filename);
} }
Lex lexer(filename, file); Lex lexer(filename, file, ::gogo->linemap());
Parse parse(&lexer, ::gogo); Parse parse(&lexer, ::gogo);
parse.program(); parse.program();
...@@ -89,6 +91,8 @@ go_parse_input_files(const char** filenames, unsigned int filename_count, ...@@ -89,6 +91,8 @@ go_parse_input_files(const char** filenames, unsigned int filename_count,
fclose(file); fclose(file);
} }
::gogo->linemap()->stop();
::gogo->clear_file_scope(); ::gogo->clear_file_scope();
// If the global predeclared names are referenced but not defined, // If the global predeclared names are referenced but not defined,
......
...@@ -66,7 +66,7 @@ Import::is_archive_magic(const char* bytes) ...@@ -66,7 +66,7 @@ Import::is_archive_magic(const char* bytes)
class Archive_file class Archive_file
{ {
public: 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_(), : filename_(filename), fd_(fd), filesize_(-1), extended_names_(),
is_thin_archive_(false), location_(location), nested_archives_() is_thin_archive_(false), location_(location), nested_archives_()
{ } { }
...@@ -91,7 +91,7 @@ class Archive_file ...@@ -91,7 +91,7 @@ class Archive_file
{ return this->is_thin_archive_; } { return this->is_thin_archive_; }
// Return the location of the import statement. // Return the location of the import statement.
source_location Location
location() const location() const
{ return this->location_; } { return this->location_; }
...@@ -133,7 +133,7 @@ class Archive_file ...@@ -133,7 +133,7 @@ class Archive_file
// Whether this is a thin archive. // Whether this is a thin archive.
bool is_thin_archive_; bool is_thin_archive_;
// The location of the import statements. // The location of the import statements.
source_location location_; Location location_;
// Table of nested archives. // Table of nested archives.
Nested_archive_table nested_archives_; Nested_archive_table nested_archives_;
}; };
...@@ -613,7 +613,7 @@ Stream_concatenate::do_advance(size_t skip) ...@@ -613,7 +613,7 @@ Stream_concatenate::do_advance(size_t skip)
Import::Stream* Import::Stream*
Import::find_archive_export_data(const std::string& filename, int fd, Import::find_archive_export_data(const std::string& filename, int fd,
source_location location) Location location)
{ {
Archive_file afile(filename, fd, location); Archive_file afile(filename, fd, location);
if (!afile.initialize()) if (!afile.initialize())
......
...@@ -59,7 +59,7 @@ const char* const Import::import_marker = "*imported*"; ...@@ -59,7 +59,7 @@ const char* const Import::import_marker = "*imported*";
// later in the search path. // later in the search path.
Import::Stream* 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)) if (!IS_ABSOLUTE_PATH(filename))
{ {
...@@ -88,7 +88,7 @@ Import::open_package(const std::string& filename, source_location location) ...@@ -88,7 +88,7 @@ Import::open_package(const std::string& filename, source_location location)
Import::Stream* Import::Stream*
Import::try_package_in_directory(const std::string& filename, Import::try_package_in_directory(const std::string& filename,
source_location location) Location location)
{ {
std::string found_filename = filename; std::string found_filename = filename;
int fd = open(found_filename.c_str(), O_RDONLY | O_BINARY); int fd = open(found_filename.c_str(), O_RDONLY | O_BINARY);
...@@ -175,7 +175,7 @@ Import::try_suffixes(std::string* pfilename) ...@@ -175,7 +175,7 @@ Import::try_suffixes(std::string* pfilename)
Import::Stream* Import::Stream*
Import::find_export_data(const std::string& filename, int fd, 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. // See if we can read this as an object file.
Import::Stream* stream = Import::find_object_export_data(filename, fd, 0, Import::Stream* stream = Import::find_object_export_data(filename, fd, 0,
...@@ -213,7 +213,7 @@ Import::Stream* ...@@ -213,7 +213,7 @@ Import::Stream*
Import::find_object_export_data(const std::string& filename, Import::find_object_export_data(const std::string& filename,
int fd, int fd,
off_t offset, off_t offset,
source_location location) Location location)
{ {
const char* errmsg; const char* errmsg;
int err; int err;
...@@ -262,7 +262,7 @@ Import::find_object_export_data(const std::string& filename, ...@@ -262,7 +262,7 @@ Import::find_object_export_data(const std::string& filename,
// Construct an Import object. We make the builtin_types_ vector // Construct an Import object. We make the builtin_types_ vector
// large enough to hold all the builtin types. // 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), : gogo_(NULL), stream_(stream), location_(location), package_(NULL),
add_to_globals_(false), add_to_globals_(false),
builtin_types_((- SMALLEST_BUILTIN_CODE) + 1), builtin_types_((- SMALLEST_BUILTIN_CODE) + 1),
...@@ -448,7 +448,7 @@ Import::import_func(Package* package) ...@@ -448,7 +448,7 @@ Import::import_func(Package* package)
if (is_varargs) if (is_varargs)
fntype->set_is_varargs(); fntype->set_is_varargs();
source_location loc = this->location_; Location loc = this->location_;
Named_object* no; Named_object* no;
if (fntype->is_method()) if (fntype->is_method())
{ {
...@@ -603,7 +603,7 @@ Import::read_type() ...@@ -603,7 +603,7 @@ Import::read_type()
package = this->package_; package = this->package_;
else else
package = this->gogo_->register_package(package_name, unique_prefix, package = this->gogo_->register_package(package_name, unique_prefix,
UNKNOWN_LOCATION); Linemap::unknown_location());
Named_object* no = package->bindings()->lookup(type_name); Named_object* no = package->bindings()->lookup(type_name);
if (no == NULL) if (no == NULL)
...@@ -798,7 +798,7 @@ Import::Stream::match_bytes(const char* bytes, size_t length) ...@@ -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. // Require that the next LENGTH bytes from the stream match BYTES.
void void
Import::Stream::require_bytes(source_location location, const char* bytes, Import::Stream::require_bytes(Location location, const char* bytes,
size_t length) size_t length)
{ {
const char* read; const char* read;
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#define GO_IMPORT_H #define GO_IMPORT_H
#include "export.h" #include "export.h"
#include "go-linemap.h"
class Gogo; class Gogo;
class Package; class Package;
...@@ -78,13 +79,13 @@ class Import ...@@ -78,13 +79,13 @@ class Import
// Give an error if the next bytes do not match STR. Advance the // Give an error if the next bytes do not match STR. Advance the
// read position by the length of STR. // read position by the length of STR.
void 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)); } { this->require_bytes(location, str, strlen(str)); }
// Given an error if the next LENGTH bytes do not match BYTES. // Given an error if the next LENGTH bytes do not match BYTES.
// Advance the read position by LENGTH. // Advance the read position by LENGTH.
void 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. // Advance the read position by SKIP bytes.
void void
...@@ -124,10 +125,10 @@ class Import ...@@ -124,10 +125,10 @@ class Import
// returns a pointer to a Stream object to read the data that it // returns a pointer to a Stream object to read the data that it
// exports. LOCATION is the location of the import statement. // exports. LOCATION is the location of the import statement.
static Stream* static Stream*
open_package(const std::string& filename, source_location location); open_package(const std::string& filename, Location location);
// Constructor. // Constructor.
Import(Stream*, source_location); Import(Stream*, Location);
// Register the builtin types. // Register the builtin types.
void void
...@@ -142,7 +143,7 @@ class Import ...@@ -142,7 +143,7 @@ class Import
import(Gogo*, const std::string& local_name, bool is_local_name_exported); import(Gogo*, const std::string& local_name, bool is_local_name_exported);
// The location of the import statement. // The location of the import statement.
source_location Location
location() const location() const
{ return this->location_; } { return this->location_; }
...@@ -190,17 +191,17 @@ class Import ...@@ -190,17 +191,17 @@ class Import
private: private:
static Stream* static Stream*
try_package_in_directory(const std::string&, source_location); try_package_in_directory(const std::string&, Location);
static int static int
try_suffixes(std::string*); try_suffixes(std::string*);
static Stream* 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* static Stream*
find_object_export_data(const std::string& filename, int fd, 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; static const int archive_magic_len = 8;
...@@ -209,7 +210,7 @@ class Import ...@@ -209,7 +210,7 @@ class Import
static Stream* static Stream*
find_archive_export_data(const std::string& filename, int fd, find_archive_export_data(const std::string& filename, int fd,
source_location); Location);
// Read the import control functions. // Read the import control functions.
void void
...@@ -244,7 +245,7 @@ class Import ...@@ -244,7 +245,7 @@ class Import
// The stream from which to read import data. // The stream from which to read import data.
Stream* stream_; Stream* stream_;
// The location of the import statement we are processing. // The location of the import statement we are processing.
source_location location_; Location location_;
// The package we are importing. // The package we are importing.
Package* package_; Package* package_;
// Whether to add new objects to the global scope, rather than to a // Whether to add new objects to the global scope, rather than to a
......
...@@ -146,7 +146,7 @@ static Keywords keywords; ...@@ -146,7 +146,7 @@ static Keywords keywords;
// Make a general token. // Make a general token.
Token::Token(Classification classification, source_location location) Token::Token(Classification classification, Location location)
: classification_(classification), location_(location) : classification_(classification), location_(location)
{ {
} }
...@@ -432,19 +432,18 @@ Token::print(FILE* file) const ...@@ -432,19 +432,18 @@ Token::print(FILE* file) const
// Class Lex. // 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), : input_file_name_(input_file_name), input_file_(input_file),
linebuf_(NULL), linebufsize_(120), linesize_(0), lineoff_(0), linemap_(linemap), linebuf_(NULL), linebufsize_(120), linesize_(0),
lineno_(0), add_semi_at_eol_(false) lineoff_(0), lineno_(0), add_semi_at_eol_(false)
{ {
this->linebuf_ = new char[this->linebufsize_]; 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() Lex::~Lex()
{ {
delete[] this->linebuf_; delete[] this->linebuf_;
linemap_add(line_table, LC_LEAVE, 0, NULL, 0);
} }
// Read a new line from the file. // Read a new line from the file.
...@@ -508,26 +507,26 @@ Lex::require_line() ...@@ -508,26 +507,26 @@ Lex::require_line()
this->linesize_= got; this->linesize_= got;
this->lineoff_ = 0; this->lineoff_ = 0;
linemap_line_start(line_table, this->lineno_, this->linesize_); this->linemap_->start_line(this->lineno_, this->linesize_);
return true; return true;
} }
// Get the current location. // Get the current location.
source_location Location
Lex::location() const 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 // Get a location slightly before the current one. This is used for
// slightly more efficient handling of operator tokens. // slightly more efficient handling of operator tokens.
source_location Location
Lex::earlier_location(int chars) const 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. // Get the next token.
...@@ -586,7 +585,7 @@ Lex::next_token() ...@@ -586,7 +585,7 @@ Lex::next_token()
else if (p[1] == '*') else if (p[1] == '*')
{ {
this->lineoff_ = p - this->linebuf_; this->lineoff_ = p - this->linebuf_;
source_location location = this->location(); Location location = this->location();
if (!this->skip_c_comment()) if (!this->skip_c_comment())
return Token::make_invalid_token(location); return Token::make_invalid_token(location);
p = this->linebuf_ + this->lineoff_; p = this->linebuf_ + this->lineoff_;
...@@ -889,7 +888,7 @@ Lex::gather_identifier() ...@@ -889,7 +888,7 @@ Lex::gather_identifier()
buf.append(ubuf); buf.append(ubuf);
} }
} }
source_location location = this->location(); Location location = this->location();
this->add_semi_at_eol_ = true; this->add_semi_at_eol_ = true;
this->lineoff_ = p - this->linebuf_; this->lineoff_ = p - this->linebuf_;
if (has_non_ascii_char) if (has_non_ascii_char)
...@@ -956,7 +955,7 @@ Lex::gather_number() ...@@ -956,7 +955,7 @@ Lex::gather_number()
const char* p = pstart; const char* p = pstart;
const char* pend = this->linebuf_ + this->linesize_; const char* pend = this->linebuf_ + this->linesize_;
source_location location = this->location(); Location location = this->location();
bool neg = false; bool neg = false;
if (*p == '+') if (*p == '+')
...@@ -1253,7 +1252,7 @@ Lex::advance_one_char(const char* p, bool is_single_quote, unsigned int* value, ...@@ -1253,7 +1252,7 @@ Lex::advance_one_char(const char* p, bool is_single_quote, unsigned int* value,
void void
Lex::append_char(unsigned int v, bool is_character, std::string* str, Lex::append_char(unsigned int v, bool is_character, std::string* str,
source_location location) Location location)
{ {
char buf[4]; char buf[4];
size_t len; size_t len;
...@@ -1319,7 +1318,7 @@ Lex::gather_character() ...@@ -1319,7 +1318,7 @@ Lex::gather_character()
mpz_t val; mpz_t val;
mpz_init_set_ui(val, value); mpz_init_set_ui(val, value);
source_location location = this->location(); Location location = this->location();
this->lineoff_ = p + 1 - this->linebuf_; this->lineoff_ = p + 1 - this->linebuf_;
Token ret = Token::make_integer_token(val, location); Token ret = Token::make_integer_token(val, location);
mpz_clear(val); mpz_clear(val);
...@@ -1338,7 +1337,7 @@ Lex::gather_string() ...@@ -1338,7 +1337,7 @@ Lex::gather_string()
std::string value; std::string value;
while (*p != '"') while (*p != '"')
{ {
source_location loc = this->location(); Location loc = this->location();
unsigned int c; unsigned int c;
bool is_character; bool is_character;
this->lineoff_ = p - this->linebuf_; this->lineoff_ = p - this->linebuf_;
...@@ -1352,7 +1351,7 @@ Lex::gather_string() ...@@ -1352,7 +1351,7 @@ Lex::gather_string()
Lex::append_char(c, is_character, &value, loc); Lex::append_char(c, is_character, &value, loc);
} }
source_location location = this->location(); Location location = this->location();
this->lineoff_ = p + 1 - this->linebuf_; this->lineoff_ = p + 1 - this->linebuf_;
return Token::make_string_token(value, location); return Token::make_string_token(value, location);
} }
...@@ -1364,7 +1363,7 @@ Lex::gather_raw_string() ...@@ -1364,7 +1363,7 @@ Lex::gather_raw_string()
{ {
const char* p = this->linebuf_ + this->lineoff_ + 1; const char* p = this->linebuf_ + this->lineoff_ + 1;
const char* pend = this->linebuf_ + this->linesize_; const char* pend = this->linebuf_ + this->linesize_;
source_location location = this->location(); Location location = this->location();
std::string value; std::string value;
while (true) while (true)
...@@ -1376,7 +1375,7 @@ Lex::gather_raw_string() ...@@ -1376,7 +1375,7 @@ Lex::gather_raw_string()
this->lineoff_ = p + 1 - this->linebuf_; this->lineoff_ = p + 1 - this->linebuf_;
return Token::make_string_token(value, location); return Token::make_string_token(value, location);
} }
source_location loc = this->location(); Location loc = this->location();
unsigned int c; unsigned int c;
bool issued_error; bool issued_error;
this->lineoff_ = p - this->linebuf_; this->lineoff_ = p - this->linebuf_;
...@@ -1630,8 +1629,7 @@ Lex::skip_cpp_comment() ...@@ -1630,8 +1629,7 @@ Lex::skip_cpp_comment()
memcpy(file, p, filelen); memcpy(file, p, filelen);
file[filelen] = '\0'; file[filelen] = '\0';
linemap_add(line_table, LC_LEAVE, 0, NULL, 0); this->linemap_->start_file(file, lineno);
linemap_add(line_table, LC_ENTER, 0, file, lineno);
this->lineno_ = lineno - 1; this->lineno_ = lineno - 1;
p = plend; p = plend;
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include <mpfr.h> #include <mpfr.h>
#include "operator.h" #include "operator.h"
#include "go-linemap.h"
struct Unicode_range; struct Unicode_range;
...@@ -88,17 +89,17 @@ class Token ...@@ -88,17 +89,17 @@ class Token
// Make a token for an invalid value. // Make a token for an invalid value.
static Token static Token
make_invalid_token(source_location location) make_invalid_token(Location location)
{ return Token(TOKEN_INVALID, location); } { return Token(TOKEN_INVALID, location); }
// Make a token representing end of file. // Make a token representing end of file.
static Token static Token
make_eof_token(source_location location) make_eof_token(Location location)
{ return Token(TOKEN_EOF, location); } { return Token(TOKEN_EOF, location); }
// Make a keyword token. // Make a keyword token.
static Token static Token
make_keyword_token(Keyword keyword, source_location location) make_keyword_token(Keyword keyword, Location location)
{ {
Token tok(TOKEN_KEYWORD, location); Token tok(TOKEN_KEYWORD, location);
tok.u_.keyword = keyword; tok.u_.keyword = keyword;
...@@ -108,7 +109,7 @@ class Token ...@@ -108,7 +109,7 @@ class Token
// Make an identifier token. // Make an identifier token.
static Token static Token
make_identifier_token(const std::string& value, bool is_exported, make_identifier_token(const std::string& value, bool is_exported,
source_location location) Location location)
{ {
Token tok(TOKEN_IDENTIFIER, location); Token tok(TOKEN_IDENTIFIER, location);
tok.u_.identifier_value.name = new std::string(value); tok.u_.identifier_value.name = new std::string(value);
...@@ -118,7 +119,7 @@ class Token ...@@ -118,7 +119,7 @@ class Token
// Make a quoted string token. // Make a quoted string token.
static 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); Token tok(TOKEN_STRING, location);
tok.u_.string_value = new std::string(value); tok.u_.string_value = new std::string(value);
...@@ -127,7 +128,7 @@ class Token ...@@ -127,7 +128,7 @@ class Token
// Make an operator token. // Make an operator token.
static Token static Token
make_operator_token(Operator op, source_location location) make_operator_token(Operator op, Location location)
{ {
Token tok(TOKEN_OPERATOR, location); Token tok(TOKEN_OPERATOR, location);
tok.u_.op = op; tok.u_.op = op;
...@@ -136,7 +137,7 @@ class Token ...@@ -136,7 +137,7 @@ class Token
// Make an integer token. // Make an integer token.
static 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); Token tok(TOKEN_INTEGER, location);
mpz_init(tok.u_.integer_value); mpz_init(tok.u_.integer_value);
...@@ -146,7 +147,7 @@ class Token ...@@ -146,7 +147,7 @@ class Token
// Make a float token. // Make a float token.
static 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); Token tok(TOKEN_FLOAT, location);
mpfr_init(tok.u_.float_value); mpfr_init(tok.u_.float_value);
...@@ -156,7 +157,7 @@ class Token ...@@ -156,7 +157,7 @@ class Token
// Make a token for an imaginary number. // Make a token for an imaginary number.
static Token static Token
make_imaginary_token(mpfr_t val, source_location location) make_imaginary_token(mpfr_t val, Location location)
{ {
Token tok(TOKEN_IMAGINARY, location); Token tok(TOKEN_IMAGINARY, location);
mpfr_init(tok.u_.float_value); mpfr_init(tok.u_.float_value);
...@@ -165,7 +166,7 @@ class Token ...@@ -165,7 +166,7 @@ class Token
} }
// Get the location of the token. // Get the location of the token.
source_location Location
location() const location() const
{ return this->location_; } { return this->location_; }
...@@ -275,7 +276,7 @@ class Token ...@@ -275,7 +276,7 @@ class Token
private: private:
// Private constructor used by make_..._token functions above. // Private constructor used by make_..._token functions above.
Token(Classification, source_location); Token(Classification, Location);
// Clear the token. // Clear the token.
void void
...@@ -307,7 +308,7 @@ class Token ...@@ -307,7 +308,7 @@ class Token
Operator op; Operator op;
} u_; } u_;
// The source location. // The source location.
source_location location_; Location location_;
}; };
// The lexer itself. // The lexer itself.
...@@ -315,7 +316,7 @@ class Token ...@@ -315,7 +316,7 @@ class Token
class Lex class Lex
{ {
public: public:
Lex(const char* input_file_name, FILE* input_file); Lex(const char* input_file_name, FILE* input_file, Linemap *linemap);
~Lex(); ~Lex();
...@@ -334,7 +335,7 @@ class Lex ...@@ -334,7 +335,7 @@ class Lex
// location is used to warn about an out of range character. // location is used to warn about an out of range character.
static void static void
append_char(unsigned int v, bool is_charater, std::string* str, 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 // 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 // in *VALUE. Return the number of bytes read from STR. Return 0
...@@ -350,11 +351,11 @@ class Lex ...@@ -350,11 +351,11 @@ class Lex
require_line(); require_line();
// The current location. // The current location.
source_location Location
location() const; location() const;
// A position CHARS column positions before the current location. // A position CHARS column positions before the current location.
source_location Location
earlier_location(int chars) const; earlier_location(int chars) const;
static bool static bool
...@@ -432,6 +433,8 @@ class Lex ...@@ -432,6 +433,8 @@ class Lex
const char* input_file_name_; const char* input_file_name_;
// The input file. // The input file.
FILE* 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. // The line buffer. This holds the current line.
char* linebuf_; char* linebuf_;
// The size of the line buffer. // The size of the line buffer.
......
...@@ -75,7 +75,7 @@ class Parse ...@@ -75,7 +75,7 @@ class Parse
// The variable name. // The variable name.
std::string name; std::string name;
// The location of the variable. // The location of the variable.
source_location location; Location location;
// The expression. // The expression.
Expression* expr; Expression* expr;
...@@ -147,7 +147,7 @@ class Parse ...@@ -147,7 +147,7 @@ class Parse
unget_token(const Token&); unget_token(const Token&);
// The location of the current token. // The location of the current token.
source_location Location
location(); location();
// For break and continue we keep a stack of statements with // For break and continue we keep a stack of statements with
...@@ -169,12 +169,12 @@ class Parse ...@@ -169,12 +169,12 @@ class Parse
Type* pointer_type(); Type* pointer_type();
Type* channel_type(); Type* channel_type();
void check_signature_names(const Typed_identifier_list*, Names*); 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); bool parameters(Typed_identifier_list**, bool* is_varargs);
Typed_identifier_list* parameter_list(bool* is_varargs); Typed_identifier_list* parameter_list(bool* is_varargs);
void parameter_decl(bool, Typed_identifier_list*, bool*, bool*); void parameter_decl(bool, Typed_identifier_list*, bool*, bool*);
bool result(Typed_identifier_list**); bool result(Typed_identifier_list**);
source_location block(); Location block();
Type* interface_type(); Type* interface_type();
void method_spec(Typed_identifier_list*); void method_spec(Typed_identifier_list*);
void declaration(); void declaration();
...@@ -188,30 +188,30 @@ class Parse ...@@ -188,30 +188,30 @@ class Parse
void var_decl(); void var_decl();
void var_spec(void*); void var_spec(void*);
void init_vars(const Typed_identifier_list*, Type*, Expression_list*, 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 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 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*, 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*, bool init_vars_from_type_guard(const Typed_identifier_list*, Type*,
Expression*, bool is_coloneq, Expression*, bool is_coloneq,
source_location); Location);
Named_object* init_var(const Typed_identifier&, Type*, Expression*, Named_object* init_var(const Typed_identifier&, Type*, Expression*,
bool is_coloneq, bool type_from_init, bool* is_new); bool is_coloneq, bool type_from_init, bool* is_new);
Named_object* create_dummy_global(Type*, Expression*, source_location); Named_object* create_dummy_global(Type*, Expression*, Location);
void simple_var_decl_or_assignment(const std::string&, source_location, void simple_var_decl_or_assignment(const std::string&, Location,
Range_clause*, Type_switch*); Range_clause*, Type_switch*);
void function_decl(); void function_decl();
Typed_identifier* receiver(); Typed_identifier* receiver();
Expression* operand(bool may_be_sink); Expression* operand(bool may_be_sink);
Expression* enclosing_var_reference(Named_object*, Named_object*, Expression* enclosing_var_reference(Named_object*, Named_object*,
source_location); Location);
Expression* composite_lit(Type*, int depth, source_location); Expression* composite_lit(Type*, int depth, Location);
Expression* function_lit(); Expression* function_lit();
Expression* create_closure(Named_object* function, Enclosing_vars*, Expression* create_closure(Named_object* function, Enclosing_vars*,
source_location); Location);
Expression* primary_expr(bool may_be_sink, bool may_be_composite_lit, Expression* primary_expr(bool may_be_sink, bool may_be_composite_lit,
bool* is_type_switch); bool* is_type_switch);
Expression* selector(Expression*, bool* is_type_switch); Expression* selector(Expression*, bool* is_type_switch);
...@@ -222,11 +222,11 @@ class Parse ...@@ -222,11 +222,11 @@ class Parse
bool expression_may_start_here(); bool expression_may_start_here();
Expression* unary_expr(bool may_be_sink, bool may_be_composite_lit, Expression* unary_expr(bool may_be_sink, bool may_be_composite_lit,
bool* is_type_switch); bool* is_type_switch);
Expression* qualified_expr(Expression*, source_location); Expression* qualified_expr(Expression*, Location);
Expression* id_to_expression(const std::string&, source_location); Expression* id_to_expression(const std::string&, Location);
void statement(Label*); void statement(Label*);
bool statement_may_start_here(); 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*); Expression* simple_stat(bool, bool*, Range_clause*, Type_switch*);
bool simple_stat_may_start_here(); bool simple_stat_may_start_here();
void statement_list(); void statement_list();
...@@ -241,10 +241,10 @@ class Parse ...@@ -241,10 +241,10 @@ class Parse
void return_stat(); void return_stat();
void if_stat(); void if_stat();
void switch_stat(Label*); 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); void expr_case_clause(Case_clauses*, bool* saw_default);
Expression_list* expr_switch_case(bool*); 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_case_clause(Named_object*, Type_case_clauses*, bool* saw_default);
void type_switch_case(std::vector<Type*>*, bool*); void type_switch_case(std::vector<Type*>*, bool*);
void select_stat(Label*); void select_stat(Label*);
......
...@@ -82,7 +82,7 @@ runtime_function_type(Runtime_function_type bft) ...@@ -82,7 +82,7 @@ runtime_function_type(Runtime_function_type bft)
go_assert(bft < NUMBER_OF_RUNTIME_FUNCTION_TYPES); go_assert(bft < NUMBER_OF_RUNTIME_FUNCTION_TYPES);
if (runtime_function_types[bft] == NULL) if (runtime_function_types[bft] == NULL)
{ {
const source_location bloc = BUILTINS_LOCATION; const Location bloc = Linemap::predeclared_location();
Type* t; Type* t;
switch (bft) switch (bft)
{ {
...@@ -193,7 +193,7 @@ runtime_function_type(Runtime_function_type bft) ...@@ -193,7 +193,7 @@ runtime_function_type(Runtime_function_type bft)
static Expression* static Expression*
convert_to_runtime_function_type(Runtime_function_type bft, Expression* e, convert_to_runtime_function_type(Runtime_function_type bft, Expression* e,
source_location loc) Location loc)
{ {
switch (bft) switch (bft)
{ {
...@@ -295,7 +295,7 @@ Runtime::runtime_declaration(Function code) ...@@ -295,7 +295,7 @@ Runtime::runtime_declaration(Function code)
{ {
const Runtime_function* pb = &runtime_functions[code]; const Runtime_function* pb = &runtime_functions[code];
source_location bloc = BUILTINS_LOCATION; Location bloc = Linemap::predeclared_location();
Typed_identifier_list* param_types = NULL; Typed_identifier_list* param_types = NULL;
if (pb->parameter_types[0] != RFT_VOID) if (pb->parameter_types[0] != RFT_VOID)
...@@ -347,7 +347,7 @@ Runtime::runtime_declaration(Function code) ...@@ -347,7 +347,7 @@ Runtime::runtime_declaration(Function code)
// Make a call to a runtime function. // Make a call to a runtime function.
Call_expression* Call_expression*
Runtime::make_call(Runtime::Function code, source_location loc, Runtime::make_call(Runtime::Function code, Location loc,
int param_count, ...) int param_count, ...)
{ {
go_assert(code < Runtime::NUMBER_OF_FUNCTIONS); go_assert(code < Runtime::NUMBER_OF_FUNCTIONS);
...@@ -387,7 +387,8 @@ Runtime::map_iteration_type() ...@@ -387,7 +387,8 @@ Runtime::map_iteration_type()
mpz_t ival; mpz_t ival;
mpz_init_set_ui(ival, map_iteration_size); 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); mpz_clear(ival);
return Type::make_array_type(runtime_function_type(RFT_POINTER), iexpr); return Type::make_array_type(runtime_function_type(RFT_POINTER), iexpr);
......
...@@ -32,7 +32,7 @@ class Runtime ...@@ -32,7 +32,7 @@ class Runtime
// Make a call to a runtime function. // Make a call to a runtime function.
static Call_expression* 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 // Convert all the types used by runtime functions to the backend
// representation. // representation.
......
...@@ -15,9 +15,9 @@ ...@@ -15,9 +15,9 @@
void void
Gogo::import_unsafe(const std::string& local_name, bool is_local_name_exported, 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; bool add_to_globals;
Package* package = this->add_imported_package("unsafe", local_name, 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, ...@@ -41,7 +41,8 @@ Gogo::import_unsafe(const std::string& local_name, bool is_local_name_exported,
if (no == NULL) if (no == NULL)
{ {
Type* type = Type::make_pointer_type(Type::make_void_type()); 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 else
{ {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment