179 lines
3.4 KiB
C++
179 lines
3.4 KiB
C++
|
// 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"
|
||
|
|
||
|
#include "go-gcc.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();
|
||
|
|
||
|
std::string
|
||
|
to_string(Location);
|
||
|
|
||
|
std::string
|
||
|
location_file(Location);
|
||
|
|
||
|
int
|
||
|
location_line(Location);
|
||
|
|
||
|
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;
|
||
|
}
|
||
|
|
||
|
// Stringify a location
|
||
|
|
||
|
std::string
|
||
|
Gcc_linemap::to_string(Location location)
|
||
|
{
|
||
|
const line_map_ordinary *lmo;
|
||
|
location_t resolved_location;
|
||
|
|
||
|
// Screen out unknown and predeclared locations; produce output
|
||
|
// only for simple file:line locations.
|
||
|
resolved_location =
|
||
|
linemap_resolve_location (line_table, location.gcc_location(),
|
||
|
LRK_SPELLING_LOCATION, &lmo);
|
||
|
if (lmo == NULL || resolved_location < RESERVED_LOCATION_COUNT)
|
||
|
return "";
|
||
|
const char *path = LINEMAP_FILE (lmo);
|
||
|
if (!path)
|
||
|
return "";
|
||
|
|
||
|
// Strip the source file down to the base file, to reduce clutter.
|
||
|
std::stringstream ss;
|
||
|
ss << lbasename(path) << ":" << SOURCE_LINE (lmo, location.gcc_location());
|
||
|
return ss.str();
|
||
|
}
|
||
|
|
||
|
// Return the file name for a given location.
|
||
|
|
||
|
std::string
|
||
|
Gcc_linemap::location_file(Location loc)
|
||
|
{
|
||
|
return LOCATION_FILE(loc.gcc_location());
|
||
|
}
|
||
|
|
||
|
// Return the line number for a given location.
|
||
|
|
||
|
int
|
||
|
Gcc_linemap::location_line(Location loc)
|
||
|
{
|
||
|
return LOCATION_LINE(loc.gcc_location());
|
||
|
}
|
||
|
|
||
|
// 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;
|
||
|
}
|