コード例 #1
0
        public static bool VisitTemplate(CXCursor cursor, NativeClass c, AST ast)
        {
            CXType   type           = clang.getCursorType(cursor);
            CXCursor templateCursor = clang.getSpecializedCursorTemplate(cursor);

            if (ClangTraits.IsInvalid(templateCursor))
            {
                return(false);
            }

            string        templateID = clang.getCursorUSR(templateCursor).ToString();
            ClassTemplate template   = ast.GetClassTemplate(templateID);

            CXCursor      originalTemplateCursor = clang.getSpecializedCursorTemplate(templateCursor);
            ClassTemplate originalTemplate;

            if (ClangTraits.IsInvalid(originalTemplateCursor))
            {
                originalTemplate = template;
            }
            else
            {
                string originalTemplateID = clang.getCursorUSR(originalTemplateCursor).ToString();
                originalTemplate = ast.GetClassTemplate(originalTemplateID);
            }

            c.SetTemplate(template, originalTemplate);
            return(true);
        }
コード例 #2
0
        private CXChildVisitResult ContextVisitor(CXCursor cursor, CXCursor parent, IntPtr data)
        {
            // prepare context handle
            GCHandle      contextHandle = (GCHandle)data;
            List <string> context       = contextHandle.Target as List <string>;

            if (ClangTraits.IsNonTypeTemplateParamLiteral(cursor))
            {
                List <string> tokens  = ASTVisitor.GetCursorTokens(cursor);
                string        literal = string.Concat(tokens);
                context.Add(literal);
            }
            else if (ClangTraits.IsTemplateRef(cursor))
            {
                CXCursor refCursor = clang.getCursorReferenced(cursor);
                if (ClangTraits.IsTemplateAlias(refCursor))
                {
                    //clang.visitChildren(refCursor, ContextVisitor, new CXClientData(data));
                    clang.visitChildren(refCursor, (CXCursor c, CXCursor p, IntPtr d) =>
                    {
                        if (CXCursorKind.CXCursor_TypeAliasDecl == c.kind)
                        {
                            return(CXChildVisitResult.CXChildVisit_Recurse);
                        }
                        ContextVisitor(c, p, d);
                        return(CXChildVisitResult.CXChildVisit_Continue);
                    }, new CXClientData(data));
                }
            }

            return(CXChildVisitResult.CXChildVisit_Continue);
        }
コード例 #3
0
        private CXChildVisitResult Visitor(CXCursor cursor, CXCursor parent, IntPtr data)
        {
            if (CXCursorKind.CXCursor_ParmDecl == cursor.kind)
            {
                // prepare client data
                GCHandle      funcHandle = (GCHandle)data;
                FunctionProto proto      = funcHandle.Target as FunctionProto;

                CXType type = clang.getCursorType(cursor);

                FunctionParameter param = new FunctionParameter
                {
                    Name = clang.getCursorSpelling(cursor).ToString(),
                    Type = TypeVisitorHelper.GetNativeType(AST_, type)
                };

                clang.visitChildren(cursor, (CXCursor c, CXCursor p, IntPtr d) =>
                {
                    if (ClangTraits.IsLiteralCursor(c))
                    {
                        // get liter-string from token
                        List <string> tokens = ASTVisitor.GetCursorTokens(c);

                        // set default literal
                        param.DefaultValue = string.Concat(tokens);
                    }
                    return(CXChildVisitResult.CXChildVisit_Continue);
                }, new CXClientData(IntPtr.Zero));

                proto.AddParameter(param);
            }

            return(CXChildVisitResult.CXChildVisit_Recurse);
        }
