From: Nigel Stewart <nstewart@nvidia.com>
Date: Wed, 10 Jul 2013 14:01:01 +0000 (-0500)
Subject: Replace dynamic_cast with virtual functions.
X-Git-Url: https://git.cworth.org/git?a=commitdiff_plain;h=abaef29db0cf1a3e2adb0c254886162368b1645a;p=apitrace

Replace dynamic_cast with virtual functions.

apitrace can be built with without RTTI (runtime type information)
providing that dynamic_cast isn't used.
---

diff --git a/cli/trace_analyzer.cpp b/cli/trace_analyzer.cpp
index 374e6ce..79f9557 100644
--- a/cli/trace_analyzer.cpp
+++ b/cli/trace_analyzer.cpp
@@ -279,7 +279,7 @@ bool
 TraceAnalyzer::recordTextureSideEffects(trace::Call *call, const char *name)
 {
     if (strcmp(name, "glGenTextures") == 0) {
-        const trace::Array *textures = dynamic_cast<const trace::Array *>(&call->arg(1));
+        const trace::Array *textures = call->arg(1).toArray();
         size_t i;
         GLuint texture;
 
diff --git a/common/trace_dump.cpp b/common/trace_dump.cpp
index 655b023..6e67e08 100644
--- a/common/trace_dump.cpp
+++ b/common/trace_dump.cpp
@@ -178,7 +178,7 @@ public:
 
             if (!memberName || !*memberName) {
                 // Anonymous structure
-                Struct *memberStruct = dynamic_cast<Struct *>(memberValue);
+                Struct *memberStruct = memberValue->toStruct();
                 assert(memberStruct);
                 if (memberStruct) {
                     sep = visitMembers(memberStruct, sep);
diff --git a/common/trace_model.cpp b/common/trace_model.cpp
index 2c0fafa..3f19bc6 100644
--- a/common/trace_model.cpp
+++ b/common/trace_model.cpp
@@ -210,7 +210,7 @@ void Visitor::visit(StackFrame *) { assert(0); }
 static Null null;
 
 const Value & Value::operator[](size_t index) const {
-    const Array *array = dynamic_cast<const Array *>(this);
+    const Array *array = toArray();
     if (array) {
         if (index < array->values.size()) {
             return *array->values[index];
diff --git a/common/trace_model.hpp b/common/trace_model.hpp
index 4a9ca47..36f0a03 100644
--- a/common/trace_model.hpp
+++ b/common/trace_model.hpp
@@ -91,6 +91,9 @@ struct BitmaskSig {
 
 
 class Visitor;
+class Null;
+class Struct;
+class Array;
 
 
 class Value
@@ -110,6 +113,15 @@ public:
     virtual unsigned long long toUIntPtr(void) const;
     virtual const char *toString(void) const;
 
+    virtual const Null *toNull(void) const { return NULL; }
+    virtual Null *toNull(void) { return NULL; }
+
+    virtual const Array *toArray(void) const { return NULL; }
+    virtual Array *toArray(void) { return NULL; }
+
+    virtual const Struct *toStruct(void) const { return NULL; }
+    virtual Struct *toStruct(void) { return NULL; }
+
     const Value & operator[](size_t index) const;
 };
 
@@ -127,6 +139,9 @@ public:
     unsigned long long toUIntPtr(void) const;
     const char *toString(void) const;
     void visit(Visitor &visitor);
+
+    const Null *toNull(void) const { return this; }
+    Null *toNull(void) { return this; }
 };
 
 
@@ -266,6 +281,9 @@ public:
     bool toBool(void) const;
     void visit(Visitor &visitor);
 
+    const Struct *toStruct(void) const { return this; }
+    Struct *toStruct(void) { return this; }
+
     const StructSig *sig;
     std::vector<Value *> members;
 };
@@ -280,6 +298,9 @@ public:
     bool toBool(void) const;
     void visit(Visitor &visitor);
 
+    const Array *toArray(void) const { return this; }
+    Array *toArray(void) { return this; }
+
     std::vector<Value *> values;
 
     inline size_t
diff --git a/retrace/glretrace_cgl.cpp b/retrace/glretrace_cgl.cpp
index f0d0e2d..73bb250 100644
--- a/retrace/glretrace_cgl.cpp
+++ b/retrace/glretrace_cgl.cpp
@@ -127,7 +127,7 @@ getContext(unsigned long long ctx) {
 static void retrace_CGLChoosePixelFormat(trace::Call &call) {
     int profile = kCGLOGLPVersion_Legacy;
 
-    const trace::Array * attribs = dynamic_cast<const trace::Array *>(&call.arg(0));
+    const trace::Array * attribs = call.arg(0).toArray();
     if (attribs) {
         size_t i = 0;
         while (i < attribs->values.size()) {
@@ -201,7 +201,7 @@ static void retrace_CGLCreateContext(trace::Call &call) {
     unsigned long long share = call.arg(1).toUIntPtr();
     Context *sharedContext = getContext(share);
 
-    const trace::Array *ctx_ptr = dynamic_cast<const trace::Array *>(&call.arg(2));
+    const trace::Array *ctx_ptr = call.arg(2).toArray();
     unsigned long long ctx = ctx_ptr->values[0]->toUIntPtr();
 
     Context *context = glretrace::createContext(sharedContext);
diff --git a/retrace/glretrace_egl.cpp b/retrace/glretrace_egl.cpp
index 27c5bb8..c03d04c 100644
--- a/retrace/glretrace_egl.cpp
+++ b/retrace/glretrace_egl.cpp
@@ -145,7 +145,7 @@ static void retrace_eglCreateContext(trace::Call &call) {
     unsigned long long orig_context = call.ret->toUIntPtr();
     unsigned long long orig_config = call.arg(1).toUIntPtr();
     Context *share_context = getContext(call.arg(2).toUIntPtr());
-    trace::Array *attrib_array = dynamic_cast<trace::Array *>(&call.arg(3));
+    trace::Array *attrib_array = call.arg(3).toArray();
     glws::Profile profile;
 
     switch (current_api) {
diff --git a/retrace/glretrace_glx.cpp b/retrace/glretrace_glx.cpp
index fe88a59..3179c1e 100644
--- a/retrace/glretrace_glx.cpp
+++ b/retrace/glretrace_glx.cpp
@@ -133,7 +133,7 @@ static void retrace_glXCreateNewContext(trace::Call &call) {
 }
 
 static void retrace_glXCreatePbuffer(trace::Call &call) {
-    const trace::Value *attrib_list = dynamic_cast<const trace::Array *>(&call.arg(2));
+    const trace::Value *attrib_list = call.arg(2).toArray();
     int width = glretrace::parseAttrib(attrib_list, GLX_PBUFFER_WIDTH, 0);
     int height = glretrace::parseAttrib(attrib_list, GLX_PBUFFER_HEIGHT, 0);
 
diff --git a/retrace/glretrace_ws.cpp b/retrace/glretrace_ws.cpp
index ab3c41a..d1e85f8 100644
--- a/retrace/glretrace_ws.cpp
+++ b/retrace/glretrace_ws.cpp
@@ -233,7 +233,7 @@ updateDrawable(int width, int height) {
 
 int
 parseAttrib(const trace::Value *attribs, int param, int default_ = 0) {
-    const trace::Array *attribs_ = dynamic_cast<const trace::Array *>(attribs);
+    const trace::Array *attribs_ = attribs ? attribs->toArray() : NULL;
 
     if (attribs_) {
         for (size_t i = 0; i + 1 < attribs_->values.size(); i += 2) {
diff --git a/retrace/retrace.hpp b/retrace/retrace.hpp
index f37f249..6e6bf13 100644
--- a/retrace/retrace.hpp
+++ b/retrace/retrace.hpp
@@ -63,11 +63,11 @@ public:
      */
     inline void *
     alloc(const trace::Value *value, size_t size) {
-        const trace::Array *array = dynamic_cast<const trace::Array *>(value);
+        const trace::Array *array = value->toArray();
         if (array) {
             return ::ScopedAllocator::alloc(array->size() * size);
         }
-        const trace::Null *null = dynamic_cast<const trace::Null *>(value);
+        const trace::Null *null = value->toNull();
         if (null) {
             return NULL;
         }
diff --git a/retrace/retrace.py b/retrace/retrace.py
index 25fa62a..1cdb092 100644
--- a/retrace/retrace.py
+++ b/retrace/retrace.py
@@ -129,7 +129,7 @@ class ValueDeserializer(stdapi.Visitor, stdapi.ExpanderMixin):
         self.seq += 1
 
         print '    if (%s) {' % (lvalue,)
-        print '        const trace::Array *%s = dynamic_cast<const trace::Array *>(&%s);' % (tmp, rvalue)
+        print '        const trace::Array *%s = (%s).toArray();' % (tmp, rvalue)
         length = '%s->values.size()' % (tmp,)
         index = '_j' + array.tag
         print '        for (size_t {i} = 0; {i} < {length}; ++{i}) {{'.format(i = index, length = length)
@@ -144,7 +144,7 @@ class ValueDeserializer(stdapi.Visitor, stdapi.ExpanderMixin):
         self.seq += 1
 
         print '    if (%s) {' % (lvalue,)
-        print '        const trace::Array *%s = dynamic_cast<const trace::Array *>(&%s);' % (tmp, rvalue)
+        print '        const trace::Array *%s = (%s).toArray();' % (tmp, rvalue)
         try:
             self.visit(pointer.type, '%s[0]' % (lvalue,), '*%s->values[0]' % (tmp,))
         finally:
@@ -190,7 +190,7 @@ class ValueDeserializer(stdapi.Visitor, stdapi.ExpanderMixin):
         tmp = '_s_' + struct.tag + '_' + str(self.seq)
         self.seq += 1
 
-        print '    const trace::Struct *%s = dynamic_cast<const trace::Struct *>(&%s);' % (tmp, rvalue)
+        print '    const trace::Struct *%s = (%s).toStruct();' % (tmp, rvalue)
         print '    assert(%s);' % (tmp)
         for i in range(len(struct.members)):
             member = struct.members[i]
@@ -251,7 +251,7 @@ class SwizzledValueRegistrator(stdapi.Visitor, stdapi.ExpanderMixin):
         pass
 
     def visitArray(self, array, lvalue, rvalue):
-        print '    const trace::Array *_a%s = dynamic_cast<const trace::Array *>(&%s);' % (array.tag, rvalue)
+        print '    const trace::Array *_a%s = (%s).toArray();' % (array.tag, rvalue)
         print '    if (_a%s) {' % (array.tag)
         length = '_a%s->values.size()' % array.tag
         index = '_j' + array.tag
@@ -263,7 +263,7 @@ class SwizzledValueRegistrator(stdapi.Visitor, stdapi.ExpanderMixin):
             print '    }'
     
     def visitPointer(self, pointer, lvalue, rvalue):
-        print '    const trace::Array *_a%s = dynamic_cast<const trace::Array *>(&%s);' % (pointer.tag, rvalue)
+        print '    const trace::Array *_a%s = (%s).toArray();' % (pointer.tag, rvalue)
         print '    if (_a%s) {' % (pointer.tag)
         try:
             self.visit(pointer.type, '%s[0]' % (lvalue,), '*_a%s->values[0]' % (pointer.tag,))
@@ -325,7 +325,7 @@ class SwizzledValueRegistrator(stdapi.Visitor, stdapi.ExpanderMixin):
         tmp = '_s_' + struct.tag + '_' + str(self.seq)
         self.seq += 1
 
-        print '    const trace::Struct *%s = dynamic_cast<const trace::Struct *>(&%s);' % (tmp, rvalue)
+        print '    const trace::Struct *%s = (%s).toStruct();' % (tmp, rvalue)
         print '    assert(%s);' % (tmp,)
         print '    (void)%s;' % (tmp,)
         for i in range(len(struct.members)):