private CSharpElement ConvertTypedef(CSharpConverter converter, CppTypedef cppTypedef, CSharpElement context)
        {
            var elementType = cppTypedef.ElementType;

            if (DefaultFunctionTypeConverter.IsFunctionType(elementType, out var cppFunctionType))
            {
                return(DefaultFunctionTypeConverter.ConvertNamedFunctionType(converter, cppFunctionType, context, cppTypedef));
            }

            var isFromSystemIncludes = converter.IsFromSystemIncludes(cppTypedef);

            var csElementType = converter.GetCSharpType(elementType, context, true);

            var noWrap = converter.Options.TypedefCodeGenKind == CppTypedefCodeGenKind.NoWrap && !converter.Options.TypedefWrapWhiteList.Contains(cppTypedef.Name);

            // If:
            // - the typedef is from system includes and the underlying type is not a pointer
            // - or the typedef mode is "no-wrap" and is not in the whitelist
            // then we bypass entirely the typedef and return immediately the element type
            bool is_size_t = isFromSystemIncludes && cppTypedef.Name == "size_t";

            if (noWrap || (isFromSystemIncludes && elementType.TypeKind != CppTypeKind.Pointer && !is_size_t))
            {
                return(csElementType);
            }

            // Otherwise we generate a small wrapper struct
            var csStructName = converter.GetCSharpName(cppTypedef, context);
            var csStruct     = new CSharpStruct(csStructName)
            {
                CppElement = cppTypedef,
            };

            var container = converter.GetCSharpContainer(cppTypedef, context);

            converter.ApplyDefaultVisibility(csStruct, container);
            container.Members.Add(csStruct);

            csStruct.Comment = converter.GetCSharpComment(cppTypedef, csStruct);

            // Requires System.Runtime.InteropServices
            csStruct.Attributes.Add(new CSharpStructLayoutAttribute(LayoutKind.Sequential)
            {
                CharSet = converter.Options.DefaultCharSet
            });

            // Required by StructLayout
            converter.AddUsing(container, "System.Runtime.InteropServices");

            var name = csStruct.Name;

            csStruct.Modifiers |= CSharpModifiers.ReadOnly;
            csStruct.BaseTypes.Add(new CSharpFreeType($"IEquatable<{name}>"));

            // Dump the type name and attached attributes for the element type
            var attachedAttributes = string.Empty;
            var csElementTypeName  = is_size_t ? "IntPtr" : converter.ConvertTypeReferenceToString(csElementType, out attachedAttributes);

            csStruct.Members.Add(new CSharpLineElement($"public {name}({csElementTypeName} value) => this.Value = value;"));
            csStruct.Members.Add(new CSharpLineElement($"{attachedAttributes}public readonly {csElementTypeName} Value;"));
            csStruct.Members.Add(new CSharpLineElement($"public bool Equals({name} other) =>  Value.Equals(other.Value);"));
            csStruct.Members.Add(new CSharpLineElement($"public override bool Equals(object obj) => obj is {name} other && Equals(other);"));
            csStruct.Members.Add(new CSharpLineElement("public override int GetHashCode() => Value.GetHashCode();"));
            csStruct.Members.Add(new CSharpLineElement("public override string ToString() => Value.ToString();"));
            csStruct.Members.Add(new CSharpLineElement($"public static implicit operator {csElementTypeName}({name} from) => from.Value;"));
            csStruct.Members.Add(new CSharpLineElement($"public static implicit operator {name}({csElementTypeName} from) => new {name}(from);"));
            csStruct.Members.Add(new CSharpLineElement($"public static bool operator ==({name} left, {name} right) => left.Equals(right);"));
            csStruct.Members.Add(new CSharpLineElement($"public static bool operator !=({name} left, {name} right) => !left.Equals(right);"));

            return(csStruct);
        }
