|
1 # HG changeset patch |
|
2 # User Ted Mielczarek <ted@mielczarek.org> |
|
3 # Date 1362600444 18000 |
|
4 # Node ID 0eb3c7ba8a38a269ab975eff3f95a1a5d5d937b9 |
|
5 # Parent 6b68e82037b8322fb392cea369d517aeeaaee9d3 |
|
6 Stop using dynamic_cast in dwarf2reader |
|
7 Patch by Julian Seward <jseward@acm.org>, R=ted |
|
8 |
|
9 diff --git a/src/common/dwarf/dwarf2reader.cc b/src/common/dwarf/dwarf2reader.cc |
|
10 --- a/src/common/dwarf/dwarf2reader.cc |
|
11 +++ b/src/common/dwarf/dwarf2reader.cc |
|
12 @@ -887,68 +887,80 @@ |
|
13 |
|
14 // If this is a base+offset rule, change its base register to REG. |
|
15 // Otherwise, do nothing. (Ugly, but required for DW_CFA_def_cfa_register.) |
|
16 virtual void SetBaseRegister(unsigned reg) { } |
|
17 |
|
18 // If this is a base+offset rule, change its offset to OFFSET. Otherwise, |
|
19 // do nothing. (Ugly, but required for DW_CFA_def_cfa_offset.) |
|
20 virtual void SetOffset(long long offset) { } |
|
21 + |
|
22 + // A RTTI workaround, to make it possible to implement equality |
|
23 + // comparisons on classes derived from this one. |
|
24 + enum CFIRTag { |
|
25 + CFIR_UNDEFINED_RULE, |
|
26 + CFIR_SAME_VALUE_RULE, |
|
27 + CFIR_OFFSET_RULE, |
|
28 + CFIR_VAL_OFFSET_RULE, |
|
29 + CFIR_REGISTER_RULE, |
|
30 + CFIR_EXPRESSION_RULE, |
|
31 + CFIR_VAL_EXPRESSION_RULE |
|
32 + }; |
|
33 + |
|
34 + // Produce the tag that identifies the child class of this object. |
|
35 + virtual CFIRTag getTag() const = 0; |
|
36 }; |
|
37 |
|
38 // Rule: the value the register had in the caller cannot be recovered. |
|
39 class CallFrameInfo::UndefinedRule: public CallFrameInfo::Rule { |
|
40 public: |
|
41 UndefinedRule() { } |
|
42 ~UndefinedRule() { } |
|
43 + CFIRTag getTag() const { return CFIR_UNDEFINED_RULE; } |
|
44 bool Handle(Handler *handler, uint64 address, int reg) const { |
|
45 return handler->UndefinedRule(address, reg); |
|
46 } |
|
47 bool operator==(const Rule &rhs) const { |
|
48 - // dynamic_cast is allowed by the Google C++ Style Guide, if the use has |
|
49 - // been carefully considered; cheap RTTI-like workarounds are forbidden. |
|
50 - const UndefinedRule *our_rhs = dynamic_cast<const UndefinedRule *>(&rhs); |
|
51 - return (our_rhs != NULL); |
|
52 + if (rhs.getTag() != CFIR_UNDEFINED_RULE) return false; |
|
53 + return true; |
|
54 } |
|
55 Rule *Copy() const { return new UndefinedRule(*this); } |
|
56 }; |
|
57 |
|
58 // Rule: the register's value is the same as that it had in the caller. |
|
59 class CallFrameInfo::SameValueRule: public CallFrameInfo::Rule { |
|
60 public: |
|
61 SameValueRule() { } |
|
62 ~SameValueRule() { } |
|
63 + CFIRTag getTag() const { return CFIR_SAME_VALUE_RULE; } |
|
64 bool Handle(Handler *handler, uint64 address, int reg) const { |
|
65 return handler->SameValueRule(address, reg); |
|
66 } |
|
67 bool operator==(const Rule &rhs) const { |
|
68 - // dynamic_cast is allowed by the Google C++ Style Guide, if the use has |
|
69 - // been carefully considered; cheap RTTI-like workarounds are forbidden. |
|
70 - const SameValueRule *our_rhs = dynamic_cast<const SameValueRule *>(&rhs); |
|
71 - return (our_rhs != NULL); |
|
72 + if (rhs.getTag() != CFIR_SAME_VALUE_RULE) return false; |
|
73 + return true; |
|
74 } |
|
75 Rule *Copy() const { return new SameValueRule(*this); } |
|
76 }; |
|
77 |
|
78 // Rule: the register is saved at OFFSET from BASE_REGISTER. BASE_REGISTER |
|
79 // may be CallFrameInfo::Handler::kCFARegister. |
|
80 class CallFrameInfo::OffsetRule: public CallFrameInfo::Rule { |
|
81 public: |
|
82 OffsetRule(int base_register, long offset) |
|
83 : base_register_(base_register), offset_(offset) { } |
|
84 ~OffsetRule() { } |
|
85 + CFIRTag getTag() const { return CFIR_OFFSET_RULE; } |
|
86 bool Handle(Handler *handler, uint64 address, int reg) const { |
|
87 return handler->OffsetRule(address, reg, base_register_, offset_); |
|
88 } |
|
89 bool operator==(const Rule &rhs) const { |
|
90 - // dynamic_cast is allowed by the Google C++ Style Guide, if the use has |
|
91 - // been carefully considered; cheap RTTI-like workarounds are forbidden. |
|
92 - const OffsetRule *our_rhs = dynamic_cast<const OffsetRule *>(&rhs); |
|
93 - return (our_rhs && |
|
94 - base_register_ == our_rhs->base_register_ && |
|
95 + if (rhs.getTag() != CFIR_OFFSET_RULE) return false; |
|
96 + const OffsetRule *our_rhs = static_cast<const OffsetRule *>(&rhs); |
|
97 + return (base_register_ == our_rhs->base_register_ && |
|
98 offset_ == our_rhs->offset_); |
|
99 } |
|
100 Rule *Copy() const { return new OffsetRule(*this); } |
|
101 // We don't actually need SetBaseRegister or SetOffset here, since they |
|
102 // are only ever applied to CFA rules, for DW_CFA_def_cfa_offset, and it |
|
103 // doesn't make sense to use OffsetRule for computing the CFA: it |
|
104 // computes the address at which a register is saved, not a value. |
|
105 private: |
|
106 @@ -959,90 +971,89 @@ |
|
107 // Rule: the value the register had in the caller is the value of |
|
108 // BASE_REGISTER plus offset. BASE_REGISTER may be |
|
109 // CallFrameInfo::Handler::kCFARegister. |
|
110 class CallFrameInfo::ValOffsetRule: public CallFrameInfo::Rule { |
|
111 public: |
|
112 ValOffsetRule(int base_register, long offset) |
|
113 : base_register_(base_register), offset_(offset) { } |
|
114 ~ValOffsetRule() { } |
|
115 + CFIRTag getTag() const { return CFIR_VAL_OFFSET_RULE; } |
|
116 bool Handle(Handler *handler, uint64 address, int reg) const { |
|
117 return handler->ValOffsetRule(address, reg, base_register_, offset_); |
|
118 } |
|
119 bool operator==(const Rule &rhs) const { |
|
120 - // dynamic_cast is allowed by the Google C++ Style Guide, if the use has |
|
121 - // been carefully considered; cheap RTTI-like workarounds are forbidden. |
|
122 - const ValOffsetRule *our_rhs = dynamic_cast<const ValOffsetRule *>(&rhs); |
|
123 - return (our_rhs && |
|
124 - base_register_ == our_rhs->base_register_ && |
|
125 + if (rhs.getTag() != CFIR_VAL_OFFSET_RULE) return false; |
|
126 + const ValOffsetRule *our_rhs = static_cast<const ValOffsetRule *>(&rhs); |
|
127 + return (base_register_ == our_rhs->base_register_ && |
|
128 offset_ == our_rhs->offset_); |
|
129 } |
|
130 Rule *Copy() const { return new ValOffsetRule(*this); } |
|
131 void SetBaseRegister(unsigned reg) { base_register_ = reg; } |
|
132 void SetOffset(long long offset) { offset_ = offset; } |
|
133 private: |
|
134 int base_register_; |
|
135 long offset_; |
|
136 }; |
|
137 |
|
138 // Rule: the register has been saved in another register REGISTER_NUMBER_. |
|
139 class CallFrameInfo::RegisterRule: public CallFrameInfo::Rule { |
|
140 public: |
|
141 explicit RegisterRule(int register_number) |
|
142 : register_number_(register_number) { } |
|
143 ~RegisterRule() { } |
|
144 + CFIRTag getTag() const { return CFIR_REGISTER_RULE; } |
|
145 bool Handle(Handler *handler, uint64 address, int reg) const { |
|
146 return handler->RegisterRule(address, reg, register_number_); |
|
147 } |
|
148 bool operator==(const Rule &rhs) const { |
|
149 - // dynamic_cast is allowed by the Google C++ Style Guide, if the use has |
|
150 - // been carefully considered; cheap RTTI-like workarounds are forbidden. |
|
151 - const RegisterRule *our_rhs = dynamic_cast<const RegisterRule *>(&rhs); |
|
152 - return (our_rhs && register_number_ == our_rhs->register_number_); |
|
153 + if (rhs.getTag() != CFIR_REGISTER_RULE) return false; |
|
154 + const RegisterRule *our_rhs = static_cast<const RegisterRule *>(&rhs); |
|
155 + return (register_number_ == our_rhs->register_number_); |
|
156 } |
|
157 Rule *Copy() const { return new RegisterRule(*this); } |
|
158 private: |
|
159 int register_number_; |
|
160 }; |
|
161 |
|
162 // Rule: EXPRESSION evaluates to the address at which the register is saved. |
|
163 class CallFrameInfo::ExpressionRule: public CallFrameInfo::Rule { |
|
164 public: |
|
165 explicit ExpressionRule(const string &expression) |
|
166 : expression_(expression) { } |
|
167 ~ExpressionRule() { } |
|
168 + CFIRTag getTag() const { return CFIR_EXPRESSION_RULE; } |
|
169 bool Handle(Handler *handler, uint64 address, int reg) const { |
|
170 return handler->ExpressionRule(address, reg, expression_); |
|
171 } |
|
172 bool operator==(const Rule &rhs) const { |
|
173 - // dynamic_cast is allowed by the Google C++ Style Guide, if the use has |
|
174 - // been carefully considered; cheap RTTI-like workarounds are forbidden. |
|
175 - const ExpressionRule *our_rhs = dynamic_cast<const ExpressionRule *>(&rhs); |
|
176 - return (our_rhs && expression_ == our_rhs->expression_); |
|
177 + if (rhs.getTag() != CFIR_EXPRESSION_RULE) return false; |
|
178 + const ExpressionRule *our_rhs = static_cast<const ExpressionRule *>(&rhs); |
|
179 + return (expression_ == our_rhs->expression_); |
|
180 } |
|
181 Rule *Copy() const { return new ExpressionRule(*this); } |
|
182 private: |
|
183 string expression_; |
|
184 }; |
|
185 |
|
186 // Rule: EXPRESSION evaluates to the address at which the register is saved. |
|
187 class CallFrameInfo::ValExpressionRule: public CallFrameInfo::Rule { |
|
188 public: |
|
189 explicit ValExpressionRule(const string &expression) |
|
190 : expression_(expression) { } |
|
191 ~ValExpressionRule() { } |
|
192 + CFIRTag getTag() const { return CFIR_VAL_EXPRESSION_RULE; } |
|
193 bool Handle(Handler *handler, uint64 address, int reg) const { |
|
194 return handler->ValExpressionRule(address, reg, expression_); |
|
195 } |
|
196 bool operator==(const Rule &rhs) const { |
|
197 - // dynamic_cast is allowed by the Google C++ Style Guide, if the use has |
|
198 - // been carefully considered; cheap RTTI-like workarounds are forbidden. |
|
199 + if (rhs.getTag() != CFIR_VAL_EXPRESSION_RULE) return false; |
|
200 const ValExpressionRule *our_rhs = |
|
201 - dynamic_cast<const ValExpressionRule *>(&rhs); |
|
202 - return (our_rhs && expression_ == our_rhs->expression_); |
|
203 + static_cast<const ValExpressionRule *>(&rhs); |
|
204 + return (expression_ == our_rhs->expression_); |
|
205 } |
|
206 Rule *Copy() const { return new ValExpressionRule(*this); } |
|
207 private: |
|
208 string expression_; |
|
209 }; |
|
210 |
|
211 // A map from register numbers to rules. |
|
212 class CallFrameInfo::RuleMap { |