1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178
|
// 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;
}
|