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 21 #include "go-location.h" 22 23 // The Linemap class is a pure abstract interface, plus some static 24 // convenience functions. The backend must implement the interface. 25 26 class Linemap 27 { 28 public: Linemap()29 Linemap() 30 { 31 // Only one instance of Linemap is allowed to exist. 32 go_assert(Linemap::instance_ == NULL); 33 Linemap::instance_ = this; 34 } 35 36 virtual ~Linemap()37 ~Linemap() { Linemap::instance_ = NULL; } 38 39 // Subsequent Location values will come from the file named 40 // FILE_NAME, starting at LINE_BEGIN. Normally LINE_BEGIN will be 41 // 0, but it will be non-zero if the Go source has a //line comment. 42 virtual void 43 start_file(const char* file_name, unsigned int line_begin) = 0; 44 45 // Subsequent Location values will come from the line LINE_NUMBER, 46 // in the current file. LINE_SIZE is the size of the line in bytes. 47 // This will normally be called for every line in a source file. 48 virtual void 49 start_line(unsigned int line_number, unsigned int line_size) = 0; 50 51 // Get a Location representing column position COLUMN on the current 52 // line in the current file. 53 virtual Location 54 get_location(unsigned int column) = 0; 55 56 // Stop generating Location values. This will be called after all 57 // input files have been read, in case any cleanup is required. 58 virtual void 59 stop() = 0; 60 61 protected: 62 // Return a special Location used for predeclared identifiers. This 63 // Location should be different from that for any actual source 64 // file. This location will be used for various different types, 65 // functions, and objects created by the frontend. 66 virtual Location 67 get_predeclared_location() = 0; 68 69 // Return a special Location which indicates that no actual location 70 // is known. This is used for undefined objects and for errors. 71 virtual Location 72 get_unknown_location() = 0; 73 74 // Return whether the argument is the Location returned by 75 // get_predeclared_location. 76 virtual bool 77 is_predeclared(Location) = 0; 78 79 // Return whether the argument is the Location returned by 80 // get_unknown_location. 81 virtual bool 82 is_unknown(Location) = 0; 83 84 // The single existing instance of Linemap. 85 static Linemap *instance_; 86 87 public: 88 // Following are convenience static functions, which allow us to 89 // access some virtual functions without explicitly passing around 90 // an instance of Linemap. 91 92 // Return the special Location used for predeclared identifiers. 93 static Location predeclared_location()94 predeclared_location() 95 { 96 go_assert(Linemap::instance_ != NULL); 97 return Linemap::instance_->get_predeclared_location(); 98 } 99 100 // Return the special Location used when no location is known. 101 static Location unknown_location()102 unknown_location() 103 { 104 go_assert(Linemap::instance_ != NULL); 105 return Linemap::instance_->get_unknown_location(); 106 } 107 108 // Return whether the argument is the special location used for 109 // predeclared identifiers. 110 static bool is_predeclared_location(Location loc)111 is_predeclared_location(Location loc) 112 { 113 go_assert(Linemap::instance_ != NULL); 114 return Linemap::instance_->is_predeclared(loc); 115 } 116 117 // Return whether the argument is the special location used when no 118 // location is known. 119 static bool is_unknown_location(Location loc)120 is_unknown_location(Location loc) 121 { 122 go_assert(Linemap::instance_ != NULL); 123 return Linemap::instance_->is_unknown(loc); 124 } 125 }; 126 127 // The backend interface must define this function. It should return 128 // a fully implemented instance of Linemap. 129 extern Linemap* go_get_linemap(); 130 131 #endif // !defined(GO_LINEMAP_H) 132