예제 #2
0
        private void AfterPreprocessing(CSharpConverter converter, CppCompilation cppCompilation, StringBuilder additionalHeaders)
        {
            var cachedRules = GetCachedRules(converter);
            var macroRules  = cachedRules.MacroRules;

            if (macroRules.Count > 0)
            {
                var matches      = new List <ICppElementMatch>();
                var enumToMacros = new Dictionary <CppMacroToEnumMappingRule, StringBuilder>();
                foreach (var cppMacro in cppCompilation.Macros)
                {
                    if (cppMacro.Parameters != null)
                    {
                        continue;
                    }

                    foreach (var cppMacroRule in macroRules)
                    {
                        matches.Clear();
                        if (cppMacroRule.Match(cppMacro, matches))
                        {
                            var regexMatch = matches.FindMatch <CppElementRegexMatch>();

                            if (cppMacroRule is CppMacroToConstMappingRule macroToConst)
                            {
                                AppendPragmaLine(cppMacroRule, additionalHeaders);

                                var macroName = cppMacro.Name;
                                if (regexMatch != null && macroToConst.ConstFieldName != null)
                                {
                                    macroName = Regex.Replace(regexMatch.RegexInput, regexMatch.RegexPattern, macroToConst.ConstFieldName);
                                }

                                foreach (var token in cppMacro.Tokens)
                                {
                                    if (token.Kind == CppTokenKind.Comment && !string.IsNullOrEmpty(token.Text))
                                    {
                                        additionalHeaders.AppendLine(token.Text);
                                    }
                                }

                                if (macroToConst.ExplicitCast)
                                {
                                    additionalHeaders.AppendLine($"const {macroToConst.ConstFieldTypeName} {cachedRules.Prefix}{macroName} = ({macroToConst.ConstFieldTypeName}){cppMacro.Value};");
                                }
                                else
                                {
                                    additionalHeaders.AppendLine($"const {macroToConst.ConstFieldTypeName} {cachedRules.Prefix}{macroName} = {cppMacro.Value};");
                                }
                            }
                            else if (cppMacroRule is CppMacroToEnumMappingRule macroToEnum)
                            {
                                if (!enumToMacros.TryGetValue(macroToEnum, out var macrosAsEnumText))
                                {
                                    macrosAsEnumText = new StringBuilder();

                                    var enumTypeName = macroToEnum.CppEnumTypeName;

                                    AppendPragmaLine(cppMacroRule, macrosAsEnumText);
                                    macrosAsEnumText.Append($"enum {enumTypeName}");
                                    if (macroToEnum.CppIntegerTypeName != "int")
                                    {
                                        macrosAsEnumText.Append(" : ").Append(macroToEnum.CppIntegerTypeName);
                                    }

                                    macrosAsEnumText.AppendLine();
                                    macrosAsEnumText.AppendLine("{");

                                    enumToMacros.Add(macroToEnum, macrosAsEnumText);
                                }

                                var enumItemName = macroToEnum.CppEnumItemName;
                                if (regexMatch != null)
                                {
                                    enumItemName = Regex.Replace(regexMatch.RegexInput, regexMatch.RegexPattern, enumItemName);
                                }

                                AppendPragmaLine(cppMacroRule, macrosAsEnumText);
                                if (macroToEnum.ExplicitCast)
                                {
                                    macrosAsEnumText.AppendLine($"    {cachedRules.Prefix}{enumItemName} = ({macroToEnum.CppIntegerTypeName}){cppMacro.Value},");
                                }
                                else
                                {
                                    macrosAsEnumText.AppendLine($"    {cachedRules.Prefix}{enumItemName} = {cppMacro.Value},");
                                }
                            }
                        }
                    }
                }

                foreach (var enumToMacroPair in enumToMacros)
                {
                    var enumDeclarationText = enumToMacroPair.Value.AppendLine("};");
                    additionalHeaders.AppendLine(enumDeclarationText.ToString());
                }
            }

            if (cachedRules.TypesToCompile.Count > 0)
            {
                for (var i = 0; i < cachedRules.TypesToCompile.Count; i++)
                {
                    var rule = cachedRules.TypesToCompile[i];
                    AppendPragmaLine(rule, additionalHeaders);
                    if (rule.TypeRemapArraySize.HasValue)
                    {
                        var value = rule.TypeRemapArraySize.Value;
                        additionalHeaders.AppendLine($"typedef {rule.TypeRemap} {cachedRules.Prefix}{i}_typedef[{(value < 0 ? string.Empty : value.ToString(CultureInfo.InvariantCulture))}];");
                    }
                    else
                    {
                        additionalHeaders.AppendLine($"typedef {rule.TypeRemap} {cachedRules.Prefix}{i}_typedef;");
                    }
                }
            }
        }
