gecko-dev/toolkit/crashreporter/breakpad-patches/08-dwarf2reader-dynamic-cas...

213 строки
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 {