0026936: Drawbacks of inlining in new type system in OCCT 7.0 -- manual
authorabv <abv@opencascade.com>
Mon, 30 Nov 2015 04:49:48 +0000 (07:49 +0300)
committerabv <abv@opencascade.com>
Fri, 4 Dec 2015 10:57:58 +0000 (13:57 +0300)
Restored possibility to have out-of-line implementation of DynamicCast() and STANDART_TYPE():
- Macro STANDARD_TYPE() now resolves to function get_type_descriptor() of the class
- Macro DEFINE_STANDARD_RTTI is replaced by two variants:
  - DEFINE_STANDARD_RTTI_INLINE works as before, defining DynamicCast() and get_type_descriptor() as inline functions
  - DEFINE_STANDARD_RTTIEXT declares DynamicCast() and get_type_descriptor() as exported
- Macro IMPLEMENT_STANDARD_RTTIEXT provides definition of DynamicCast() and get_type_descriptor() for a class

Upgrade script amended to replace DEFINE_STANDARD_RTTI by pair of DEFINE_STANDARD_RTTIEXT / IMPLEMENT_STANDARD_RTTIEXT if source file with the same name as header is found in the same folder, and by DEFINE_STANDARD_RTTI_INLINE if either source is not found or class is defined in the source (i.e. not in header)

Upgrade tool improved to recognize include statements with path prefix, like #include <occt/gp_Pnt.hxx>
Code corrected to eliminate warnings reported by upgrade tool.
Template of CXX file for testing upgrade tool added.

Documentation of upgrade procedure updated.

23 files changed:
adm/upgrade.tcl
adm/upgrade_sample_orig.dat [new file with mode: 0644]
dox/dev_guides/upgrade/upgrade.md
src/Cocoa/Cocoa_Window.hxx
src/Cocoa/Cocoa_Window.mm
src/Geom/Geom_OffsetCurve.cxx
src/Geom2d/Geom2d_OffsetCurve.cxx
src/Image/Image_AlienPixMap.cxx
src/MAT2d/MAT2d_Circuit.cxx
src/OpenGl/OpenGl_Context.cxx
src/QANCollection/QANCollection_Handle.cxx
src/Standard/Standard_DefineHandle.hxx
src/Standard/Standard_Transient.cxx
src/Standard/Standard_Transient.hxx
src/Standard/Standard_Type.cxx
src/Standard/Standard_Type.hxx
src/StepDimTol/StepDimTol_RunoutZoneDefinition.cxx
src/StepDimTol/StepDimTol_RunoutZoneDefinition.hxx
src/TDF/TDF_ClosureTool.cxx
src/TDF/TDF_CopyTool.cxx
src/WNT/WNT_Window.cxx
src/XmlMXCAFDoc/XmlMXCAFDoc_LocationDriver.cxx
src/Xw/Xw_Window.cxx

index 204fca6..6193e64 100644 (file)
@@ -477,6 +477,77 @@ proc ConvertTColFwd {thePackagePath theHeaderExtensions} {
   }
 }
 
