C++: Various tweaks

Indent output
Handle bool fields
Skip comments and methods
Check that every line that matters is parsed
Update test to check every Unity version
This commit is contained in:
Katy Coe
2020-06-27 21:47:55 +02:00
parent 8f56aea002
commit 8a85acb242
2 changed files with 106 additions and 8 deletions

View File

@@ -151,7 +151,7 @@ namespace Il2CppInspector.CppUtils
if (Fields.Any()) {
sb.AppendLine("{");
foreach (var field in Fields.Values.SelectMany(f => f))
sb.AppendLine(" " + field);
sb.AppendLine(" " + string.Join("\n ", field.ToString().Split('\n')));
sb.Append($"}} {Name}{(Name.Length > 0 ? " " : "")}/* Size: 0x{SizeBytes:x2} */;");
}
@@ -236,6 +236,7 @@ namespace Il2CppInspector.CppUtils
new CppType("int", 32),
new CppType("float", 32),
new CppType("double", 64),
new CppType("bool", 8),
new CppType("void", 0)
};
@@ -270,10 +271,13 @@ namespace Il2CppInspector.CppUtils
var rgxAlignment = new Regex(@"__attribute__\(\(aligned\(([0-9]+)\)\)\)");
var rgxIsBitDirective = new Regex(@"#ifdef\s+IS_(32|64)BIT");
var rgxSingleLineComment = new Regex(@"/\*.*?\*/");
var currentType = new Stack<CppComplexType>();
bool inEnum = false;
bool falseIfBlock = false;
bool inComment = false;
bool inMethod = false;
string line;
// TODO: function pointer signatures
@@ -281,9 +285,65 @@ namespace Il2CppInspector.CppUtils
while ((line = lines.ReadLine()) != null) {
// Sanitize
// Remove comments
if (line.Contains("//"))
line = line.Substring(0, line.IndexOf("//", StringComparison.Ordinal));
// End of multi-line comment?
if (line.Contains("*/") && inComment) {
inComment = false;
line = line.Substring(line.IndexOf("*/", StringComparison.Ordinal) + 2);
}
if (inComment) {
Debug.WriteLine($"[COMMENT ] {line}");
continue;
}
// Remove all single-line comments
line = rgxSingleLineComment.Replace(line, "");
// Start of multi-line comment?
if (line.Contains("/*") && !inComment) {
inComment = true;
line = line.Substring(0, line.IndexOf("/*"));
}
// Ignore global variables
if (line.StartsWith("const ") && currentType.Count == 0) {
Debug.WriteLine($"[GLOBAL ] {line}");
continue;
}
// Ignore methods
// Note: This is a very lazy way of processing early version IL2CPP headers
if (line != "}" && inMethod) {
Debug.WriteLine($"[METHOD ] {line}");
continue;
}
if (line == "}" && inMethod) {
inMethod = false;
Debug.WriteLine($"[METHOD END ] {line}");
continue;
}
if (line.StartsWith("static inline ")) {
inMethod = true;
Debug.WriteLine($"[METHOD START ] {line}");
continue;
}
// Remove keywords we don't care about
line = rgxStripKeywords.Replace(line, "");
// Remove whitespace in multiple indirections
line = rgxCompressPtrs.Replace(line, "**");
// Process __attribute((aligned(x)))
var alignment = 0;
var alignmentMatch = rgxAlignment.Match(line);
if (alignmentMatch.Success) {
@@ -293,6 +353,10 @@ namespace Il2CppInspector.CppUtils
line = line.Trim();
// Ignore blank lines
if (line.Length == 0)
continue;
// Process #ifs before anything else
// Doesn't handle nesting but we probably don't need to (use a Stack if we do)
var ifdef = rgxIsBitDirective.Match(line);
@@ -544,16 +608,42 @@ namespace Il2CppInspector.CppUtils
continue;
}
// Make sure we're not ignoring anything we shouldn't
Debug.WriteLine($"[IGNORE ] {line}");
// Block opens
if (line == "{")
continue;
// Enum values
if (inEnum)
continue;
// Global variables
if (line.StartsWith("static"))
continue;
// Pragma directives
if (line.StartsWith("#pragma"))
continue;
// Imports
if (line.StartsWith("extern"))
continue;
throw new InvalidOperationException("Could not understand C++ code: " + line);
}
}
// Generate a populated CppTypes object from a set of Unity headers
public static CppTypes FromUnityHeaders(UnityVersion version, int wordSize = 32) {
public static CppTypes FromUnityVersion(UnityVersion version, int wordSize = 32)
=> FromUnityHeaders(UnityHeader.GetHeaderForVersion(version));
public static CppTypes FromUnityHeaders(UnityHeader header, int wordSize = 32) {
var cppTypes = new CppTypes(wordSize);
// Process Unity headers
var headers = UnityHeader.GetHeaderForVersion(version).GetHeaderText();
var headers = header.GetHeaderText();
cppTypes.AddFromDeclarationText(headers);
return cppTypes;