예제 #1
0
        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);
        }
예제 #2
0
        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);
        }