Issue 501 (#505)

* Fixed #501 (more Qt ownership management) - this commit contains some more changes because I had to regenerate the Qt binding sources.

* Fixed #501 (Qt object ownership transfer) - repairs, added tests

* Updated Jenkinsfile to not publish a PR build

* Update Jenkinsfile - exclude PR's from build
This commit is contained in:
Matthias Köfferlein
2020-02-21 18:25:22 +01:00
committed by GitHub
parent 161068c70a
commit 69e7704430
17 changed files with 252 additions and 23 deletions
+3 -3
View File
@@ -170,7 +170,7 @@ if [ $update != 0 ]; then
if [ $reuse == 0 ]; then
for d in Qt*; do
for d in $qt_mods; do
echo "--------------------------------------------------------"
echo "Parsing $d ..."
@@ -181,7 +181,7 @@ if [ $update != 0 ]; then
echo "Running gcc preprocessor .."
# By using -D_GCC_LIMITS_H_ we make the gcc not include constants such as ULONG_MAX which will
# remain as such. This way the generated code is more generic.
gcc -I$qt -fPIC -D_GCC_LIMITS_H_ -E -o allofqt.x allofqt.cpp
gcc -std=gnu++98 -I$qt -fPIC -D_GCC_LIMITS_H_ -E -o allofqt.x allofqt.cpp
echo "Stripping hash lines .."
egrep -v '^#' <allofqt.x >allofqt.e
@@ -225,7 +225,7 @@ else
cd $work_dir
fi
for d in Qt*; do
for d in $qt_mods; do
echo "--------------------------------------------------------"
echo "Processing $d ..."
+7
View File
@@ -482,6 +482,10 @@ drop_method "QClipboardEvent", /QClipboardEvent::data/
drop_method "QClipboardEvent", /QClipboardEvent::QClipboardEvent\(QEventPrivate/
drop_method "QCursor", /QCursor::QCursor\s*\(\s*Qt::HANDLE/ # not available on WIN
drop_method "QApplication", /QApplication::compressEvent/ # QPostEventList is missing
drop_method "QApplication", /QApplication::commitDataRequest/ # Signal with a out argument (QSessionManager &)
drop_method "QApplication", /QApplication::saveStateRequest/ # Signal with a out argument (QSessionManager &)
drop_method "QApplication", /QApplication::saveState\s*\(/ # QSessionManager is not always available
drop_method "QApplication", /QApplication::commitData\s*\(/ # QSessionManager is not always available
drop_method "QWidget", /QWidget::painters/ # whatever that is, it's not a method ..
drop_method "QWidget", /QWidget::handle/ # not available on WIN
drop_method "QPixmap", /QPixmap::handle/ # not available on WIN
@@ -597,6 +601,7 @@ rename "QIcon", /QIcon::pixmap\(int\s+extent/, "pixmap_ext"
rename "QKeySequence", /QKeySequence::QKeySequence\(QKeySequence::StandardKey/, "new_std"
keep_arg "QBoxLayout", /::addLayout/, 0 # will take ownership of layout
keep_arg "QGridLayout", /::addLayout/, 0 # will take ownership of layout
keep_arg "QWidget", /::setLayout\s*\(/, 0 # will take ownership of layout
keep_arg "QLayout", /::addChildLayout/, 0 # will take ownership of layout
keep_arg "QLayout", /::addItem/, 0 # will take ownership of item
keep_arg "QTreeWidgetItem", /::addChild\(/, 0 # will take ownership of the child
@@ -618,6 +623,8 @@ keep_arg "QGraphicsScene", /::addItem\(/, 0 # will take ownership of the item
owner_arg "QTreeWidgetItem", /::QTreeWidgetItem\(QTreeWidgetItem\s+\*/, 0 # will construct a new object owned by arg #0
owner_arg "QTreeWidgetItem", /::QTreeWidgetItem\(QTreeWidget\s+\*/, 0 # will construct a new object owned by arg #0
owner_arg "QListWidgetItem", /::QListWidgetItem\(QListWidget\s+\*/, 0 # will construct a new object owned by arg #0
owner_arg "QObject", /::setParent\(QObject\s+\*/, 0 # will make self owned by arg #0
owner_arg "QWidget", /::setParent\(QWidget\s+\*/, 0 # will make self owned by arg #0
# this would make sense, but the pointer is const: so how can setItemPrototype take
# over ownership of it?
# keep_arg "QTableWidget", /::setItemPrototype\(/, 0 # will take ownership of the child
+3
View File
@@ -713,6 +713,7 @@ rename "QIcon", /QIcon::pixmap\(int\s+extent/, "pixmap_ext"
rename "QKeySequence", /QKeySequence::QKeySequence\(QKeySequence::StandardKey/, "new_std"
keep_arg "QBoxLayout", /::addLayout/, 0 # will take ownership of layout
keep_arg "QGridLayout", /::addLayout/, 0 # will take ownership of layout
keep_arg "QWidget", /::setLayout\s*\(/, 0 # will take ownership of layout
keep_arg "QLayout", /::addChildLayout/, 0 # will take ownership of layout
keep_arg "QLayout", /::addItem/, 0 # will take ownership of item
keep_arg "QTreeWidgetItem", /::addChild\(/, 0 # will take ownership of the child
@@ -734,6 +735,8 @@ keep_arg "QGraphicsScene", /::addItem\(/, 0 # will take ownership of the item
owner_arg "QTreeWidgetItem", /::QTreeWidgetItem\(QTreeWidgetItem\s+\*/, 0 # will construct a new object owned by arg #0
owner_arg "QTreeWidgetItem", /::QTreeWidgetItem\(QTreeWidget\s+\*/, 0 # will construct a new object owned by arg #0
owner_arg "QListWidgetItem", /::QListWidgetItem\(QListWidget\s+\*/, 0 # will construct a new object owned by arg #0
owner_arg "QObject", /::setParent\(QObject\s+\*/, 0 # will make self owned by arg #0
owner_arg "QWidget", /::setParent\(QWidget\s+\*/, 0 # will make self owned by arg #0
# this would make sense, but the pointer is const: so how can setItemPrototype take
# over ownership of it?
# keep_arg "QTableWidget", /::setItemPrototype\(/, 0 # will take ownership of the child
+39 -13
View File
@@ -50,7 +50,7 @@ grammar CPP
end
rule a
s ( "__attribute__" s attribute_value s / "__asm" s attribute_value s / "__extension__" s )*
s ( "__attribute__" s attribute_value s / "__asm" s attribute_value s / "__extension__" s / "decltype" s attribute_value s )*
end
rule unary_op
@@ -110,11 +110,11 @@ grammar CPP
end
rule bool_type
"bool" <PBoolType>
"bool" ![a-zA-Z0-9_] <PBoolType>
end
rule void_type
"void" <PVoidType>
"void" ![a-zA-Z0-9_] <PVoidType>
end
rule float_type
@@ -134,12 +134,20 @@ grammar CPP
end
rule virtual_spec
"virtual" <PVirtual>
"virtual" ![a-zA-Z0-9_] <PVirtual>
end
rule explicit_key
"explicit" ![a-zA-Z0-9_]
end
rule mutable_key
"mutable" ![a-zA-Z0-9_]
end
rule member_declaration_wo_semicolon
template:( d:template_decl s )?
attr:( ( "explicit" / "mutable" / storage_class / inline_spec / virtual_spec ) s )*
attr:( ( explicit_key / mutable_key / storage_class / inline_spec / virtual_spec / constexpr_key ) s )*
t:type
# type declaration ends with a } .. does not need a semicolon
# (i.e. nested struct or enum)
@@ -155,7 +163,7 @@ grammar CPP
rule member_declaration_w_semicolon
template:( d:template_decl s )?
attr:( ( "explicit" / "mutable" / storage_class / inline_spec / virtual_spec ) s )*
attr:( ( explicit_key / mutable_key / storage_class / inline_spec / virtual_spec / constexpr_key ) s )*
t:type
# opposite case (member_see declaration_wo_semicolon)
# (i.e. nested struct or enum)
@@ -214,11 +222,11 @@ grammar CPP
end
rule concrete_type
( class_or_struct_type / enum_type / float_type / char_type / int_type / bool_type / void_type / typeof / class_id )?
( constexpr_key / class_or_struct_type / enum_type / float_type / char_type / int_type / bool_type / void_type / typeof / class_id )?
end
rule cv
( "const" ![a-zA-Z0-9_] / "__const" ![a-zA-Z0-9_] / "volatile" ![a-zA-Z0-9_] / "__volatile" ![a-zA-Z0-9_] ) <PCV>
( constexpr_key / "const" ![a-zA-Z0-9_] / "__const" ![a-zA-Z0-9_] / "volatile" ![a-zA-Z0-9_] / "__volatile" ![a-zA-Z0-9_] ) <PCV>
end
rule pointer
@@ -247,8 +255,12 @@ grammar CPP
ellipsis
end
rule noexcept_spec
"noexcept" ( s "=" s block / s "(" s block ")" )?
end
rule func_spec
"(" s fa:( a:func_args )? s ")" cvspec:( s cv:cv )? ( s "throw" s "(" s ( type_wo_comma s )? ")" )* a <PFuncSpec>
"(" s fa:( a:func_args )? s ")" cvspec:( s cv:cv )? ( s "throw" s "(" s ( type_wo_comma s )? ")" / s noexcept_spec )* ( s override_key )? a <PFuncSpec>
end
rule member_pointer
@@ -308,6 +320,14 @@ grammar CPP
( "static" ![a-zA-Z0-9_] / "extern" ![a-zA-Z0-9_] ( s '"C"' / s '"C++"' / s '"Pascal"' )? ) <PStorageClass>
end
rule override_key
"override" ![a-zA-Z0-9_]
end
rule constexpr_key
"constexpr" ![a-zA-Z0-9_]
end
rule inline_spec
"inline" ![a-zA-Z0-9_] <PInline>
end
@@ -346,6 +366,10 @@ grammar CPP
"using" ![a-zA-Z0-9_] ( s "namespace" )? ![a-zA-Z0-9_] s id:qualified_id a ";" <PUsing>
end
rule static_assert
"static_assert" s "(" s block s ")"
end
rule typedef
a "typedef" ![a-zA-Z0-9_] s t:type a ";" <PTypedef>
end
@@ -362,8 +386,9 @@ grammar CPP
rule declaration_w_semicolon
template:( d:template_decl s )?
template_member:( d_member:template_decl s )?
attr:( ( storage_class / inline_spec ) s )*
attr:( ( storage_class / inline_spec / constexpr_key ) s )*
a
( constexpr_key s )?
t:type
# type declaration ends with a } .. does not need a semicolon
# (i.e. nested struct or enum)
@@ -378,8 +403,9 @@ grammar CPP
rule declaration_wo_semicolon
template:( d:template_decl s )?
attr:( ( storage_class / inline_spec ) s )*
attr:( ( storage_class / inline_spec / constexpr_key ) s )*
a
( constexpr_key s )?
t:type
# opposite case (see declaration_wo_semicolon)
# (i.e. nested struct or enum)
@@ -398,7 +424,7 @@ grammar CPP
rule namespace
"namespace" ![a-zA-Z0-9_] s n:id
a "{" decls:( a ( ";" / using / typedef / namespace / declaration ) )* s "}" <PNamespace>
a "{" decls:( a ( ";" / static_assert / using / typedef / namespace / declaration ) )* s "}" <PNamespace>
end
rule extern_decl
@@ -407,7 +433,7 @@ grammar CPP
end
rule module
( a ( ";" / using / typedef / namespace / extern_decl / declaration ) )* s <PModule>
( a ( ";" / static_assert / using / typedef / namespace / extern_decl / declaration ) )* s <PModule>
end
end
+14 -5
View File
@@ -1669,6 +1669,18 @@ END
end
def produce_keep_self(ofile, alist, obj, owner_args = [])
owner_args.each do |a|
ofile.puts(" if (#{alist[a]}) {");
ofile.puts(" qt_gsi::qt_keep (#{obj});")
ofile.puts(" } else {");
ofile.puts(" qt_gsi::qt_release (#{obj});")
ofile.puts(" }");
end
end
def produce_arg_read(ofile, decl_obj, func, alist, kept_args = [])
n_args = func.max_args
@@ -2005,6 +2017,7 @@ END
ofile.puts("{")
ofile.puts(" __SUPPRESS_UNUSED_WARNING(args);")
produce_arg_read(ofile, decl_obj, func, alist, conf.kept_args(bd))
produce_keep_self(ofile, alist, "(#{cls} *)cls", conf.owner_args(bd))
if !rt.is_void?
ofile.puts(" ret.write<#{rt.gsi_decl_return(decl_obj)} > ((#{rt.gsi_decl_return(decl_obj)})" + rt.access_gsi_return(decl_obj, "((#{cls} *)cls)->#{mid} (#{qt_alist.join(', ')})") + ");")
else
@@ -2615,11 +2628,7 @@ END
produce_arg_read(ofile, decl_obj, func, alist, conf.kept_args(bd))
if conf.owner_args(bd).size > 0
ofile.puts(" #{clsn}_Adaptor *obj = new #{clsn}_Adaptor (#{qt_alist.join(', ')});")
conf.owner_args(bd).each do |a|
ofile.puts(" if (#{alist[a]}) {");
ofile.puts(" qt_gsi::qt_keep (obj);")
ofile.puts(" }");
end
produce_keep_self(ofile, alist, "obj", conf.owner_args(bd))
ofile.puts(" ret.write<#{clsn}_Adaptor *> (obj);")
else
ofile.puts(" ret.write<#{clsn}_Adaptor *> (new #{clsn}_Adaptor (#{qt_alist.join(', ')}));")