Example #1
0
 public static extern ClangString clang_getTypeKindSpelling(ClangSharp.Type.Kind k);
 public static string GetFullyQualifiedName(ClangSharp.Cursor cursor)
 {
     string name;
     if (cursor.Type.TypeKind != ClangSharp.Type.Kind.Invalid)
     {
         return GetFullyQualifiedName(cursor.Type);
     }
     else
     {
         name = cursor.Spelling;
         while (cursor.SemanticParent.Kind == ClangSharp.CursorKind.ClassDecl ||
             cursor.SemanticParent.Kind == ClangSharp.CursorKind.StructDecl ||
             cursor.SemanticParent.Kind == ClangSharp.CursorKind.ClassTemplate ||
             cursor.SemanticParent.Kind == ClangSharp.CursorKind.Namespace)
         {
             name = cursor.SemanticParent.Spelling + "::" + name;
             cursor = cursor.SemanticParent;
         }
     }
     return name;
 }
 public static string GetFullyQualifiedName(ClangSharp.Type type)
 {
     string name;
     var decl = type.Declaration;
     if (decl.IsInvalid)
     {
         name = "[unexposed type]";
     }
     else if (!decl.SpecializedCursorTemplate.IsInvalid)
     {
         name = decl.DisplayName;
     }
     else
     {
         name = decl.Spelling;
         while (decl.SemanticParent.Kind == ClangSharp.CursorKind.ClassDecl ||
             decl.SemanticParent.Kind == ClangSharp.CursorKind.StructDecl ||
             decl.SemanticParent.Kind == ClangSharp.CursorKind.ClassTemplate ||
             decl.SemanticParent.Kind == ClangSharp.CursorKind.Namespace)
         {
             name = decl.SemanticParent.Spelling + "::" + name;
             decl = decl.SemanticParent;
         }
     }
     return name;
 }
        public TypeRefDefinition(ClangSharp.Type type)
        {
            if (!type.Declaration.IsInvalid &&
                !type.Declaration.IsDefinition &&
                type.Declaration.SpecializedCursorTemplate.IsInvalid)
            {
                // Forward reference
                IsIncomplete = true;
            }

            IsConst = type.IsConstQualifiedType;

            switch (type.TypeKind)
            {
                case ClangSharp.Type.Kind.Void:
                case ClangSharp.Type.Kind.Bool:
                case ClangSharp.Type.Kind.CharS:
                case ClangSharp.Type.Kind.Double:
                case ClangSharp.Type.Kind.Float:
                case ClangSharp.Type.Kind.Int:
                case ClangSharp.Type.Kind.UChar:
                case ClangSharp.Type.Kind.UInt:
                    Name = type.Spelling;
                    IsBasic = true;
                    break;
                case ClangSharp.Type.Kind.Long:
                    Name = "long";
                    IsBasic = true;
                    break;
                case ClangSharp.Type.Kind.LongLong:
                    Name = "long long";
                    IsBasic = true;
                    break;
                case ClangSharp.Type.Kind.Short:
                    Name = "short";
                    IsBasic = true;
                    break;
                case ClangSharp.Type.Kind.ULong:
                    Name = "unsigned long";
                    IsBasic = true;
                    break;
                case ClangSharp.Type.Kind.UShort:
                    Name = "unsigned short";
                    IsBasic = true;
                    break;
                case ClangSharp.Type.Kind.Typedef:
                    Name = GetFullyQualifiedName(type);
                    Referenced = new TypeRefDefinition(type.Canonical);
                    IsBasic = Referenced.IsBasic;
                    break;
                case ClangSharp.Type.Kind.Pointer:
                    Referenced = new TypeRefDefinition(type.Pointee);
                    IsPointer = true;
                    break;
                case ClangSharp.Type.Kind.LValueReference:
                    Referenced = new TypeRefDefinition(type.Pointee);
                    IsReference = true;
                    break;
                case ClangSharp.Type.Kind.ConstantArray:
                    Referenced = new TypeRefDefinition(type.ArrayElementType);
                    IsConstantArray = true;
                    break;
                case ClangSharp.Type.Kind.FunctionProto:
                    // ??
                    break;
                case ClangSharp.Type.Kind.Enum:
                    Name = type.Canonical.Declaration.Spelling;
                    IsBasic = true;
                    break;
                case ClangSharp.Type.Kind.Record:
                case ClangSharp.Type.Kind.Unexposed:
                    Name = GetFullyQualifiedName(type);
                    break;
                case ClangSharp.Type.Kind.DependentSizedArray:
                    break;
                default:
                    throw new NotImplementedException();
            }
        }
        public TypeRefDefinition(ClangSharp.Type type, Cursor cursor = null)
        {
            Kind = (TypeKind)type.TypeKind;

            if (!type.Declaration.IsInvalid &&
                !type.Declaration.IsDefinition &&
                type.Declaration.SpecializedCursorTemplate.IsInvalid)
            {
                // Forward reference
                IsIncomplete = true;
            }

            IsConst = type.IsConstQualifiedType;

            if (type.Pointee.TypeKind != ClangSharp.Type.Kind.Invalid)
            {
                Cursor pointeeCursor = cursor?.Children.FirstOrDefault(c => c.Type.Equals(type.Pointee));
                if (pointeeCursor == null)
                {
                    pointeeCursor = cursor?.Children.FirstOrDefault(c => c.Kind == CursorKind.TypeRef)?.Referenced;
                }
                Referenced = new TypeRefDefinition(type.Pointee, pointeeCursor);
            }
            else if (Kind != TypeKind.Typedef)
            {
                if (cursor != null && (Kind == TypeKind.Record || Kind == TypeKind.Unexposed))
                {
                    if (cursor.Kind == CursorKind.TypeRef)
                    {
                        if (cursor.Referenced.Kind == CursorKind.TemplateTypeParameter)
                        {
                            HasTemplateTypeParameter = true;
                        }
                    }
                    else if (cursor.Kind == CursorKind.CxxMethod)
                    {
                        var children = cursor.Children.TakeWhile(c => c.Kind != CursorKind.ParmDecl);
                        var typeRef = children.FirstOrDefault();
                        if (typeRef != null && typeRef.Kind == CursorKind.TypeRef)
                        {
                            if (typeRef.Referenced.Kind == CursorKind.TemplateTypeParameter)
                            {
                                HasTemplateTypeParameter = true;
                            }
                        }
                    }
                    else if (cursor.Kind == CursorKind.ParmDecl)
                    {
                        var typeRef = cursor.Children.FirstOrDefault();
                        if (typeRef != null && typeRef.Kind == CursorKind.TypeRef)
                        {
                            if (typeRef.Referenced.Kind == CursorKind.TemplateTypeParameter)
                            {
                                HasTemplateTypeParameter = true;
                            }
                        }
                    }
                }

                // Capture template parameters
                var firstChild = cursor?.Children.FirstOrDefault();
                if (firstChild != null && firstChild.Kind == CursorKind.TemplateRef)
                {
                    if (cursor.Children.Count == 1)
                    {
                        string displayName = GetFullyQualifiedName(type, cursor);
                        int typeStart = displayName.IndexOf('<') + 1;
                        int typeEnd = displayName.LastIndexOf('>');
                        displayName = displayName.Substring(typeStart, typeEnd - typeStart);
                        TemplateParams = new List<TypeRefDefinition> { new TypeRefDefinition(displayName) };
                    }
                    else
                    {
                        TemplateParams = cursor.Children.Skip(1)
                            .Select(c => new TypeRefDefinition(c.Type, c)).ToList();
                    }
                }
            }

            switch (Kind)
            {
                case TypeKind.Void:
                case TypeKind.Bool:
                case TypeKind.Char_S:
                case TypeKind.Double:
                case TypeKind.Float:
                case TypeKind.Int:
                case TypeKind.UChar:
                case TypeKind.UInt:
                    Name = type.Spelling;
                    break;
                case TypeKind.Long:
                    Name = "long";
                    break;
                case TypeKind.LongLong:
                    Name = "long long";
                    break;
                case TypeKind.Short:
                    Name = "short";
                    break;
                case TypeKind.ULong:
                    Name = "unsigned long";
                    break;
                case TypeKind.ULongLong:
                    Name = "unsigned long long";
                    break;
                case TypeKind.UShort:
                    Name = "unsigned short";
                    break;

                case TypeKind.Typedef:
                    Name = GetFullyQualifiedName(type);
                    Referenced = new TypeRefDefinition(type.Canonical, cursor?.Referenced);
                    break;

                case TypeKind.FunctionProto:
                case TypeKind.LValueReference:
                case TypeKind.Pointer:
                    break;
                case TypeKind.ConstantArray:
                    Referenced = new TypeRefDefinition(type.ArrayElementType, cursor);
                    break;

                case TypeKind.Enum:
                    Name = type.Canonical.Declaration.Spelling;
                    break;
                case TypeKind.Record:
                    Name = GetFullyQualifiedName(type, cursor);
                    break;
                case TypeKind.Unexposed:
                    if (type.Canonical.TypeKind != ClangSharp.Type.Kind.Unexposed)
                    {
                        Kind = (TypeKind)type.Canonical.TypeKind;
                        Name = GetFullyQualifiedName(type.Canonical, cursor);
                    }
                    else
                    {
                        Name = GetFullyQualifiedName(type, cursor);
                    }
                    break;
                case TypeKind.DependentSizedArray:
                    break;
                default:
                    throw new NotImplementedException();
            }
        }
        public static string GetFullyQualifiedName(ClangSharp.Type type, Cursor cursor = null)
        {
            var decl = type.Declaration;
            if (!decl.IsInvalid) return GetFullyQualifiedName(decl);

            return GetFullyQualifiedName(cursor);
        }