From f8a079ec7147b037b98460930ddc40052774ec90 Mon Sep 17 00:00:00 2001 From: Thomas Brain Date: Thu, 18 Apr 2024 13:47:06 -0500 Subject: [PATCH] write template directive before template instance (#1679) * Rework swig template declarations to be written before used in the containing class so that private methods are honored * Fix SIM_test_ip for swig 4.2.0 and implemented review suggestions * Additional review comment fixes --------- Co-authored-by: Thomas Brain --- libexec/trick/convert_swig | 73 +++++++++++++------ .../models/test_ip/include/Namespace_tests.hh | 6 +- 2 files changed, 56 insertions(+), 23 deletions(-) diff --git a/libexec/trick/convert_swig b/libexec/trick/convert_swig index c43f4d40..27296bdb 100755 --- a/libexec/trick/convert_swig +++ b/libexec/trick/convert_swig @@ -590,18 +590,19 @@ sub process_class($$$$$) { my ($class_name) ; my $template_typedefs ; - ## Extract the class_name from the class_string $class_string =~ /^(?:class|struct)\s+ # keyword class or struct ([_A-Za-z]\w*) # class name \s*[\{\:]$ /sx or die "Internal error" ; $class_name = $1 ; - $$new_contents_ref .= $class_string ; + + my $class_content; + $class_content .= $class_string ; if ( $class_string !~ /\{$/ ) { $$contents_ref =~ s/^(.*?\s*\{)//s ; - $$new_contents_ref .= $1 ; + $class_content .= $1 ; } ($extracted, $$contents_ref) = extract_bracketed( "{" . $$contents_ref , "{}") ; @@ -614,10 +615,21 @@ sub process_class($$$$$) { #print "*** extracted = $extracted ***\n" ; #print "*** contents = $$contents_ref ***\n" ; + my $save_namespace_content; + + if ( $curr_namespace ne "" ) { + my @split_namespaces = split "::", $curr_namespace; + my $sanitized_namespace = $split_namespaces[-1] ; + my @namespace_split = split /namespace\s*$sanitized_namespace/, $$new_contents_ref; + $save_namespace_content = 'namespace ' . $sanitized_namespace . $namespace_split[-1]; + $$new_contents_ref = join('namespace ' . $sanitized_namespace, $namespace_split[0 .. $#namespace_split-1]); + } # SWIG doesn't like "const static". Change it to "static const" $extracted =~ s/const\s+static/static const/g ; + my $isSwigExcludeBlock = 0; + # templated variables need to be declared with the SWIG %template directive. # This loop looks for any templated variables and creates the %template lines. while ( $extracted =~ s/^(.*?)(?:($template_var_def))//sx ) { @@ -626,7 +638,17 @@ sub process_class($$$$$) { if ( $non_var ne "" ) { #print "*** non_var = $non_var ***\n" ; - $$new_contents_ref .= $non_var ; + $class_content .= $non_var ; + my $ifndefSwig = $non_var; + if ($isSwigExcludeBlock == 0) { + if ($ifndefSwig =~ /(?:ifndef\s*SWIG|if\s*!\s*defined\s*\(\s*SWIG\s*\))/ ) { + $isSwigExcludeBlock = 1; + } + } else { + if ($ifndefSwig =~ /endif/ ) { + $isSwigExcludeBlock = 1; + } + } } if ( $template_var_def_str ne "" ) { @@ -635,7 +657,6 @@ sub process_class($$$$$) { $template_var_def_str =~ /(.*?>)\s*([_A-Za-z]\w*).*?;/s ; my ($template_full_type) = $1 ; my ($var_name) = $2 ; - $$new_contents_ref .= $template_var_def_str ; $template_full_type =~ /([_A-Za-z][:\w]*)\s* 0x040000\n\%pythoncode \%{\n __setattr__ = _swig_setattr_nondynamic_instance_variable(object.__setattr__)\n\%}\n#endif\n" ; - $$new_contents_ref .= $extracted . ";\n" ; - # write out the templated variable declaration lines found in this class. - $$new_contents_ref .= $template_typedefs ; + $class_content .= "\n#if SWIG_VERSION > 0x040000\n\%pythoncode \%{\n __setattr__ = _swig_setattr_nondynamic_instance_variable(object.__setattr__)\n\%}\n#endif\n" ; + $class_content .= $extracted . ";\n" ; my $c_ = "$curr_namespace$class_name" ; $c_ =~ s/\:/_/g ; # Add a #define line that signals that this class has been processed by swig. Classes excluded in #if 0 blocks will # not have this #define defined. - $$new_contents_ref .= "#define TRICK_SWIG_DEFINED_$c_" ; + $class_content .= "#define TRICK_SWIG_DEFINED_$c_" ; + if ( $save_namespace_content ne "" ) { + $$new_contents_ref .= $save_namespace_content; + } + $$new_contents_ref .= $class_content; } ## ================================================================================ diff --git a/test/SIM_test_ip/models/test_ip/include/Namespace_tests.hh b/test/SIM_test_ip/models/test_ip/include/Namespace_tests.hh index 9977fcd8..a765b809 100644 --- a/test/SIM_test_ip/models/test_ip/include/Namespace_tests.hh +++ b/test/SIM_test_ip/models/test_ip/include/Namespace_tests.hh @@ -54,8 +54,12 @@ namespace NS2 { class B { public : //TODO: in the clang based convert_swig, we can use NS1 without the leading :: - //NS1::A< int > m ; + //Since swig 4.2.0, leading :: causes error. +#if SWIG_VERSION >= 0x040200 + NS1::A< int > m ; +#else ::NS1::A< int > m ; +#endif } ; } #endif