Beispiel #1
0
        public bool DoVisit(CXCursor cursor, CXCursor parent)
        {
            CXType           cxType  = clang.getCursorType(cursor);
            TypeVisitContext context = new TypeVisitContext(cursor);
            NativeType       type    = TypeVisitorHelper.GetNativeType(AST_, cxType, context);

            return(true);
        }
Beispiel #2
0
        public static NativeType GetNativeType(AST ast, CXType cxType, TypeVisitContext context = null)
        {
            CXType type = cxType;

            if (ClangTraits.IsElaboratedType(type) || ClangTraits.IsUnexposedType(type))
            {
                type = clang.getCursorType(clang.getTypeDeclaration(type));
            }
            Debug.Assert(!ClangTraits.IsInvalid(type));

            string typeName = clang.getTypeSpelling(type).ToString();

            Debug.Assert(typeName.Length > 0);
            NativeType nativeType = ast.GetType(typeName);

            if (!nativeType.Parsed)
            {
                nativeType.Parsed = true;

                // get cursor spelling as unscoped name
                CXCursor declaration = clang.getTypeDeclaration(type);
                nativeType.UnscopedName = clang.getCursorSpelling(declaration).ToString();

                // not a type reference nor a type with qualifiers
                if (ClangTraits.IsTypeEntity(type) || typeName == "std::nullptr_t")
                {
                    ProcessTypeEntity(ast, nativeType, type, context);
                }
                // using or typedef
                else if (ClangTraits.IsTypedef(type))
                {
                    ProcessTypedef(ast, nativeType, type, context);
                }
                else if (ClangTraits.IsArray(type))
                {
                    ProcessArray(ast, nativeType, type, context);
                }
                // reference and pointer
                else if (ClangTraits.IsReference(type) || ClangTraits.IsPointer(type))
                {
                    ProcessReferencePointer(ast, nativeType, type, context);
                }
                else if (ClangTraits.IsMemberPointer(type))
                {
                    ProcessMemberPointer(ast, nativeType, cxType, context);
                }
                else
                {
                    Debug.Assert(false);
                }
            }

            return(nativeType);
        }
Beispiel #3
0
        private static void ProcessArray(AST ast, NativeType type, CXType cxType, TypeVisitContext context)
        {
            // set as array
            CXType          elementType = clang.getArrayElementType(cxType);
            NativeArrayType arr         = new NativeArrayType
            {
                Count = (int)clang.getArraySize(cxType),
                Type  = GetNativeType(ast, elementType, context)
            };

            type.SetArray(arr);
        }
Beispiel #4
0
        private static void ProcessTypedef(AST ast, NativeType type, CXType cxType, TypeVisitContext context)
        {
            // get type redirection
            CXCursor typedefedCursor = clang.getTypeDeclaration(cxType);

            CXCursor refCursor = clang.getCursorReferenced(typedefedCursor);

            CXType     typedefedType       = clang.getTypedefDeclUnderlyingType(typedefedCursor);
            NativeType typedefedNativeType = GetNativeType(ast, typedefedType, context);

            type.SetTypedef(typedefedNativeType);
        }
Beispiel #5
0
        private static FunctionProto GetFunctionProto(AST ast, CXType funcType, TypeVisitContext context)
        {
            Debug.Assert(ClangTraits.IsFunction(funcType));
            FunctionProto proto = new FunctionProto();

            proto.ResultType = GetNativeType(ast, clang.getResultType(funcType), context);
            uint arity = (uint)clang.getNumArgTypes(funcType);

            for (uint loop = 0; loop < arity; ++loop)
            {
                CXType            argType = clang.getArgType(funcType, loop);
                FunctionParameter param   = new FunctionParameter();
                param.Type = GetNativeType(ast, argType, context);
                proto.AddParameter(param);
            }

            return(proto);
        }