예제 #3
0
 public void Register(CSharpConverter converter, CSharpConverterPipeline pipeline)
 {
     pipeline.FunctionTypeConverters.Add(ConvertAnonymousFunctionType);
 }
 /// <inheritdoc />
 public void Register(CSharpConverter converter, CSharpConverterPipeline pipeline)
 {
     pipeline.TypedefConverters.Add(ConvertTypedef);
 }
예제 #5
0
 public void Register(CSharpConverter converter, CSharpConverterPipeline pipeline)
 {
     pipeline.ClassConverters.Add(ConvertClass);
 }
예제 #6
0
 public void Register(CSharpConverter converter, CSharpConverterPipeline pipeline)
 {
     pipeline.GetCSharpContainerResolvers.Add(GetSharpContainer);
 }
 /// <inheritdoc />
 public void Register(CSharpConverter converter, CSharpConverterPipeline pipeline)
 {
     pipeline.FunctionConverters.Add(ConvertFunction);
 }
예제 #8
0
 public void Register(CSharpConverter converter, CSharpConverterPipeline pipeline)
 {
     pipeline.Converted.Add(AddDefaultDllImport);
 }
예제 #9
0
 /// <inheritdoc />
 public void Register(CSharpConverter converter, CSharpConverterPipeline pipeline)
 {
     pipeline.GetCSharpTypeResolvers.Add(GetCSharpType);
 }
