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>
* Make-lang.in (gospec.o): Pass SHLIB instead of SHLIB_LINK.
......
......@@ -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)
......
// 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
{
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.
......
......@@ -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)
......
......@@ -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();
......
// 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
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,
......
......@@ -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())
......
......@@ -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;
......
......@@ -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
......
......@@ -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;
......
......@@ -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.
......
......@@ -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*);
......
......@@ -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);
......
......@@ -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.
......
......@@ -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
{
......
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