zucchini: Swap the order of two declarations.
This allows compilers targeting the MS ABI to select the correct
inheritance model for the member function pointer types ReaderFactory
and WriterFactory using the complete type of Disassembler. It will
allow us to enable the new Clang flag -fcomplete-member-pointers
globally.
Bug: 847724
Change-Id: Iead5fd97da5f67c336d8904a7a305a34df37065b
Reviewed-on: https://chromium-review.googlesource.com/1098470
Commit-Queue: Peter Collingbourne <pcc@chromium.org>
Reviewed-by: Samuel Huang <huangs@chromium.org>
Cr-Commit-Position: refs/heads/master@{#567016}
NOKEYCHECK=True
GitOrigin-RevId: fea64fd2f17f40d572923de0705def0016ad4a9f
diff --git a/disassembler.h b/disassembler.h
index eced3cf..4f528ed 100644
--- a/disassembler.h
+++ b/disassembler.h
@@ -17,7 +17,65 @@
namespace zucchini {
-class Disassembler;
+// Disassembler needs to be declared before ReferenceGroup because the latter
+// contains member pointers based on the former, and we use a compiler flag,
+// -fcomplete-member-pointers, which enforces that member pointer base types are
+// complete. This flag helps prevent us from running into problems in the
+// Microsoft C++ ABI (see https://crbug.com/847724).
+
+class ReferenceGroup;
+
+// A Disassembler is used to encapsulate architecture specific operations, to:
+// - Describe types of references found in the architecture using traits.
+// - Extract references contained in an image file.
+// - Correct target for some references.
+class Disassembler {
+ public:
+ // Attempts to parse |image| and create an architecture-specifc Disassembler,
+ // as determined by DIS, which is inherited from Disassembler. Returns an
+ // instance of DIS if successful, and null otherwise.
+ template <class DIS>
+ static std::unique_ptr<DIS> Make(ConstBufferView image) {
+ auto disasm = std::make_unique<DIS>();
+ if (!disasm->Parse(image))
+ return nullptr;
+ return disasm;
+ }
+
+ virtual ~Disassembler();
+
+ // Returns the type of executable handled by the Disassembler.
+ virtual ExecutableType GetExeType() const = 0;
+
+ // Returns a more detailed description of the executable type.
+ virtual std::string GetExeTypeString() const = 0;
+
+ // Creates and returns a vector that contains all groups of references.
+ // Groups must be aggregated by pool.
+ virtual std::vector<ReferenceGroup> MakeReferenceGroups() const = 0;
+
+ ConstBufferView image() const { return image_; }
+ size_t size() const { return image_.size(); }
+
+ int num_equivalence_iterations() const { return num_equivalence_iterations_; }
+
+ protected:
+ explicit Disassembler(int num_equivalence_iterations);
+
+ // Parses |image| and initializes internal states. Returns true on success.
+ // This must be called once and before any other operation.
+ virtual bool Parse(ConstBufferView image) = 0;
+
+ // Raw image data. After Parse(), a Disassembler should shrink this to contain
+ // only the portion containing the executable file it recognizes.
+ ConstBufferView image_;
+
+ // The number of iterations to run for equivalence map generation. This should
+ // roughly be the max length of reference indirection chains.
+ int num_equivalence_iterations_;
+
+ DISALLOW_COPY_AND_ASSIGN(Disassembler);
+};
// A ReferenceGroup is associated with a specific |type| and has convenience
// methods to obtain readers and writers for that type. A ReferenceGroup does
@@ -82,58 +140,6 @@
WriterFactory writer_factory_ = nullptr;
};
-// A Disassembler is used to encapsulate architecture specific operations, to:
-// - Describe types of references found in the architecture using traits.
-// - Extract references contained in an image file.
-// - Correct target for some references.
-class Disassembler {
- public:
- // Attempts to parse |image| and create an architecture-specifc Disassembler,
- // as determined by DIS, which is inherited from Disassembler. Returns an
- // instance of DIS if successful, and null otherwise.
- template <class DIS>
- static std::unique_ptr<DIS> Make(ConstBufferView image) {
- auto disasm = std::make_unique<DIS>();
- if (!disasm->Parse(image))
- return nullptr;
- return disasm;
- }
-
- virtual ~Disassembler();
-
- // Returns the type of executable handled by the Disassembler.
- virtual ExecutableType GetExeType() const = 0;
-
- // Returns a more detailed description of the executable type.
- virtual std::string GetExeTypeString() const = 0;
-
- // Creates and returns a vector that contains all groups of references.
- // Groups must be aggregated by pool.
- virtual std::vector<ReferenceGroup> MakeReferenceGroups() const = 0;
-
- ConstBufferView image() const { return image_; }
- size_t size() const { return image_.size(); }
-
- int num_equivalence_iterations() const { return num_equivalence_iterations_; }
-
- protected:
- explicit Disassembler(int num_equivalence_iterations);
-
- // Parses |image| and initializes internal states. Returns true on success.
- // This must be called once and before any other operation.
- virtual bool Parse(ConstBufferView image) = 0;
-
- // Raw image data. After Parse(), a Disassembler should shrink this to contain
- // only the portion containing the executable file it recognizes.
- ConstBufferView image_;
-
- // The number of iterations to run for equivalence map generation. This should
- // roughly be the max length of reference indirection chains.
- int num_equivalence_iterations_;
-
- DISALLOW_COPY_AND_ASSIGN(Disassembler);
-};
-
} // namespace zucchini
#endif // COMPONENTS_ZUCCHINI_DISASSEMBLER_H_