예제 #10
0
        public static CSharpType GetCSharpType(CSharpConverter converter, CppType cppType, CSharpElement context, bool nested)
        {
            // Early exit for primitive types
            if (cppType is CppPrimitiveType cppPrimitiveType)
            {
                // Special case for bool
                return(cppPrimitiveType.Kind == CppPrimitiveKind.Bool
                    ? GetBoolType(converter)
                    : CSharpHelper.GetCSharpPrimitive(cppPrimitiveType));
            }

            // Check if a particular CppType has been already converted
            var csType = converter.FindCSharpType(cppType);

            if (csType != null)
            {
                return(csType);
            }

            // Pre-decode the type by extracting any const/pointer and get the element type directly
            DecodeSimpleType(cppType, out var isConst, out var isPointer, out var elementType);

            if (isPointer)
            {
                if (isConst && elementType.Equals(CppPrimitiveType.Char))
                {
                    // const char* => string (with marshal)
                    csType = GetStringType(converter);
                }
                else
                {
                    var pointedCSharpType = converter.GetCSharpType(elementType, context, true);

                    var isParam  = context is CSharpParameter;
                    var isReturn = context is CSharpMethod;
                    if (!nested && (isParam || isReturn))
                    {
                        switch (elementType.TypeKind)
                        {
                        case CppTypeKind.Array:
                            break;

                        case CppTypeKind.Reference:
                            break;

                        case CppTypeKind.Qualified:
                            var qualifiedType = (CppQualifiedType)elementType;
                            csType = new CSharpRefType(qualifiedType.Qualifier == CppTypeQualifier.Const ? (isParam ? CSharpRefKind.In : CSharpRefKind.RefReadOnly) : CSharpRefKind.Ref, converter.GetCSharpType(qualifiedType.ElementType, context, true));
                            break;

                        case CppTypeKind.Function:
                            csType = pointedCSharpType;
                            break;

                        case CppTypeKind.Typedef:
                            csType = new CSharpRefType(CSharpRefKind.Ref, pointedCSharpType);
                            break;

                        case CppTypeKind.StructOrClass:
                            // Is the struct is an opaque definition (which can is transformed into passing the struct directly as
                            // the struct contains the pointer)
                            if (pointedCSharpType is CSharpStruct csStruct && csStruct.IsOpaque)
                            {
                                csType = csStruct;
                            }
                            else
                            {
                                csType = new CSharpRefType(isConst ? (isParam ? CSharpRefKind.In : CSharpRefKind.RefReadOnly) : CSharpRefKind.Ref, pointedCSharpType);
                            }
                            break;
        public static CSharpComment ConvertComment(CSharpConverter converter, CppElement element, CSharpElement context)
        {
            if (!(element is ICppDeclaration cppDecl))
            {
                return(null);
            }

            var comment = cppDecl.Comment;

            if (comment?.Children == null)
            {
                return(null);
            }

            var csFullComment = new CSharpFullComment();

            CSharpXmlComment csRemarks = null;

            for (var i = 0; i < comment.Children.Count; i++)
            {
                var childComment = comment.Children[i];
                if (i == 0)
                {
                    var summary = new CSharpXmlComment("summary");
                    summary.Children.Add(GetAsCSharpComment(childComment));
                    csFullComment.Children.Add(summary);
                    continue;
                }

                switch (childComment.Kind)
                {
                case CppCommentKind.ParamCommand:
                    var paramComment = (CppCommentParamCommand)childComment;

                    var csParamComment = new CSharpParamComment(paramComment.ParamName);
                    csParamComment.Children.Add(GetChildAsCSharpComment(paramComment));
                    csFullComment.Children.Add(csParamComment);
                    break;

                case CppCommentKind.BlockCommand:
                    var blockCommand = (CppCommentBlockCommand)childComment;
                    if (blockCommand.CommandName == "return")
                    {
                        var returnComment = new CSharpReturnComment();
                        returnComment.Children.Add(GetChildAsCSharpComment(blockCommand));
                        csFullComment.Children.Add(returnComment);
                    }
                    else if (blockCommand.CommandName == "see")
                    {
                        var seealso = new CSharpXmlComment("seealso")
                        {
                            IsSelfClosing = true
                        };
                        seealso.Attributes.Add(new CSharpXmlAttribute("cref", GetChildAsText(childComment)));
                        csFullComment.Children.Add(seealso);
                    }
                    else
                    {
                        if (csRemarks == null)
                        {
                            csRemarks = new CSharpXmlComment("remarks");
                        }
                        AddComment(csRemarks, childComment);
                    }
                    break;

                default:
                    if (csRemarks == null)
                    {
                        csRemarks = new CSharpXmlComment("remarks");
                    }
                    AddComment(csRemarks, childComment);
                    break;
                }
            }

            if (csRemarks != null && csRemarks.Children.Count > 0)
            {
                csFullComment.Children.Add(csRemarks);
            }

            return(csFullComment);
        }
 /// <inheritdoc />
 public void Register(CSharpConverter converter, CSharpConverterPipeline pipeline)
 {
     pipeline.CommentConverters.Add(ConvertComment);
 }
예제 #13
0
 public void Register(CSharpConverter converter, CSharpConverterPipeline pipeline)
 {
     pipeline.ParameterConverters.Add(ConvertParameter);
 }
예제 #14
0
 public void Register(CSharpConverter converter, CSharpConverterPipeline pipeline)
 {
     pipeline.FieldConverters.Add(ConvertField);
 }
예제 #15
0
        public static CSharpElement ConvertClass(CSharpConverter converter, CppClass cppClass, CSharpElement context)
        {
            // This converter supports only plain struct or union
            if (cppClass.ClassKind == CppClassKind.Class && cppClass.Functions.Any(x => (x.Flags & CppFunctionFlags.Virtual) != 0))
            {
                return(null);
            }

            // Register the struct as soon as possible
            var csStructName = converter.GetCSharpName(cppClass, context);
            var csStruct     = new CSharpStruct(csStructName)
            {
                CppElement = cppClass,
            };

            var container = converter.GetCSharpContainer(cppClass, context);

            converter.ApplyDefaultVisibility(csStruct, container);
            if (container is CSharpInterface)
            {
                container = container.Parent;
            }
            container.Members.Add(csStruct);

            csStruct.Comment = converter.GetCSharpComment(cppClass, csStruct);

            bool isUnion = cppClass.ClassKind == CppClassKind.Union;

            // Requires System.Runtime.InteropServices
            csStruct.Attributes.Add(isUnion ?
                                    new CSharpStructLayoutAttribute(LayoutKind.Explicit)
            {
                CharSet = converter.Options.DefaultCharSet
            } :
                                    new CSharpStructLayoutAttribute(LayoutKind.Sequential)
            {
                CharSet = converter.Options.DefaultCharSet
            }
                                    );

            // Required by StructLayout
            converter.AddUsing(container, "System.Runtime.InteropServices");

            if (cppClass.BaseTypes.Count == 1)
            {
                var csBaseType = converter.GetCSharpType(cppClass.BaseTypes[0].Type, context, false);
                csStruct.Members.Add(new CSharpField("@base")
                {
                    FieldType = csBaseType, Visibility = CSharpVisibility.Public
                });
            }

            // For opaque type we use a standard representation
            if (!cppClass.IsDefinition && cppClass.Fields.Count == 0)
            {
                csStruct.Modifiers |= CSharpModifiers.ReadOnly;
                csStruct.BaseTypes.Add(new CSharpFreeType($"IEquatable<{csStruct.Name}>"));

                csStruct.Members.Add(new CSharpLineElement("private readonly IntPtr _handle;"));
                csStruct.Members.Add(new CSharpLineElement($"public {csStruct.Name}(IntPtr handle) => _handle = handle;"));
                csStruct.Members.Add(new CSharpLineElement("public IntPtr Handle => _handle;"));
                csStruct.Members.Add(new CSharpLineElement($"public bool Equals({csStruct.Name} other) => _handle.Equals(other._handle);"));
                csStruct.Members.Add(new CSharpLineElement($"public override bool Equals(object obj) => obj is {csStruct.Name} other && Equals(other);"));
                csStruct.Members.Add(new CSharpLineElement($"public override int GetHashCode() => _handle.GetHashCode();"));
                csStruct.Members.Add(new CSharpLineElement($"public override string ToString() => \"0x\" + (IntPtr.Size == 8 ? _handle.ToString(\"X16\") : _handle.ToString(\"X8\"));"));
                csStruct.Members.Add(new CSharpLineElement($"public static bool operator ==({csStruct.Name} left, {csStruct.Name} right) => left.Equals(right);"));
                csStruct.Members.Add(new CSharpLineElement($"public static bool operator !=({csStruct.Name} left, {csStruct.Name} right) => !left.Equals(right);"));
            }

            // If we have any anonymous structs/unions for a field type
            // try to compute a name for them before processing them
            foreach (var cppField in cppClass.Fields)
            {
                var fieldType = cppField.Type;

                if (fieldType is CppClass cppFieldTypeClass && cppFieldTypeClass.IsAnonymous && string.IsNullOrEmpty(cppFieldTypeClass.Name))
                {
                    var parentName = string.Empty;
                    if (cppFieldTypeClass.Parent is CppClass cppParentClass)
                    {
                        parentName = cppParentClass.Name;
                    }

                    if (cppFieldTypeClass.ClassKind == CppClassKind.Union)
                    {
                        parentName = parentName == string.Empty ? "union" : parentName + "_union";
                    }
                    cppFieldTypeClass.Name = $"{parentName}_{cppField.Name}";
                }
            }

            return(csStruct);
        }
예제 #16
0
        public static CSharpElement ConvertField(CSharpConverter converter, CppField cppField, CSharpElement context)
        {
            // Early exit if this is a global variable (we don't handle dllexport)
            bool isConst = cppField.Type is CppQualifiedType qualifiedType && qualifiedType.Qualifier == CppTypeQualifier.Const;
            var isGlobalVariable = (!(cppField.Parent is CppClass) && !isConst) || cppField.StorageQualifier == CppStorageQualifier.Static;
            if (isGlobalVariable)
            {
                return null;
            }

            var isParentClass = cppField.Parent is CppClass;

            var csContainer = converter.GetCSharpContainer(cppField, context);

            var isUnion = ((cppField.Parent as CppClass)?.ClassKind ?? CppClassKind.Struct) == CppClassKind.Union;

            var csFieldName = converter.GetCSharpName(cppField, (CSharpElement)csContainer);

            if (cppField.IsBitField)
            {
                CSharpBitField csBitFieldStorage = null;
                for (var index = csContainer.Members.Count - 1; index >= 0; index--)
                {
                    var member = csContainer.Members[index];
                    if (member is CSharpField csPreviousField)
                    {
                        csBitFieldStorage = csPreviousField as CSharpBitField;
                        break;
                    }
                }

                if (csBitFieldStorage == null || (csBitFieldStorage.CurrentBitWidth + cppField.BitFieldWidth) > csBitFieldStorage.MaxBitWidth)
                {
                    var canonicalType = (CppPrimitiveType)cppField.Type.GetCanonicalType();
                    csBitFieldStorage = new CSharpBitField(BitFieldName + csContainer.Members.Count)
                    {
                        Visibility = CSharpVisibility.Private, 
                    };
                    switch (canonicalType.Kind)
                    {
                        case CppPrimitiveKind.Bool:
                            csBitFieldStorage.FieldType = CSharpPrimitiveType.Byte;
                            csBitFieldStorage.MaxBitWidth = 8;
                            break;
                        case CppPrimitiveKind.WChar:
                            csBitFieldStorage.FieldType = CSharpPrimitiveType.UShort;
                            csBitFieldStorage.MaxBitWidth = 16;
                            break;
                        case CppPrimitiveKind.Char:
                            csBitFieldStorage.FieldType = CSharpPrimitiveType.Byte;
                            csBitFieldStorage.MaxBitWidth = 8;
                            break;
                        case CppPrimitiveKind.Short:
                            csBitFieldStorage.FieldType = CSharpPrimitiveType.Short;
                            csBitFieldStorage.MaxBitWidth = 16;
                            break;
                        case CppPrimitiveKind.Int:
                            csBitFieldStorage.FieldType = CSharpPrimitiveType.Int;
                            csBitFieldStorage.MaxBitWidth = 32;
                            break;
                        case CppPrimitiveKind.LongLong:
                            csBitFieldStorage.FieldType = CSharpPrimitiveType.Long;
                            csBitFieldStorage.MaxBitWidth = 64;
                            break;
                        case CppPrimitiveKind.UnsignedChar:
                            csBitFieldStorage.FieldType = CSharpPrimitiveType.Byte;
                            csBitFieldStorage.MaxBitWidth = 8;
                            break;
                        case CppPrimitiveKind.UnsignedShort:
                            csBitFieldStorage.FieldType = CSharpPrimitiveType.UShort;
                            csBitFieldStorage.MaxBitWidth = 16;
                            break;
                        case CppPrimitiveKind.UnsignedInt:
                            csBitFieldStorage.FieldType = CSharpPrimitiveType.UInt;
                            csBitFieldStorage.MaxBitWidth = 32;
                            break;
                        case CppPrimitiveKind.UnsignedLongLong:
                            csBitFieldStorage.FieldType = CSharpPrimitiveType.ULong;
                            csBitFieldStorage.MaxBitWidth = 64;
                            break;
                        default:
                            csBitFieldStorage.FieldType = new CSharpFreeType("unsupported_bitfield_type_" + canonicalType);
                            csBitFieldStorage.MaxBitWidth = 128;
                            break;
                    } 
                    csContainer.Members.Add(csBitFieldStorage);
                }

                int currentBitOffset = csBitFieldStorage.CurrentBitWidth;
                csBitFieldStorage.CurrentBitWidth += cppField.BitFieldWidth;

                var csProperty = new CSharpProperty(csFieldName)
                {
                    CppElement = cppField,
                    LinkedField = csBitFieldStorage,
                };
                converter.ApplyDefaultVisibility(csProperty, csContainer);
                csProperty.Comment = converter.GetCSharpComment(cppField, csProperty);

                var bitmask = (1L << cppField.BitFieldWidth) - 1;
                var bitmaskStr = $"0b{Convert.ToString(bitmask, 2)}";
                var notBitMaskStr = Convert.ToString(~(bitmask << currentBitOffset), 2);
                if (notBitMaskStr.Length > csBitFieldStorage.MaxBitWidth)
                {
                    notBitMaskStr = notBitMaskStr.Substring(notBitMaskStr.Length - csBitFieldStorage.MaxBitWidth);
                }
                
                csProperty.ReturnType = converter.GetCSharpType(cppField.Type, csProperty);
                csProperty.GetBody = (writer, element) =>
                {
                    writer.Write($"return unchecked((");
                    csProperty.ReturnType.DumpReferenceTo(writer);
                    writer.Write(")");
                    writer.Write($"(({csBitFieldStorage.Name} >> {currentBitOffset}) & {bitmaskStr})");
                    writer.Write(");");
                    writer.WriteLine();
                };
                csProperty.SetBody = (writer, element) =>
                {
                    writer.Write($"{csBitFieldStorage.Name} = ({csBitFieldStorage.Name} & unchecked((");
                    csBitFieldStorage.FieldType.DumpReferenceTo(writer);
                    writer.Write($")0b{notBitMaskStr})) | ((((");
                    csBitFieldStorage.FieldType.DumpReferenceTo(writer);
                    writer.Write(")value) & (unchecked((");
                    csBitFieldStorage.FieldType.DumpReferenceTo(writer);
                    writer.Write($"){bitmaskStr})) << {currentBitOffset}));");
                    writer.WriteLine();
                };
    
                csContainer.Members.Add(csProperty);
                return csProperty;
            }
            else
            {
                var parentName = cppField.Parent is CppClass cppClass ? cppClass.Name : string.Empty;
                var csField = new CSharpField(csFieldName) { CppElement = cppField };
                converter.ApplyDefaultVisibility(csField, csContainer);

                if (isConst)
                {
                    if (isParentClass)
                    {
                        csField.Modifiers |= CSharpModifiers.ReadOnly;
                    }
                    else
                    {
                        csField.Modifiers |= CSharpModifiers.Const;
                    }
                }

                csContainer.Members.Add(csField);

                csField.Comment = converter.GetCSharpComment(cppField, csField);

                if (isUnion)
                {
                    csField.Attributes.Add(new CSharpFreeAttribute("FieldOffset(0)"));
                    converter.AddUsing(csContainer, "System.Runtime.InteropServices");
                }
                csField.FieldType = converter.GetCSharpType(cppField.Type, csField);

                if (cppField.InitExpression != null)
                {
                    if (cppField.InitExpression.Kind == CppExpressionKind.Unexposed)
                    {
                        csField.InitValue = cppField.InitValue?.Value?.ToString();
                    }
                    else
                    {
                        csField.InitValue = converter.ConvertExpression(cppField.InitExpression, context, csField.FieldType);
                    }
                }

                return csField;
            }
        }
예제 #17
0
 /// <inheritdoc />
 public void Register(CSharpConverter converter, CSharpConverterPipeline pipeline)
 {
     pipeline.GetCSharpNameResolvers.Add(DefaultGetCSharpName);
 }