Line data Source code
1 : // go-linemap.h -- interface to location tracking -*- C++ -*-
2 :
3 : // Copyright 2011 The Go Authors. All rights reserved.
4 : // Use of this source code is governed by a BSD-style
5 : // license that can be found in the LICENSE file.
6 :
7 : #ifndef GO_LINEMAP_H
8 : #define GO_LINEMAP_H
9 :
10 : #include "go-system.h"
11 :
12 : // The backend must define a type named Location which holds
13 : // information about a location in a source file. The only thing the
14 : // frontend does with instances of Location is pass them back to the
15 : // backend interface. The Location type must be assignable, and it
16 : // must be comparable: i.e., it must support operator= and operator<.
17 : // The type is normally passed by value rather than by reference, and
18 : // it should support that efficiently. The type should be defined in
19 : // "go-location.h".
20 : #include "go-location.h"
21 :
22 : // The Linemap class is a pure abstract interface, plus some static
23 : // convenience functions. The backend must implement the interface.
24 :
25 : class Linemap
26 : {
27 : public:
28 4646 : Linemap()
29 4646 : {
30 : // Only one instance of Linemap is allowed to exist.
31 4646 : go_assert(Linemap::instance_ == NULL);
32 4646 : Linemap::instance_ = this;
33 4646 : }
34 :
35 : virtual
36 : ~Linemap() { Linemap::instance_ = NULL; }
37 :
38 : // Subsequent Location values will come from the file named
39 : // FILE_NAME, starting at LINE_BEGIN. Normally LINE_BEGIN will be
40 : // 0, but it will be non-zero if the Go source has a //line comment.
41 : virtual void
42 : start_file(const char* file_name, unsigned int line_begin) = 0;
43 :
44 : // Subsequent Location values will come from the line LINE_NUMBER,
45 : // in the current file. LINE_SIZE is the size of the line in bytes.
46 : // This will normally be called for every line in a source file.
47 : virtual void
48 : start_line(unsigned int line_number, unsigned int line_size) = 0;
49 :
50 : // Get a Location representing column position COLUMN on the current
51 : // line in the current file.
52 : virtual Location
53 : get_location(unsigned int column) = 0;
54 :
55 : // Stop generating Location values. This will be called after all
56 : // input files have been read, in case any cleanup is required.
57 : virtual void
58 : stop() = 0;
59 :
60 : // Produce a human-readable description of a Location, e.g.
61 : // "foo.go:10". Returns an empty string for predeclared, builtin or
62 : // unknown locations.
63 : virtual std::string
64 : to_string(Location) = 0;
65 :
66 : // Return the file name for a given location.
67 : virtual std::string
68 : location_file(Location) = 0;
69 :
70 : // Return the line number for a given location.
71 : virtual int
72 : location_line(Location) = 0;
73 :
74 : protected:
75 : // Return a special Location used for predeclared identifiers. This
76 : // Location should be different from that for any actual source
77 : // file. This location will be used for various different types,
78 : // functions, and objects created by the frontend.
79 : virtual Location
80 : get_predeclared_location() = 0;
81 :
82 : // Return a special Location which indicates that no actual location
83 : // is known. This is used for undefined objects and for errors.
84 : virtual Location
85 : get_unknown_location() = 0;
86 :
87 : // Return whether the argument is the Location returned by
88 : // get_predeclared_location.
89 : virtual bool
90 : is_predeclared(Location) = 0;
91 :
92 : // Return whether the argument is the Location returned by
93 : // get_unknown_location.
94 : virtual bool
95 : is_unknown(Location) = 0;
96 :
97 : // The single existing instance of Linemap.
98 : static Linemap *instance_;
99 :
100 : public:
101 : // Following are convenience static functions, which allow us to
102 : // access some virtual functions without explicitly passing around
103 : // an instance of Linemap.
104 :
105 : // Return the special Location used for predeclared identifiers.
106 : static Location
107 6028024 : predeclared_location()
108 : {
109 6028024 : go_assert(Linemap::instance_ != NULL);
110 6028024 : return Linemap::instance_->get_predeclared_location();
111 : }
112 :
113 : // Return the special Location used when no location is known.
114 : static Location
115 11104600 : unknown_location()
116 : {
117 11104600 : go_assert(Linemap::instance_ != NULL);
118 11104600 : return Linemap::instance_->get_unknown_location();
119 : }
120 :
121 : // Return whether the argument is the special location used for
122 : // predeclared identifiers.
123 : static bool
124 9163351 : is_predeclared_location(Location loc)
125 : {
126 9163351 : go_assert(Linemap::instance_ != NULL);
127 9163351 : return Linemap::instance_->is_predeclared(loc);
128 : }
129 :
130 : // Return whether the argument is the special location used when no
131 : // location is known.
132 : static bool
133 643030 : is_unknown_location(Location loc)
134 : {
135 643030 : go_assert(Linemap::instance_ != NULL);
136 643030 : return Linemap::instance_->is_unknown(loc);
137 : }
138 :
139 : // Produce a human-readable description of a Location.
140 : static std::string
141 0 : location_to_string(Location loc)
142 : {
143 0 : go_assert(Linemap::instance_ != NULL);
144 0 : return Linemap::instance_->to_string(loc);
145 : }
146 :
147 : // Return the file name of a location.
148 : static std::string
149 16707 : location_to_file(Location loc)
150 : {
151 16707 : go_assert(Linemap::instance_ != NULL);
152 16707 : return Linemap::instance_->location_file(loc);
153 : }
154 :
155 : // Return line number of a location.
156 : static int
157 122751 : location_to_line(Location loc)
158 : {
159 122751 : go_assert(Linemap::instance_ != NULL);
160 122751 : return Linemap::instance_->location_line(loc);
161 : }
162 : };
163 :
164 : #endif // !defined(GO_LINEMAP_H)
|