mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
213 lines
9.1 KiB
Diff
213 lines
9.1 KiB
Diff
# HG changeset patch
|
|
# User Ted Mielczarek <ted@mielczarek.org>
|
|
# Date 1362600444 18000
|
|
# Node ID 0eb3c7ba8a38a269ab975eff3f95a1a5d5d937b9
|
|
# Parent 6b68e82037b8322fb392cea369d517aeeaaee9d3
|
|
Stop using dynamic_cast in dwarf2reader
|
|
Patch by Julian Seward <jseward@acm.org>, R=ted
|
|
|
|
diff --git a/src/common/dwarf/dwarf2reader.cc b/src/common/dwarf/dwarf2reader.cc
|
|
--- a/src/common/dwarf/dwarf2reader.cc
|
|
+++ b/src/common/dwarf/dwarf2reader.cc
|
|
@@ -887,68 +887,80 @@
|
|
|
|
// If this is a base+offset rule, change its base register to REG.
|
|
// Otherwise, do nothing. (Ugly, but required for DW_CFA_def_cfa_register.)
|
|
virtual void SetBaseRegister(unsigned reg) { }
|
|
|
|
// If this is a base+offset rule, change its offset to OFFSET. Otherwise,
|
|
// do nothing. (Ugly, but required for DW_CFA_def_cfa_offset.)
|
|
virtual void SetOffset(long long offset) { }
|
|
+
|
|
+ // A RTTI workaround, to make it possible to implement equality
|
|
+ // comparisons on classes derived from this one.
|
|
+ enum CFIRTag {
|
|
+ CFIR_UNDEFINED_RULE,
|
|
+ CFIR_SAME_VALUE_RULE,
|
|
+ CFIR_OFFSET_RULE,
|
|
+ CFIR_VAL_OFFSET_RULE,
|
|
+ CFIR_REGISTER_RULE,
|
|
+ CFIR_EXPRESSION_RULE,
|
|
+ CFIR_VAL_EXPRESSION_RULE
|
|
+ };
|
|
+
|
|
+ // Produce the tag that identifies the child class of this object.
|
|
+ virtual CFIRTag getTag() const = 0;
|
|
};
|
|
|
|
// Rule: the value the register had in the caller cannot be recovered.
|
|
class CallFrameInfo::UndefinedRule: public CallFrameInfo::Rule {
|
|
public:
|
|
UndefinedRule() { }
|
|
~UndefinedRule() { }
|
|
+ CFIRTag getTag() const { return CFIR_UNDEFINED_RULE; }
|
|
bool Handle(Handler *handler, uint64 address, int reg) const {
|
|
return handler->UndefinedRule(address, reg);
|
|
}
|
|
bool operator==(const Rule &rhs) const {
|
|
- // dynamic_cast is allowed by the Google C++ Style Guide, if the use has
|
|
- // been carefully considered; cheap RTTI-like workarounds are forbidden.
|
|
- const UndefinedRule *our_rhs = dynamic_cast<const UndefinedRule *>(&rhs);
|
|
- return (our_rhs != NULL);
|
|
+ if (rhs.getTag() != CFIR_UNDEFINED_RULE) return false;
|
|
+ return true;
|
|
}
|
|
Rule *Copy() const { return new UndefinedRule(*this); }
|
|
};
|
|
|
|
// Rule: the register's value is the same as that it had in the caller.
|
|
class CallFrameInfo::SameValueRule: public CallFrameInfo::Rule {
|
|
public:
|
|
SameValueRule() { }
|
|
~SameValueRule() { }
|
|
+ CFIRTag getTag() const { return CFIR_SAME_VALUE_RULE; }
|
|
bool Handle(Handler *handler, uint64 address, int reg) const {
|
|
return handler->SameValueRule(address, reg);
|
|
}
|
|
bool operator==(const Rule &rhs) const {
|
|
- // dynamic_cast is allowed by the Google C++ Style Guide, if the use has
|
|
- // been carefully considered; cheap RTTI-like workarounds are forbidden.
|
|
- const SameValueRule *our_rhs = dynamic_cast<const SameValueRule *>(&rhs);
|
|
- return (our_rhs != NULL);
|
|
+ if (rhs.getTag() != CFIR_SAME_VALUE_RULE) return false;
|
|
+ return true;
|
|
}
|
|
Rule *Copy() const { return new SameValueRule(*this); }
|
|
};
|
|
|
|
// Rule: the register is saved at OFFSET from BASE_REGISTER. BASE_REGISTER
|
|
// may be CallFrameInfo::Handler::kCFARegister.
|
|
class CallFrameInfo::OffsetRule: public CallFrameInfo::Rule {
|
|
public:
|
|
OffsetRule(int base_register, long offset)
|
|
: base_register_(base_register), offset_(offset) { }
|
|
~OffsetRule() { }
|
|
+ CFIRTag getTag() const { return CFIR_OFFSET_RULE; }
|
|
bool Handle(Handler *handler, uint64 address, int reg) const {
|
|
return handler->OffsetRule(address, reg, base_register_, offset_);
|
|
}
|
|
bool operator==(const Rule &rhs) const {
|
|
- // dynamic_cast is allowed by the Google C++ Style Guide, if the use has
|
|
- // been carefully considered; cheap RTTI-like workarounds are forbidden.
|
|
- const OffsetRule *our_rhs = dynamic_cast<const OffsetRule *>(&rhs);
|
|
- return (our_rhs &&
|
|
- base_register_ == our_rhs->base_register_ &&
|
|
+ if (rhs.getTag() != CFIR_OFFSET_RULE) return false;
|
|
+ const OffsetRule *our_rhs = static_cast<const OffsetRule *>(&rhs);
|
|
+ return (base_register_ == our_rhs->base_register_ &&
|
|
offset_ == our_rhs->offset_);
|
|
}
|
|
Rule *Copy() const { return new OffsetRule(*this); }
|
|
// We don't actually need SetBaseRegister or SetOffset here, since they
|
|
// are only ever applied to CFA rules, for DW_CFA_def_cfa_offset, and it
|
|
// doesn't make sense to use OffsetRule for computing the CFA: it
|
|
// computes the address at which a register is saved, not a value.
|
|
private:
|
|
@@ -959,90 +971,89 @@
|
|
// Rule: the value the register had in the caller is the value of
|
|
// BASE_REGISTER plus offset. BASE_REGISTER may be
|
|
// CallFrameInfo::Handler::kCFARegister.
|
|
class CallFrameInfo::ValOffsetRule: public CallFrameInfo::Rule {
|
|
public:
|
|
ValOffsetRule(int base_register, long offset)
|
|
: base_register_(base_register), offset_(offset) { }
|
|
~ValOffsetRule() { }
|
|
+ CFIRTag getTag() const { return CFIR_VAL_OFFSET_RULE; }
|
|
bool Handle(Handler *handler, uint64 address, int reg) const {
|
|
return handler->ValOffsetRule(address, reg, base_register_, offset_);
|
|
}
|
|
bool operator==(const Rule &rhs) const {
|
|
- // dynamic_cast is allowed by the Google C++ Style Guide, if the use has
|
|
- // been carefully considered; cheap RTTI-like workarounds are forbidden.
|
|
- const ValOffsetRule *our_rhs = dynamic_cast<const ValOffsetRule *>(&rhs);
|
|
- return (our_rhs &&
|
|
- base_register_ == our_rhs->base_register_ &&
|
|
+ if (rhs.getTag() != CFIR_VAL_OFFSET_RULE) return false;
|
|
+ const ValOffsetRule *our_rhs = static_cast<const ValOffsetRule *>(&rhs);
|
|
+ return (base_register_ == our_rhs->base_register_ &&
|
|
offset_ == our_rhs->offset_);
|
|
}
|
|
Rule *Copy() const { return new ValOffsetRule(*this); }
|
|
void SetBaseRegister(unsigned reg) { base_register_ = reg; }
|
|
void SetOffset(long long offset) { offset_ = offset; }
|
|
private:
|
|
int base_register_;
|
|
long offset_;
|
|
};
|
|
|
|
// Rule: the register has been saved in another register REGISTER_NUMBER_.
|
|
class CallFrameInfo::RegisterRule: public CallFrameInfo::Rule {
|
|
public:
|
|
explicit RegisterRule(int register_number)
|
|
: register_number_(register_number) { }
|
|
~RegisterRule() { }
|
|
+ CFIRTag getTag() const { return CFIR_REGISTER_RULE; }
|
|
bool Handle(Handler *handler, uint64 address, int reg) const {
|
|
return handler->RegisterRule(address, reg, register_number_);
|
|
}
|
|
bool operator==(const Rule &rhs) const {
|
|
- // dynamic_cast is allowed by the Google C++ Style Guide, if the use has
|
|
- // been carefully considered; cheap RTTI-like workarounds are forbidden.
|
|
- const RegisterRule *our_rhs = dynamic_cast<const RegisterRule *>(&rhs);
|
|
- return (our_rhs && register_number_ == our_rhs->register_number_);
|
|
+ if (rhs.getTag() != CFIR_REGISTER_RULE) return false;
|
|
+ const RegisterRule *our_rhs = static_cast<const RegisterRule *>(&rhs);
|
|
+ return (register_number_ == our_rhs->register_number_);
|
|
}
|
|
Rule *Copy() const { return new RegisterRule(*this); }
|
|
private:
|
|
int register_number_;
|
|
};
|
|
|
|
// Rule: EXPRESSION evaluates to the address at which the register is saved.
|
|
class CallFrameInfo::ExpressionRule: public CallFrameInfo::Rule {
|
|
public:
|
|
explicit ExpressionRule(const string &expression)
|
|
: expression_(expression) { }
|
|
~ExpressionRule() { }
|
|
+ CFIRTag getTag() const { return CFIR_EXPRESSION_RULE; }
|
|
bool Handle(Handler *handler, uint64 address, int reg) const {
|
|
return handler->ExpressionRule(address, reg, expression_);
|
|
}
|
|
bool operator==(const Rule &rhs) const {
|
|
- // dynamic_cast is allowed by the Google C++ Style Guide, if the use has
|
|
- // been carefully considered; cheap RTTI-like workarounds are forbidden.
|
|
- const ExpressionRule *our_rhs = dynamic_cast<const ExpressionRule *>(&rhs);
|
|
- return (our_rhs && expression_ == our_rhs->expression_);
|
|
+ if (rhs.getTag() != CFIR_EXPRESSION_RULE) return false;
|
|
+ const ExpressionRule *our_rhs = static_cast<const ExpressionRule *>(&rhs);
|
|
+ return (expression_ == our_rhs->expression_);
|
|
}
|
|
Rule *Copy() const { return new ExpressionRule(*this); }
|
|
private:
|
|
string expression_;
|
|
};
|
|
|
|
// Rule: EXPRESSION evaluates to the address at which the register is saved.
|
|
class CallFrameInfo::ValExpressionRule: public CallFrameInfo::Rule {
|
|
public:
|
|
explicit ValExpressionRule(const string &expression)
|
|
: expression_(expression) { }
|
|
~ValExpressionRule() { }
|
|
+ CFIRTag getTag() const { return CFIR_VAL_EXPRESSION_RULE; }
|
|
bool Handle(Handler *handler, uint64 address, int reg) const {
|
|
return handler->ValExpressionRule(address, reg, expression_);
|
|
}
|
|
bool operator==(const Rule &rhs) const {
|
|
- // dynamic_cast is allowed by the Google C++ Style Guide, if the use has
|
|
- // been carefully considered; cheap RTTI-like workarounds are forbidden.
|
|
+ if (rhs.getTag() != CFIR_VAL_EXPRESSION_RULE) return false;
|
|
const ValExpressionRule *our_rhs =
|
|
- dynamic_cast<const ValExpressionRule *>(&rhs);
|
|
- return (our_rhs && expression_ == our_rhs->expression_);
|
|
+ static_cast<const ValExpressionRule *>(&rhs);
|
|
+ return (expression_ == our_rhs->expression_);
|
|
}
|
|
Rule *Copy() const { return new ValExpressionRule(*this); }
|
|
private:
|
|
string expression_;
|
|
};
|
|
|
|
// A map from register numbers to rules.
|
|
class CallFrameInfo::RuleMap {
|