mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-08-04 13:13:25 +03:00
0026936: Drawbacks of inlining in new type system in OCCT 7.0 -- manual
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.
This commit is contained in:
138
adm/upgrade.tcl
138
adm/upgrade.tcl
@@ -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
|
||||
|
67
adm/upgrade_sample_orig.dat
Normal file
67
adm/upgrade_sample_orig.dat
Normal file
@@ -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();
|
||||
|
Reference in New Issue
Block a user