// // Determines if this is a structure that is part of native interop, so we would // keep the layout the same as managed code // public bool IsStructure(CXXRecordDecl decl) { // Quick and dirty: it really should use our manually curated list of known value types, // but for now, this will do var classesNotStructs = new[] {"String", "Skeleton", "XMLElement"}; if (classesNotStructs.Contains(decl.Name)) return false; if (decl.TagKind == TagDeclKind.Struct || !(decl.IsDerivedFrom(ScanBaseTypes.UrhoRefCounted) || decl == ScanBaseTypes.UrhoRefCounted)) return true; return false; }
void Bind(CXXRecordDecl baseDecl, CXXRecordDecl decl) { var name = decl.Name; //Console.WriteLine(name); bool isStruct = IsStructure (decl); PushType(new TypeDeclaration { Name = RemapTypeName (decl.Name), ClassType = isStruct ? ClassType.Struct : ClassType.Class, Modifiers = Modifiers.Partial | Modifiers.Public | Modifiers.Unsafe }, StringUtil.GetTypeComments(decl)); if (baseDecl != null) { foreach (var baseType in decl.Bases) { var baseName = baseType.Decl?.Name; if (baseName == null) continue; // WorkItem is a structure, with a RefCount base class, avoid that if (IsStructure(decl)) continue; // // Only a (File, MemoryBuffer, VectorBuffer) // implement that, and the Serializer class is never // surfaced as an API entry point, so we should just inline the methods // from those classes into the generated class // if (baseName == "GPUObject" || baseName == "Thread" || baseName == "Octant" || baseName == "b2Draw" || baseName == "b2ContactListener" || baseName == "btIDebugDraw" || baseName == "btMotionState") continue; if (currentType.BaseTypes.Count > 0) baseName = "I" + baseName; currentType.BaseTypes.Add(new SimpleType(RemapTypeName(baseName))); } } // Determines if this is a subclass of RefCounted (but not RefCounted itself) bool refCountedSubclass = decl.TagKind == TagDeclKind.Class && decl.QualifiedName != "Urho3D::RefCounted" && decl.IsDerivedFrom(ScanBaseTypes.UrhoRefCounted); // Same for Urho3D::Object bool objectSubclass = decl.TagKind == TagDeclKind.Class && decl.QualifiedName != "Urho3D::Object" && decl.IsDerivedFrom(ScanBaseTypes.UrhoObjectType); if (refCountedSubclass) { var nativeCtor = new ConstructorDeclaration { Modifiers = Modifiers.Public, Body = new BlockStatement(), Initializer = new ConstructorInitializer() }; nativeCtor.Parameters.Add(new ParameterDeclaration(new SimpleType("IntPtr"), "handle")); nativeCtor.Initializer.Arguments.Add(new IdentifierExpression("handle")); currentType.Members.Add(nativeCtor); // The construtor with the emtpy chain flag nativeCtor = new ConstructorDeclaration { Modifiers = Modifiers.Protected, Body = new BlockStatement(), Initializer = new ConstructorInitializer() }; nativeCtor.Parameters.Add(new ParameterDeclaration(new SimpleType("UrhoObjectFlag"), "emptyFlag")); nativeCtor.Initializer.Arguments.Add(new IdentifierExpression("emptyFlag")); currentType.Members.Add(nativeCtor); } else if (IsStructure(decl)) { var serializable = new Attribute() { Type = new SimpleType("StructLayout") }; serializable.Arguments.Add(new TypeReferenceExpression(new MemberType(new SimpleType("LayoutKind"), "Sequential"))); var attrs = new AttributeSection(); attrs.Attributes.Add(serializable); currentType.Attributes.Add(attrs); } }
public override void VisitCXXRecordDecl(CXXRecordDecl decl, VisitKind visitKind) { //Console.WriteLine($"{decl.QualifiedName} {visitKind} "); if (decl.QualifiedName == ("Urho3D::String")) { //Console.WriteLine($"{decl.QualifiedName} {visitKind} {decl.IsCompleteDefinition}"); } if (visitKind != VisitKind.Enter || !decl.IsCompleteDefinition || decl.Name == null) { return; } if (visitKind == VisitKind.Leave) currentType = null; BaseNodeType baseNodeType; if (baseNodeTypes.TryGetValue(decl.QualifiedName, out baseNodeType)) { baseNodeType.Decl = decl; baseNodeType.Bind(); return; } foreach (var bnt in baseNodeTypes.Values) { if (bnt.Decl != null && decl.IsDerivedFrom(bnt.Decl)) { bnt.Bind(decl); return; } } }