Beispiel #6
0
        private static void ProcessTypeEntity(
            AST ast,
            NativeType type,
            CXType cxType,
            TypeVisitContext context)
        {
            type.IsConst = ClangTraits.IsConst(cxType);
            if (ClangTraits.IsBuiltInType(cxType))
            {
                type.SetBuiltin(ClangTraits.ToBasicType(cxType));
            }
            else
            {
                CXCursor cursor              = clang.getTypeDeclaration(cxType);
                CXType   theType             = clang.getCursorType(cursor);
                string   removeQualifierName = clang.getTypeSpelling(theType).ToString();

                if (ClangTraits.IsEnum(cxType))
                {
                    type.SetEnum(ast.GetEnum(removeQualifierName));
                }
                else if (ClangTraits.IsFunction(cxType))
                {
                    type.SetFunction(GetFunctionProto(ast, cxType, context));
                }
                else if (ClangTraits.IsUserDefiendType(cxType))
                {
                    NativeClass nativeClass = ast.GetClass(removeQualifierName);

                    // if native class is parsed already, the native class is a full specialization
                    // or the native class is a instantiation of a template or partial specialization
                    if (!nativeClass.IsClassEntity && !nativeClass.Parsed)
                    {
                        nativeClass.Parsed = true;
                        if (TemplateHelper.VisitTemplate(cursor, nativeClass, ast))
                        {
                            TemplateHelper.VisitTemplateParameter(cursor, theType, nativeClass, ast, context);
                        }
                    }

                    type.SetClass(nativeClass);
                }
            }
        }
Beispiel #7
0
        private void ProcessClassDetail(
            NativeClass thisClass,              // this class to parse
            CXCursor cursor,                    // current cursor
            CXType type,                        // current cursor type
            CXCursor parent                     // parent cursor
            )
        {
            // set unscoped name
            thisClass.UnscopedName = clang.getCursorSpelling(cursor).ToString();

            // set struct or class
            thisClass.ClassTag = ClangTraits.ToStructOrClass(cursor.kind);

            // abstract
            thisClass.IsAbstract = clang.CXXRecord_isAbstract(cursor) != 0;

            // virtual base
            thisClass.IsVirtualBase = clang.isVirtualBase(cursor) != 0;

            // set template instance info
            if (TemplateHelper.VisitTemplate(cursor, thisClass, AST_))
            {
                thisClass.IsFullSpecialization = true;

                TypeVisitContext context = new TypeVisitContext(cursor);
                TemplateHelper.VisitTemplateParameter(cursor, type, thisClass, AST_, context);
            }

            // set subclass
            if (ClangTraits.IsUserDefinedTypeDecl(parent))
            {
                Debug.Assert(OwnerClass_ != null);
                thisClass.IsEmbedded = true;
                thisClass.OwnerClass = OwnerClass_;

                SubClass subClass = new SubClass
                {
                    Access = ClangTraits.ToAccessSpecifier(clang.getCXXAccessSpecifier(cursor)),
                    Class  = thisClass
                };

                OwnerClass_.AddSubClass(subClass);
            }
        }
Beispiel #8
0
        private void ProcessTypeExport(NativeClass thisClass, CXCursor cursor, CXCursor parent)
        {
            // createfield context
            TypeVisitContext context = new TypeVisitContext(cursor);

            // get field type
            CXType     type       = clang.getCursorType(cursor);
            NativeType nativeType = TypeVisitorHelper.GetNativeType(AST_, type, context);

            // get field access specifier
            AccessSpecifier access = ClangTraits.ToAccessSpecifier(clang.getCXXAccessSpecifier(cursor));

            // create the exported member type
            MemberType memberType = new MemberType
            {
                Access = access,
                Type   = nativeType
            };

            thisClass.AddMemberType(memberType);
        }
