private Type FromCXType(CXType type, IEnumerable <Type> hintTypes = null) { Type typeResult = null; switch (type.kind) { case CXTypeKind.CXType_DependentSizedArray: case CXTypeKind.CXType_ConstantArray: typeResult = new Type.Pointer(FromCXType(clang.getArrayElementType(type), hintTypes)); break; case CXTypeKind.CXType_MemberPointer: case CXTypeKind.CXType_Pointer: typeResult = new Type.Pointer(FromCXType(clang.getPointeeType(type), hintTypes)); break; case CXTypeKind.CXType_LValueReference: case CXTypeKind.CXType_RValueReference: typeResult = new Type.Reference(FromCXType(clang.getPointeeType(type), hintTypes)); break; case CXTypeKind.CXType_FirstBuiltin: return(Units.Types.Void); case CXTypeKind.CXType_Bool: return(Units.Types.Bool); case CXTypeKind.CXType_SChar: return(Units.Types.S8); case CXTypeKind.CXType_Char_S: return(Units.Types.S8); case CXTypeKind.CXType_UChar: return(Units.Types.U8); case CXTypeKind.CXType_Char_U: return(Units.Types.U8); case CXTypeKind.CXType_Short: return(Units.Types.S16); case CXTypeKind.CXType_UShort: return(Units.Types.U16); case CXTypeKind.CXType_Int: return(Units.Types.S32); case CXTypeKind.CXType_UInt: return(Units.Types.U32); case CXTypeKind.CXType_LongLong: return(Units.Types.S64); case CXTypeKind.CXType_ULongLong: return(Units.Types.U64); case CXTypeKind.CXType_Float: return(Units.Types.Single); case CXTypeKind.CXType_Double: return(Units.Types.Double); case CXTypeKind.CXType_Unexposed: { string name = clang.getCString(clang.getTypeSpelling(type)).Replace("...", "").Replace("const ", "").Replace("volatile ", ""); typeResult = hintTypes?.FirstOrDefault(t => t?.Name == name) ?? CppType.GetReference(name, hintTypes); break; } case CXTypeKind.CXType_Record: { string name = clang.getCString(clang.getTypeSpelling(type)).Replace("...", "").Replace("const ", "").Replace("volatile ", ""); typeResult = hintTypes?.FirstOrDefault(t => t?.Name == name) ?? CppType.GetReference(name, hintTypes); break; } case CXTypeKind.CXType_Enum: case CXTypeKind.CXType_Typedef: { CXCursor cursor = clang.getTypeDeclaration(type); Unit resolvedType; typeResult = units.TryGetValue(cursor, out resolvedType) ? resolvedType as Type : null; break; } } int templateCount = clang.Type_getNumTemplateArguments(type); if (typeResult != null && templateCount > 0 && !typeResult.Templates.Any() && typeResult is CppType) { for (uint i = 0; i < templateCount; i++) { Type templateType = FromCXType(clang.Type_getTemplateArgumentAsType(type, i), hintTypes); if (templateType != null) { (typeResult as CppType).templates.Add(templateType); } } } return(typeResult); }
private CXChildVisitResult VisitMethod(CXCursor cursor, CXCursor parent, IntPtr data) { Unit unitParent = units[parent]; string unitName = clang.getCString(clang.getCursorSpelling(cursor)); CXCursorKind unitKind = clang.getCursorKind(cursor); CppMethod unit; if (unitKind == CXCursorKind.CXCursor_Constructor && unitParent is CppType) { unit = new CppConstructor(unitParent as CppType); } else if (unitKind == CXCursorKind.CXCursor_Destructor && unitParent is CppType) { unit = new CppDestructor(unitParent as CppType); } else { unit = new CppMethod(unitParent, unitName); } // Find modifiers if (unitParent is Type && modifiers.ContainsKey(unitParent as Type)) { unit.modifiers = modifiers[unitParent as Type]; } if (clang.CXXMethod_isStatic(cursor) > 0) { unit.modifiers |= Modifiers.Static; } // Find result type if (unitKind != CXCursorKind.CXCursor_Constructor && unitKind != CXCursorKind.CXCursor_Destructor) { CXType result = clang.getCursorResultType(cursor); unit.result = FromCXType(result, GetAllTemplates(unitParent).Concat(new[] { unitParent as Type })); } // Merge with properties /*if (unitName.StartsWith("Get") || unitName.StartsWith("Set")) * { * CppField property = properties.FirstOrDefault(p => p.Name == unitName.Substring(3) && p.Parent == unitParent) as CppField; * if (property != null) * { * if (unitName.StartsWith("Get")) * property.getAccessor = unit; * else * property.setAccessor = unit; * } * }*/ // Parse templates int startPosition = unitName.IndexOf('<'); int stopPosition = startPosition == -1 ? -1 : unitName.IndexOf('>', startPosition); if (startPosition >= 0 && stopPosition >= 0) { string[] typeStrings = unitName.Substring(startPosition, stopPosition - startPosition).Split(',').Select(t => t.Trim()).ToArray(); foreach (string typeString in typeStrings) { unit.templates.Add(CppType.GetReference(typeString)); } if (unitParent is Type) { foreach (Type type in (unitParent as Type).Templates) { unit.templates.RemoveAll(t => t.Equals(type)); } } } units.Add(cursor, unit); if (unitParent is CppType) { (unitParent as CppType).methods.Add(unit); } return(CXChildVisitResult.CXChildVisit_Recurse); }