コード例 #4
0
        private void ProcessMethod(NativeClass thisClass, CXCursor cursor, CXCursor parent)
        {
            string name       = clang.getCursorSpelling(cursor).ToString();
            bool   isStataic  = clang.CXXMethod_isStatic(cursor) != 0;
            bool   isConst    = clang.CXXMethod_isConst(cursor) != 0;
            bool   isVirtual  = clang.CXXMethod_isVirtual(cursor) != 0;
            bool   isAbastrct = clang.CXXMethod_isPureVirtual(cursor) != 0;

            // create method
            Method memberFunc = new Method(thisClass,
                                           name, isStataic, isConst, isVirtual, isAbastrct);
            OnVisitFunctionParameter func = (FunctionParameter param) =>
            {
                memberFunc.AddParameter(param);
            };

            // proces result type
            CXType resultType = clang.getCursorResultType(cursor);

            memberFunc.ResultType = TypeVisitorHelper.GetNativeType(AST_, resultType);

            // deep visit children
            GCHandle delegateHandler = GCHandle.Alloc(func);

            clang.visitChildren(cursor, ParameterVisitor, new CXClientData((IntPtr)delegateHandler));

            // process access specifier
            memberFunc.Access = ClangTraits.ToAccessSpecifier(clang.getCXXAccessSpecifier(cursor));

            // register method
            thisClass.AddMethod(memberFunc);
        }
コード例 #5
0
        void ProcessEnumDetail(Enumeration @enum, CXCursor cursor, CXCursor parent)
        {
            // unscoped name
            @enum.UnscopedName = clang.getCursorSpelling(cursor).ToString();

            // underlying type
            CXType    underlyingType = clang.getEnumDeclIntegerType(cursor);
            BasicType type           = ClangTraits.ToBasicType(underlyingType);

            @enum.Type = type;

            // is scoped
            @enum.IsEnumClass = clang.EnumDecl_isScoped(cursor) != 0;

            // check is parent is a class
            if (OwnerClass_ != null)
            {
                Debug.Assert(ClangTraits.IsUserDefinedTypeDecl(parent));
                OwnerClass_.AddSubEnum(new SubEnum
                {
                    Access = ClangTraits.ToAccessSpecifier(clang.getCXXAccessSpecifier(cursor)),
                    Enum   = @enum
                });
            }
        }
コード例 #6
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)
                });
            }
        }
コード例 #7
0
        private bool DealingWithDiagnostic(CXDiagnostic d)
        {
            // error spelling
            string spelling = clang.getDiagnosticSpelling(d).ToString();

            // category text
            string categoryText = clang.getDiagnosticCategoryText(d).ToString();

            // severity text
            CXDiagnosticSeverity severity = clang.getDiagnosticSeverity(d);
            string severityStr            = ClangTraits.ToString(severity);

            // source location
            CXSourceLocation location = clang.getDiagnosticLocation(d);
            CXFile           file     = new CXFile(IntPtr.Zero);

            clang.getInstantiationLocation(
                location,
                out file,
                out uint line,
                out uint column,
                out uint offset);

            string fileName = clang.getFileName(file).ToString();

            clang.disposeDiagnostic(d);

            string errorString = string.Format("{0}: {1}-{2}, IN {3}, line: {4}, column: {5}",
                                               severityStr, spelling, categoryText, fileName, line, column);

            return(ClangTraits.IsFatal(severity));
        }
コード例 #8
0
        private TemplateParameter GetTemplateTypeParameter(CXCursor cursor)
        {
            string            paramName  = clang.getCursorSpelling(cursor).ToString();
            bool              isVariadic = ClangTraits.IsVariadicTemplateParameter(cursor);
            TemplateParameter param      = new TemplateParameter(paramName, TemplateParameterKind.Type, isVariadic);

            return(param);
        }
コード例 #9
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);
        }
