예제 #1
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);
        }
예제 #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
        public static bool IsVariadicTemplateParameter(CXCursor cursor)
        {
            List <string> tokens = ASTVisitor.GetCursorTokens(cursor);
            int           count  = tokens.Count;

            if (count < 2)
            {
                return(false);
            }
            if (tokens[count - 1] == "...")
            {
                return(true);
            }
            return(tokens[count - 2] == "...");
        }
예제 #4
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);
        }
예제 #5
0
        public AST ParseWithClangArgs(CppConfig config)
        {
            if (config.Sources.Count == 0)
            {
                Console.WriteLine("No input sources or includes");
                return(null);
            }

            // the index object
            CXIndex Index = clang.createIndex(0, 0);

            // prepare some vars for parse
            uint option = clang.defaultEditingTranslationUnitOptions()
                          | (uint)CXTranslationUnit_Flags.CXTranslationUnit_SkipFunctionBodies;
            CXUnsavedFile unsavedFile = new CXUnsavedFile();

            CXTranslationUnit TU;
            var error = clang.parseTranslationUnit2(Index, config.Sources[0], config.Extras, config.Extras.Length, out unsavedFile, 0,
                                                    option, out TU);

            if (error != CXErrorCode.CXError_Success)
            {
                Console.WriteLine("Failed to parse Translation Unit!");
                return(null);
            }

            bool fatal          = false;
            var  numDiagnostics = clang.getNumDiagnostics(TU);

            for (uint loop = 0; loop < numDiagnostics; ++loop)
            {
                fatal |= DealingWithDiagnostic(clang.getDiagnostic(TU, loop));
            }
            if (fatal)
            {
                return(null);
            }

            ASTVisitor visitor = new ASTVisitor();
            AST        ast     = visitor.Visit(TU);

            clang.disposeIndex(Index);
            return(ast);
        }
예제 #6
0
        private void ProcessConstructor(NativeClass thisClass, CXCursor cursor, CXCursor parent)
        {
            bool isDefault = clang.CXXConstructor_isDefaultConstructor(cursor) != 0;
            bool isConvert = clang.CXXConstructor_isConvertingConstructor(cursor) != 0;
            bool isCopy    = clang.CXXConstructor_isCopyConstructor(cursor) != 0;
            bool isMove    = clang.CXXConstructor_isMoveConstructor(cursor) != 0;

            Constructor ctor = new Constructor(isDefault, isConvert, isCopy, isMove);
            OnVisitFunctionParameter func = (FunctionParameter param) =>
            {
                ctor.AddParameter(param);
            };

            List <string> tokens = ASTVisitor.GetCursorTokens(cursor);

            if (tokens.Count > 0)
            {
                if (tokens[0] == "explicit")
                {
                    ctor.IsExplicit = true;
                }
                int count = tokens.Count;
                if (tokens[count - 2] == "=")
                {
                    string lastToken = tokens[count - 1];
                    if (lastToken == "default")
                    {
                        ctor.Composite = DefaultCompositeKind.Default;
                    }
                    else if (lastToken == "delete")
                    {
                        ctor.Composite = DefaultCompositeKind.Delete;
                    }
                }
            }

            // deep visit
            GCHandle delegateHandle = GCHandle.Alloc(func);

            clang.visitChildren(cursor, ParameterVisitor, new CXClientData((IntPtr)delegateHandle));
            thisClass.AddConstructor(ctor);
        }
예제 #7
0
 public ClassTemplateVisitor(AST ast, ASTVisitor visitor, bool isPartial)
 {
     AST_       = ast;
     visitor_   = visitor;
     isPartial_ = isPartial;
 }