diff options
author | Stephen Kelly <steveire@gmail.com> | 2017-01-14 22:13:49 +0000 |
---|---|---|
committer | Stephen Kelly <steveire@gmail.com> | 2017-01-15 11:18:50 +0000 |
commit | 636d6acc7adf8bf7169d38833340161dc42d3484 (patch) | |
tree | 2ff1bbefa5808aec21e902b10c9547e359067604 /find-modules/sip_generator.py | |
parent | 8c347c61abafa68e247ff4664ae658cfa15af932 (diff) | |
download | extra-cmake-modules-636d6acc7adf8bf7169d38833340161dc42d3484.tar.gz extra-cmake-modules-636d6acc7adf8bf7169d38833340161dc42d3484.tar.bz2 |
Bindings: Fix handling of forward declarations
It is not appropriate to decorate each forward declaration with the SIP
attribute /External/. That is only needed for forward declarations of
types which are defined in a different module.
Local forward declarations can be omitted from the sip code. In sip
code, a forward declaration followed later by a full class definition is
an error.
Omit forward declarations unless they are decorated with the external
attribute. Introduce a rules database for consumers to decorate them
with the attribute as required.
Diffstat (limited to 'find-modules/sip_generator.py')
-rw-r--r-- | find-modules/sip_generator.py | 82 |
1 files changed, 47 insertions, 35 deletions
diff --git a/find-modules/sip_generator.py b/find-modules/sip_generator.py index 41dd6369..7df9de3d 100644 --- a/find-modules/sip_generator.py +++ b/find-modules/sip_generator.py @@ -313,30 +313,51 @@ class SipGenerator(object): pad = " " * ((level + 1) * 4) body += pad + "// {}\n".format(SipGenerator.describe(member)) body += decl + + + if container.kind == CursorKind.TRANSLATION_UNIT: + return body + + if container.kind == CursorKind.NAMESPACE: + container_type = "namespace " + name + elif container.kind in [CursorKind.CLASS_DECL, CursorKind.CLASS_TEMPLATE, + CursorKind.CLASS_TEMPLATE_PARTIAL_SPECIALIZATION]: + container_type = "class " + name + elif container.kind == CursorKind.STRUCT_DECL: + container_type = "struct " + name + elif container.kind == CursorKind.UNION_DECL: + container_type = "union " + name + else: + raise AssertionError( + _("Unexpected container {}: {}[{}]").format(container.kind, name, container.extent.start.line)) + + sip["decl"] = container_type + sip["template_parameters"] = template_type_parameters + + pad = " " * (level * 4) + # # Empty containers are still useful if they provide namespaces or forward declarations. # - if not body and level >= 0: - body = "\n" + if not body: text = self._read_source(container.extent) if not text.endswith("}"): # # Forward declaration. # - sip["annotations"].add("External") - if body and level >= 0: - if container.kind == CursorKind.NAMESPACE: - container_type = "namespace " + name - elif container.kind in [CursorKind.CLASS_DECL, CursorKind.CLASS_TEMPLATE, - CursorKind.CLASS_TEMPLATE_PARTIAL_SPECIALIZATION]: - container_type = "class " + name - elif container.kind == CursorKind.STRUCT_DECL: - container_type = "struct " + name - elif container.kind == CursorKind.UNION_DECL: - container_type = "union " + name - else: - raise AssertionError( - _("Unexpected container {}: {}[{}]").format(container.kind, name, container.extent.start.line)) + modifying_rule = self.rules.forward_declaration_rules().apply(container, sip) + if sip["name"]: + if modifying_rule: + body += "// Modified {} (by {}):\n".format(SipGenerator.describe(container), modifying_rule) + if "External" in sip["annotations"]: + body += pad + sip["decl"] + body += " /External/;\n" + else: + body = pad + "// Discarded {} (by {})\n".format(SipGenerator.describe(container), "default forward declaration handling") + + else: + body = pad + "// Discarded {} (by {})\n".format(SipGenerator.describe(container), modifying_rule) + else: # # Generate private copy constructor for non-copyable types. # @@ -345,33 +366,24 @@ class SipGenerator(object): # # Flesh out the SIP context for the rules engine. # - sip["template_parameters"] = template_type_parameters - sip["decl"] = container_type sip["base_specifiers"] = base_specifiers sip["body"] = body modifying_rule = self.rules.container_rules().apply(container, sip) - pad = " " * (level * 4) if sip["name"]: decl = "" if modifying_rule: decl += "// Modified {} (by {}):\n".format(SipGenerator.describe(container), modifying_rule) decl += pad + sip["decl"] - if "External" in sip["annotations"]: - # - # SIP /External/ does not seem to work as one might wish. Suppress. - # - body = decl + " /External/;\n" - body = pad + "// Discarded {} (by {})\n".format(SipGenerator.describe(container), "/External/ handling") - else: - if sip["base_specifiers"]: - decl += ": " + ", ".join(sip["base_specifiers"]) - if sip["annotations"]: - decl += " /" + ",".join(sip["annotations"]) + "/" - if sip["template_parameters"]: - decl = pad + "template <" + ", ".join(sip["template_parameters"]) + ">\n" + decl - decl += "\n" + pad + "{\n" - decl += "%TypeHeaderCode\n#include <{}>\n%End\n".format(include_filename) - body = decl + sip["body"] + pad + "};\n" + + if sip["base_specifiers"]: + decl += ": " + ", ".join(sip["base_specifiers"]) + if sip["annotations"]: + decl += " /" + ",".join(sip["annotations"]) + "/" + if sip["template_parameters"]: + decl = pad + "template <" + ", ".join(sip["template_parameters"]) + ">\n" + decl + decl += "\n" + pad + "{\n" + decl += "%TypeHeaderCode\n#include <{}>\n%End\n".format(include_filename) + body = decl + sip["body"] + pad + "};\n" else: body = pad + "// Discarded {} (by {})\n".format(SipGenerator.describe(container), modifying_rule) return body |