C++: Output C++ enums as enum classes
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2017-2020 Katy Coe - http://www.djkaty.com - https://github.com/djkaty
|
||||
Copyright 2017-2021 Katy Coe - http://www.djkaty.com - https://github.com/djkaty
|
||||
Copyright 2020 Robert Xiao - https://robertxiao.ca
|
||||
|
||||
All rights reserved.
|
||||
@@ -152,11 +152,12 @@ namespace Il2CppInspector.Cpp
|
||||
if (ti.IsEnum) {
|
||||
// Enums should be represented using enum syntax
|
||||
// They otherwise behave like value types
|
||||
var namer = CreateNamespace().MakeNamer<FieldInfo>((field) => field.Name.ToCIdentifier());
|
||||
var underlyingType = AsCType(ti.GetEnumUnderlyingType());
|
||||
valueType = types.Enum(underlyingType, name);
|
||||
foreach (var field in ti.DeclaredFields) {
|
||||
if (field.Name != "value__")
|
||||
((CppEnumType)valueType).AddField(EnumNamer.GetName(field), field.DefaultValue);
|
||||
((CppEnumType)valueType).AddField(namer.GetName(field), field.DefaultValue);
|
||||
}
|
||||
|
||||
boxedType = GenerateObjectStruct(name + "__Boxed", ti);
|
||||
@@ -530,7 +531,6 @@ namespace Il2CppInspector.Cpp
|
||||
|
||||
GlobalsNamespace = CreateNamespace();
|
||||
GlobalNamer = GlobalsNamespace.MakeNamer<MethodBase>((method) => $"{TypeNamer.GetName(method.DeclaringType)}_{method.Name.ToCIdentifier()}");
|
||||
EnumNamer = GlobalsNamespace.MakeNamer<FieldInfo>((field) => $"{TypeNamer.GetName(field.DeclaringType)}_{field.Name.ToCIdentifier()}");
|
||||
}
|
||||
|
||||
// Reserve C/C++ keywords and built-in names
|
||||
@@ -571,11 +571,10 @@ namespace Il2CppInspector.Cpp
|
||||
public CppNamespace.Namer<TypeInfo> TypeNamer { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Namespace for global variables, enum values and methods
|
||||
/// Namespace for global variables and methods
|
||||
/// </summary>
|
||||
public CppNamespace GlobalsNamespace { get; private set; }
|
||||
public CppNamespace.Namer<MethodBase> GlobalNamer { get; private set; }
|
||||
public CppNamespace.Namer<FieldInfo> EnumNamer { get; private set; }
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2020 Katy Coe - http://www.djkaty.com - https://github.com/djkaty
|
||||
Copyright 2020-2021 Katy Coe - http://www.djkaty.com - https://github.com/djkaty
|
||||
|
||||
All rights reserved.
|
||||
*/
|
||||
@@ -78,10 +78,14 @@ namespace Il2CppInspector.Cpp
|
||||
// An enum key and value pair
|
||||
public class CppEnumField : CppField
|
||||
{
|
||||
// The enum type this field belongs to
|
||||
public CppEnumType DeclaringType { get; }
|
||||
|
||||
// The value of this key name
|
||||
public object Value { get; }
|
||||
|
||||
public CppEnumField(string name, CppType type, object value) : base(name, type) => Value = value;
|
||||
public CppEnumField(CppEnumType declType, string name, CppType type, object value) : base(name, type)
|
||||
=> (DeclaringType, Value) = (declType, value);
|
||||
|
||||
// We output as hex to avoid unsigned value compiler errors for top bit set values in VS <= 2017
|
||||
// We'll get compiler warnings instead but it will still compile
|
||||
@@ -91,10 +95,12 @@ namespace Il2CppInspector.Cpp
|
||||
// Signed number with top bit set (only perform cast if underlying type is signed)
|
||||
var fieldIsNegative = signed && ((long) Convert.ChangeType(Value, typeof(long))) < 0;
|
||||
|
||||
if (fieldIsNegative)
|
||||
return $"{Name} = {Value}";
|
||||
var fieldName = (format.Contains('c')? DeclaringType.Name + "_" : "") + Name;
|
||||
|
||||
return string.Format("{0} = 0x{1:x" + Type.SizeBytes * 2 + "}", Name, Value);
|
||||
if (fieldIsNegative)
|
||||
return $"{fieldName} = {Value}";
|
||||
|
||||
return string.Format("{0} = 0x{1:x" + Type.SizeBytes * 2 + "}", fieldName, Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2020 Katy Coe - http://www.djkaty.com - https://github.com/djkaty
|
||||
Copyright 2020-2021 Katy Coe - http://www.djkaty.com - https://github.com/djkaty
|
||||
|
||||
All rights reserved.
|
||||
*/
|
||||
@@ -418,13 +418,13 @@ namespace Il2CppInspector.Cpp
|
||||
|
||||
public CppEnumType(CppType underlyingType) : base(ComplexValueType.Enum) => UnderlyingType = underlyingType;
|
||||
|
||||
public void AddField(string name, object value) => AddField(new CppEnumField(name, UnderlyingType, value));
|
||||
public void AddField(string name, object value) => AddField(new CppEnumField(this, name, UnderlyingType, value));
|
||||
|
||||
// Return the type as a field
|
||||
public override string ToFieldString(string fieldName, string format = "") {
|
||||
// C++
|
||||
if (!format.Contains('c'))
|
||||
return "enum " + Name + " " + fieldName;
|
||||
return Name + " " + fieldName;
|
||||
|
||||
// For the C-compatible definition, we have an alignment problem when the enum
|
||||
// does not derive from the architecture integer width.
|
||||
@@ -439,7 +439,7 @@ namespace Il2CppInspector.Cpp
|
||||
if (format.Contains('c'))
|
||||
sb.Append($"enum {Name} {{");
|
||||
else
|
||||
sb.Append($"enum {Name} : {UnderlyingType.Name} {{");
|
||||
sb.Append($"enum class {Name} : {UnderlyingType.Name} {{");
|
||||
|
||||
foreach (var field in Fields.Values.SelectMany(f => f))
|
||||
sb.Append("\n " + string.Join("\n ", field.ToString(format).Split('\n')) + ",");
|
||||
|
||||
Reference in New Issue
Block a user