C++: Separate compiler option from CppDeclarationGenerator

This commit is contained in:
Katy Coe
2020-07-02 15:17:12 +02:00
parent 01519c4c29
commit 0731b380fd
2 changed files with 24 additions and 21 deletions

View File

@@ -0,0 +1,18 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace Il2CppInspector.Cpp
{
public static class CppCompiler
{
public enum Type
{
BinaryFormat, // Inheritance structs use C syntax, and will automatically choose MSVC or GCC based on inferred compiler.
MSVC, // Inheritance structs are laid out assuming the MSVC compiler, which recursively includes base classes
GCC, // Inheritance structs are laid out assuming the GCC compiler, which packs members from all bases + current class together
}
public static Type GuessFromImage(IFileFormatReader image) => (image is PEReader? Type.MSVC : Type.GCC);
}
}

View File

@@ -28,13 +28,7 @@ namespace Il2CppInspector.Cpp
// Different C++ compilers lay out C++ class structures differently, // Different C++ compilers lay out C++ class structures differently,
// meaning that the compiler must be known in order to generate class type structures // meaning that the compiler must be known in order to generate class type structures
// with the correct layout. // with the correct layout.
public enum InheritanceStyleEnum public CppCompiler.Type InheritanceStyle;
{
C, // Inheritance structs use C syntax, and will automatically choose MSVC or GCC based on inferred compiler.
MSVC, // Inheritance structs are laid out assuming the MSVC compiler, which recursively includes base classes
GCC, // Inheritance structs are laid out assuming the GCC compiler, which packs members from all bases + current class together
}
public InheritanceStyleEnum InheritanceStyle;
public CppDeclarationGenerator(Il2CppModel model, UnityVersion version) { public CppDeclarationGenerator(Il2CppModel model, UnityVersion version) {
this.model = model; this.model = model;
@@ -53,15 +47,9 @@ namespace Il2CppInspector.Cpp
InitializeNaming(); InitializeNaming();
InitializeConcreteImplementations(); InitializeConcreteImplementations();
}
private void GuessInheritanceStyle() { // Configure inheritance style based on binary type; this can be overridden by setting InheritanceStyle in the object initializer
if (InheritanceStyle == InheritanceStyleEnum.C) { InheritanceStyle = CppCompiler.GuessFromImage(model.Package.BinaryImage);
if (model.Package.BinaryImage is PEReader)
InheritanceStyle = InheritanceStyleEnum.MSVC;
else
InheritanceStyle = InheritanceStyleEnum.GCC;
}
} }
// C type declaration used to name variables of the given C# type // C type declaration used to name variables of the given C# type
@@ -206,9 +194,6 @@ namespace Il2CppInspector.Cpp
return; return;
} }
if (InheritanceStyle == InheritanceStyleEnum.C)
GuessInheritanceStyle();
/* Generate a list of all base classes starting from the root */ /* Generate a list of all base classes starting from the root */
List<TypeInfo> baseClasses = new List<TypeInfo>(); List<TypeInfo> baseClasses = new List<TypeInfo>();
for (var bti = ti; bti != null; bti = bti.BaseType) for (var bti = ti; bti != null; bti = bti.BaseType)
@@ -217,7 +202,7 @@ namespace Il2CppInspector.Cpp
var ns = CreateNamespace(); var ns = CreateNamespace();
if (InheritanceStyle == InheritanceStyleEnum.MSVC) { if (InheritanceStyle == CppCompiler.Type.MSVC) {
/* MSVC style: classes directly contain their base class as the first member. /* MSVC style: classes directly contain their base class as the first member.
* This causes all classes to be aligned to the alignment of their base class. */ * This causes all classes to be aligned to the alignment of their base class. */
TypeInfo firstNonEmpty = null; TypeInfo firstNonEmpty = null;
@@ -255,7 +240,7 @@ namespace Il2CppInspector.Cpp
csrc.Append($" struct {name}__Fields fields;\n"); csrc.Append($" struct {name}__Fields fields;\n");
csrc.Append($"}};\n"); csrc.Append($"}};\n");
} }
} else if (InheritanceStyle == InheritanceStyleEnum.GCC) { } else if (InheritanceStyle == CppCompiler.Type.GCC) {
/* GCC style: after the base class, all fields in the hierarchy are concatenated. /* GCC style: after the base class, all fields in the hierarchy are concatenated.
* This saves space (fields are "packed") but requires us to repeat fields from * This saves space (fields are "packed") but requires us to repeat fields from
* base classes. */ * base classes. */