+# try to find source file corresponding to the specified header and either
+# inject macro IMPLEMENT_STANDARD_RTTIEXT in it, or check it already present,
+# and depending on this, return suffix to be used for corresponding macro
+# DEFINE_STANDARD_RTTI... (either inline or out-of-line variant)
+proc DefineExplicitRtti {hxxfile class base theSourceExtensions} {
+  # if current file is not a header (by extension), exit with "inline" variant
+  # (there is no need to bother with out-of-line instantiations for local class)
+  set ext [string range [file extension $hxxfile] 1 end]
+  if { [lsearch -exact [split $theSourceExtensions ,] $ext] >=0 } {
+    return "_INLINE"
+  }
+
+  # try to find source file with the same name but source-type extension 
+  # in the same folder
+  set filename [file rootname $hxxfile]
+  foreach ext [split $theSourceExtensions ,] {
+#    puts "Checking ${filename}.$ext"
+    if { ! [file readable ${filename}.$ext] } { continue }
+
+    # check the file content
+    set aFileContent [ReadFileToList ${filename}.$ext aFileRawContent aEOL]
+
+    # try to find existing macro IMPLEMENT_STANDARD_RTTIEXT and check that 
+    # it is consistent
+    foreach line $aFileContent {
+      if { [regexp "^\\s*IMPLEMENT_STANDARD_RTTIEXT\\s*\\(\\s*$class\\s*,\\s*(\[A-Za-z0-9_\]+)\\s*\\)" $line res impl_base] } {
+        # implementation is in place, just report warning if second argument
+        # is different
+        if { $base != $impl_base } {
+          logwarn "Warning in ${filename}.$ext: second argument of macro"
+          logwarn "        IMPLEMENT_STANDARD_RTTIEXT($class,$impl_base)"
+          logwarn "        is not the same as detected base class, $base"
+        }
+        return "EXT"
+      }
+    }
+
+    # inject a new macro before the first non-empty, non-comment, and 
+    # non-preprocessor line
+    set aNewFileContent {}
+    set injected 0
+    set inc_found 0
+    foreach line $aFileContent {
+      if { ! $injected } {
+        # add macro before first non-empty line after #includes
+        if { [regexp {^\s*$} $line] } {
+        } elseif { [regexp {^\s*\#\s*include} $line] } {
+          set inc_found 1
+        } elseif { $inc_found } {
+          set injected 1
+          lappend aNewFileContent "IMPLEMENT_STANDARD_RTTIEXT($class,$base)"
+          if { ! [regexp "^IMPLEMENT_" $line] } {
+            lappend aNewFileContent ""
+          }
+        }
+      }
+      lappend aNewFileContent $line
+    }
+    if { ! $injected } {
+      lappend aNewFileContent "IMPLEMENT_STANDARD_RTTIEXT($class,$base)"
+    }
+    SaveListToFile ${filename}.$ext $aNewFileContent $aEOL
+
+    return "EXT"
+  }
+
+  logwarn "Warning in ${hxxfile}: cannot find corresponding source file,"
+  logwarn "           will use inline version of DEFINE_STANDARD_RTTI"
+  return "_INLINE"
+}
+
 # Parse source files and:
 #
 # - add second argument to macro DEFINE_STANDARD_RTTI specifying first base 
@@ -521,13 +592,14 @@ proc ConvertRtti {theProcessedPath theIncPaths theCheckMode theCompatibleMode \
 
     # find all instances of DEFINE_STANDARD_RTTI with single or two arguments
     set index 0
-    set pattern_rtti {^(\s*DEFINE_STANDARD_RTTI\s*)\(\s*([A-Za-z_0-9,\s]+)\s*\)}
+    set pattern_rtti {^(\s*DEFINE_STANDARD_RTTI)([_A-Z]+)?\s*\(\s*([A-Za-z_0-9,\s]+)\s*\)}
     while { [regexp -start $index -indices -lineanchor $pattern_rtti \
-                    $aProcessedFileContent location start clist] } {
+                    $aProcessedFileContent location start suffix clist] } {
       set index [lindex $location 1]
 
-      set start [eval string range \$aProcessedFileContent $start]
-      set clist [split [eval string range \$aProcessedFileContent $clist] ,]
+      set start  [eval string range \$aProcessedFileContent $start]
+      set suffix [eval string range \$aProcessedFileContent $suffix]
+      set clist  [split [eval string range \$aProcessedFileContent $clist] ,]
 
       if { [llength $clist] == 1 } {
         set class [string trim [lindex $clist 0]]
@@ -538,7 +610,8 @@ proc ConvertRtti {theProcessedPath theIncPaths theCheckMode theCompatibleMode \
               logwarn "macro DEFINE_STANDARD_RTTI is changed assuming it inherits $inherits($class), please check!"
             }
             set change_flag 1
-            ReplaceSubString aProcessedFileContent $location "${start}($class, $inherits($class))" index
+            ReplaceSubString aProcessedFileContent $location \
+                             "${start}EXT($class,$inherits($class))" index
           }
         } else {
           logwarn "Error in $aProcessedFile: Macro DEFINE_STANDARD_RTTI used for class $class whose declaration is not found in this file, cannot fix"
@@ -548,12 +621,19 @@ proc ConvertRtti {theProcessedPath theIncPaths theCheckMode theCompatibleMode \
         set base  [string trim [lindex $clist 1]]
         if { ! [info exists inherits($class)] } {
           logwarn "Warning in $aProcessedFile: Macro DEFINE_STANDARD_RTTI used for class $class whose declaration is not found in this file"
-        } elseif { $base != $inherits($class) } {
+        } elseif { $base != $inherits($class) && ! [info exists inherits($class,multiple)] } {
           logwarn "Warning in $aProcessedFile: Second argument in macro DEFINE_STANDARD_RTTI for class $class is $base while $class seems to inherit from $inherits($class)"
-          if { ! $theCheckMode && ! [info exists inherits($class,multiple)] } {
-            set change_flag 1
-            ReplaceSubString aProcessedFileContent $location "${start}($class, $inherits($class))" index
-          }
+        }
+        # convert intermediate version of macro DEFINE_STANDARD_RTTI
+        # with two arguments to either _INLINE or EXT variant
+        if { ! $theCheckMode && "$suffix" == "" } {
+          set change_flag 1
+          # try to inject macro IMPLEMENT_STANDARD_RTTIEXT in the 
+          # corresponding source file (or check it already present),
+          # and depending on this, use either inline or out-of-line variant
+          set rtti_suffix [DefineExplicitRtti $aProcessedFile $class $base $theSourceExtensions]
+          ReplaceSubString aProcessedFileContent $location \
+                           "${start}${rtti_suffix}($class,$base)" index
         }
       }
     }
@@ -578,8 +658,12 @@ proc ConvertRtti {theProcessedPath theIncPaths theCheckMode theCompatibleMode \
       set index 0
       set first_newline \n\n
       set pattern_implement {\\?\n\s*IMPLEMENT_(DOWNCAST|STANDARD_[A-Z_]+|HARRAY1|HARRAY2|HUBTREE|HEBTREE|HSEQUENCE)\s*\([A-Za-z0-9_ ,]*\)\s*;?}
-      while { [regexp -start $index -indices -lineanchor $pattern_implement $aProcessedFileContent location] } {
+      while { [regexp -start $index -indices -lineanchor $pattern_implement $aProcessedFileContent location macro] } {
         set index [lindex $location 1]
+        # macro IMPLEMENT_STANDARD_RTTIEXT is retained
+        if { [eval string range \$aProcessedFileContent $macro] == "STANDARD_RTTIEXT" } {
+          continue
+        }
         if { ! $theCheckMode } {
           set change_flag 1
           ReplaceSubString aProcessedFileContent $location $first_newline index
@@ -594,7 +678,7 @@ proc ConvertRtti {theProcessedPath theIncPaths theCheckMode theCompatibleMode \
 
     # find all uses of macro STANDARD_TYPE and method DownCast and ensure that
     # argument class is explicitly included
-    set pattern_incbeg {\s*#\s*include\s*[\"<]\s*}
+    set pattern_incbeg {\s*#\s*include\s*[\"<]\s*([A-Za-z0-9_/]*/)?}
     set pattern_incend {[.][a-zA-Z]+\s*[\">]}
     set index 0
     set addtype {}
@@ -622,7 +706,9 @@ proc ConvertRtti {theProcessedPath theIncPaths theCheckMode theCompatibleMode \
       if { ! $theCheckMode } {
         set addinc ""
         foreach type $addtype {
-          append addinc "\n#include <$type.hxx>"
+          if { "$aProcessedFileName" != "$type.hxx" } {
+            append addinc "\n#include <$type.hxx>"
+          }
         }
         if { [regexp -indices ".*\n${pattern_incbeg}\[A-Za-z0-9_/\]+${pattern_incend}" $aProcessedFileContent location] } {
           set change_flag 1
@@ -649,6 +735,7 @@ proc ConvertHandle {theTargetPath theIncPaths theCheckMode theExtensions} {
 
   # iterate by header files
   foreach aHeader [glob -nocomplain -type f -directory $theTargetPath *.{$theExtensions}] {
+    set aCurrentHeaderName [file tail $aHeader]
 
     # skip gxx files, as names Handle_xxx used there are in most cases 
     # placeholders of the argument types substituted by #define
@@ -682,8 +769,9 @@ proc ConvertHandle {theTargetPath theIncPaths theCheckMode theExtensions} {
       set anUpdatedHeaderContent {}    
       set pattern_handle {\mHandle_([A-Za-z0-9_]+)}
       foreach line $aHeaderContent {
-        # do not touch #include and #if... statements
-        if { [regexp {\s*\#\s*include} $line] || [regexp {\s*\#\s*if} $line] } {
+        # do not touch typedefs, #include, and #if... statements
+        if { [regexp {^\s*typedef} $line] || 
+             [regexp {^\s*\#\s*include} $line] || [regexp {^\s*\#\s*if} $line] } {
           lappend anUpdatedHeaderContent $line
           continue
         }
@@ -763,8 +851,8 @@ proc ConvertHandle {theTargetPath theIncPaths theCheckMode theExtensions} {
         } else {
           # replace by forward declaration of a class or its include unless 
           # it is already declared or included
-          if { ! [regexp "^\s*\#\s*include\s*\[\<\"\]\s*$aForwardDeclHandledClass\s*\[\>\"\]" $aHeaderContent] } {
-            if { $isQObject } {
+          if { ! [regexp "\#\\s*include\\s*\[\<\"\]\\s*(\[A-Za-z0-9_/\]*/)?$aForwardDeclHandledClass\[.\]hxx\\s*\[\>\"\]" $aHeaderContent] } {
+            if { $isQObject && "$aCurrentHeaderName" != "${aForwardDeclHandledClass}.hxx" } {
               lappend anUpdatedHeaderContent "#include <${aForwardDeclHandledClass}.hxx>"
               if { ! [SearchForFile $theIncPaths ${aForwardDeclHandledClass}.hxx] } {
                 loginfo "Warning: include ${aForwardDeclHandledClass}.hxx added in $aHeader, assuming it exists and defines Handle_$aForwardDeclHandledClass"
@@ -946,7 +1034,10 @@ proc ConvertCStyleHandleCast {pkpath theExtensions theCheckMode} {
     while { [regexp -start $index -indices -lineanchor $pattern_refcast0 $hxx location class var] } {
       set index [lindex $location 1]
 
-      logwarn "Warning in $afile: C-style cast: [eval string range \$hxx $location]"
+      set var   [eval string range \$hxx $var]
+      if { "$var" != "const" && "$var" != "Standard_OVERRIDE" } {
+        logwarn "Warning in $afile: C-style cast: [eval string range \$hxx $location]"
+      }
     }
 
     # replace const Handle(A)& a = Handle(B)::DownCast (b); by 
@@ -1081,10 +1172,11 @@ proc ReadFileToList {theFilePath theFileContent theFileEOL} {
     regsub -all {$aFileEOL} $aFileContent "\n" aFileContent
   }
 
-  set aList {}
-  foreach aLine [split $aFileContent "\n"] {
-    lappend aList [string trimright $aLine]
-  }
+  set aList [split $aFileContent "\n"]
+#  set aList {}
+#  foreach aLine [split $aFileContent "\n"] {
+#    lappend aList [string trimright $aLine]
+#  }
 
   return $aList
 }
@@ -1154,6 +1246,8 @@ proc SaveListToFile {theFilePath theData {theEOL "auto"}} {
   fconfigure $aFile -translation binary
   puts -nonewline $aFile [join $theData $anUsedEol]
   close $aFile
+
+  loginfo "File $theFilePath modified"
 }
 
 # collect all subdirs of theBaseDir
diff --git a/adm/upgrade_sample_orig.dat b/adm/upgrade_sample_orig.dat
new file mode 100644 (file)
index 0000000..96683c7
--- /dev/null
@@ -0,0 +1,67 @@
+// This is sample C++ file intended for testing and verifyig automatic upgrade 
+// script. Copy it with extension .cxx and apply upgrade procedure to see
+// the result, as follows:
+// > upgrade.bat -src=./adm -inc=./src -recurse -all
+
+// Include of Geom_Line.hxx and Geom_Plane.hxx should be added below
+#include <gp.hxx>
+
+//========================================================================
+// OCCT 7.0
+//========================================================================
+
+//------------------------------------------------------------------------
+// Option -rtti
+//------------------------------------------------------------------------
+
+// Should be replaced by <Standard_Type.hxx>
+#include <Standard_DefineHandle.hxx>
+
+class A_0
+{
+}
+
+class B_1 : 
+public A_0
+{
+  // second argument "A_0" should be added
+  DEFINE_STANDARD_RTTI(B_1)
+};
+
+class C_2 : public Standard_Transient, B_1
+{
+  // second argument "Standard_Transient" should be added
+  DEFINE_STANDARD_RTTI(C_2)
+};
+
+void for_rtti ()
+{
+  Handle(Geom_Curve) aCurve = new Geom_Line (gp::Origin(), gp::DZ());
+  Handle(Geom_Line) aLine = Handle(Geom_Line)::DownCast (aCurve);
+}
+
+// should be removed
+IMPLEMENT_DOWNCAST(A)
+IMPLEMENT_STANDARD_RTTIEXT(A, B)
+
+//------------------------------------------------------------------------
+// Option -fwd
+//------------------------------------------------------------------------
+
+// force safe mode used for Qt objects
+Q_OBJECT
+slots:
+
+// these includes should be recognized as corresponding to forward declarations 
+#include <occt/TColStd_HArray1OfReal.hxx>
+
+// these declarations should be just removed
+class Handle(TColStd_HArray1OfReal);
+
+// should be replaced by include of corresponding header
+class TColStd_Array1OfReal;
+class Handle(Geom_Curve);
+
+// check that trailing spaces at the following line are preserved
+void ff();       
+
index b54c907..518c3f1 100644 (file)
@@ -86,7 +86,7 @@ Alternative solution is to use legacy generator of project files (extracted from
 
 @subsubsection upgrade_occt700_cdl_auto Automatic upgrade
 
-Most of typical changes required for upgrading code to use OCCT 7.0 can be done automatically using the *upgrade* tool included in OCCT 7.0.
+Most of typical changes required for upgrading code for OCCT 7.0 can be done automatically using the *upgrade* tool included in OCCT 7.0.
 This tool is a Tcl script, thus Tcl should be available on your workstation to run it.
 
 Example:
@@ -106,11 +106,16 @@ Run upgrade tool without arguments to see the list of available options.
 
 Upgrade tool performs the following changes in the code.
 
-1. Adds second argument to macro DEFINE_STANDARD_RTTI indicating base class for its argument class (if inheritance is recognized by the script):
+1. Replaces macro DEFINE_STANDARD_RTTI by DEFINE_STANDARD_RTTIEXT, with second argument indicating base class for the main argument class (if inheritance is recognized by the script):
 ~~~~~
-DEFINE_STANDARD_RTTI(Class) -> DEFINE_STANDARD_RTTI(Class, Base)
+DEFINE_STANDARD_RTTI(Class) -> DEFINE_STANDARD_RTTIEXT(Class, Base)
 ~~~~~
 
+   @note If macro DEFINE_STANDARD_RTTI with two arguments (used in intermediate development versions of OCCT 7.0) is found, the script will convert it to either DEFINE_STANDARD_RTTIEXT or DEFINE_STANDARD_RTTI_INLINE. 
+   The former case is used if current file is header and source file with the same name is found in the same folder. 
+   In this case, macro IMPLEMENT_STANDARD_RTTI is injected in the corresponding source file.
+   The latter variant defines all methods for RTTI as inline, and does not require IMPLEMENT_STANDARD_RTTIEXT macro. 
+
 2. Replaces forward declarations of collection classes previously generated from CDL generics (defined in TCollection package) by \#include of corresponding header:
 ~~~~~
 class TColStd_Array1OfReal; -> #include <TColStd_Array1OfReal.hxx>
@@ -159,9 +164,11 @@ Namespace::Handle(Class) -> Handle(Namespace::Class)
 
 10. Adds \#include for all classes used as argument to macro STANDARD_TYPE(), except of already included ones;
 
-11. Removes uses of obsolete macros IMPLEMENT_DOWNCAST() and IMPLEMENT_STANDARD_*().
+11. Removes uses of obsolete macros IMPLEMENT_DOWNCAST and IMPLEMENT_STANDARD_*, except IMPLEMENT_STANDARD_RTTIEXT.
+
+    @note If you plan to keep compatibility of your code with older versions of OCCT, add option "-compat" to avoid the latter change. See also @ref upgrade_occt700_cdl_compat.
 
-  > If you plan to keep compatibility of your code with older versions of OCCT, add option "-compat" to avoid the latter change. See also @ref upgrade_occt700_cdl_compat.
+.
 
 As long as the upgrade routine runs, some information messages are sent to the standard output. 
 In some cases the warnings or errors like the following may appear:
@@ -171,7 +178,7 @@ In some cases the warnings or errors like the following may appear:
 ~~~~~
 
 Be sure to check carefully all reported errors and warnings, as corresponding places likely will require manual corrections.
-In some cases these messages may help you to detect errors in your code, for instance, cases where DEFINE_STANDARD_RTTI macro passes invalid class name as an argument.
+In some cases these messages may help you to detect errors in your code, for instance, cases where DEFINE_STANDARD_RTTI macro is used with incorrect class name as an argument.
 
 @subsubsection upgrade_occt700_cdl_compiler Possible compiler errors
 
@@ -323,16 +330,17 @@ aBC->Transform (T); // access violation in OCCT 7.0
 
 If you like to preserve compatibility of your application code with OCCT versions 6.x even after upgrade to 7.0, consider the following suggestions:
 
-1. When running automatic upgrade tool, add option *-compat*.
+1. If your code used sequences of macros IMPLEMENT_STANDARD_... generated by WOK, replace them by single macro IMPLEMENT_STANDARD_RTTIEXT
+
+2. When running automatic upgrade tool, add option *-compat*.
 
-2. In order to overcome incompatibility of macro DEFINE_STANDARD_RTTI which has additional argument in OCCT 7.0, you can replace (after upgrade) its use in your code by your own version-dependent macro, which resolves to either 6.x or 7.x version.
+3. Define macros DEFINE_STANDARD_RTTIEXT and DEFINE_STANDARD_RTTI_INLINE when building with previous versions of OCCT, resolving to DEFINE_STANDARD_RTTI with single argument 
 
    Example:
 ~~~~~   
 #if OCC_VERSION_HEX < 0x070000
-  #define DEFINE_STANDARD_RTTI_COMPAT(C1,C2) DEFINE_STANDARD_RTTI(C1) 
-#else
-  #define DEFINE_STANDARD_RTTI_COMPAT(C1,C2) DEFINE_STANDARD_RTTI(C1,C2) 
+  #define DEFINE_STANDARD_RTTIEXT(C1,C2) DEFINE_STANDARD_RTTI(C1)
+  #define DEFINE_STANDARD_RTTI_INLINE(C1,C2) DEFINE_STANDARD_RTTI(C1)
 #endif
 ~~~~~
 
index 0ee8da4..1793597 100644 (file)
@@ -158,7 +158,7 @@ protected:
 
 public:
 
-  DEFINE_STANDARD_RTTI(Cocoa_Window, Aspect_Window)
+  DEFINE_STANDARD_RTTIEXT(Cocoa_Window,Aspect_Window)
 
 };
 
index 902db3d..168857e 100644 (file)
@@ -29,6 +29,8 @@
 #include <Aspect_Convert.hxx>
 #include <Aspect_WindowDefinitionError.hxx>
 
+IMPLEMENT_STANDARD_RTTIEXT(Cocoa_Window,Aspect_Window)
+
 #if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
   //
 #else
index 1b1e507..4b3a0ae 100644 (file)
@@ -43,6 +43,7 @@
 #include <Standard_RangeError.hxx>
 #include <Standard_Type.hxx>
 
+IMPLEMENT_STANDARD_RTTIEXT(Geom_OffsetCurve,Geom_Curve)
 
 static const Standard_Real MyAngularToleranceForG1 = Precision::Angular();
 
index fb47b71..0f323a9 100644 (file)
@@ -41,6 +41,7 @@
 #include <Standard_RangeError.hxx>
 #include <Standard_Type.hxx>
 
+IMPLEMENT_STANDARD_RTTIEXT(Geom2d_OffsetCurve,Geom2d_Curve)
 
 static const Standard_Real MyAngularToleranceForG1 = Precision::Angular();
 
index 04e7e04..68a525c 100644 (file)
@@ -31,6 +31,8 @@
 #include <fstream>
 #include <algorithm>
 
+IMPLEMENT_STANDARD_RTTIEXT(Image_AlienPixMap,Image_PixMap)
+
 #ifdef HAVE_FREEIMAGE
 namespace
 {
index 60287e1..f420762 100644 (file)
 // Alternatively, this file may be used under the terms of Open CASCADE
 // commercial license or contractual agreement.
 
-#ifdef DRAW
-#include <Draw_Appli.hxx>
-#include <DrawTrSurf_Curve2d.hxx>
-#include <Draw_Marker2D.hxx>
-#endif
-#ifdef OCCT_DEBUG
-#include <GCE2d_MakeSegment.hxx>
-#include <Geom2d_Curve.hxx>
-#include <Geom2d_Parabola.hxx>
-#include <Geom2d_Hyperbola.hxx>
-#include <Geom2d_TrimmedCurve.hxx>
-#include <Geom2d_CartesianPoint.hxx>
-#include <Geom2d_Line.hxx>
-#include <Geom2d_Circle.hxx>
-#endif
-
-
 #include <Adaptor2d_OffsetCurve.hxx>
 #include <Geom2d_CartesianPoint.hxx>
 #include <Geom2d_Geometry.hxx>
 #include <TColStd_Array1OfInteger.hxx>
 #include <TColStd_SequenceOfInteger.hxx>
 
+IMPLEMENT_STANDARD_RTTIEXT(MAT2d_Circuit,MMgt_TShared)
+
+#ifdef OCCT_DEBUG
+#include <GCE2d_MakeSegment.hxx>
+#include <Geom2d_Curve.hxx>
+#include <Geom2d_Parabola.hxx>
+#include <Geom2d_Hyperbola.hxx>
+#include <Geom2d_TrimmedCurve.hxx>
+#include <Geom2d_CartesianPoint.hxx>
+#include <Geom2d_Line.hxx>
+#include <Geom2d_Circle.hxx>
+#endif
+
 #ifdef DRAW
+#include <Draw_Appli.hxx>
+#include <DrawTrSurf_Curve2d.hxx>
+#include <Draw_Marker2D.hxx>
   static Handle(DrawTrSurf_Curve2d) draw;
   Standard_EXPORT Draw_Viewer dout;
 #endif
index 06f4d18..8e8a0af 100644 (file)
@@ -37,6 +37,8 @@
 
 #include <Standard_ProgramError.hxx>
 
+IMPLEMENT_STANDARD_RTTIEXT(OpenGl_Context,Standard_Transient)
+
 #if defined(HAVE_EGL)
   #include <EGL/egl.h>
   #ifdef _MSC_VER
index 907b97c..4ccfd25 100644 (file)
@@ -240,7 +240,7 @@ public:
   virtual const char* Name() const { return "Transient_Root"; }
   virtual Standard_Transient* CreateParent() const { return new Standard_Transient; }
   virtual Standard_Transient* Clone()        const { return new Transient_Root; }
-  DEFINE_STANDARD_RTTI(Transient_Root, Standard_Transient)
+  DEFINE_STANDARD_RTTI_INLINE(Transient_Root,Standard_Transient)
 };
 DEFINE_STANDARD_HANDLE(Transient_Root, Standard_Transient)
 
@@ -252,11 +252,9 @@ public:\
   virtual const char* Name() const Standard_OVERRIDE { return #theClass; } \
   virtual Standard_Transient* CreateParent() const Standard_OVERRIDE { return new theParent(); } \
   virtual Standard_Transient* Clone()        const Standard_OVERRIDE { return new theClass(); } \
-  DEFINE_STANDARD_RTTI(theClass, theParent) \
+  DEFINE_STANDARD_RTTI_INLINE(theClass,theParent) \
 };\
-DEFINE_STANDARD_HANDLE    (theClass, theParent) \
-IMPLEMENT_STANDARD_HANDLE (theClass, theParent) \
-IMPLEMENT_STANDARD_RTTIEXT(theClass, theParent)
+DEFINE_STANDARD_HANDLE    (theClass, theParent) 
 
 #define QA_NAME(theNum) qaclass ## theNum ## _ ## 50
 #define QA_HANDLE_NAME(theNum) Handle(qaclass ## theNum ## _ ## 50)
index c33381a..f03415c 100644 (file)
@@ -36,6 +36,5 @@ class Standard_Type;
 #define IMPLEMENT_STANDARD_SUPERTYPE_ARRAY()
 #define IMPLEMENT_STANDARD_SUPERTYPE_ARRAY_END()
 #define IMPLEMENT_STANDARD_TYPE_END(C1)
-#define IMPLEMENT_STANDARD_RTTIEXT(C1,C2)
 
 #endif
index e209c78..561069f 100644 (file)
@@ -23,11 +23,16 @@ void Standard_Transient::Delete() const
   delete this;
 }
 
+const Handle(Standard_Type)& Standard_Transient::get_type_descriptor ()
+{
+  return opencascade::type_instance<Standard_Transient>::get();
+}
+
 //
 //
 const Handle(Standard_Type)& Standard_Transient::DynamicType() const
 {
-  return opencascade::type_instance<Standard_Transient>::get();
+  return get_type_descriptor();
 }
 
 //
index e4ead07..cd47cd1 100644 (file)
@@ -58,7 +58,10 @@ public:
 
   static const char* get_type_name () { return "Standard_Transient"; }
 
-  //! Returns a type information object about this object.
+  //! Returns type descriptor of Standard_Transient class
+  Standard_EXPORT static const opencascade::handle<Standard_Type>& get_type_descriptor ();
+
+  //! Returns a type descriptor about this object.
   Standard_EXPORT virtual const opencascade::handle<Standard_Type>& DynamicType() const;
 
   //! Returns a true value if this is an instance of Type.
index c7ac3cd..06f6ac3 100644 (file)
@@ -19,6 +19,8 @@
 
 #include <NCollection_DataMap.hxx>
 
+IMPLEMENT_STANDARD_RTTIEXT(Standard_Type,Standard_Transient)
+
 //============================================================================
 
 Standard_Boolean Standard_Type::SubType (const Handle(Standard_Type)& theOther) const
index d36234a..283d0a6 100644 (file)
 #include <typeinfo>
 
 //! Helper macro to get instance of a type descriptor for a class in a legacy way.
-#define STANDARD_TYPE(theType) Standard_Type::Instance<theType>()
+#define STANDARD_TYPE(theType) theType::get_type_descriptor()
 
 //! Helper macro to be included in definition of the classes inheriting
-//! Standard_Transient to enable use of OCCT RTTI and smart pointers (handles).
-#define DEFINE_STANDARD_RTTI(Class,Base) \
+//! Standard_Transient to enable use of OCCT RTTI.
+//!
+//! Inline version, does not require IMPLEMENT_STANDARD_RTTIEXT, but when used
+//! for big hierarchies of classes may cause considerable increase of size of binaries.
+#define DEFINE_STANDARD_RTTI_INLINE(Class,Base) \
 public: \
   typedef Base base_type; \
   static const char* get_type_name () { return #Class; } \
+  static const Handle(Standard_Type)& get_type_descriptor () { return Standard_Type::Instance<Class>(); } \
   virtual const Handle(Standard_Type)& DynamicType() const Standard_OVERRIDE \
   { return STANDARD_TYPE(Class); }
 
+//! Helper macro to be included in definition of the classes inheriting
+//! Standard_Transient to enable use of OCCT RTTI.
+//!
+//! Out-of-line version, requires IMPLEMENT_STANDARD_RTTIEXT.
+#define DEFINE_STANDARD_RTTIEXT(Class,Base) \
+public: \
+  typedef Base base_type; \
+  static const char* get_type_name () { return #Class; } \
+  Standard_EXPORT static const Handle(Standard_Type)& get_type_descriptor (); \
+  Standard_EXPORT virtual const Handle(Standard_Type)& DynamicType() const Standard_OVERRIDE;
+
+//! Defines implementation of type descriptor and DynamicType() function
+#define IMPLEMENT_STANDARD_RTTIEXT(Class,Base) \
+  const Handle(Standard_Type)& Class::get_type_descriptor () { return Standard_Type::Instance<Class>(); } \
+  const Handle(Standard_Type)& Class::DynamicType() const { return get_type_descriptor(); }
+
 // forward declaration of type_instance class
 namespace opencascade {
   template <typename T>
@@ -117,7 +137,7 @@ public:
   Standard_EXPORT ~Standard_Type ();
 
   // Define own RTTI
-  DEFINE_STANDARD_RTTI(Standard_Type, Standard_Transient)
+  DEFINE_STANDARD_RTTIEXT(Standard_Type,Standard_Transient)
 
 private:
 
index 7fcb8d7..fa0fe34 100644 (file)
@@ -18,6 +18,8 @@
 #include <StepRepr_HArray1OfShapeAspect.hxx>
 #include <StepDimTol_RunoutZoneOrientation.hxx>
 
+IMPLEMENT_STANDARD_RTTIEXT(StepDimTol_RunoutZoneDefinition,StepDimTol_ToleranceZoneDefinition)
+
 //=======================================================================
 //function : StepDimTol_RunoutZoneDefinition
 //purpose  : 
index 4587d73..ad917e2 100644 (file)
@@ -27,6 +27,7 @@ class StepRepr_HArray1OfShapeAspect;
 
 class StepDimTol_RunoutZoneDefinition;
 DEFINE_STANDARD_HANDLE(StepDimTol_RunoutZoneDefinition, StepDimTol_ToleranceZoneDefinition)
+
 //! Representation of STEP entity ToleranceZoneDefinition
 class StepDimTol_RunoutZoneDefinition : public StepDimTol_ToleranceZoneDefinition
 {
@@ -53,7 +54,7 @@ public:
     myOrientation = theOrientation;
   }
   
-  DEFINE_STANDARD_RTTI(StepDimTol_ToleranceZoneDefinition, StepDimTol_ToleranceZoneDefinition)
+  DEFINE_STANDARD_RTTIEXT(StepDimTol_RunoutZoneDefinition,StepDimTol_ToleranceZoneDefinition)
 
 private: 
   Handle(StepDimTol_RunoutZoneOrientation) myOrientation;
index 1891409..a6377c7 100644 (file)
 #include <TDF_MapIteratorOfAttributeMap.hxx>
 #include <TDF_MapIteratorOfLabelMap.hxx>
 
-//#include <TDF_Reference.hxx>
-#define DeclareAndSpeedCast(V,T,Vdown) Handle(T) Vdown = Handle(T)::DownCast (V)
-#define DeclareConstAndSpeedCast(V,T,Vdown) const Handle(T)& Vdown = (Handle(T)&) V
-#define SpeedCast(V,T,Vdown) Vdown = Handle(T)::DownCast (V)
-
-
 //=======================================================================
 //function : Closure
 //purpose  : Builds the transitive closure whithout attribute filter.
index 4cf853b..295fcc6 100644 (file)
 #include <TDF_MapIteratorOfLabelMap.hxx>
 #include <TDF_RelocationTable.hxx>
 
-#define DeclareAndSpeedCast(V,T,Vdown) Handle(T) Vdown = Handle(T)::DownCast (V)
-#define DeclareConstAndSpeedCast(V,T,Vdown) const Handle(T)& Vdown = (Handle(T)&) V
-#define SpeedCast(V,T,Vdown) Vdown = Handle(T)::DownCast (V)
-
-
 //=======================================================================
 //function : Copy
 //purpose  : 
index 0a415f7..7f8b076 100644 (file)
@@ -25,6 +25,9 @@
 #include <WNT_Window.hxx>
 
 #include <stdio.h>
+
+IMPLEMENT_STANDARD_RTTIEXT(WNT_Window,Aspect_Window)
+
 // =======================================================================
 // function : WNT_Window
 // purpose  :
index 3d0d895..e819f72 100644 (file)
@@ -29,6 +29,7 @@
 #include <XmlObjMgt_GP.hxx>
 #include <XmlObjMgt_Persistent.hxx>
 
+IMPLEMENT_STANDARD_RTTIEXT(XmlMXCAFDoc_LocationDriver,XmlMDF_ADriver)
 IMPLEMENT_DOMSTRING (DatumString,    "datum")
 IMPLEMENT_DOMSTRING (LocationString, "location")
 IMPLEMENT_DOMSTRING (PowerString,    "power")
@@ -176,7 +177,7 @@ Standard_Boolean XmlMXCAFDoc_LocationDriver::Translate
       Standard_Integer aDatumID;
       aLocElem.getAttribute (::DatumString()).GetInteger (aDatumID);
       if (aDatumID > 0 && theMap.IsBound (aDatumID))
-        aDatum = (Handle(TopLoc_Datum3D)&) theMap.Find (aDatumID);
+        aDatum = Handle(TopLoc_Datum3D)::DownCast (theMap.Find (aDatumID));
       else
         return Standard_False;
     }else{
index 39b9a28..48e1965 100644 (file)
@@ -22,6 +22,8 @@
 
 #include <GL/glx.h>
 
+IMPLEMENT_STANDARD_RTTIEXT(Xw_Window,Aspect_Window)
+
 namespace
 {