Branch data Line data Source code
1 : : // $Id: Obj.h 6781 2009-06-28 00:50:04Z vern $
2 : : //
3 : : // See the file "COPYING" in the main distribution directory for copyright.
4 : :
5 : : #ifndef obj_h
6 : : #define obj_h
7 : :
8 : : #include <limits.h>
9 : :
10 : : #include "input.h"
11 : : #include "Desc.h"
12 : : #include "SerialObj.h"
13 : :
14 : : class Serializer;
15 : : class SerialInfo;
16 : :
17 : 903706 : class Location : SerialObj {
18 : : public:
19 : 298205 : Location(const char* fname, int line_f, int line_l, int col_f, int col_l)
20 : 298205 : {
21 : 298205 : filename = fname;
22 : 298205 : first_line = line_f;
23 : 298205 : last_line = line_l;
24 : 298205 : first_column = col_f;
25 : 298205 : last_column = col_l;
26 : 298205 : delete_data = false;
27 : :
28 : 298205 : timestamp = 0;
29 : 298205 : text = 0;
30 : 298205 : }
31 : :
32 : 639 : Location()
33 : 639 : {
34 : 639 : filename = 0;
35 : 639 : first_line = last_line = first_column = last_column = 0;
36 : 639 : delete_data = false;
37 : 639 : timestamp = 0;
38 : 639 : text = 0;
39 : 639 : }
40 : :
41 : 275011 : virtual ~Location()
42 : 275011 : {
43 [ - + ][ # # ]: 275011 : if ( delete_data )
44 [ # # ][ # # ]: 0 : delete [] filename;
45 [ + + ][ # # ]: 275011 : }
46 : :
47 : : bool Serialize(SerialInfo* info) const;
48 : : static Location* Unserialize(UnserialInfo* info);
49 : :
50 : : bool operator==(const Location& l) const;
51 : 0 : bool operator!=(const Location& l) const
52 : 0 : { return ! (*this == l); }
53 : :
54 : : const char* filename;
55 : : int first_line, last_line;
56 : : int first_column, last_column;
57 : : bool delete_data;
58 : :
59 : : // Timestamp and text for compatibility with Bison's default yyltype.
60 : : int timestamp;
61 : : char* text;
62 : : protected:
63 : 64 : DECLARE_SERIAL(Location);
64 : : };
65 : :
66 : : #define YYLTYPE yyltype
67 : : typedef Location yyltype;
68 : : YYLTYPE GetCurrentLocation();
69 : :
70 : : // Used to mean "no location associated with this object".
71 : : extern Location no_location;
72 : :
73 : : // Current start/end location.
74 : : extern Location start_location;
75 : : extern Location end_location;
76 : :
77 : : // Used by parser to set the above.
78 : 51435 : inline void set_location(const Location loc)
79 : : {
80 : 51435 : start_location = end_location = loc;
81 : 51435 : }
82 : :
83 : 52525 : inline void set_location(const Location start, const Location end)
84 : : {
85 : 52525 : start_location = start;
86 : 52525 : end_location = end;
87 : 52525 : }
88 : :
89 : : class BroObj : public SerialObj {
90 : : public:
91 : 1291724 : BroObj()
92 : 1291724 : {
93 : 1291724 : ref_cnt = 1;
94 : 1291724 : in_ser_cache = false;
95 : :
96 : : // A bit of a hack. We'd like to associate location
97 : : // information with every object created when parsing,
98 : : // since for them, the location is generally well-defined.
99 : : // We could maintain a separate flag that tells us whether
100 : : // we're inside a parse, but the parser also sets the
101 : : // location to no_location when it's done, so it makes
102 : : // sense to just check for that. *However*, start_location
103 : : // and end_location are maintained as their own objects
104 : : // rather than pointers or references, so we can't directly
105 : : // check them for equality with no_location. So instead
106 : : // we check for whether start_location has a line number
107 : : // of 0, which should only happen if it's been assigned
108 : : // to no_location (or hasn't been initialized at all).
109 : 1291724 : location = 0;
110 [ + + ]: 1291724 : if ( start_location.first_line != 0 )
111 : 205913 : SetLocationInfo(&start_location, &end_location);
112 : 1291724 : }
113 : :
114 : : virtual ~BroObj();
115 : :
116 : : // Report user warnings/errors. If obj2 is given, then it's
117 : : // included in the message, though if pinpoint_only is non-zero,
118 : : // then obj2 is only used to pinpoint the location.
119 : : void Warn(const char* msg, const BroObj* obj2 = 0,
120 : : int pinpoint_only = 0) const;
121 : : void Error(const char* msg, const BroObj* obj2 = 0,
122 : : int pinpoint_only = 0) const;
123 : : void RunTime(const char* msg, const BroObj* obj2 = 0,
124 : : int pinpoint_only = 0) const;
125 : :
126 : : // Report internal errors.
127 : : void BadTag(const char* msg, const char* t1 = 0,
128 : : const char* t2 = 0) const;
129 : : #define CHECK_TAG(t1, t2, text, tag_to_text_func) \
130 : : { \
131 : : if ( t1 != t2 ) \
132 : : BadTag(text, tag_to_text_func(t1), tag_to_text_func(t2)); \
133 : : }
134 : :
135 : : void Internal(const char* msg) const;
136 : : void InternalWarning(const char* msg) const;
137 : :
138 : 0 : virtual void Describe(ODesc* d) const { /* FIXME: Add code */ };
139 : :
140 : : void AddLocation(ODesc* d) const;
141 : :
142 : : // Get location info for debugging.
143 : 17457 : const Location* GetLocationInfo() const
144 [ + - ]: 17457 : { return location ? location : &no_location; }
145 : :
146 : 44 : virtual bool SetLocationInfo(const Location* loc)
147 : 44 : { return SetLocationInfo(loc, loc); }
148 : :
149 : : // Location = range from start to end.
150 : : virtual bool SetLocationInfo(const Location* start, const Location* end);
151 : :
152 : : // Set new end-of-location information. This is used to
153 : : // extend compound objects such as statement lists.
154 : : virtual void UpdateLocationEndInfo(const Location& end);
155 : :
156 : 3554 : int RefCnt() const { return ref_cnt; }
157 : :
158 : : // Helper class to temporarily suppress run-time errors
159 : : // as long as there exist any instances.
160 : : class SuppressRunTimeErrors {
161 : : public:
162 : 0 : SuppressRunTimeErrors() { ++BroObj::suppress_runtime; }
163 : 0 : ~SuppressRunTimeErrors() { --BroObj::suppress_runtime; }
164 : : };
165 : :
166 : : bool in_ser_cache;
167 : :
168 : : protected:
169 : : friend class SerializationCache;
170 : :
171 : : DECLARE_ABSTRACT_SERIAL(BroObj);
172 : :
173 : : Location* location; // all that matters in real estate
174 : :
175 : : private:
176 : : friend class SuppressRunTimeErrors;
177 : :
178 : : void DoMsg(const char s1[], const char s2[], const BroObj* obj2 = 0,
179 : : int pinpoint_only = 0) const;
180 : : void PinPoint(ODesc* d, const BroObj* obj2 = 0,
181 : : int pinpoint_only = 0) const;
182 : : void Fatal() const;
183 : :
184 : : friend inline void Ref(BroObj* o);
185 : : friend inline void Unref(BroObj* o);
186 : :
187 : : int ref_cnt;
188 : :
189 : : // If non-zero, do not print runtime errors. Useful for
190 : : // speculative evaluation.
191 : : static int suppress_runtime;
192 : : };
193 : :
194 : : // Prints obj to stderr, primarily for debugging.
195 : : extern void print(const BroObj* obj);
196 : :
197 : : extern void bad_ref(int type);
198 : :
199 : : // Sometimes useful when dealing with BroObj subclasses that have their
200 : : // own (protected) versions of Error.
201 : : inline void Error(const BroObj* o, const char* msg)
202 : : {
203 : : o->Error(msg);
204 : : }
205 : :
206 : 3283765 : inline void Ref(BroObj* o)
207 : : {
208 [ - + ]: 3283765 : if ( ++o->ref_cnt <= 1 )
209 : 0 : bad_ref(0);
210 [ - + ]: 3283765 : if ( o->ref_cnt == INT_MAX )
211 : 0 : bad_ref(1);
212 : 3283765 : }
213 : :
214 : 6332470 : inline void Unref(BroObj* o)
215 : : {
216 [ + + ][ + + ]: 6332470 : if ( o && --o->ref_cnt <= 0 )
[ + + ]
217 : : {
218 [ - + ]: 1099511 : if ( o->ref_cnt < 0 )
219 : 0 : bad_ref(2);
220 [ + - ]: 1099511 : delete o;
221 : :
222 : : // We could do the following if o were passed by reference.
223 : : // o = (BroObj*) 0xcd;
224 : : }
225 : 6332470 : }
226 : :
227 : : // A dict_delete_func that knows to Unref() dictionary entries.
228 : : extern void bro_obj_delete_func(void* v);
229 : :
230 : : #endif
|