summaryrefslogtreecommitdiff
path: root/tools/libdol2asm/data
diff options
context:
space:
mode:
authorJulgodis <>2021-04-08 01:47:05 +0200
committerJulgodis <>2021-04-08 01:47:05 +0200
commita23a10639979ee10cbea5ffdadadc490d9e60227 (patch)
tree75a86f6d6760a9f4183f3e97606eb7747399a0a8 /tools/libdol2asm/data
parentdca1d2a1c032f239c65aa1b7767132c12e89f628 (diff)
demangle data-symbols
Diffstat (limited to 'tools/libdol2asm/data')
-rw-r--r--tools/libdol2asm/data/base.py114
-rw-r--r--tools/libdol2asm/data/function/base.py33
-rw-r--r--tools/libdol2asm/data/symbol.py15
3 files changed, 96 insertions, 66 deletions
diff --git a/tools/libdol2asm/data/base.py b/tools/libdol2asm/data/base.py
index 17fc8db82a..6ceada5eb9 100644
--- a/tools/libdol2asm/data/base.py
+++ b/tools/libdol2asm/data/base.py
@@ -40,6 +40,17 @@ class ArbitraryData(Symbol):
return True
@property
+ def is_class_symbol(self):
+ # @!game
+ # don't generate static class variables for 'cNullVec__6Z2Calc', because it will not compile.
+ # Z2Calc::cNullVec seems to be static data that is initialized in the class definition, thus,
+ # every translation unit which uses Z2Calc will have a copy of the Z2Calc::cNullVec in the data
+ # section. Could not find a way to make this compile without easily.
+ if self.identifier.name == "cNullVec__6Z2Calc":
+ return False
+ return self.demangled_name and self.has_class and not self.has_template
+
+ @property
def element_size(self):
return 1
@@ -67,18 +78,42 @@ class ArbitraryData(Symbol):
def array_type(self):
if self.zero_length:
- return ZeroArrayType.create(self.element_type())
+ return ZeroArrayType.create(self.element_type())
return PaddingArrayType.create(
self.element_type(),
self.size // self.element_size,
self.padding // self.element_size)
def cpp_reference(self, accessor, addr):
+ name = self.declaration_name(forward=False, c_export=False,full_qualified_name=True)
if addr == self.addr:
- return f"&{self.identifier.label}"
+ return f"&{name}"
else:
offset = addr - self.addr
- return f"(((char*)&{self.identifier.label})+0x{offset:X})"
+ return f"(((char*)&{name})+0x{offset:X})"
+
+ def declaration_name(self, forward: bool,
+ c_export: bool,
+ full_qualified_name: bool):
+ if not self.is_class_symbol or c_export:
+ return self.identifier.label
+
+ if full_qualified_name:
+ return self.demangled_name.to_str()
+ else:
+ return self.demangled_name.last.to_str()
+
+ async def export_declaration_header(self, exporter,
+ builder: AsyncBuilder,
+ forward: bool,
+ c_export: bool,
+ full_qualified_name: bool):
+ name = self.declaration_name(c_export=c_export,
+ forward=forward,
+ full_qualified_name=full_qualified_name)
+
+ decl_type = self.array_type()
+ await builder.write_nonewline(decl_type.decl(name))
async def export_forward_references(self,
exporter,
@@ -86,54 +121,53 @@ class ArbitraryData(Symbol):
c_export: bool = False):
if not c_export:
return
-
- if self.is_static and self.export_static:
- if not self.require_forward_reference:
- return
- await self.export_section_header(builder)
+ if not self.is_class_symbol:
+ if self.is_static and self.export_static:
+ if not self.require_forward_reference:
+ return
- if not (self.is_static and self.export_static):
- await self.export_extern(builder)
+ await self.export_section_header(builder)
- name = self.identifier.label
- if self.demangled_name:
- name = self.demangled_name.to_str(specialize_templates=False,
- without_template=False)
+ if not self.is_class_symbol:
+ if not (self.is_static and self.export_static):
+ await self.export_extern(builder)
- decl_type = self.array_type()
- await builder.write_nonewline(decl_type.decl(name))
+ await self.export_declaration_header(exporter, builder,
+ forward=True,
+ c_export=c_export,
+ full_qualified_name=False)
await builder.write(";")
async def export_declaration_head(self, exporter, builder: AsyncBuilder):
- if self.demangled_name:
- name = self.demangled_name.to_str(specialize_templates=False,
- without_template=False)
- else:
- name = self.identifier.label
+ name = self.declaration_name(c_export=False,
+ forward=False,
+ full_qualified_name=True)
decl_type = self.array_type()
- # for empty symbols that should be exported, we need to double declare it.
- # otherwise, the compiler thinks that we're not actual declaring it.
- is_extern = not (self.is_static and self.export_as_static)
- if not self.data and is_extern:
- await self.export_section(builder)
- if self.force_section:
- await self.export_section_header(builder)
+ if not self.is_class_symbol:
+ # for empty symbols that should be exported, we need to double declare it.
+ # otherwise, the compiler thinks that we're not actual declaring it.
+ is_extern = not (self.is_static and self.export_as_static)
+ if not self.data and is_extern:
+ await self.export_section(builder)
+ if self.force_section:
+ await self.export_section_header(builder)
- await self.export_extern(builder)
- await builder.write_nonewline(decl_type.decl(name))
- await builder.write(";")
+ await self.export_extern(builder)
+ await builder.write_nonewline(decl_type.decl(name))
+ await builder.write(";")
await self.export_section(builder)
if self.force_section:
await self.export_section_header(builder)
- if not is_extern:
- await self.export_static(builder)
- elif self.data and is_extern:
- await self.export_extern(builder)
+ if not self.is_class_symbol:
+ if not is_extern:
+ await self.export_static(builder)
+ elif self.data and is_extern:
+ await self.export_extern(builder)
await builder.write_nonewline(decl_type.decl(name))
@@ -168,11 +202,11 @@ class ArbitraryData(Symbol):
if self._section == ".rodata":
await builder.write(f"COMPILER_STRIP_GATE({self.addr:08X}, {self.cpp_reference(None, self.addr)});")
- #await builder.write_nonewline("SECTION_DEAD ")
- #await builder.write_nonewline("void* const ")
- #await builder.write_nonewline(f"cg_{self.addr:08X} = (void*)(")
- #await builder.write_nonewline(self.cpp_reference(None, self.addr))
- #await builder.write(f");")
+ # await builder.write_nonewline("SECTION_DEAD ")
+ # await builder.write_nonewline("void* const ")
+ # await builder.write_nonewline(f"cg_{self.addr:08X} = (void*)(")
+ # await builder.write_nonewline(self.cpp_reference(None, self.addr))
+ # await builder.write(f");")
if self.requires_force_active:
await builder.write(f"#pragma pop")
diff --git a/tools/libdol2asm/data/function/base.py b/tools/libdol2asm/data/function/base.py
index e74d2aeaa6..0eda461881 100644
--- a/tools/libdol2asm/data/function/base.py
+++ b/tools/libdol2asm/data/function/base.py
@@ -18,15 +18,13 @@ special_func_no_return = set([
class Function(Symbol):
return_type: Type = None
argument_types: List[Type] = field(default_factory=list)
- func_name: libdemangle.QualifiedName = None
special_func_name: str = None
func_is_const: bool = False
- template_index: int = -1
asm: bool = False
@property
def uses_any_templates(self):
- if self.func_name and self.func_name.has_template:
+ if self.demangled_name and self.demangled_name.has_template:
return True
is_templated = [False]
@@ -45,10 +43,6 @@ class Function(Symbol):
return is_templated[0]
@property
- def uses_class_template(self):
- return self.func_name and self.func_name.has_template
-
- @property
def is_static(self):
s = self.reference_count.static
e = self.reference_count.extern
@@ -57,7 +51,7 @@ class Function(Symbol):
if not static_by_references:
return False
- if not self.func_name:
+ if not self.demangled_name:
# very arbitrary, but function begining with __ are often special
if self.identifier.name and self.identifier.name.startswith("__"):
return False
@@ -70,13 +64,13 @@ class Function(Symbol):
return self.identifier.label
def function_name(self, c_export: bool, full_qualified_name: bool):
- if not self.func_name or c_export:
+ if not self.demangled_name or c_export:
return self.identifier.label
- if self.func_name.require_specialization:
+ if self.demangled_name.require_specialization:
return self.identifier.label
- name = self.func_name
+ name = self.demangled_name
if self.special_func_name and self.has_class:
# fix up the constructor and destructor if the function is template specialized
special_name = None
@@ -87,16 +81,13 @@ class Function(Symbol):
if special_name:
name = NamedType(
- self.func_name.names[:-1] + [ClassName(special_name, [])])
+ self.demangled_name.names[:-1] + [ClassName(special_name, [])])
if full_qualified_name:
return name.to_str()
else:
return name.last.to_str()
- def is_demangled(self):
- return self.func_name != None
-
def valid_reference(self, addr):
return addr % 4 == 0
@@ -115,14 +106,6 @@ class Function(Symbol):
def types(self):
return set()
- @property
- def has_class(self):
- return self.func_name and self.func_name.has_class
-
- @property
- def has_template(self):
- return self.func_name and self.func_name.has_template
-
async def export_function_header(self, exporter,
builder: AsyncBuilder,
forward: bool,
@@ -158,7 +141,7 @@ class Function(Symbol):
if self._section == ".init":
await builder.write_nonewline(f"SECTION_INIT ")
- elif c_export or (self.func_name and self.func_name.require_specialization and full_qualified_name):
+ elif c_export or (self.demangled_name and self.demangled_name.require_specialization and full_qualified_name):
await builder.write_nonewline(f"extern \"C\" ")
if self.is_static and not self.has_class:
@@ -173,7 +156,7 @@ class Function(Symbol):
is_special_function = (
self.special_func_name in special_func_no_return)
specialized = (
- self.func_name and self.func_name.require_specialization)
+ self.demangled_name and self.demangled_name.require_specialization)
if c_export:
await builder.write_nonewline(f"{return_type.type()} ")
await builder.write_nonewline(f"{self.function_name(c_export=True,full_qualified_name=full_qualified_name)}")
diff --git a/tools/libdol2asm/data/symbol.py b/tools/libdol2asm/data/symbol.py
index 8c4c2dccb4..5a708fb361 100644
--- a/tools/libdol2asm/data/symbol.py
+++ b/tools/libdol2asm/data/symbol.py
@@ -62,6 +62,7 @@ class Symbol:
_section: str = None
alignment: int = 0
relative_addr: int = -1
+ template_index: int = -1
demangled_name: NamedType = None
references: Set[int] = field(default_factory=set)
@@ -101,8 +102,20 @@ class Symbol:
return True
@property
+ def has_class(self):
+ return self.demangled_name and self.demangled_name.has_class
+
+ @property
+ def has_template(self):
+ return self.demangled_name and self.demangled_name.has_template
+
+ @property
def uses_class_template(self):
- return False
+ return self.demangled_name and self.demangled_name.has_template
+
+ @property
+ def is_demangled(self):
+ return self.demangled_name != None
@property
def requires_force_active(self):