Beispiel #9
0
        private void ProcessBaseClass(NativeClass thisClass, CXCursor cursor, CXCursor parent)
        {
            // get class name
            CXType type = clang.getCursorType(cursor);

            // type visit context
            TypeVisitContext context = new TypeVisitContext(cursor);

            // create the base class
            BaseClass baseClass = new BaseClass
            {
                // check access specifier
                Access = ClangTraits.ToAccessSpecifier(clang.getCXXAccessSpecifier(cursor)),
                // native class type
                Type = TypeVisitorHelper.GetNativeType(AST_, type, context),
                // check is virtual base
                IsVirtual = clang.isVirtualBase(cursor) != 0
            };

            // register base class
            thisClass.AddBaseClass(baseClass);
        }
Beispiel #10
0
        public static bool VisitTemplateParameter(
            CXCursor cursor,
            CXType type,
            NativeClass @class,
            AST ast,
            TypeVisitContext context)
        {
            ClassTemplate template = @class.OriginalTemplate;

            Debug.Assert(template != null);
            Debug.Assert(template.TP != null);

            int templateArgNum = clang.Type_getNumTemplateArguments(type);

            if (templateArgNum < 0)
            {
                return(false);
            }

            @class.SetTemplateParameterCount(templateArgNum);
            int contextIndex = 0;

            for (uint loop = 0; loop < templateArgNum; ++loop)
            {
                TemplateParameter param = template.TP.GetTemplateParameter(loop);
                Debug.Assert(param != null);

                if (param.Kind == TemplateParameterKind.Type)
                {
                    CXType argType = clang.Type_getTemplateArgumentAsType(type, loop);
                    Debug.Assert(!ClangTraits.IsInvalid(argType));
                    NativeType nativeArgType = TypeVisitorHelper.GetNativeType(ast, argType, context);
                    @class.SetTemplateParameter(loop, nativeArgType);
                }
                else if (param.Kind == TemplateParameterKind.NoneType ||
                         param.Kind == TemplateParameterKind.Dependent)
                {
                    string literal;
                    if (context != null && !context.Empty)
                    {
                        literal = context.Consume();
                    }
                    else
                    {
                        literal = (param.Extra as TemplateNonTypeParam).DefaultLiteral;
                    }

                    Debug.Assert(literal != null);

                    @class.SetTemplateParameter(loop, literal);
                    ++contextIndex;
                }
                else
                {
                    Debug.Assert(TemplateParameterKind.Template == param.Kind);
                    // not support now
                    ClassTemplate templateParam = null;
                    @class.SetTemplateParameter(loop, templateParam);
                }
            }

            return(true);
        }
Beispiel #11
0
        private static void ProcessMemberPointer(AST ast, NativeType type, CXType cxType, TypeVisitContext context)
        {
            CXType      classType   = clang.Type_getClassType(cxType);
            string      className   = clang.getTypeSpelling(classType).ToString();
            NativeClass nativeClass = ast.GetClass(className);

            CXType pointeeType = clang.getPointeeType(cxType);

            if (ClangTraits.IsFunction(pointeeType))
            {
                type.SetPMF(new MemberFunctionPointer
                {
                    Class    = nativeClass,
                    Function = GetFunctionProto(ast, pointeeType, context)
                });
            }
            else
            {
                type.SetPMD(new MemberDataPointer
                {
                    Class = nativeClass,
                    Data  = GetNativeType(ast, pointeeType, context)
                });
            }
        }
Beispiel #12
0
        private static void ProcessReferencePointer(AST ast, NativeType type, CXType cxType, TypeVisitContext context)
        {
            Debug.Assert(type.TypeKind == BasicType.Unknown);
            type.IsConst = ClangTraits.IsConst(cxType);

            CXType     pointeeType = clang.getPointeeType(cxType);
            NativeType nativeType  = GetNativeType(ast, pointeeType, context);

            if (ClangTraits.IsLValueReference(cxType))
            {
                type.SetTypeLValRef(nativeType);
            }
            else if (ClangTraits.IsRValueReference(cxType))
            {
                type.SetTypeRValRef(nativeType);
            }
            else if (ClangTraits.IsPointer(cxType))
            {
                type.SetPointer(nativeType);
            }

            Debug.Assert(type.TypeKind != BasicType.Unknown);
        }