# HG changeset patch # User Ted Mielczarek # Date 1362600444 18000 # Node ID 0eb3c7ba8a38a269ab975eff3f95a1a5d5d937b9 # Parent 6b68e82037b8322fb392cea369d517aeeaaee9d3 Stop using dynamic_cast in dwarf2reader Patch by Julian Seward , 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(&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(&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(&rhs); - return (our_rhs && - base_register_ == our_rhs->base_register_ && + if (rhs.getTag() != CFIR_OFFSET_RULE) return false; + const OffsetRule *our_rhs = static_cast(&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(&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(&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(&rhs); - return (our_rhs && register_number_ == our_rhs->register_number_); + if (rhs.getTag() != CFIR_REGISTER_RULE) return false; + const RegisterRule *our_rhs = static_cast(&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(&rhs); - return (our_rhs && expression_ == our_rhs->expression_); + if (rhs.getTag() != CFIR_EXPRESSION_RULE) return false; + const ExpressionRule *our_rhs = static_cast(&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(&rhs); - return (our_rhs && expression_ == our_rhs->expression_); + static_cast(&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 {