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