コード例 #10
0
        private TemplateParameter GetTemplateNonTypeParameter(AST ast, TemplateProto tp, CXCursor cursor)
        {
            string paramName  = clang.getCursorSpelling(cursor).ToString();
            bool   isVariadic = ClangTraits.IsVariadicTemplateParameter(cursor);

            // check if dependent or nontype
            bool   isDependent   = false;
            string dependName    = null;
            string default_value = null;

            clang.visitChildren(cursor, (CXCursor c, CXCursor p, IntPtr data) =>
            {
                if (ClangTraits.IsTypeRef(c))
                {
                    CXType t = clang.getCursorType(c);
                    if (ClangTraits.IsUnexposedType(t))
                    {
                        isDependent = true;
                        dependName  = clang.getCursorSpelling(c).ToString();
                    }
                }
                else if (ClangTraits.IsNonTypeTemplateParamLiteral(c))
                {
                    List <string> tokens = ASTVisitor.GetCursorTokens(c);
                    default_value        = string.Concat(tokens);
                }
                return(CXChildVisitResult.CXChildVisit_Continue);
            }, new CXClientData(IntPtr.Zero));

            TemplateParameter param;

            if (isDependent)
            {
                Debug.Assert(dependName != null);
                param = new TemplateParameter(paramName, TemplateParameterKind.Dependent, isVariadic);
                TemplateParameter dependeParam = tp.GetTemplateParameter(dependName);
                Debug.Assert(dependeParam != null);
                param.SetExtra(dependeParam, default_value);
            }
            else
            {
                CXType     type       = clang.getCursorType(cursor);
                NativeType nativeType = TypeVisitorHelper.GetNativeType(AST_, type);
                param = new TemplateParameter(paramName, TemplateParameterKind.NoneType, isVariadic);
                param.SetExtra(nativeType, default_value);
            }
            return(param);
        }
コード例 #11
0
        private CXChildVisitResult ParameterVisitor(CXCursor cursor, CXCursor parent, IntPtr data)
        {
            if (CXCursorKind.CXCursor_ParmDecl == cursor.kind)
            {
                // prepare client data
                GCHandle astHandle            = (GCHandle)data;
                OnVisitFunctionParameter func = astHandle.Target as OnVisitFunctionParameter;

                CXType type = clang.getCursorType(cursor);

                FunctionParameter param = new FunctionParameter
                {
                    Name = clang.getCursorSpelling(cursor).ToString(),
                    Type = TypeVisitorHelper.GetNativeType(AST_, type)
                };

                clang.visitChildren(cursor, (CXCursor c, CXCursor p, IntPtr d) =>
                {
                    if (ClangTraits.IsLiteralCursor(c))
                    {
                        // get liter-string from token
                        CXSourceRange range = clang.getCursorExtent(c);
                        IntPtr tokens       = IntPtr.Zero;
                        uint numToken;
                        string liter = "";
                        clang.tokenize(ASTVisitor.CurrentTU, range, out tokens, out numToken);
                        IntPtr tmp = tokens;
                        for (uint loop = 0; loop < numToken; ++loop, IntPtr.Add(tmp, 1))
                        {
                            CXToken token = Marshal.PtrToStructure <CXToken>(tmp);
                            liter        += clang.getTokenSpelling(ASTVisitor.CurrentTU, token).ToString();
                        }
                        clang.disposeTokens(ASTVisitor.CurrentTU, tokens, numToken);

                        // set default literal
                        param.DefaultValue = liter;
                    }
                    return(CXChildVisitResult.CXChildVisit_Continue);
                }, new CXClientData(IntPtr.Zero));

                func(param);
            }

            return(CXChildVisitResult.CXChildVisit_Recurse);
        }
コード例 #12
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);
        }
コード例 #13
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);
            }
        }
コード例 #14
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);
                }
            }
        }
コード例 #15
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);
        }
コード例 #16
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);
        }
コード例 #17
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);
        }
コード例 #18
0
        private void ProcessField(NativeClass thisClass, CXCursor cursor, CXCursor parent, bool isStatic = false)
        {
            // get field name
            string fieldName = clang.getCursorSpelling(cursor).ToString();

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

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

            // create field object
            Field f = new Field
            {
                Name     = fieldName,
                Access   = access,
                Type     = nativeType,
                IsStatic = isStatic
            };

            thisClass.AddField(f);
        }
コード例 #19
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);
        }