Merge branch 'qt6'

This commit is contained in:
Matthias Koefferlein
2022-01-06 21:48:02 +01:00
2334 changed files with 759796 additions and 59323 deletions
+71 -37
View File
@@ -49,8 +49,35 @@ grammar CPP
"(" ( s ( "," s )? attribute_value )* s ")" / numeric_const / string_const / id
end
rule ignored_attr
"__attribute__" s attribute_value /
"__asm" s attribute_value /
"constexpr" ![a-zA-Z0-9_] /
"__extension__" /
"__inline" /
"__m64" /
"__m128" /
"__m128d" /
"__m128i" /
"__m256" /
"__m256d" /
"__m256i" /
"__m512" /
"__m512d" /
"__m512i" /
"__mmask8" /
"__mmask16" /
"__v8df" /
"__v8di" /
"__v16sf" /
"__v16si" /
"decltype" s attribute_value /
"alignas" s "(" s block s ")" /
"[[" s block s "]]"
end
rule a
s ( "__attribute__" s attribute_value s / "__asm" s attribute_value s / "__extension__" s / "decltype" s attribute_value s )*
s ( ignored_attr s )*
end
rule unary_op
@@ -70,7 +97,7 @@ grammar CPP
rule id
"operator" s "," /
"operator" s ( bin_op / unary_op / "," ) /
"operator" sp [a-zA-Z\*\& \t\n\r]+ &( s "(" ) /
"operator" sp [a-zA-Z_0-9\*\& \t\n\r]+ &( s "(" ) /
"~"? [a-zA-Z_] [a-zA-Z_0-9]*
end
@@ -122,15 +149,15 @@ grammar CPP
end
rule enum_spec
id:id initspec:( s "=" s init:block_wo_comma )? <PEnumSpec>
a id:id a initspec:( s "=" s init:block_wo_comma )? <PEnumSpec>
end
rule enum_body
enum_spec ( s "," s enum_spec )*
enum_spec ( s "," s enum_spec )* ","?
end
rule enum_type
"enum" ![a-zA-Z0-9_] a s id:id? bodyspec:( s "{" s body:enum_body s "}" )? <PEnumType>
"enum" ![a-zA-Z0-9_] a is_class:(s "class" )? s id:id? ( s ":" s type )? bodyspec:( s "{" s body:enum_body s "}" )? <PEnumType>
end
rule virtual_spec
@@ -147,13 +174,14 @@ grammar CPP
rule member_declaration_wo_semicolon
template:( d:template_decl s )?
attr:( ( explicit_key / mutable_key / storage_class / inline_spec / virtual_spec / constexpr_key ) s )*
attr:( ( explicit_key / mutable_key / storage_class / inline_spec / virtual_spec / ignored_attr ) s )*
t:type
# type declaration ends with a } .. does not need a semicolon
# (i.e. nested struct or enum)
&{ |seq| seq[-1].text_value_ends_with_curly_brace }
s
( ":" s block_wo_curly_braces s )?
( trailing_return_type )?
a
(
"{" s block s "}" /
@@ -163,13 +191,14 @@ grammar CPP
rule member_declaration_w_semicolon
template:( d:template_decl s )?
attr:( ( explicit_key / mutable_key / storage_class / inline_spec / virtual_spec / constexpr_key ) s )*
attr:( ( explicit_key / mutable_key / storage_class / inline_spec / virtual_spec / ignored_attr ) s )*
t:type
# opposite case (member_see declaration_wo_semicolon)
# (i.e. nested struct or enum)
!{ |seq| seq[-1].text_value_ends_with_curly_brace }
s
( ":" s block_wo_curly_braces s )?
( trailing_return_type )?
a
(
"{" s block s "}" /
@@ -186,7 +215,7 @@ grammar CPP
end
rule class_struct_body_declarations
( s ";" / s friend_decl / s using / s typedef / s !( "public" / "private" / "protected" ) member_declaration )*
( s ";" / s static_assert / s friend_decl / s using / s typedef / s !( "public" / "private" / "protected" ) member_declaration )*
end
rule class_struct_body
@@ -201,8 +230,8 @@ grammar CPP
rule class_id
# In order to easily distinguish between constructor methods without
# a return type and class or typedef names we assume that all "name("
# constructs are considered constructor names but "name (*func_ptr) ()" is not.
qualified_id s !( "(" !( s "*" ) )
# constructs are considered constructor names but "name (*func_ptr) ()" or "name (class::*method_ptr) ()" is not.
qualified_id s ( "..." s )? !( "(" !( s "*" / s qualified_id s "::*" ) )
end
rule typeof
@@ -222,11 +251,11 @@ grammar CPP
end
rule concrete_type
( constexpr_key / class_or_struct_type / enum_type / float_type / char_type / int_type / bool_type / void_type / typeof / class_id )?
( class_or_struct_type / enum_type / float_type / char_type / int_type / bool_type / void_type / typeof / class_id )?
end
rule cv
( constexpr_key / "const" ![a-zA-Z0-9_] / "__const" ![a-zA-Z0-9_] / "volatile" ![a-zA-Z0-9_] / "__volatile" ![a-zA-Z0-9_] ) <PCV>
( "const" ![a-zA-Z0-9_] / "__const" ![a-zA-Z0-9_] / "volatile" ![a-zA-Z0-9_] / "__volatile" ![a-zA-Z0-9_] ) <PCV>
end
rule pointer
@@ -256,15 +285,15 @@ grammar CPP
end
rule noexcept_spec
"noexcept" ( s "=" s block / s "(" s block ")" )?
"noexcept" ( s "(" s block s ")" )?
end
rule func_spec
"(" 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>
"(" s fa:( a:func_args )? s ")" cvspec:( s cv:cv )? refspec:( s ref:( "&" !"&" / "&&" ) )? ( s "throw" s "(" s ( type_wo_comma s )? ")" / s noexcept_spec / s override_key )* a <PFuncSpec>
end
rule member_pointer
cspec:( qid:qualified_id s "::*" s ) itspec:( it:inner_type )? cvspec:( s cv:cv )? <PMemberPointer>
cspec:( qid:qualified_id s "::*" s ) itspec:( it:inner_type )? cvspec:( s cv:cv )? refspec:( s ref:( "&" !"&" / "&&" ) )? <PMemberPointer>
end
rule inner_type_with_cv
@@ -278,21 +307,25 @@ grammar CPP
pointer /
reference /
member_pointer /
( "__restrict" ![a-zA-Z0-9_] s )? qualified_id
( "__restrict" ![a-zA-Z0-9_] s / "..." s )* qualified_id
)
pfx:( s spec:( array_spec / func_spec ) )*
<PInnerType>
end
rule init_spec
block_wo_comma / "default" / "delete" / "0"
end
rule type
cvspec:( cv:cv s )?
a
( "typename" ![a-zA-Z0-9_] s )?
ct:concrete_type
a
il:( s t1:inner_type i1:(s "=" s is1:block_wo_comma)? tt:( s "," s t2:inner_type i2:(s "=" s is2:block_wo_comma)? )* )?
il:( s t1:inner_type i1:(s "=" s is1:init_spec)? tt:( s "," s t2:inner_type i2:(s "=" s is2:init_spec)? )* )?
# alternative initialization if only a concrete type is given:
pi:( s "=" s is:block_wo_comma )?
pi:( s "=" s is:init_spec )?
<PType>
end
@@ -301,16 +334,16 @@ grammar CPP
a
( "typename" ![a-zA-Z0-9_] s )?
ct:concrete_type
il:( s t:inner_type i:(s "=" s is:block_wo_comma)? )?
il:( s t:inner_type i:(s "=" s is:init_spec)? )?
# alternative initialization if only a concrete type is given:
pi:( s "=" s is:block_wo_comma )?
pi:( s "=" s is:init_spec )?
<PTypeWoComma>
end
rule type_for_template
cvspec:( cv:cv s )?
a
( "typename" ![a-zA-Z0-9_] s )?
( ( "typename" / "class" ) ![a-zA-Z0-9_] s ( "..." s )? )?
ct:concrete_type
il:( s t:inner_type )?
<PTypeForTemplate>
@@ -324,19 +357,15 @@ grammar CPP
"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
# parse over blocks as gracefully as possible ...
rule block_atom_wo_gt
"(" s block s ")" / "[" s block s "]" / "<" s block_wo_gt ( s "," s block_wo_gt )* s ">" /
"(" s block s ")" / "[" s block s "]" / "<" !"=" s block_wo_gt ( s "," s block_wo_gt )* s ">" /
numeric_const / hex_const / string_const / char_const /
id / unary_op / bin_op_wo_gt / "?" / "::" / "." / ":" / ";"
id ( s "{" s block s "}" )? / unary_op / bin_op_wo_gt / "?" / "::" / "." / ":" / ";"
end
rule block_wo_gt
@@ -347,7 +376,7 @@ grammar CPP
rule block_atom
"(" s block s ")" / "[" s block s "]" / "<" s block_wo_gt ( s "," s block_wo_gt )* s ">" /
numeric_const / hex_const / string_const / char_const /
id / unary_op / bin_op / "?" / "::" / "." / ":"
id ( s "{" s block s "}" )? / unary_op / bin_op / "?" / "::" / "." / ":"
end
rule block
@@ -375,25 +404,27 @@ grammar CPP
end
rule template_decl_arg
( "class" / "typename" ) ![a-zA-Z0-9_] s id:id dtspec:( s "=" s dt:type_for_template )? <PClassTemplateArg> /
t:type_for_template initspec:( s "=" s init:block_wo_gt )? <PDirectTemplateArg>
t:type_for_template dtspec:( s "=" s dt:block_wo_gt )? <PClassTemplateArg>
end
rule template_decl
"template" s "<" s ( !">" template_decl_arg s ( "," s template_decl_arg )* )? s ">" <PTemplateDecl>
end
rule trailing_return_type
"->" s ( "decltype" s "(" s block s ")" / type )
end
rule declaration_w_semicolon
template:( d:template_decl s )?
template_member:( d_member:template_decl s )?
attr:( ( storage_class / inline_spec / constexpr_key ) s )*
a
( constexpr_key s )?
attr:( ( storage_class / inline_spec / ignored_attr ) s )*
t:type
# type declaration ends with a } .. does not need a semicolon
# (i.e. nested struct or enum)
!{ |seq| seq[-1].text_value_ends_with_curly_brace }
s ( ":" s block_wo_curly_braces s )?
( trailing_return_type )?
a
(
"{" s block s "}" /
@@ -403,14 +434,13 @@ grammar CPP
rule declaration_wo_semicolon
template:( d:template_decl s )?
attr:( ( storage_class / inline_spec / constexpr_key ) s )*
a
( constexpr_key s )?
attr:( ( storage_class / inline_spec / ignored_attr ) s )*
t:type
# opposite case (see declaration_wo_semicolon)
# (i.e. nested struct or enum)
&{ |seq| seq[-1].text_value_ends_with_curly_brace }
s ( ":" s block_wo_curly_braces s )?
( trailing_return_type )?
a
(
"{" s block s "}" /
@@ -432,8 +462,12 @@ grammar CPP
a "{" decls:( a ( ";" / typedef / namespace / extern_decl / declaration ) )* s "}" <PExternBlock>
end
rule asm
"asm" s "(" s block s ")"
end
rule module
( a ( ";" / static_assert / using / typedef / namespace / extern_decl / declaration ) )* s <PModule>
( a ( ";" / static_assert / using / typedef / namespace / extern_decl / declaration / asm ) )* s <PModule>
end
end
+41 -34
View File
@@ -122,10 +122,17 @@ def add_native_impl_QPersistentQModelIndex
# alternative implementation for QPersistentQModelIndex::operator const QModelIndex &
add_native_impl("QPersistentModelIndex", <<'CODE', <<'DECL')
#if QT_VERSION < 0x60000
static const QModelIndex &castToQModelIndex(const QPersistentModelIndex *m)
{
return m->operator const QModelIndex &();
}
#else
static QModelIndex castToQModelIndex(const QPersistentModelIndex *m)
{
return m->operator QModelIndex();
}
#endif
CODE
gsi::method_ext("castToQModelIndex", &castToQModelIndex, "@brief Binding for \"operator const QModelIndex &\".")
DECL
@@ -215,25 +222,25 @@ def add_native_impl_streams
return v;
}
static qt_gsi::Converter<class QChar>::target_type f_QDataStream_read_qchar(QDataStream *s)
static qt_gsi::Converter<QChar>::target_type f_QDataStream_read_qchar(QDataStream *s)
{
QChar v = 0;
QChar v = QChar (0);
*s >> v;
return qt_gsi::Converter<class QChar>::toc (v);
return qt_gsi::Converter<QChar>::toc (v);
}
static qt_gsi::Converter<class QList<int> >::target_type f_QDataStream_read_int_list(QDataStream *s)
static qt_gsi::Converter<QList<int> >::target_type f_QDataStream_read_int_list(QDataStream *s)
{
QList<int> v;
*s >> v;
return qt_gsi::Converter<class QList<int> >::toc (v);
return qt_gsi::Converter<QList<int> >::toc (v);
}
static qt_gsi::Converter<class QVector<int> >::target_type f_QDataStream_read_int_vector(QDataStream *s)
static qt_gsi::Converter<QVector<int> >::target_type f_QDataStream_read_int_vector(QDataStream *s)
{
QVector<int> v;
*s >> v;
return qt_gsi::Converter<class QVector<int> >::toc (v);
return qt_gsi::Converter<QVector<int> >::toc (v);
}
static QString f_QDataStream_read_string(QDataStream *s)
@@ -316,21 +323,21 @@ def add_native_impl_streams
return s;
}
static QDataStream *f_QDataStream_put_qchar(QDataStream *s, const qt_gsi::Converter<class QChar>::target_type &v)
static QDataStream *f_QDataStream_put_qchar(QDataStream *s, const qt_gsi::Converter<QChar>::target_type &v)
{
*s << qt_gsi::Converter<class QChar>::toq (v);
*s << qt_gsi::Converter<QChar>::toq (v);
return s;
}
static QDataStream *f_QDataStream_put_int_list(QDataStream *s, const qt_gsi::Converter<class QList<int> >::target_type &v)
static QDataStream *f_QDataStream_put_int_list(QDataStream *s, const qt_gsi::Converter<QList<int> >::target_type &v)
{
*s << qt_gsi::Converter<class QList<int> >::toq (v);
*s << qt_gsi::Converter<QList<int> >::toq (v);
return s;
}
static QDataStream *f_QDataStream_put_int_vector(QDataStream *s, const qt_gsi::Converter<class QVector<int> >::target_type &v)
static QDataStream *f_QDataStream_put_int_vector(QDataStream *s, const qt_gsi::Converter<QVector<int> >::target_type &v)
{
*s << qt_gsi::Converter<class QVector<int> >::toq (v);
*s << qt_gsi::Converter<QVector<int> >::toq (v);
return s;
}
@@ -441,7 +448,7 @@ add_native_impl("QTextStream", <<'CODE', <<'DECL')
static qt_gsi::Converter<QChar>::target_type f_QTextStream_read_qchar(QTextStream *s)
{
QChar v = 0;
QChar v = QChar (0);
*s >> v;
return qt_gsi::Converter<QChar>::toc (v);
}
@@ -617,52 +624,52 @@ def add_native_impl_polygons
static void f_QPolygon_clear (QPolygon *m)
{
return m->clear();
m->clear();
}
static void f_QPolygon_remove (QPolygon *m, int i)
{
return m->remove (i);
m->remove (i);
}
static void f_QPolygon_insert (QPolygon *m, int i, const QPoint &p)
{
return m->insert (i, p);
m->insert (i, p);
}
static void f_QPolygon_replace (QPolygon *m, int i, const QPoint &p)
{
return m->replace (i, p);
m->replace (i, p);
}
static void f_QPolygon_pop_front (QPolygon *m)
{
return m->pop_front ();
m->pop_front ();
}
static void f_QPolygon_pop_back (QPolygon *m)
{
return m->pop_back ();
m->pop_back ();
}
static void f_QPolygon_push_front (QPolygon *m, const QPoint &p)
{
return m->push_front (p);
m->push_front (p);
}
static void f_QPolygon_push_back (QPolygon *m, const QPoint &p)
{
return m->push_back (p);
m->push_back (p);
}
static void f_QPolygon_reserve (QPolygon *m, int n)
{
return m->reserve (n);
m->reserve (n);
}
static void f_QPolygon_resize (QPolygon *m, int n)
{
return m->resize (n);
m->resize (n);
}
static void f_QPolygon_fill (QPolygon *m, const QPoint &p, int n)
@@ -747,52 +754,52 @@ DECL
static void f_QPolygonF_clear (QPolygonF *m)
{
return m->clear();
m->clear();
}
static void f_QPolygonF_remove (QPolygonF *m, int i)
{
return m->remove (i);
m->remove (i);
}
static void f_QPolygonF_insert (QPolygonF *m, int i, const QPointF &p)
{
return m->insert (i, p);
m->insert (i, p);
}
static void f_QPolygonF_replace (QPolygonF *m, int i, const QPointF &p)
{
return m->replace (i, p);
m->replace (i, p);
}
static void f_QPolygonF_pop_front (QPolygonF *m)
{
return m->pop_front ();
m->pop_front ();
}
static void f_QPolygonF_pop_back (QPolygonF *m)
{
return m->pop_back ();
m->pop_back ();
}
static void f_QPolygonF_push_front (QPolygonF *m, const QPointF &p)
{
return m->push_front (p);
m->push_front (p);
}
static void f_QPolygonF_push_back (QPolygonF *m, const QPointF &p)
{
return m->push_back (p);
m->push_back (p);
}
static void f_QPolygonF_reserve (QPolygonF *m, int n)
{
return m->reserve (n);
m->reserve (n);
}
static void f_QPolygonF_resize (QPolygonF *m, int n)
{
return m->resize (n);
m->resize (n);
}
static void f_QPolygonF_fill (QPolygonF *m, const QPointF &p, int n)
+15 -24
View File
@@ -87,8 +87,8 @@ end
# "cv" is a CPPCV object.
class CPPFunc < CPPOuterType
attr_accessor :inner, :args, :cv
def_initializer :inner, :args, :cv
attr_accessor :inner, :args, :cv, :ref
def_initializer :inner, :args, :cv, :ref
def to_s
a = self.args
@@ -96,12 +96,13 @@ class CPPFunc < CPPOuterType
if !a.is_a?(Array)
a = [a]
end
self.inner.to_s + " (" + a.join(", ") + ")" + (self.cv ? " " + self.cv.to_s : "")
self.inner.to_s + " (" + a.join(", ") + ")" + (self.cv ? " " + self.cv.to_s : "") + (self.ref ? " " + self.ref.to_s : "")
end
def dump(i)
i + "CPPFunc\n" + i + " inner:\n" + self.inner.dump(i + " ") + "\n" +
i + " cv: " + self.cv.to_s + "\n" +
i + " ref: " + self.ref.to_s + "\n" +
i + " args:\n" + (self.args || []).collect { |f| f.dump(i + " ") }.join("\n")
end
@@ -469,29 +470,19 @@ class CPPFriendDecl < CPPObject
end
# @brief A type template argument (with an optional initializer)
# @attribute id The name of the argument (a string)
# @attribute type The template argument (a type)
# @attribute def_type The default type (nil or a CPPType object)
class CPPClassTemplateArg < CPPObject
attr_accessor :id, :def_type
def_initializer :id, :def_type
attr_accessor :type, :def_type
def_initializer :type, :def_type
def to_s
self.id + (self.def_type ? ("=" + self.def_type.to_s) : "")
end
end
# @brief A value template argument (with an optional initializer)
# @attribute type A CPPType object describing the type
# @attribute def_expr The initializer expression (a string) or nil if no initializer is given
class CPPDirectTemplateArg < CPPObject
attr_accessor :type, :def_expr
def_initializer :type, :def_expr
def to_s
self.type.to_s + (self.def_expr ? ("=" + self.def_expr.to_s) : "")
if self.def_type
self.type.to_s + "=" + self.def_type.to_s
else
self.type.to_s
end
end
end
@@ -624,15 +615,15 @@ end
# @attribute specs the enum members (an array of CPPEnumSpec objects)
class CPPEnum < CPPObject
attr_accessor :name, :specs
def_initializer :name, :specs
attr_accessor :name, :specs, :is_class
def_initializer :name, :specs, :is_class
def to_s
"enum " + (self.name || "")
end
def dump(i)
l = i + self.to_s + " {\n"
l = i + self.to_s + (self.is_class ? " class" : "") + " {\n"
l += (self.specs || []).collect { |s| i + " " + s.to_s + "\n" }.join("")
l += i + "}"
end
@@ -128,7 +128,7 @@ module PEnumType
def cpp
name = id ? id.text_value : nil
specs = bodyspec.nonterminal? ? bodyspec.body.cpp : nil
CPPEnum::new(name, specs)
CPPEnum::new(name, specs, is_class.nonterminal?)
end
end
@@ -241,7 +241,7 @@ end
module PFuncSpec
def cpp
CPPFunc::new(nil, (fa.nonterminal? && fa.text_value != "void") ? (fa.a.cpp || []) : [], cvspec.nonterminal? && cvspec.cv.to_symbol)
CPPFunc::new(nil, (fa.nonterminal? && fa.text_value != "void") ? (fa.a.cpp || []) : [], cvspec.nonterminal? && cvspec.cv.to_symbol, refspec.nonterminal? && refspec.ref.text_value)
end
end
@@ -404,13 +404,7 @@ end
module PClassTemplateArg
def cpp
CPPClassTemplateArg::new(id.text_value, dtspec.nonterminal? ? dtspec.cpp : nil)
end
end
module PDirectTemplateArg
def cpp
CPPDirectTemplateArg::new(t.cpp, initspec.nonterminal? ? initspec.text_value : nil)
CPPClassTemplateArg::new(t.cpp, dtspec.nonterminal? ? dtspec.cpp : nil)
end
end
+1 -1
View File
@@ -29,7 +29,7 @@ $:.push(File.dirname($0))
require 'oj'
require 'treetop'
Treetop.load "c++"
Treetop.load File.join(File.dirname($0), "c++")
input="all.e"
output="all.db"
+267 -256
View File
@@ -73,6 +73,10 @@ class CPPDeclaration
self.type.func.cv == :const
end
def ref
self.type.func.ref
end
def hash_str
# TODO: this is a hack for making the hash values unique:
@@ -83,6 +87,13 @@ class CPPDeclaration
nmax = func.max_args
hk = (self.is_const? ? "c" : "")
if self.ref
if self.ref == "&"
hk += "r"
elsif self.ref == "&&"
hk += "rr"
end
end
if nmax > 0
@@ -111,17 +122,28 @@ class CPPDeclaration
nmax = func.max_args
args = nmax.times.collect { |ia| func.args[ia].anonymous_type.to_s }.join(", ")
res = "(" + args + ")"
if self.is_const?
"(" + args + ") const"
else
"(" + args + ")"
res += " const"
end
if self.ref
res += " " + self.ref
end
res
end
def sig(cls)
self.type.name_substituted_type(CPPQualifiedId::new(false, [ cls, self.type.func.func_name ])).to_s
end
def raw_sig(cls)
# backward compatibility for signature computation
s = self.type.name_substituted_type(CPPQualifiedId::new(false, [ cls, self.type.func.func_name ])).to_s
if self.ref
s = s.sub(/\s+&+$/, "")
end
if self.is_const?
s = s.sub(/\s+const$/, "")
end
@@ -144,6 +166,33 @@ class CPPNamespace
end
class CPPModule
def collect_enum_decls(map, &filter)
self.decls.each do |bd|
if bd.is_a?(CPPEnumDeclaration)
bd.enum && filter.call(bd) && (map[bd.enum.name] ||= bd)
end
end
end
end
class CPPEnum
def resolve_typedefs(scope)
end
def rescope(prev_scope, other_scope, idpath)
end
def each_qid(&block)
end
end
class CPPStruct
def resolve_typedefs(scope)
@@ -216,7 +265,7 @@ class CPPStruct
cls = self.id.to_s
# collect enums from inner classes
# collect used enums from inner classes
(self.body_decl || []).each do |bd|
decl = nil
if bd.is_a?(CPPStructDeclaration) && bd.visibility == :public && bd.struct.body_decl && bd.myself != "" && !conf.is_class_dropped?(cls, bd.myself)
@@ -224,6 +273,14 @@ class CPPStruct
end
end
# collect used enums from base classes
(self.base_classes || []).each do |bc|
bc_obj = self.parent.resolve_qid(bc.class_id)
if bc_obj.is_a?(CPPStructDeclaration) && bc_obj.visibility == :public && bc_obj.struct.body_decl && bc_obj.myself != "" && !conf.is_class_dropped?(cls, bc_obj.myself)
bc_obj.struct.collect_used_enums(map, conf)
end
end
methods = {}
self.collect_all_methods(methods, conf)
@@ -266,7 +323,7 @@ class CPPStruct
end
def collect_methods(map)
def collect_methods(map, weak = false)
mmap = {}
@@ -306,6 +363,7 @@ class CPPStruct
end
# take non-duplicates (by call signature) for the map
# weak ones do not redefine methods
mmap.each do |mn,decls|
seen = {}
@@ -313,7 +371,9 @@ class CPPStruct
s = d.call_sig
if !seen[s]
seen[s] = true
(map[mn] ||= []) << d
if !weak || !map[mn]
(map[mn] ||= []) << d
end
end
end
@@ -426,7 +486,7 @@ class CPPStruct
end
elsif bc_obj
raise("#{bc.class_id.to_s} is not a base class in #{self.id.to_s}")
puts("Warning: #{bc.class_id.to_s} is not a base class in #{self.id.to_s}")
else
puts("Cannot find base class: #{bc.class_id.to_s} of #{self.parent.myself} - declaration ignored")
end
@@ -739,7 +799,13 @@ class CPPType
return "#{self.anonymous_type.to_s}(" + expr + ")"
elsif self.is_special(decl_obj)
ta = self.anonymous_type.to_s
if ta =~ /^const (.*) &$/
if ta =~ /^const (.*) &&$/
ta = $1
acc = ".cmove()"
elsif ta =~ /^(.*) &&$/
ta = $1
acc = ".move()"
elsif ta =~ /^const (.*) &$/
ta = $1
acc = ".cref()"
elsif ta =~ /^(.*) &$/
@@ -776,6 +842,8 @@ class CPPType
# but can at least read them.
if ta =~ /^const (.*) &$/ || ta =~ /^(.*) &$/
ta = $1
elsif ta =~ /^const (.*) &&$/ || ta =~ /^(.*) &&$/
ta = $1
elsif ta =~ /^const (.*) \*$/ || ta =~ /^(.*) \*$/
ta = $1
acc = "*"
@@ -911,6 +979,7 @@ class Configurator
@dropped_methods = {}
@dropped_classes = {}
@dropped_enums = {}
@included_enums = {}
@renamed_methods = {}
@kept_args = {}
@owner_args = {}
@@ -1038,9 +1107,9 @@ class Configurator
else
dc = (@dropped_classes[:all_classes] || []) + (@dropped_classes[cls] || [])
if sig != :whole_class
return dc.find { |d| sig =~ d } != nil
return dc.find { |d| d == :whole_class || sig =~ d } != nil
else
return dc.find { |d| sig == d } != nil
return dc.find { |d| d == :whole_class || sig == d } != nil
end
end
end
@@ -1140,6 +1209,7 @@ class Configurator
# static and non-static methods
if bd.storage_class == :static
sig = "static " + sig
sig2 = "static " + sig2
end
if is_dropped?(cls, sig) || is_dropped?(cls2, sig2)
@@ -1151,6 +1221,11 @@ class Configurator
# replace assignment operator
if name == "="
# drop assignment if the class does not have a copy ctor ("no copy semantics")
# (required because otherwise operator= is exposed for adaptor classes)
if !has_copy_ctor?(cls)
return nil
end
name = "assign"
end
@@ -1225,6 +1300,16 @@ class Configurator
gsub(/\s+/, "")
end
def include_enum(cls, sig)
@included_enums[cls] ||= []
@included_enums[cls] << sig
end
def is_enum_included?(cls, sig)
dm = (@included_enums[:all_classes] || []) + (@included_enums[cls] || [])
dm.find { |d| sig =~ d } != nil
end
def drop_enum(cls, sig)
@dropped_enums[cls] ||= []
@dropped_enums[cls] << sig
@@ -1300,7 +1385,7 @@ end
class BindingProducer
attr_accessor :modn
attr_accessor :modn, :root
# @brief Read the input file (JSON)
#
@@ -1394,7 +1479,7 @@ class BindingProducer
def produce_cpp_from_decl(conf, decl_obj)
if !decl_obj.is_a?(CPPStructDeclaration) && !decl_obj.is_a?(CPPNamespace)
if !decl_obj.is_a?(CPPStructDeclaration) && !decl_obj.is_a?(CPPNamespace) && !decl_obj.is_a?(CPPEnumDeclaration)
return
end
@@ -1455,6 +1540,8 @@ END
cont = produce_class(conf, decl_obj, ofile, index)
elsif decl_obj.is_a?(CPPNamespace)
cont = produce_namespace(conf, decl_obj, ofile, index)
elsif decl_obj.is_a?(CPPEnumDeclaration)
cont = produce_enum(conf, decl_obj, ofile, index)
end
puts("#{ofile_name} written.")
@@ -1559,7 +1646,26 @@ END
ofile.puts("#include \"gsiQt.h\"")
ofile.puts("#include \"gsi#{modn}Common.h\"")
ofile.puts("#include \"gsiDecl#{modn}TypeTraits.h\"")
end
def produce_enum(conf, decl_obj, ofile, index)
( cls, clsn ) = make_cls_names(decl_obj)
produce_class_include(conf, decl_obj, ofile)
ofile.puts("#include <memory>")
ofile.puts("")
ofile.puts("// -----------------------------------------------------------------------")
ofile.puts("// enum #{cls}")
ofile.puts("")
# emit enum wrapper classes (top level, hence container class is nil)
produce_enum_wrapper_class(ofile, conf, nil, cls, decl_obj)
return false
end
@@ -1611,7 +1717,7 @@ END
def produce_enum_wrapper_class(ofile, conf, cls, en, ed)
clsn = make_cls_name(cls)
clsn = cls && make_cls_name(cls)
# emit enum wrapper classes
@@ -1620,53 +1726,86 @@ END
ofile.puts("namespace qt_gsi")
ofile.puts("{")
ofile.puts("")
ofile.puts("static gsi::Enum<#{cls}::#{en}> decl_#{clsn}_#{en}_Enum (\"#{modn}\", \"#{clsn}_#{en}\",")
if cls
ofile.puts("static gsi::Enum<#{cls}::#{en}> decl_#{clsn}_#{en}_Enum (\"#{modn}\", \"#{clsn}_#{en}\",")
else
ofile.puts("static gsi::Enum<#{en}> decl_#{en}_Enum (\"#{modn}\", \"#{en}\",")
end
edecl = []
ec = ed.enum.specs.collect { |s| s.name }
ec.each_with_index do |ei,i|
ei_name = conf.target_name_for_enum_const(cls, "#{en}::#{ei}", ei)
ei_name = conf.target_name_for_enum_const(cls ? cls : "::", "#{en}::#{ei}", ei)
if ! ei_name
# enum dropped
next
end
edecl << " gsi::enum_const (\"#{ei_name}\", #{cls}::#{ei}, \"@brief Enum constant #{cls}::#{ei}\")"
if cls
if ed.enum.is_class
edecl << " gsi::enum_const (\"#{ei_name}\", #{cls}::#{en}::#{ei}, \"@brief Enum constant #{cls}::#{en}::#{ei}\")"
else
edecl << " gsi::enum_const (\"#{ei_name}\", #{cls}::#{ei}, \"@brief Enum constant #{cls}::#{ei}\")"
end
else
if ed.enum.is_class
edecl << " gsi::enum_const (\"#{ei_name}\", #{en}::#{ei}, \"@brief Enum constant #{en}::#{ei}\")"
else
edecl << " gsi::enum_const (\"#{ei_name}\", #{ei}, \"@brief Enum constant #{ei}\")"
end
end
end
ofile.puts(" " + edecl.join(" +\n ") + ",\n")
ofile.puts(" \"@qt\\n@brief This class represents the #{cls}::#{en} enum\");")
if cls
ofile.puts(" \"@qt\\n@brief This class represents the #{cls}::#{en} enum\");")
else
ofile.puts(" \"@qt\\n@brief This class represents the #{en} enum\");")
end
ofile.puts("")
ofile.puts("static gsi::QFlagsClass<#{cls}::#{en} > decl_#{clsn}_#{en}_Enums (\"#{modn}\", \"#{clsn}_QFlags_#{en}\",")
ofile.puts(" \"@qt\\n@brief This class represents the QFlags<#{cls}::#{en}> flag set\");")
ofile.puts("")
ofile.puts("// Inject the declarations into the parent")
# inject the declarations into the parent namespace or class
pdecl_obj = ed.parent
pcls = pdecl_obj.myself
o = pdecl_obj
while o.parent && o.parent.myself
o = o.parent
pcls = o.myself + "::" + pcls
if cls
ofile.puts("static gsi::QFlagsClass<#{cls}::#{en} > decl_#{clsn}_#{en}_Enums (\"#{modn}\", \"#{clsn}_QFlags_#{en}\",")
ofile.puts(" \"@qt\\n@brief This class represents the QFlags<#{cls}::#{en}> flag set\");")
ofile.puts("")
else
ofile.puts("static gsi::QFlagsClass<#{en} > decl_#{en}_Enums (\"#{modn}\", \"QFlags_#{en}\",")
ofile.puts(" \"@qt\\n@brief This class represents the QFlags<#{en}> flag set\");")
ofile.puts("")
end
pname = pcls
if pdecl_obj.is_a?(CPPNamespace)
pname = pcls + "_Namespace"
if cls
# inject the declarations into the parent namespace or class
pdecl_obj = ed.parent
pcls = pdecl_obj.myself
o = pdecl_obj
while o.parent && o.parent.myself
o = o.parent
pcls = o.myself + "::" + pcls
end
pname = pcls
if pdecl_obj.is_a?(CPPNamespace)
pname = pcls + "_Namespace"
end
if ! ed.enum.is_class
ofile.puts("// Inject the declarations into the parent")
ofile.puts("static gsi::ClassExt<#{pname}> inject_#{clsn}_#{en}_Enum_in_parent (decl_#{clsn}_#{en}_Enum.defs ());")
end
ofile.puts("static gsi::ClassExt<#{pname}> decl_#{clsn}_#{en}_Enum_as_child (decl_#{clsn}_#{en}_Enum, \"#{en}\");")
ofile.puts("static gsi::ClassExt<#{pname}> decl_#{clsn}_#{en}_Enums_as_child (decl_#{clsn}_#{en}_Enums, \"QFlags_#{en}\");")
ofile.puts("")
end
ofile.puts("static gsi::ClassExt<#{pname}> inject_#{clsn}_#{en}_Enum_in_parent (decl_#{clsn}_#{en}_Enum.defs ());")
ofile.puts("static gsi::ClassExt<#{pname}> decl_#{clsn}_#{en}_Enum_as_child (decl_#{clsn}_#{en}_Enum, \"#{en}\");")
ofile.puts("static gsi::ClassExt<#{pname}> decl_#{clsn}_#{en}_Enums_as_child (decl_#{clsn}_#{en}_Enums, \"QFlags_#{en}\");")
ofile.puts("")
ofile.puts("}")
ofile.puts("")
@@ -1779,6 +1918,10 @@ END
base_cls = base_classes[0] && base_classes[0].class_id.to_s
base_clsn = base_cls && make_cls_name(base_cls)
# as we only support single base classes (a tribute to Ruby), we treat all other base classes as
# mixins
mixin_base_classes = base_classes[1..] || []
methods_by_name = {}
all_methods_by_name = {}
enum_decls_by_name = {}
@@ -1786,13 +1929,13 @@ END
bc_methods_by_name = {}
base_classes.each do |bc|
bc_decl_obj = decl_obj.resolve_qid(bc.class_id)
bc_decl_obj && bc_decl_obj.struct.collect_all_methods(bc_methods_by_name, conf)
bc_decl_obj && bc_decl_obj.respond_to?(:struct) && bc_decl_obj.struct.collect_all_methods(bc_methods_by_name, conf)
end
mmap = {}
struct.collect_methods(methods_by_name)
struct.collect_all_methods(all_methods_by_name, conf)
struct.collect_enum_decls(enum_decls_by_name) { |bd| self.is_enum_used?(bd) }
struct.collect_methods(methods_by_name)
struct.collect_enum_decls(enum_decls_by_name) { |bd| self.is_enum_used?(bd) || conf.is_enum_included?(cls, bd.myself) }
# if one method is abstract, omit ctors for example
is_abstract = all_methods_by_name.values.find do |m|
@@ -1832,7 +1975,7 @@ END
# create a default ctor if there is no ctor at all and we can have one
if ctors.empty? && conf.has_default_ctor?(cls)
func = CPPFunc::new(CPPQualifiedId::new(false, [ CPPId::new(decl_obj.myself, nil) ]), [], nil)
func = CPPFunc::new(CPPQualifiedId::new(false, [ CPPId::new(decl_obj.myself, nil) ]), [], nil, nil)
type = CPPType::new(nil, func, nil)
def_ctor = CPPDeclaration::new(type, nil, :public, nil, false, false)
def_ctor.parent = decl_obj
@@ -1861,6 +2004,7 @@ END
native_impl = conf.native_impl(cls)
has_metaobject = ((struct.body_decl || []).find { |bd| bd.is_a?(CPPDeclaration) && bd.type.name == "metaObject" } != nil)
has_metaobject = has_metaobject && !conf.is_dropped?(cls, cls + "::staticMetaObject")
mdecl = []
mdecl_ctors = []
@@ -1905,6 +2049,7 @@ END
func = bd.type.func
hk = bd.hash_str
sig = bd.sig(cls)
rsig = bd.raw_sig(cls)
mn = decl_obj.myself # ctor!
mn_name = conf.target_name(cls, bd, mn)
@@ -1923,7 +2068,7 @@ END
qt_alist = n_args.times.collect { |ia| func.args[ia].renamed_type(alist[ia]).access_qt_arg(decl_obj) }
ofile.puts("")
ofile.puts("// Constructor #{sig}")
ofile.puts("// Constructor #{rsig}")
ofile.puts("")
ofile.puts("")
@@ -1951,7 +2096,7 @@ END
ofile.puts("}")
ofile.puts("")
mdecl_ctors << "new qt_gsi::GenericStaticMethod (\"#{mn_name}\", \"@brief Constructor #{sig}\\nThis method creates an object of class #{cls}.\", &_init_ctor_#{clsn}_#{hk}, &_call_ctor_#{clsn}_#{hk});"
mdecl_ctors << "new qt_gsi::GenericStaticMethod (\"#{mn_name}\", \"@brief Constructor #{rsig}\\nThis method creates an object of class #{cls}.\", &_init_ctor_#{clsn}_#{hk}, &_call_ctor_#{clsn}_#{hk});"
end
@@ -1978,6 +2123,7 @@ END
const = bd.is_const?
hk = bd.hash_str
sig = bd.sig(cls)
rsig = bd.raw_sig(cls)
if conf.event_args(cls, sig) && bd.type.return_type.is_void?
# don't produce bindings for signals (which are public in Qt5)
@@ -2005,7 +2151,7 @@ END
qt_alist = n_args.times.collect { |ia| func.args[ia].renamed_type(alist[ia]).access_qt_arg(decl_obj) }
ofile.puts("")
ofile.puts("// #{sig}")
ofile.puts("// #{rsig}")
ofile.puts("")
ofile.puts("")
@@ -2030,7 +2176,7 @@ END
ofile.puts("}")
ofile.puts("")
mdecl << "new qt_gsi::GenericMethod (\"#{mn_name}\", \"@brief Method #{sig}\\n" + (is_reimp ? "This is a reimplementation of #{is_reimp.parent.myself}::#{mid}" : "") + "\", #{const.to_s}, &_init_f_#{mn}_#{hk}, &_call_f_#{mn}_#{hk});"
mdecl << "new qt_gsi::GenericMethod (\"#{mn_name}\", \"@brief Method #{rsig}\\n" + (is_reimp ? "This is a reimplementation of #{is_reimp.parent.myself}::#{mid}" : "") + "\", #{const.to_s}, &_init_f_#{mn}_#{hk}, &_call_f_#{mn}_#{hk});"
end
@@ -2065,6 +2211,7 @@ END
end
sig = bd_short.sig(cls)
rsig = bd_short.raw_sig(cls)
hk = bd_short.hash_str
n_args = func.max_args
@@ -2078,7 +2225,7 @@ END
al = ant.collect { |a| a.to_s }.join(", ")
aln = ren_args.collect { |a| a.to_s }.join(", ")
sig_wo_void = sig.sub(/^void /, "")
rsig_wo_void = rsig.sub(/^void /, "")
al_subst = al
SignalSubstitutions.each do |t,s|
@@ -2087,9 +2234,9 @@ END
argspecs = argnames.collect { |a| "gsi::arg(\"#{a}\"), " }.join("")
if gsi_args.empty?
mdecl << "gsi::qt_signal (\"#{mid}(#{al_subst})\", \"#{mn_name}\", \"@brief Signal declaration for #{sig_wo_void}\\nYou can bind a procedure to this signal.\");"
mdecl << "gsi::qt_signal (\"#{mid}(#{al_subst})\", \"#{mn_name}\", \"@brief Signal declaration for #{rsig_wo_void}\\nYou can bind a procedure to this signal.\");"
else
mdecl << "gsi::qt_signal<#{event_al} > (\"#{mid}(#{al_subst})\", \"#{mn_name}\", #{argspecs}\"@brief Signal declaration for #{sig_wo_void}\\nYou can bind a procedure to this signal.\");"
mdecl << "gsi::qt_signal<#{event_al} > (\"#{mid}(#{al_subst})\", \"#{mn_name}\", #{argspecs}\"@brief Signal declaration for #{rsig_wo_void}\\nYou can bind a procedure to this signal.\");"
end
end
@@ -2114,6 +2261,7 @@ END
const = bd.is_const?
hk = bd.hash_str
sig = bd.sig(cls)
rsig = bd.raw_sig(cls)
mn = conf.mid2str(mid)
mn_name = conf.target_name(cls, bd, mid, all_methods_by_name, bd)
@@ -2132,7 +2280,7 @@ END
qt_alist = n_args.times.collect { |ia| func.args[ia].renamed_type(alist[ia]).access_qt_arg(decl_obj) }
ofile.puts("")
ofile.puts("// static #{sig}")
ofile.puts("// static #{rsig}")
ofile.puts("")
ofile.puts("")
@@ -2156,7 +2304,7 @@ END
ofile.puts("}")
ofile.puts("")
mdecl << "new qt_gsi::GenericStaticMethod (\"#{mn_name}\", \"@brief Static method #{sig}\\nThis method is static and can be called without an instance.\", &_init_f_#{mn}_#{hk}, &_call_f_#{mn}_#{hk});"
mdecl << "new qt_gsi::GenericStaticMethod (\"#{mn_name}\", \"@brief Static method #{rsig}\\nThis method is static and can be called without an instance.\", &_init_f_#{mn}_#{hk}, &_call_f_#{mn}_#{hk});"
end
@@ -2173,6 +2321,7 @@ END
const = bd.is_const?
hk = bd.hash_str
sig = bd.sig("")
rsig = bd.raw_sig("")
# operators may be present twice with the same signature
# (here: same hash key)
@@ -2206,7 +2355,7 @@ END
args = rnt.collect { |t| t.gsi_decl_arg(decl_obj) }.join(", ")
ofile.puts("")
ofile.puts("// #{sig}")
ofile.puts("// #{rsig}")
ofile.puts("static #{rt.gsi_decl_return(decl_obj)} op_#{clsn}_#{mn}_#{hk}(#{args}) {")
if !rt.is_void?
@@ -2219,7 +2368,7 @@ END
argspecs = argnames[1..-1].collect { |a| "gsi::arg (\"#{a}\"), " }.join("")
mdecl << "gsi::method_ext(\"#{mn_name}\", &::op_#{clsn}_#{mn}_#{hk}, #{argspecs}\"@brief Operator #{sig}\\nThis is the mapping of the global operator to the instance method.\");"
mdecl << "gsi::method_ext(\"#{mn_name}\", &::op_#{clsn}_#{mn}_#{hk}, #{argspecs}\"@brief Operator #{rsig}\\nThis is the mapping of the global operator to the instance method.\");"
end
@@ -2231,35 +2380,35 @@ END
base_classes.each do |bc|
bc_name = bc.class_id.to_s
bc_name = bc.class_id.to_s
ofile.puts("// base class cast for #{bc_name}")
ofile.puts("")
ofile.puts("static void _init_f_#{clsn}_as_#{bc_name} (qt_gsi::GenericMethod *decl)")
ofile.puts("{")
ofile.puts(" decl->set_return<#{bc_name} *> ();")
ofile.puts("}")
ofile.puts("")
ofile.puts("static void _call_f_#{clsn}_as_#{bc_name} (const qt_gsi::GenericMethod *, void *cls, gsi::SerialArgs &, gsi::SerialArgs &ret) ")
ofile.puts("{")
ofile.puts(" ret.write<#{bc_name} *> ((#{bc_name} *)(#{cls} *)cls);")
ofile.puts("}")
ofile.puts("")
ofile.puts("// base class cast for #{bc_name}")
ofile.puts("")
ofile.puts("static void _init_f_#{clsn}_as_#{bc_name} (qt_gsi::GenericMethod *decl)")
ofile.puts("{")
ofile.puts(" decl->set_return<#{bc_name} *> ();")
ofile.puts("}")
ofile.puts("")
ofile.puts("static void _call_f_#{clsn}_as_#{bc_name} (const qt_gsi::GenericMethod *, void *cls, gsi::SerialArgs &, gsi::SerialArgs &ret) ")
ofile.puts("{")
ofile.puts(" ret.write<#{bc_name} *> ((#{bc_name} *)(#{cls} *)cls);")
ofile.puts("}")
ofile.puts("")
mdecl_bcc << "new qt_gsi::GenericMethod (\"as#{bc_name}\", \"@brief Delivers the base class interface #{bc_name} of #{cls}\\nClass #{cls} is derived from multiple base classes. This method delivers the #{bc_name} base class aspect.\", false, &_init_f_#{clsn}_as_#{bc_name}, &_call_f_#{clsn}_as_#{bc_name});"
mdecl_bcc << "new qt_gsi::GenericMethod (\"as#{bc_name}\", \"@brief Delivers the base class interface #{bc_name} of #{cls}\\nClass #{cls} is derived from multiple base classes. This method delivers the #{bc_name} base class aspect.\", false, &_init_f_#{clsn}_as_#{bc_name}, &_call_f_#{clsn}_as_#{bc_name});"
ofile.puts("static void _init_f_#{clsn}_as_const_#{bc_name} (qt_gsi::GenericMethod *decl)")
ofile.puts("{")
ofile.puts(" decl->set_return<const #{bc_name} *> ();")
ofile.puts("}")
ofile.puts("")
ofile.puts("static void _call_f_#{clsn}_as_const_#{bc_name} (const qt_gsi::GenericMethod *, void *cls, gsi::SerialArgs &, gsi::SerialArgs &ret) ")
ofile.puts("{")
ofile.puts(" ret.write<const #{bc_name} *> ((const #{bc_name} *)(const #{cls} *)cls);")
ofile.puts("}")
ofile.puts("")
ofile.puts("static void _init_f_#{clsn}_as_const_#{bc_name} (qt_gsi::GenericMethod *decl)")
ofile.puts("{")
ofile.puts(" decl->set_return<const #{bc_name} *> ();")
ofile.puts("}")
ofile.puts("")
ofile.puts("static void _call_f_#{clsn}_as_const_#{bc_name} (const qt_gsi::GenericMethod *, void *cls, gsi::SerialArgs &, gsi::SerialArgs &ret) ")
ofile.puts("{")
ofile.puts(" ret.write<const #{bc_name} *> ((const #{bc_name} *)(const #{cls} *)cls);")
ofile.puts("}")
ofile.puts("")
mdecl_bcc << "new qt_gsi::GenericMethod (\"asConst#{bc_name}\", \"@brief Delivers the base class interface #{bc_name} of #{cls}\\nClass #{cls} is derived from multiple base classes. This method delivers the #{bc_name} base class aspect.\\n\\nUse this version if you have a const reference.\", true, &_init_f_#{clsn}_as_const_#{bc_name}, &_call_f_#{clsn}_as_const_#{bc_name});"
mdecl_bcc << "new qt_gsi::GenericMethod (\"asConst#{bc_name}\", \"@brief Delivers the base class interface #{bc_name} of #{cls}\\nClass #{cls} is derived from multiple base classes. This method delivers the #{bc_name} base class aspect.\\n\\nUse this version if you have a const reference.\", true, &_init_f_#{clsn}_as_const_#{bc_name}, &_call_f_#{clsn}_as_const_#{bc_name});"
end
@@ -2335,25 +2484,29 @@ END
# forward decl
@ext_decls << "#{struct.kind.to_s} #{cls};\n\n"
# type traits included ...
tt = "namespace tl { template <> struct type_traits<#{cls}> : public type_traits<void> {\n"
if !conf.has_copy_ctor?(cls) || is_abstract || (eq_op && eq_op.visibility == :private)
tt += " typedef tl::false_tag has_copy_constructor;\n"
end
if !conf.has_default_ctor?(cls) || is_abstract
tt += " typedef tl::false_tag has_default_constructor;\n"
end
if (dtor = struct.get_dtor) && dtor.visibility != :public
tt += " typedef tl::false_tag has_public_destructor;\n"
end
tt += "}; }\n\n"
@ext_decls << tt
# only for top-level classes external declarations are produced currently
@ext_decls << "namespace gsi { GSI_#{modn.upcase}_PUBLIC gsi::Class<#{cls}> &qtdecl_#{clsn} (); }\n\n"
end
# Produce the mixin base classes
if ! mixin_base_classes.empty?
ofile.puts("")
ofile.puts("// Additional base classes")
ofile.puts("")
mixin_base_classes.each do |bc|
bc_name = bc.class_id.to_s
ofile.puts("gsi::Class<#{bc_name}> &qtdecl_#{bc_name} ();")
end
ofile.puts("")
end
mixin_base_classes.each do |bc|
bc_name = bc.class_id.to_s
ofile.puts("gsi::ClassExt<#{cls}> base_class_#{bc_name}_in_#{clsn} (qtdecl_#{bc_name} ());")
end
ofile.puts("")
ofile.puts("GSI_#{modn.upcase}_PUBLIC gsi::Class<#{cls}> &qtdecl_#{clsn} () { return decl_#{clsn}; }")
ofile.puts("")
@@ -2383,6 +2536,7 @@ END
func = bd.type.func
hk = bd.hash_str
sig = bd.sig(cls)
rsig = bd.raw_sig(cls)
mn = decl_obj.myself # ctor!
mn_name = conf.target_name(cls, bd, mn)
@@ -2406,7 +2560,7 @@ END
args = rnt.collect { |t| t.to_s }.join(", ")
ofile.puts("")
ofile.puts(" // [adaptor ctor] #{sig}")
ofile.puts(" // [adaptor ctor] #{rsig}")
ofile.puts(" #{clsn}_Adaptor(#{args}) : #{cls}(#{argnames.join(', ')})")
ofile.puts(" {")
ofile.puts(" qt_gsi::QtObjectBase::init (this);")
@@ -2430,6 +2584,7 @@ END
func = bd.type.func
hk = bd.hash_str
sig = bd.sig(cls)
rsig = bd.raw_sig(cls)
const = bd.is_const?
# exclude events
@@ -2453,7 +2608,7 @@ END
argexpr = rnt.collect { |t| t.access_qt_arg(decl_obj) }.join(", ")
ofile.puts("")
ofile.puts(" // [expose] #{sig}")
ofile.puts(" // [expose] #{rsig}")
ofile.puts(" " + (bd.storage_class == :static ? "static " : "") + "#{rt.gsi_decl_return(decl_obj)} fp_#{clsn}_#{mn}_#{hk} (#{args}) " + (const ? "const " : "") + "{")
if rt.is_void?
ofile.puts(" #{cls}::#{mid}(#{argexpr});")
@@ -2481,6 +2636,7 @@ END
func = bd.type.func
hk = bd.hash_str
sig = bd.sig(cls)
rsig = bd.raw_sig(cls)
const = bd.is_const?
rt = bd.type.return_type
@@ -2504,6 +2660,7 @@ END
end
sig = bd_short.sig(cls)
rsig = bd_short.raw_sig(cls)
# for events produce an emitter function
@@ -2517,7 +2674,7 @@ END
call_args = argnames.join(", ")
ofile.puts("")
ofile.puts(" // [emitter impl] #{sig}")
ofile.puts(" // [emitter impl] #{rsig}")
ofile.puts(" #{rt.to_s} emitter_#{clsn}_#{mn}_#{hk}(#{raw_args})")
ofile.puts(" {")
if is_private
@@ -2560,7 +2717,7 @@ END
call_args = argnames.join(", ")
ofile.puts("")
ofile.puts(" // [adaptor impl] #{sig}")
ofile.puts(" // [adaptor impl] #{rsig}")
ofile.puts(" #{rt.gsi_decl_return(decl_obj)} cbs_#{mn}_#{hk}_#{i_var}(#{args})" + (const ? " const" : ""))
ofile.puts(" {")
if abstract
@@ -2625,6 +2782,7 @@ END
func = bd.type.func
hk = bd.hash_str
sig = bd.sig(cls)
rsig = bd.raw_sig(cls)
mn = decl_obj.myself # ctor!
mn_name = conf.target_name(cls, bd, mn)
@@ -2642,7 +2800,7 @@ END
qt_alist = n_args.times.collect { |ia| func.args[ia].renamed_type(alist[ia]).access_qt_arg(decl_obj) }
ofile.puts("")
ofile.puts("// Constructor #{sig} (adaptor class)")
ofile.puts("// Constructor #{rsig} (adaptor class)")
ofile.puts("")
ofile.puts("static void _init_ctor_#{clsn}_Adaptor_#{hk} (qt_gsi::GenericStaticMethod *decl)")
ofile.puts("{")
@@ -2664,7 +2822,7 @@ END
ofile.puts("}")
ofile.puts("")
mdecl << "new qt_gsi::GenericStaticMethod (\"#{mn_name}\", \"@brief Constructor #{sig}\\nThis method creates an object of class #{cls}.\", &_init_ctor_#{clsn}_Adaptor_#{hk}, &_call_ctor_#{clsn}_Adaptor_#{hk});"
mdecl << "new qt_gsi::GenericStaticMethod (\"#{mn_name}\", \"@brief Constructor #{rsig}\\nThis method creates an object of class #{cls}.\", &_init_ctor_#{clsn}_Adaptor_#{hk}, &_call_ctor_#{clsn}_Adaptor_#{hk});"
end
@@ -2677,6 +2835,7 @@ END
func = bd.type.func
hk = bd.hash_str
sig = bd.sig(cls)
rsig = bd.raw_sig(cls)
const = bd.is_const?
rt = bd.type.return_type
@@ -2698,6 +2857,7 @@ END
end
sig = bd_short.sig(cls)
rsig = bd_short.raw_sig(cls)
n_args = func.max_args
n_min_args = func.min_args
@@ -2707,7 +2867,7 @@ END
ifc_obj = "GenericMethod"
ofile.puts("")
ofile.puts("// emitter #{sig}")
ofile.puts("// emitter #{rsig}")
ofile.puts("")
ofile.puts("static void _init_emitter_#{mn}_#{hk} (qt_gsi::#{ifc_obj} *decl)")
ofile.puts("{")
@@ -2728,7 +2888,7 @@ END
if bd_short.storage_class != :static
const_flag = ", " + const.to_s
end
mdecl << "new qt_gsi::#{ifc_obj} (\"emit_#{mn_name}\", \"@brief Emitter for signal #{sig}\\nCall this method to emit this signal.\"#{const_flag}, &_init_emitter_#{mn}_#{hk}, &_call_emitter_#{mn}_#{hk});"
mdecl << "new qt_gsi::#{ifc_obj} (\"emit_#{mn_name}\", \"@brief Emitter for signal #{rsig}\\nCall this method to emit this signal.\"#{const_flag}, &_init_emitter_#{mn}_#{hk}, &_call_emitter_#{mn}_#{hk});"
elsif !bd.virtual && bd.visibility == :protected
@@ -2742,7 +2902,7 @@ END
ifc_obj = bd.storage_class == :static ? "GenericStaticMethod" : "GenericMethod"
ofile.puts("")
ofile.puts("// exposed #{sig}")
ofile.puts("// exposed #{rsig}")
ofile.puts("")
ofile.puts("static void _init_fp_#{mn}_#{hk} (qt_gsi::#{ifc_obj} *decl)")
ofile.puts("{")
@@ -2781,7 +2941,7 @@ END
if bd.storage_class != :static
const_flag = ", " + const.to_s
end
mdecl << "new qt_gsi::#{ifc_obj} (\"*#{mn_name}\", \"@brief Method #{sig}\\nThis method is protected and can only be called from inside a derived class.\"#{const_flag}, &_init_fp_#{mn}_#{hk}, &_call_fp_#{mn}_#{hk});"
mdecl << "new qt_gsi::#{ifc_obj} (\"*#{mn_name}\", \"@brief Method #{rsig}\\nThis method is protected and can only be called from inside a derived class.\"#{const_flag}, &_init_fp_#{mn}_#{hk}, &_call_fp_#{mn}_#{hk});"
elsif bd.virtual
@@ -2798,7 +2958,7 @@ END
alist = n_args.times.collect { |ia| "arg#{ia + 1}" }
ofile.puts("")
ofile.puts("// #{sig}")
ofile.puts("// #{rsig}")
ofile.puts("")
ofile.puts("static void _init_cbs_#{mn}_#{hk}_#{i_var} (qt_gsi::GenericMethod *decl)")
ofile.puts("{")
@@ -2834,7 +2994,7 @@ END
ofile.puts("}")
ofile.puts("")
mdecl << "new qt_gsi::GenericMethod (\"#{pp}#{mn_name}\", \"@brief Virtual method #{sig}\\nThis method can be reimplemented in a derived class.\", #{const.to_s}, &_init_cbs_#{mn}_#{hk}_#{i_var}, &_call_cbs_#{mn}_#{hk}_#{i_var});"
mdecl << "new qt_gsi::GenericMethod (\"#{pp}#{mn_name}\", \"@brief Virtual method #{rsig}\\nThis method can be reimplemented in a derived class.\", #{const.to_s}, &_init_cbs_#{mn}_#{hk}_#{i_var}, &_call_cbs_#{mn}_#{hk}_#{i_var});"
mdecl << "new qt_gsi::GenericMethod (\"#{pp}#{mn_name}\", \"@hide\", #{const.to_s}, &_init_cbs_#{mn}_#{hk}_#{i_var}, &_call_cbs_#{mn}_#{hk}_#{i_var}, &_set_callback_cbs_#{mn}_#{hk}_#{i_var});"
end
@@ -2900,152 +3060,6 @@ END
end
def produce_ttfile_traits(ttfile, conf, decl_obj)
(cls, clsn) = make_cls_names(decl_obj)
struct = decl_obj.struct
mm = {}
struct.collect_all_methods(mm, conf)
# if one method is abstract, omit ctors for example
is_abstract = mm.values.find do |m|
m.find { |bd| bd.virtual && bd.type.init == "0" } != nil
end
eq_op = (mm["operator="] || [])[0]
# Note: right now, there is no way to specify type traits globally for nested
# classes because there is no forward declaration of inner classes. In that case we
# use the header
if cls =~ /^(.*?)::/
ttfile.puts("#include <#{$1}>")
else
ttfile.puts("#{struct.kind.to_s} #{cls};")
end
ttfile.puts("namespace tl {")
ttfile.puts "template <> struct type_traits<#{cls}> : public type_traits<void> {"
if !conf.has_copy_ctor?(cls) || is_abstract || (eq_op && eq_op.visibility == :private)
ttfile.puts " typedef tl::false_tag has_copy_constructor;"
end
if !conf.has_default_ctor?(cls) || is_abstract
ttfile.puts " typedef tl::false_tag has_default_constructor;"
end
if (dtor = struct.get_dtor) && dtor.visibility != :public
ttfile.puts " typedef tl::false_tag has_public_destructor;"
end
ttfile.puts "};"
ttfile.puts "}"
ttfile.puts ""
if struct.needs_adaptor(conf)
ttfile.puts("class #{clsn}_Adaptor;")
ttfile.puts("namespace tl {")
ttfile.puts "template <> struct type_traits<#{clsn}_Adaptor> : public type_traits<void> {"
if !conf.has_copy_ctor?(cls) || (eq_op && eq_op.visibility == :private)
ttfile.puts " typedef tl::false_tag has_copy_constructor;"
end
if !conf.has_default_ctor?(cls)
ttfile.puts " typedef tl::false_tag has_default_constructor;"
end
ttfile.puts "};"
ttfile.puts "}"
ttfile.puts ""
end
# walk through the subclasses
(struct.body_decl || []).each do |bd|
if bd.is_a?(CPPStructDeclaration) && bd.visibility == :public && bd.struct.body_decl && bd.myself != "" && !conf.is_class_dropped?(cls, bd.myself)
produce_ttfile_traits(ttfile, conf, bd)
end
end
end
def produce_ttfile(conf)
ttfile_name = "gsiDecl#{modn}TypeTraits.h"
ttfile_path = $gen_dir + "/" + ttfile_name
ttfile_path && File.open(ttfile_path, "w") do |ttfile|
ttfile.puts(<<"END");
/*
KLayout Layout Viewer
Copyright (C) 2006-2022 Matthias Koefferlein
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
END
ttfile.puts("/**")
ttfile.puts("* @file #{ttfile_path}")
ttfile.puts("* @brief Type traits for the Qt binding classes")
ttfile.puts("*")
ttfile.puts("* DO NOT EDIT THIS FILE. ")
ttfile.puts("* This file has been created automatically")
ttfile.puts("*/")
ttfile.puts("")
ttfile.puts("#ifndef _HDR_gsiDecl#{modn}TypeTraits")
ttfile.puts("#define _HDR_gsiDecl#{modn}TypeTraits")
ttfile.puts("")
ttfile.puts("#include \"gsiTypes.h\"")
ttfile.puts("")
ttfile.puts("")
prod_list(conf).each do |decl_obj|
if decl_obj.is_a?(CPPStructDeclaration)
decl_obj.myself && produce_ttfile_traits(ttfile, conf, decl_obj)
elsif decl_obj.is_a?(CPPNamespace)
cls = decl_obj.myself
ttfile.puts("class #{cls}_Namespace;")
ttfile.puts("namespace tl {")
ttfile.puts "template <> struct type_traits<#{cls}_Namespace> : public type_traits<void> {"
ttfile.puts " typedef tl::false_tag has_copy_constructor;"
ttfile.puts " typedef tl::false_tag has_default_constructor;"
ttfile.puts "};"
ttfile.puts("}")
ttfile.puts ""
end
end
ttfile.puts("")
ttfile.puts("#endif")
puts("#{ttfile_name} written.")
end
end
def produce_externals
externals_name = "gsiQtExternals.h"
@@ -3232,7 +3246,7 @@ bp.read(input_file)
puts("Collecting used enums ..")
l = bp.prod_list(conf)
l.each_with_index do |decl_obj,i|
puts "#{decl_obj.myself}: #{i+1}/#{l.size}"
decl_obj.myself && puts("#{decl_obj.myself}: #{i+1}/#{l.size}")
bp.collect_used_enums(conf, decl_obj)
end
@@ -3253,9 +3267,6 @@ end
puts("Producing class list")
bp.produce_class_list
puts("Producing type traits file ..")
bp.produce_ttfile(conf)
puts("Producing main source file ..")
bp.produce_main_source
+38 -9
View File
@@ -196,7 +196,7 @@ module QualifiedNameResolver
@id2obj && @id2obj[id]
end
def resolve_qid(qid)
def resolve_qid(qid, stop = nil, include_other = true)
qid.is_a?(CPPQualifiedId) || raise("Argument of resolve_qid must be a CPPQualifiedId object")
@@ -206,22 +206,30 @@ module QualifiedNameResolver
while root.parent
root = root.parent
end
obj = root.resolve_qid(qid)
obj = root.resolve_qid(qid, nil, false)
else
obj = id2obj(qid.parts[0].id)
if obj && qid.parts.size > 1
# The part may be a typedef: resolve it in that case before we proceed
while obj && obj.is_a?(CPPTypedef)
obj = obj.type.concrete.is_a?(CPPQualifiedId) && self.resolve_qid(obj.type.concrete)
obj = obj.type.concrete.is_a?(CPPQualifiedId) && self.resolve_qid(obj.type.concrete, stop, include_other)
end
if obj
qid_new = qid.dup
qid_new.parts = qid.parts[1 .. -1]
obj = obj.respond_to?(:resolve_qid) && obj.resolve_qid(qid_new)
obj = obj.respond_to?(:resolve_qid) && obj.resolve_qid(qid_new, stop, include_other)
end
end
if ! obj && self.parent
obj = self.parent.resolve_qid(qid)
if ! obj && include_other
# try base classes
self.other_children.each do |bc|
if bc != self && bc.respond_to?(:resolve_qid)
(obj = bc.resolve_qid(qid, self, false)) && break
end
end
end
if ! obj && self.parent && self.parent != stop
obj = self.parent.resolve_qid(qid, stop, include_other)
end
end
@@ -281,6 +289,10 @@ class CPPDeclaration
[]
end
def other_children
[]
end
def myself
self.type.name
end
@@ -295,8 +307,13 @@ class CPPEnumDeclaration
[]
end
def other_children
[]
end
def myself
self.enum.name.to_s
# exclude forward declarations
self.enum.specs && self.enum.name.to_s
end
end
@@ -309,6 +326,10 @@ class CPPEnumSpec
[]
end
def other_children
[]
end
def myself
self.name.to_s
end
@@ -352,6 +373,10 @@ class CPPTypedef
[]
end
def other_children
[]
end
end
class CPPStructDeclaration
@@ -366,7 +391,7 @@ class CPPStructDeclaration
# add enum constants (CPPEnumSpec)
(self.struct.body_decl || []).each do |bd|
if bd.is_a?(CPPEnumDeclaration) && bd.enum && bd.enum.specs
if bd.is_a?(CPPEnumDeclaration) && bd.enum && bd.enum.specs && !bd.enum.is_class
c += bd.enum.specs
end
end
@@ -394,7 +419,7 @@ class CPPStructDeclaration
# The parent may be null for template base classes which are
# forward-declared .. we're not interested in this case.
if self.parent
bc_obj = self.parent.resolve_qid(bc.class_id)
bc_obj = self.parent.resolve_qid(bc.class_id, nil, false)
# NOTE: it may look strange to test whether the base class is the class itself but
# since we do a half-hearted job of resolving template variants, this may happen
# if we derive a template specialization from another one (specifically
@@ -523,6 +548,10 @@ class CPPModule
end
def other_children
[]
end
def remove(d)
self.decls.delete(d)
end