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); }
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); }
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); }
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); }
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 }); } }
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) }); } }
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)); }
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); }
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); }
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); }
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); }
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); }
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); } }
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); } } }
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); }
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); }
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); }
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); }
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); }