Example #1
0
        public override bool VisitFieldDecl(Field field)
        {
            if (!VisitDeclaration(field))
                return false;

            var type = field.Type;

            Declaration decl;
            type.TryGetDeclaration(out decl);
            string msg = "internal";
            if (decl == null || (decl.GenerationKind != GenerationKind.Internal && !HasInvalidType(type, out msg)))
                return false;

            field.GenerationKind = GenerationKind.Internal;

            var @class = (Class)field.Namespace;

            var cppTypePrinter = new CppTypePrinter();
            var typeName = type.Visit(cppTypePrinter);

            Log.Debug("Field '{0}::{1}' was ignored due to {2} type '{3}'",
                @class.Name, field.Name, msg, typeName);

            return true;
        }
Example #2
0
        private bool IsStdType(QualifiedType type)
        {
            var typePrinter = new CppTypePrinter(Driver.TypeDatabase);
            var typeName = type.Visit(typePrinter);

            return typeName.Contains("std::");
        }
Example #3
0
        public void TestPrintingSpecializationWithConstValue()
        {
            var template       = AstContext.FindDecl <ClassTemplate>("TestSpecializationArguments").First();
            var cppTypePrinter = new CppTypePrinter {
                ScopeKind = TypePrintScopeKind.Qualified
            };

            Assert.That(template.Specializations.Last().Visit(cppTypePrinter).Type,
                        Is.EqualTo("TestSpecializationArguments<const TestASTEnumItemByName>"));
        }
Example #4
0
        public void TestPrintNestedInSpecialization()
        {
            var template       = AstContext.FindDecl <ClassTemplate>("TestTemplateClass").First();
            var cppTypePrinter = new CppTypePrinter {
                ScopeKind = TypePrintScopeKind.Qualified
            };

            Assert.That(template.Specializations[3].Classes.First().Visit(cppTypePrinter).Type,
                        Is.EqualTo("TestTemplateClass<Math::Complex>::NestedInTemplate"));
        }
Example #5
0
        public void TestPrintQualifiedSpecialization()
        {
            var functionWithSpecializationArg = AstContext.FindFunction("functionWithSpecializationArg").First();
            var cppTypePrinter = new CppTypePrinter {
                ScopeKind = TypePrintScopeKind.Qualified
            };

            Assert.That(functionWithSpecializationArg.Parameters[0].Visit(cppTypePrinter).Type,
                        Is.EqualTo("const TestTemplateClass<int>"));
        }
Example #6
0
        public override bool VisitPointerType(PointerType pointer, TypeQualifiers quals)
        {
            if (!VisitType(pointer, quals))
            {
                return(false);
            }

            var pointee = pointer.Pointee.Desugar();

            if (pointee is FunctionType)
            {
                var cppTypePrinter = new CppTypePrinter();
                var cppTypeName    = pointer.Visit(cppTypePrinter, quals);

                return(VisitDelegateType(cppTypeName));
            }

            Enumeration @enum;

            if (pointee.TryGetEnum(out @enum))
            {
                var isRef = Context.Parameter.Usage == ParameterUsage.Out ||
                            Context.Parameter.Usage == ParameterUsage.InOut;

                ArgumentPrefix.Write("&");
                Context.Return.Write("(::{0}){1}{2}", @enum.QualifiedOriginalName,
                                     isRef ? string.Empty : "*", Context.Parameter.Name);
                return(true);
            }

            Class @class;

            if (pointee.TryGetClass(out @class) && @class.IsValueType)
            {
                if (Context.Function == null)
                {
                    Context.Return.Write("&");
                }
                return(pointer.QualifiedPointee.Visit(this));
            }

            var finalPointee = pointer.GetFinalPointee();

            if (finalPointee.IsPrimitiveType())
            {
                var cppTypePrinter = new CppTypePrinter();
                var cppTypeName    = pointer.Visit(cppTypePrinter, quals);

                Context.Return.Write("({0})", cppTypeName);
                Context.Return.Write(Context.Parameter.Name);
                return(true);
            }

            return(pointer.QualifiedPointee.Visit(this));
        }
Example #7
0
        public SymbolsCodeGenerator(BindingContext context, IEnumerable <TranslationUnit> units)
            : base(context, units)
        {
            cppTypePrinter = new CppTypePrinter(Context)
            {
                ScopeKind       = TypePrintScopeKind.Qualified,
                ResolveTypedefs = true
            };

            cppTypePrinter.PushContext(TypePrinterContextKind.Native);
        }
Example #8
0
        public override bool VisitEnumDecl(Enumeration @enum)
        {
            var typePrinter = new CppTypePrinter(Context.Context);

            typePrinter.PushContext(TypePrinterContextKind.Managed);
            var typeName = typePrinter.VisitDeclaration(@enum);

            Context.Return.Write($"({typeName}){Context.ReturnVarName}");

            return(true);
        }
Example #9
0
        public void TestVolatile()
        {
            var cppTypePrinter = new CppTypePrinter {
                PrintScopeKind = TypePrintScopeKind.Qualified
            };
            var builtin = new BuiltinType(PrimitiveType.Char);
            var pointee = new QualifiedType(builtin, new TypeQualifiers {
                IsConst = true, IsVolatile = true
            });
            var type = pointee.Visit(cppTypePrinter);

            Assert.That(type, Is.EqualTo("const volatile char"));
        }
        public override bool VisitTemplateSpecializationType(TemplateSpecializationType template, TypeQualifiers quals)
        {
            if (AlreadyVisited(template) || template.Template.Access == AccessSpecifier.Private)
                return false;

            if (template.Arguments.Select(a => a.Type.Type.Desugar()).All(t => t.IsAddress() && !t.GetFinalPointee().IsDependent))
            {
                var cppTypePrinter = new CppTypePrinter { PrintScopeKind = CppTypePrintScopeKind.Qualified };
                templateInstantiations.Add(string.Format("{0}<{1}>", template.Template.Name,
                    string.Join(", ", template.Arguments.Select(a => a.Type.Type.Visit(cppTypePrinter)))));
            }

            return true;
        }
Example #11
0
        public override void CLIMarshalToNative(MarshalContext ctx)
        {
            var templateType = Type as TemplateSpecializationType;
            var type         = templateType.Arguments[0].Type;

            var entryString = (ctx.Parameter != null) ? ctx.Parameter.Name
                : ctx.ArgName;

            var tmpVarName = "_tmp" + entryString;

            var cppTypePrinter = new CppTypePrinter(ctx.Driver.TypeDatabase);
            var nativeType     = type.Type.Visit(cppTypePrinter);

            ctx.SupportBefore.WriteLine("auto {0} = std::vector<{1}>();",
                                        tmpVarName, nativeType);
            ctx.SupportBefore.WriteLine("for each({0} _element in {1})",
                                        type.ToString(), entryString);
            ctx.SupportBefore.WriteStartBraceIndent();
            {
                var param = new Parameter
                {
                    Name          = "_element",
                    QualifiedType = type
                };

                var elementCtx = new MarshalContext(ctx.Driver)
                {
                    Parameter = param,
                    ArgName   = param.Name,
                };

                var marshal = new CLIMarshalManagedToNativePrinter(elementCtx);
                type.Type.Visit(marshal);

                if (!string.IsNullOrWhiteSpace(marshal.Context.SupportBefore))
                {
                    ctx.SupportBefore.Write(marshal.Context.SupportBefore);
                }

                ctx.SupportBefore.WriteLine("auto _marshalElement = {0};",
                                            marshal.Context.Return);

                ctx.SupportBefore.WriteLine("{0}.push_back(_marshalElement);",
                                            tmpVarName);
            }

            ctx.SupportBefore.WriteCloseBraceIndent();

            ctx.Return.Write(tmpVarName);
        }
Example #12
0
        public override bool VisitFieldDecl(Field field)
        {
            if (field.Ignore)
                return false;

            var typePrinter = new CppTypePrinter(Driver.TypeDatabase);
            var typeName = field.QualifiedType.Visit(typePrinter);

            if (!typeName.Contains("std::"))
                return false;

            field.ExplicityIgnored = true;
            return true;
        }
Example #13
0
        public void TestPrintingConstPointerWithConstType()
        {
            var cppTypePrinter = new CppTypePrinter {
                PrintScopeKind = TypePrintScopeKind.Qualified
            };
            var builtin = new BuiltinType(PrimitiveType.Char);
            var pointee = new QualifiedType(builtin, new TypeQualifiers {
                IsConst = true
            });
            var pointer = new QualifiedType(new PointerType(pointee), new TypeQualifiers {
                IsConst = true
            });
            var type = pointer.Visit(cppTypePrinter);

            Assert.That(type, Is.EqualTo("const char* const"));
        }
Example #14
0
        public void TestPrintingConstPointerWithConstType()
        {
            var template       = AstContext.FindDecl <ClassTemplate>("TestSpecializationArguments").First();
            var cppTypePrinter = new CppTypePrinter {
                PrintScopeKind = CppTypePrintScopeKind.Qualified
            };
            var builtin = new BuiltinType(PrimitiveType.Char);
            var pointee = new QualifiedType(builtin, new TypeQualifiers {
                IsConst = true
            });
            var pointer = new QualifiedType(new PointerType(pointee), new TypeQualifiers {
                IsConst = true
            });
            var type = pointer.Visit(cppTypePrinter);

            Assert.AreEqual(type, "const char* const");
        }
Example #15
0
        public override bool VisitTypedefType(TypedefType typedef, TypeQualifiers quals)
        {
            var decl = typedef.Declaration;

            TypeMap typeMap;

            if (Context.Context.TypeMaps.FindTypeMap(decl.Type, out typeMap) &&
                typeMap.DoesMarshalling)
            {
                typeMap.CppMarshalToNative(Context);
                return(typeMap.IsValueType);
            }

            FunctionType func;

            if (decl.Type.IsPointerTo(out func))
            {
                var typePrinter = new CppTypePrinter(Context.Context);
                typePrinter.PushContext(TypePrinterContextKind.Native);
                var declName = decl.Visit(typePrinter);
                typePrinter.PopContext();

                // Use the original typedef name if available, otherwise just use the function pointer type
                string cppTypeName;
                if (!decl.IsSynthetized)
                {
                    cppTypeName = "::" + typedef.Declaration.QualifiedOriginalName;
                }
                else
                {
                    cppTypeName = decl.Type.Visit(typePrinter, quals);
                }

                VisitDelegateType(cppTypeName);
                return(true);
            }

            PrimitiveType primitive;

            if (decl.Type.IsPrimitiveType(out primitive))
            {
                Context.Return.Write($"(::{typedef.Declaration.QualifiedOriginalName})");
            }

            return(decl.Type.Visit(this));
        }
Example #16
0
        public override bool VisitTemplateSpecializationType(TemplateSpecializationType template, TypeQualifiers quals)
        {
            if (AlreadyVisited(template) || template.Template.Access == AccessSpecifier.Private)
            {
                return(false);
            }

            if (template.Arguments.Select(a => a.Type.Type.Desugar()).All(t => t.IsAddress() && !t.GetFinalPointee().IsDependent))
            {
                var cppTypePrinter = new CppTypePrinter {
                    PrintScopeKind = CppTypePrintScopeKind.Qualified
                };
                templateInstantiations.Add(string.Format("{0}<{1}>", template.Template.Name,
                                                         string.Join(", ", template.Arguments.Select(a => a.Type.Type.Visit(cppTypePrinter)))));
            }

            return(true);
        }
Example #17
0
 public Documentation(string docsPath, string module, Dictionary<Type, List<TypedefDecl>> typeDefsPerType)
 {
     this.documentation = Get(docsPath, module);
     CppTypePrinter cppTypePrinter = new CppTypePrinter(new TypeMapDatabase());
     cppTypePrinter.PrintKind = CppTypePrintKind.Local;
     this.typeDefsPerType = new Dictionary<string, List<TypedefDecl>>();
     foreach (KeyValuePair<Type, List<TypedefDecl>> typeTypeDefs in typeDefsPerType)
     {
         if (!(typeTypeDefs.Key is DependentNameType) && !(typeTypeDefs.Key is InjectedClassNameType))
         {
             string typeName = typeTypeDefs.Key.Visit(cppTypePrinter);
             if (!this.typeDefsPerType.ContainsKey(typeName))
             {
                 this.typeDefsPerType.Add(typeName, typeTypeDefs.Value);
             }
         }
     }
 }
Example #18
0
        public override bool VisitFieldDecl(Field field)
        {
            if (field.Ignore)
            {
                return(false);
            }

            var typePrinter = new CppTypePrinter(Driver.TypeDatabase);
            var typeName    = field.QualifiedType.Visit(typePrinter);

            if (!typeName.Contains("std::"))
            {
                return(false);
            }

            field.ExplicityIgnored = true;
            return(true);
        }
Example #19
0
        private static void DisableSingleTypeMap(Class mapped, BindingContext context)
        {
            var names = new List <string> {
                mapped.OriginalName
            };

            foreach (TypePrintScopeKind kind in Enum.GetValues(typeof(TypePrintScopeKind)))
            {
                var cppTypePrinter = new CppTypePrinter {
                    ScopeKind = kind
                };
                names.Add(mapped.Visit(cppTypePrinter));
            }
            foreach (var name in names.Where(context.TypeMaps.TypeMaps.ContainsKey))
            {
                context.TypeMaps.TypeMaps[name].IsEnabled = false;
            }
        }
Example #20
0
        private bool TryMatch(Function function, string docs, bool markObsolete, bool completeSignature = true)
        {
            const string   memberDoc      = @"\n{{2}}(\[(\w+\s*)+\] )?([\w :*&<>,]+)?(({0}(\s*&)?::)| ){1}(const)?( \[(\w+\s*)+\])?\n(?<docs>\w.*?)(\n\s*){{1,2}}((\n\s*){{2}})";
            const string   separator      = @",\s*";
            StringBuilder  signatureRegex = new StringBuilder(Regex.Escape(function.OriginalName)).Append(@"\s*\(\s*(");
            bool           anyArgs        = false;
            CppTypePrinter cppTypePrinter = new CppTypePrinter(new TypeMapDatabase());

            cppTypePrinter.PrintScopeKind = CppTypePrintScopeKind.Local;
            foreach (string argType in function.Parameters.Where(p => p.Kind == ParameterKind.Regular).Select(p => p.Type.Visit(cppTypePrinter)))
            {
                if (!anyArgs)
                {
                    signatureRegex.Append("?<args>");
                    anyArgs = true;
                }
                signatureRegex.Append(this.GetTypeRegex(argType, completeSignature)).Append(@"(\s+\w+(\s*=\s*[^,\r\n]+(\(\s*\))?)?)?");
                signatureRegex.Append(separator);
            }
            if (anyArgs)
            {
                signatureRegex.Insert(signatureRegex.Length - separator.Length, '(');
            }
            else
            {
                signatureRegex.Append('(');
            }
            signatureRegex.Append(@"[\w :*&<>]+\s*=\s*[^,\r\n]+(\(\s*\))?(,\s*)?)*)\s*(,\s*\.{3}\s*)?\)\s*");
            Match match = Regex.Match(docs, string.Format(memberDoc, function.Namespace.Name, signatureRegex),
                                      RegexOptions.Singleline | RegexOptions.ExplicitCapture);

            if (match.Success)
            {
                function.Comment           = new RawComment();
                function.Comment.BriefText = match.Groups["docs"].Value;
                FillMissingParameterNames(function, match.Groups["args"].Value);
                if (markObsolete)
                {
                    AddObsoleteAttribute(function);
                }
                return(true);
            }
            return(false);
        }
Example #21
0
        public Documentation(string docsPath, string module, Dictionary <Type, List <TypedefDecl> > typeDefsPerType)
        {
            this.documentation = Get(docsPath, module);
            CppTypePrinter cppTypePrinter = new CppTypePrinter(new TypeMapDatabase());

            cppTypePrinter.PrintScopeKind = CppTypePrintScopeKind.Local;
            this.typeDefsPerType          = new Dictionary <string, List <TypedefDecl> >();
            foreach (KeyValuePair <Type, List <TypedefDecl> > typeTypeDefs in typeDefsPerType)
            {
                if (!(typeTypeDefs.Key is DependentNameType) && !(typeTypeDefs.Key is InjectedClassNameType))
                {
                    string typeName = typeTypeDefs.Key.Visit(cppTypePrinter);
                    if (!this.typeDefsPerType.ContainsKey(typeName))
                    {
                        this.typeDefsPerType.Add(typeName, typeTypeDefs.Value);
                    }
                }
            }
        }
Example #22
0
        private void DocumentQtProperty(Property property)
        {
            string file = GetFileForDeclarationContext(property.Namespace);

            if (this.documentation.ContainsKey(file))
            {
                string         docs           = this.documentation[file];
                CppTypePrinter cppTypePrinter = new CppTypePrinter(new TypeMapDatabase());
                cppTypePrinter.PrintScopeKind = CppTypePrintScopeKind.Local;
                string type  = property.Type.Visit(cppTypePrinter);
                Match  match = Regex.Match(docs, "Property Documentation.*" + property.Name + @" : (const )?(\w+::)?" + type.Replace("*", @"\s*\*") +
                                           @"(\s+const)?\n(?<docs>.*?)\nAccess functions:", RegexOptions.Singleline | RegexOptions.ExplicitCapture);
                if (match.Success)
                {
                    property.Comment           = new RawComment();
                    property.Comment.BriefText = match.Groups["docs"].Value;
                }
            }
        }
Example #23
0
        public void TestPrintingConstPointerWithConstType()
        {
            var cppTypePrinter = new CppTypePrinter(Context)
            {
                ResolveTypeMaps = false
            };

            cppTypePrinter.PushScope(TypePrintScopeKind.Qualified);
            var builtin = new BuiltinType(PrimitiveType.Char);
            var pointee = new QualifiedType(builtin, new TypeQualifiers {
                IsConst = true
            });
            var pointer = new QualifiedType(new PointerType(pointee), new TypeQualifiers {
                IsConst = true
            });
            string type = pointer.Visit(cppTypePrinter);

            Assert.That(type, Is.EqualTo("const char* const"));
        }
 public override bool VisitClassTemplateSpecializationDecl(ClassTemplateSpecialization specialization)
 {
     if (!specialization.IsDependent &&
         (!specialization.TranslationUnit.IsSystemHeader ||
         specialization.IsSupportedStdSpecialization()))
     {
         var cppTypePrinter = new CppTypePrinter
         {
             PrintScopeKind = CppTypePrintScopeKind.Qualified,
             PrintLogicalNames = true
         };
         var cppCode = specialization.Visit(cppTypePrinter);
         var module = specialization.TranslationUnit.Module;
         if (templateInstantiations.ContainsKey(module))
             templateInstantiations[module].Add(cppCode);
         else
             templateInstantiations.Add(module, new HashSet<string> { cppCode });
     }
     return true;
 }
Example #25
0
        void GenerateGetHashCode(Class @class, Block block)
        {
            var hashcodeOverride = @class.Methods.FirstOrDefault(m =>
            {
                var expansions = m.PreprocessedEntities.OfType <MacroExpansion>();
                return(expansions.Any(e => e.Text == "FLD_HASHCODE"));
            });

            if (hashcodeOverride == null)
            {
                return;
            }

            var cppTypePrinter = new CppTypePrinter(Driver.TypeDatabase);
            var classCppType   = @class.Visit(cppTypePrinter);

            block.Text.StringBuilder.Clear();
            block.WriteLine("return (({0}*)NativePtr)->{1}();",
                            classCppType, hashcodeOverride.OriginalName);
        }
Example #26
0
        public void HandleRefOutNonDefaultIntegerEnum(Enumeration @enum)
        {
            // This deals with marshaling of managed enums with non-C default
            // backing types (ie. enum : short).

            // Unlike C++ or Objective-C, C enums always have the default integer
            // type size, so we need to create a local variable of the right type
            // for marshaling with the managed runtime and cast it back to the
            // correct type.

            var backingType = @enum.BuiltinType.Type;
            var typePrinter = new CppTypePrinter();
            var integerType = typePrinter.VisitPrimitiveType(backingType);
            var newArgName = CGenerator.GenId(Context.ArgName);
            Context.SupportBefore.WriteLine("{0} {1} = *(({0}*) {2});",
                integerType, newArgName, Context.ArgName);
            Context.Return.Write("&{0}", newArgName);
            Context.SupportAfter.WriteLine("*{0} = ({1}) {2};", Context.ArgName,
                @enum.QualifiedName, newArgName);
        }
Example #27
0
        public override void GenerateClassEvents(Class @class)
        {
            foreach (var @event in @class.Events)
            {
                if ([email protected])
                {
                    continue;
                }

                var cppTypePrinter = new CppTypePrinter(Context);
                cppTypePrinter.PushContext(TypePrinterContextKind.Native);
                var cppArgs = cppTypePrinter.VisitParameters(@event.Parameters, hasNames: true);

                WriteLine("private:");
                Indent();

                var delegateName = string.Format("_{0}Delegate", @event.Name);
                WriteLine("delegate void {0}({1});", delegateName, cppArgs);
                WriteLine("{0}^ {0}Instance;", delegateName);

                WriteLine("void _{0}Raise({1});", @event.Name, cppArgs);
                WriteLine("{0} _{1};", @event.Type, @event.Name);

                Unindent();
                WriteLine("public:");
                Indent();

                WriteLine("event {0} {1}", @event.Type, @event.Name);
                WriteOpenBraceAndIndent();

                WriteLine("void add({0} evt);", @event.Type);
                WriteLine("void remove({0} evt);", @event.Type);

                var cliTypePrinter = new CLITypePrinter(Context);
                var cliArgs        = cliTypePrinter.VisitParameters(@event.Parameters, hasNames: true);

                WriteLine("void raise({0});", cliArgs);
                UnindentAndWriteCloseBrace();
                Unindent();
            }
        }
        public override bool VisitClassDecl(Class @class)
        {
            if (!base.VisitClassDecl(@class) || [email protected])
                return false;

            var cppTypePrinter = new CppTypePrinter
            {
                PrintScopeKind = CppTypePrintScopeKind.Qualified,
                PrintLogicalNames = true
            };
            foreach (var specialization in @class.Specializations.Where(s => !s.IsDependent && !s.Ignore))
            {
                var cppCode = specialization.Visit(cppTypePrinter);
                var module = specialization.TranslationUnit.Module;
                if (templateInstantiations.ContainsKey(module))
                    templateInstantiations[module].Add(cppCode);
                else
                    templateInstantiations.Add(module, new HashSet<string> { cppCode });
            }
            return true;
        }
Example #29
0
        public override bool VisitPointerType(PointerType pointer, TypeQualifiers quals)
        {
            var pointee = pointer.Pointee;

            if ((pointee.IsPrimitiveType(PrimitiveType.Char) ||
                 pointee.IsPrimitiveType(PrimitiveType.WideChar)) &&
                pointer.QualifiedPointee.Qualifiers.IsConst)
            {
                Context.SupportBefore.WriteLine(
                    "auto _{0} = clix::marshalString<clix::E_UTF8>({1});",
                    Context.ArgName, Context.Parameter.Name);

                Context.Return.Write("_{0}.c_str()", Context.ArgName);
                return(true);
            }

            if (pointee is FunctionType)
            {
                var function = pointee as FunctionType;

                var cppTypePrinter = new CppTypePrinter(Context.Driver.TypeDatabase);
                var cppTypeName    = pointer.Visit(cppTypePrinter, quals);

                return(VisitDelegateType(function, cppTypeName));
            }

            PrimitiveType primitive;

            if (pointee.Desugar().IsPrimitiveType(out primitive))
            {
                var cppTypePrinter = new CppTypePrinter(Context.Driver.TypeDatabase);
                var cppTypeName    = pointer.Visit(cppTypePrinter, quals);

                Context.Return.Write("({0})", cppTypeName);
                Context.Return.Write("{0}.ToPointer()", Context.Parameter.Name);
                return(true);
            }

            return(pointee.Visit(this, quals));
        }
        public void GenerateClassEvents(Class @class)
        {
            foreach (var @event in @class.Events)
            {
                if ([email protected])
                {
                    continue;
                }

                var cppTypePrinter = new CppTypePrinter(Driver.TypeDatabase);
                var cppArgs        = cppTypePrinter.VisitParameters(@event.Parameters, hasNames: true);

                WriteLine("private:");
                PushIndent();

                var delegateName = string.Format("_{0}Delegate", @event.Name);
                WriteLine("delegate void {0}({1});", delegateName, cppArgs);
                WriteLine("{0}^ {0}Instance;", delegateName);

                WriteLine("void _{0}Raise({1});", @event.Name, cppArgs);
                WriteLine("{0} _{1};", @event.Type, @event.Name);

                PopIndent();
                WriteLine("public:");
                PushIndent();

                WriteLine("event {0} {1}", @event.Type, @event.Name);
                WriteStartBraceIndent();

                WriteLine("void add({0} evt);", @event.Type);
                WriteLine("void remove({0} evt);", @event.Type);

                var cliTypePrinter = new CLITypePrinter(Driver);
                var cliArgs        = cliTypePrinter.VisitParameters(@event.Parameters, hasNames: true);

                WriteLine("void raise({0});", cliArgs);
                WriteCloseBraceIndent();
                PopIndent();
            }
        }
Example #31
0
        void SetupTypePrinter()
        {
            CppSharp.AST.Type.TypePrinterDelegate = type =>
            {
                CppTypePrintFlavorKind kind = CppTypePrintFlavorKind.Cpp;
                switch (Options.GeneratorKind)
                {
                case GeneratorKind.C:
                    kind = CppTypePrintFlavorKind.C;
                    break;

                case GeneratorKind.ObjectiveC:
                    kind = CppTypePrintFlavorKind.ObjC;
                    break;
                }

                var typePrinter = new CppTypePrinter {
                    PrintFlavorKind = kind
                };
                return(type.Visit(typePrinter));
            };
        }
Example #32
0
        public override bool VisitTypedefType(TypedefType typedef, TypeQualifiers quals)
        {
            var decl = typedef.Declaration;

            TypeMap typeMap;
            if (Context.Driver.TypeDatabase.FindTypeMap(decl, out typeMap) && typeMap.DoesMarshalling)
            {
                typeMap.CLIMarshalToNative(Context);
                return typeMap.IsValueType;
            }

            FunctionType func;
            if (decl.Type.IsPointerTo(out func))
            {
                // Use the original typedef name if available, otherwise just use the function pointer type
                string cppTypeName;
                if (!decl.IsSynthetized)
                    cppTypeName = "::" + typedef.Declaration.QualifiedOriginalName;
                else
                {
                    var cppTypePrinter = new CppTypePrinter(Context.Driver.TypeDatabase);
                    cppTypeName = decl.Type.Visit(cppTypePrinter, quals);
                }

                VisitDelegateType(func, cppTypeName);
                return true;
            }

            PrimitiveType primitive;
            if (decl.Type.IsPrimitiveType(out primitive))
            {
                Context.Return.Write("(::{0})", typedef.Declaration.QualifiedOriginalName);
            }

            return decl.Type.Visit(this);
        }
Example #33
0
        public override bool VisitPointerType(PointerType pointer, TypeQualifiers quals)
        {
            if (!VisitType(pointer, quals))
                return false;

            var pointee = pointer.Pointee.Desugar();

            if ((pointee.IsPrimitiveType(PrimitiveType.Char) ||
                pointee.IsPrimitiveType(PrimitiveType.WideChar)) &&
                pointer.QualifiedPointee.Qualifiers.IsConst)
            {
                Context.SupportBefore.WriteLine(
                    "auto _{0} = clix::marshalString<clix::E_UTF8>({1});",
                    Context.ArgName, Context.Parameter.Name);

                Context.Return.Write("_{0}.c_str()", Context.ArgName);
                return true;
            }

            if (pointee is FunctionType)
            {
                var function = pointee as FunctionType;

                var cppTypePrinter = new CppTypePrinter(Context.Driver.TypeDatabase);
                var cppTypeName = pointer.Visit(cppTypePrinter, quals);

                return VisitDelegateType(function, cppTypeName);
            }

            Enumeration @enum;
            if (pointee.TryGetEnum(out @enum))
            {
                var isRef = Context.Parameter.Usage == ParameterUsage.Out ||
                    Context.Parameter.Usage == ParameterUsage.InOut;

                ArgumentPrefix.Write("&");
                Context.Return.Write("(::{0}){1}{2}", @enum.QualifiedOriginalName,
                    isRef ? string.Empty : "*", Context.Parameter.Name);
                return true;
            }

            Class @class;
            if (pointee.TryGetClass(out @class) && @class.IsValueType)
            {
                if (Context.Function == null)
                    Context.Return.Write("&");
                return pointee.Visit(this, quals);
            }

            var finalPointee = pointer.GetFinalPointee();
            if (finalPointee.IsPrimitiveType())
            {
                var cppTypePrinter = new CppTypePrinter(Context.Driver.TypeDatabase);
                var cppTypeName = pointer.Visit(cppTypePrinter, quals);

                Context.Return.Write("({0})", cppTypeName);
                Context.Return.Write(Context.Parameter.Name);
                return true;
            }

            return pointer.Pointee.Visit(this, quals);
        }
Example #34
0
        public override void CLIMarshalToNative(MarshalContext ctx)
        {
            var templateType = Type as TemplateSpecializationType;
            var type = templateType.Arguments[0].Type;
            var isPointerToPrimitive = type.Type.IsPointerToPrimitiveType();
            var managedType = isPointerToPrimitive
                ? new CILType(typeof(System.IntPtr))
                : type.Type;

            var entryString = (ctx.Parameter != null) ? ctx.Parameter.Name
                : ctx.ArgName;

            var tmpVarName = "_tmp" + entryString;

            var cppTypePrinter = new CppTypePrinter();
            var nativeType = type.Type.Visit(cppTypePrinter);

            ctx.SupportBefore.WriteLine("auto {0} = std::vector<{1}>();",
                tmpVarName, nativeType);
            ctx.SupportBefore.WriteLine("for each({0} _element in {1})",
                managedType, entryString);
            ctx.SupportBefore.WriteStartBraceIndent();
            {
                var param = new Parameter
                {
                    Name = "_element",
                    QualifiedType = type
                };

                var elementCtx = new MarshalContext(ctx.Context)
                                     {
                                         Parameter = param,
                                         ArgName = param.Name,
                                     };

                var marshal = new CLIMarshalManagedToNativePrinter(elementCtx);
                type.Type.Visit(marshal);

                if (!string.IsNullOrWhiteSpace(marshal.Context.SupportBefore))
                    ctx.SupportBefore.Write(marshal.Context.SupportBefore);

                if (isPointerToPrimitive)
                    ctx.SupportBefore.WriteLine("auto _marshalElement = {0}.ToPointer();",
                        marshal.Context.Return);
                else
                    ctx.SupportBefore.WriteLine("auto _marshalElement = {0};",
                    marshal.Context.Return);

                ctx.SupportBefore.WriteLine("{0}.push_back(_marshalElement);",
                    tmpVarName);
            }
            
            ctx.SupportBefore.WriteCloseBraceIndent();

            ctx.Return.Write(tmpVarName);
        }
Example #35
0
        public override bool VisitPointerType(PointerType pointer, TypeQualifiers quals)
        {
            if (!VisitType(pointer, quals))
                return false;

            var pointee = pointer.Pointee.Desugar();

            if (pointee.IsPrimitiveType(PrimitiveType.Void))
            {
                Context.Return.Write("::System::IntPtr({0})", Context.ReturnVarName);
                return true;
            }

            if (CSharpTypePrinter.IsConstCharString(pointer))
            {
                Context.Return.Write(MarshalStringToManaged(Context.ReturnVarName,
                    pointer.Pointee.Desugar() as BuiltinType));
                return true;
            }

            PrimitiveType primitive;
            var param = Context.Parameter;
            if (param != null && (param.IsOut || param.IsInOut) &&
                pointee.IsPrimitiveType(out primitive))
            {
                Context.Return.Write(Context.ReturnVarName);
                return true;
            }

            if (pointee.IsPrimitiveType(out primitive))
            {
                var returnVarName = Context.ReturnVarName;
                if (quals.IsConst != Context.ReturnType.Qualifiers.IsConst)
                {
                    var nativeTypePrinter = new CppTypePrinter(Context.Driver.TypeDatabase, false);
                    var returnType = Context.ReturnType.Type.Desugar();
                    var constlessPointer = new PointerType()
                    {
                        IsDependent = pointer.IsDependent,
                        Modifier = pointer.Modifier,
                        QualifiedPointee = new QualifiedType(returnType.GetPointee())
                    };
                    var nativeConstlessTypeName = constlessPointer.Visit(nativeTypePrinter, new TypeQualifiers());
                    returnVarName = string.Format("const_cast<{0}>({1})",
                        nativeConstlessTypeName, Context.ReturnVarName);
                }
                if (pointer.Pointee is TypedefType)
                {
                    var desugaredPointer = new PointerType()
                    {
                        IsDependent = pointer.IsDependent,
                        Modifier = pointer.Modifier,
                        QualifiedPointee = new QualifiedType(pointee)
                    };
                    var nativeTypePrinter = new CppTypePrinter(Context.Driver.TypeDatabase);
                    var nativeTypeName = desugaredPointer.Visit(nativeTypePrinter, quals);
                    Context.Return.Write("reinterpret_cast<{0}>({1})", nativeTypeName,
                        returnVarName);
                }
                else
                    Context.Return.Write(returnVarName);
                return true;
            }

            TypeMap typeMap = null;
            Context.Driver.TypeDatabase.FindTypeMap(pointee, out typeMap);

            Class @class;
            if (pointee.TryGetClass(out @class) && typeMap == null)
            {
                var instance = (pointer.IsReference) ? "&" + Context.ReturnVarName
                    : Context.ReturnVarName;
                WriteClassInstance(@class, instance);
                return true;
            }

            return pointer.Pointee.Visit(this, quals);
        }
Example #36
0
        public override bool VisitPointerType(PointerType pointer, TypeQualifiers quals)
        {
            if (!VisitType(pointer, quals))
            {
                return(false);
            }

            var pointee = pointer.Pointee.Desugar();

            if ((pointee.IsPrimitiveType(PrimitiveType.Char) ||
                 pointee.IsPrimitiveType(PrimitiveType.WideChar)) &&
                pointer.QualifiedPointee.Qualifiers.IsConst)
            {
                Context.SupportBefore.WriteLine(
                    "auto _{0} = clix::marshalString<clix::E_UTF8>({1});",
                    Context.ArgName, Context.Parameter.Name);

                Context.Return.Write("_{0}.c_str()", Context.ArgName);
                return(true);
            }

            if (pointee is FunctionType)
            {
                var function = pointee as FunctionType;

                var cppTypePrinter = new CppTypePrinter(Context.Driver.TypeDatabase);
                var cppTypeName    = pointer.Visit(cppTypePrinter, quals);

                return(VisitDelegateType(function, cppTypeName));
            }

            Enumeration @enum;

            if (pointee.TryGetEnum(out @enum))
            {
                var isRef = Context.Parameter.Usage == ParameterUsage.Out ||
                            Context.Parameter.Usage == ParameterUsage.InOut;

                ArgumentPrefix.Write("&");
                Context.Return.Write("(::{0}){1}{2}", @enum.QualifiedOriginalName,
                                     isRef ? string.Empty : "*", Context.Parameter.Name);
                return(true);
            }

            Class @class;

            if (pointee.TryGetClass(out @class) && @class.IsValueType)
            {
                if (Context.Function == null)
                {
                    Context.Return.Write("&");
                }
                return(pointee.Visit(this, quals));
            }

            var finalPointee = pointer.GetFinalPointee();

            if (finalPointee.IsPrimitiveType())
            {
                var cppTypePrinter = new CppTypePrinter(Context.Driver.TypeDatabase);
                var cppTypeName    = pointer.Visit(cppTypePrinter, quals);

                Context.Return.Write("({0})", cppTypeName);
                Context.Return.Write(Context.Parameter.Name);
                return(true);
            }

            return(pointer.Pointee.Visit(this, quals));
        }
Example #37
0
        public void GenerateFunctionCall(Function function, Class @class = null, Type publicRetType = null)
        {
            CheckArgumentRange(function);

            if (function.OperatorKind == CXXOperatorKind.EqualEqual ||
                function.OperatorKind == CXXOperatorKind.ExclaimEqual)
            {
                WriteLine("bool {0}Null = ReferenceEquals({0}, nullptr);",
                          function.Parameters[0].Name);
                WriteLine("bool {0}Null = ReferenceEquals({0}, nullptr);",
                          function.Parameters[1].Name);
                WriteLine("if ({0}Null || {1}Null)",
                          function.Parameters[0].Name, function.Parameters[1].Name);
                WriteLineIndent("return {0}{1}Null && {2}Null{3};",
                                function.OperatorKind == CXXOperatorKind.EqualEqual ? string.Empty : "!(",
                                function.Parameters[0].Name, function.Parameters[1].Name,
                                function.OperatorKind == CXXOperatorKind.EqualEqual ? string.Empty : ")");
            }

            var retType = function.ReturnType;

            if (publicRetType == null)
            {
                publicRetType = retType.Type;
            }
            var needsReturn = !publicRetType.IsPrimitiveType(PrimitiveType.Void);

            const string valueMarshalName = "_this0";
            var          isValueType      = @class != null && @class.IsValueType;

            if (isValueType && !IsNativeFunctionOrStaticMethod(function))
            {
                WriteLine("auto {0} = ::{1}();", valueMarshalName, @class.QualifiedOriginalName);

                var param = new Parameter {
                    Name = "(*this)", Namespace = function.Namespace
                };
                var ctx = new MarshalContext(Context)
                {
                    MarshalVarPrefix = valueMarshalName,
                    Parameter        = param
                };

                var marshal = new CLIMarshalManagedToNativePrinter(ctx);
                marshal.MarshalValueClassProperties(@class, valueMarshalName);

                if (!string.IsNullOrWhiteSpace(marshal.Context.Before))
                {
                    Write(marshal.Context.Before);
                }
            }

            var @params = GenerateFunctionParamsMarshal(function.Parameters, function);

            var returnIdentifier = Helpers.ReturnIdentifier;

            if (needsReturn)
            {
                if (retType.Type.IsReference())
                {
                    Write("auto &{0} = ", returnIdentifier);
                }
                else
                {
                    Write("auto {0} = ", returnIdentifier);
                }
            }

            if (function.OperatorKind == CXXOperatorKind.Conversion ||
                function.OperatorKind == CXXOperatorKind.ExplicitConversion)
            {
                var method      = function as Method;
                var typePrinter = new CppTypePrinter();
                var typeName    = method.ConversionType.Visit(typePrinter);
                WriteLine("({0}) {1};", typeName, @params[0].Name);
            }
            else if (function.IsOperator &&
                     function.OperatorKind != CXXOperatorKind.Subscript)
            {
                var opName = function.Name.Replace("operator", "").Trim();

                switch (Operators.ClassifyOperator(function))
                {
                case CXXOperatorArity.Unary:
                    WriteLine("{0} {1};", opName, @params[0].Name);
                    break;

                case CXXOperatorArity.Binary:
                    WriteLine("{0} {1} {2};", @params[0].Name, opName, @params[1].Name);
                    break;
                }
            }
            else
            {
                if (IsNativeFunctionOrStaticMethod(function))
                {
                    Write("::{0}(", function.QualifiedOriginalName);
                }
                else
                {
                    if (isValueType)
                    {
                        Write("{0}.", valueMarshalName);
                    }
                    else if (IsNativeMethod(function))
                    {
                        Write("((::{0}*)NativePtr)->", @class.QualifiedOriginalName);
                    }
                    Write("{0}(", function.OriginalName);
                }

                GenerateFunctionParams(@params);
                WriteLine(");");
            }

            foreach (var paramInfo in @params)
            {
                var param = paramInfo.Param;
                if (param.Usage != ParameterUsage.Out && param.Usage != ParameterUsage.InOut)
                {
                    continue;
                }

                if (param.Type.IsPointer() && !param.Type.GetFinalPointee().IsPrimitiveType())
                {
                    param.QualifiedType = new QualifiedType(param.Type.GetFinalPointee());
                }

                var nativeVarName = paramInfo.Name;

                var ctx = new MarshalContext(Context)
                {
                    ArgName       = nativeVarName,
                    ReturnVarName = nativeVarName,
                    ReturnType    = param.QualifiedType
                };

                var marshal = new CLIMarshalNativeToManagedPrinter(ctx);
                param.Visit(marshal);

                if (!string.IsNullOrWhiteSpace(marshal.Context.Before))
                {
                    Write(marshal.Context.Before);
                }

                WriteLine("{0} = {1};", param.Name, marshal.Context.Return);
            }

            if (isValueType && !IsNativeFunctionOrStaticMethod(function))
            {
                GenerateStructMarshaling(@class, valueMarshalName + ".");
            }

            if (needsReturn)
            {
                var retTypeName = retType.Visit(TypePrinter).ToString();
                var isIntPtr    = retTypeName.Contains("IntPtr");

                if (retType.Type.IsPointer() && (isIntPtr || retTypeName.EndsWith("^", StringComparison.Ordinal)))
                {
                    WriteLine("if ({0} == nullptr) return {1};",
                              returnIdentifier,
                              isIntPtr ? "System::IntPtr()" : "nullptr");
                }

                var ctx = new MarshalContext(Context)
                {
                    ArgName       = returnIdentifier,
                    ReturnVarName = returnIdentifier,
                    ReturnType    = retType
                };

                var marshal = new CLIMarshalNativeToManagedPrinter(ctx);
                retType.Visit(marshal);

                if (!string.IsNullOrWhiteSpace(marshal.Context.Before))
                {
                    Write(marshal.Context.Before);
                }

                // Special case for indexer - needs to dereference if the internal
                // function is a pointer type and the property is not.
                if (retType.Type.IsPointer() &&
                    retType.Type.GetPointee().Equals(publicRetType) &&
                    publicRetType.IsPrimitiveType())
                {
                    WriteLine("return *({0});", marshal.Context.Return);
                }
                else if (retType.Type.IsReference() && publicRetType.IsReference())
                {
                    WriteLine("return ({0})({1});", publicRetType, marshal.Context.Return);
                }
                else
                {
                    WriteLine("return {0};", marshal.Context.Return);
                }
            }
        }
Example #38
0
        public override void CLIMarshalToNative(MarshalContext ctx)
        {
            var templateType = Type as TemplateSpecializationType;
            var type1 = templateType.Arguments[0].Type;
            var type2 = templateType.Arguments[1].Type;

            var entryString = (ctx.Parameter != null) ? ctx.Parameter.Name : ctx.ArgName;

            var tmpVarName = "_tmp" + entryString;

            var cppTypePrinter = new CppTypePrinter(ctx.Driver.TypeDatabase);
            var nativeType1 = type1.Type.Visit(cppTypePrinter);
            var nativeType2 = type2.Type.Visit(cppTypePrinter);

            ctx.SupportBefore.WriteLine("auto {0} = HashMap<{1}, {2}>();",
                tmpVarName, nativeType1, nativeType2);
            ctx.SupportBefore.WriteLine("auto _keys = {0}->Keys->GetEnumerator();", entryString);
            ctx.SupportBefore.WriteLine("while (_keys.MoveNext())");
            ctx.SupportBefore.WriteStartBraceIndent();
            {
                ctx.SupportBefore.WriteLine("{0} _key = _keys.Current;", type1.ToString());
                ctx.SupportBefore.WriteLine("{0} _val = {1}[_key];", type2.ToString(), entryString);
                var param1 = new Parameter
                {
                    Name = "_key",
                    QualifiedType = type1
                };

                var elementCtx1 = new MarshalContext(ctx.Driver)
                {
                    Parameter = param1,
                    ArgName = param1.Name,
                };

                var marshal1 = new CLIMarshalManagedToNativePrinter(elementCtx1);
                type1.Type.Visit(marshal1);

                if (!string.IsNullOrWhiteSpace(marshal1.Context.SupportBefore))
                    ctx.SupportBefore.Write(marshal1.Context.SupportBefore);

                ctx.SupportBefore.WriteLine("auto _marshalKey = {0};",
                    marshal1.Context.Return);

                var param2 = new Parameter
                {
                    Name = "_val",
                    QualifiedType = type2
                };

                var elementCtx2 = new MarshalContext(ctx.Driver)
                {
                    Parameter = param2,
                    ArgName = param2.Name,
                };

                var marshal2 = new CLIMarshalManagedToNativePrinter(elementCtx2);
                type2.Type.Visit(marshal2);

                if (!string.IsNullOrWhiteSpace(marshal2.Context.SupportBefore))
                    ctx.SupportBefore.Write(marshal2.Context.SupportBefore);

                ctx.SupportBefore.WriteLine("auto _marshalValue = {0};",
                    marshal2.Context.Return);

                ctx.SupportBefore.WriteLine("{0}[_marshalKey] = _marshalValue;", tmpVarName);
            }

            ctx.SupportBefore.WriteCloseBraceIndent();

            ctx.Return.Write(tmpVarName);
        }
Example #39
0
        public bool FindTypeMap(Type type, out TypeMap typeMap)
        {
            var typePrinter = new CppTypePrinter(this);

            var template = type as TemplateSpecializationType;
            if (template != null)
                return FindTypeMap(template.Template.TemplatedDecl, type,
                    out typeMap);

            if (FindTypeMap(type.Visit(typePrinter), out typeMap))
            {
                typeMap.Type = type;
                return true;
            }

            typePrinter.PrintKind = CppTypePrintKind.Qualified;
            if (FindTypeMap(type.Visit(typePrinter), out typeMap))
            {
                typeMap.Type = type;
                return true;
            }

            return false;
        }
Example #40
0
        public bool FindTypeMap(Declaration decl, Type type, out TypeMap typeMap)
        {
            // We try to find type maps from the most qualified to less qualified
            // types. Example: '::std::vector', 'std::vector' and 'vector'

            var typePrinter = new CppTypePrinter(this)
                {
                    PrintKind = CppTypePrintKind.GlobalQualified
                };

            if (FindTypeMap(decl.Visit(typePrinter), out typeMap))
            {
                typeMap.Type = type;
                return true;
            }

            typePrinter.PrintKind = CppTypePrintKind.Qualified;
            if (FindTypeMap(decl.Visit(typePrinter), out typeMap))
            {
                typeMap.Type = type;
                return true;
            }

            typePrinter.PrintKind = CppTypePrintKind.Local;
            if (FindTypeMap(decl.Visit(typePrinter), out typeMap))
            {
                typeMap.Type = type;
                return true;
            }

            return false;
        }
Example #41
0
        public override bool VisitFieldDecl(Field field)
        {
            if (!VisitDeclaration(field))
                return false;

            var type = field.Type;

            string msg;
            if (!HasInvalidType(type, out msg))
                return false;

            field.ExplicitlyIgnore();

            var @class = (Class)field.Namespace;

            var cppTypePrinter = new CppTypePrinter(Driver.TypeDatabase);
            var typeName = type.Visit(cppTypePrinter);

            Log.Debug("Field '{0}::{1}' was ignored due to {2} type '{3}'",
                @class.Name, field.Name, msg, typeName);

            return true;
        }
Example #42
0
        public bool FindTypeMap(Declaration decl, Type type, out TypeMap typeMap)
        {
            // We try to find type maps from the most qualified to less qualified
            // types. Example: '::std::vector', 'std::vector' and 'vector'

            var typePrinter = new CppTypePrinter { PrintLogicalNames = true };

            if (FindTypeMap(decl.Visit(typePrinter), out typeMap))
            {
                typeMap.Type = type;
                return true;
            }

            typePrinter.PrintScopeKind = CppTypePrintScopeKind.Qualified;
            if (FindTypeMap(decl.Visit(typePrinter), out typeMap))
            {
                typeMap.Type = type;
                return true;
            }

            typePrinter.PrintScopeKind = CppTypePrintScopeKind.Local;
            if (FindTypeMap(decl.Visit(typePrinter), out typeMap))
            {
                typeMap.Type = type;
                return true;
            }

            var specialization = decl as ClassTemplateSpecialization;
            if (specialization != null &&
                FindTypeMap(specialization.TemplatedDecl.Visit(typePrinter), out typeMap))
            {
                typeMap.Type = type;
                return true;
            }

            var typedef = decl as TypedefDecl;
            return typedef != null && FindTypeMap(typedef.Type, out typeMap);
        }
Example #43
0
 private bool TryMatch(Function function, string docs, bool markObsolete, bool completeSignature = true)
 {
     const string memberDoc = @"(^|( --)|\n)\n([\w :*&<>,]+)?(({0}(\s*&)?::)| ){1}(const)?( \[(\w+\s*)+\])?\n(?<docs>\w.*?)(\n\s*){{1,2}}((&?\S* --)|((\n\s*){{2}}))";
     const string separator = @",\s*";
     StringBuilder signatureRegex = new StringBuilder(Regex.Escape(function.OriginalName)).Append(@"\s*\(\s*(");
     bool anyArgs = false;
     CppTypePrinter cppTypePrinter = new CppTypePrinter(new TypeMapDatabase());
     cppTypePrinter.PrintKind = CppTypePrintKind.Local;
     foreach (string argType in function.Parameters.Where(p => p.Kind == ParameterKind.Regular).Select(p => p.Type.Visit(cppTypePrinter)))
     {
         if (!anyArgs)
         {
             signatureRegex.Append("?<args>");
             anyArgs = true;
         }
         signatureRegex.Append(this.GetTypeRegex(argType, completeSignature)).Append(@"(\s+\w+(\s*=\s*[^,\r\n]+(\(\s*\))?)?)?");
         signatureRegex.Append(separator);
     }
     if (anyArgs)
     {
         signatureRegex.Insert(signatureRegex.Length - separator.Length, '(');
     }
     else
     {
         signatureRegex.Append('(');
     }
     signatureRegex.Append(@"[\w :*&<>]+\s*=\s*[^,\r\n]+(\(\s*\))?(,\s*)?)*)\s*\)\s*");
     Match match = Regex.Match(docs, string.Format(memberDoc, function.Namespace.Name, signatureRegex),
                               RegexOptions.Singleline | RegexOptions.ExplicitCapture);
     if (match.Success)
     {
         function.Comment = new RawComment();
         function.Comment.BriefText = match.Groups["docs"].Value;
         FillMissingParameterNames(function, match.Groups["args"].Value);
         if (markObsolete)
         {
             AddObsoleteAttribute(function);
         }
         return true;
     }
     return false;
 }
Example #44
0
        void GenerateGetHashCode(Class @class, Block block)
        {
            var hashcodeOverride = @class.Methods.FirstOrDefault(m =>
            {
                var expansions = m.PreprocessedEntities.OfType<MacroExpansion>();
                return expansions.Any(e => e.Text == "FLD_HASHCODE");
            });

            if (hashcodeOverride == null)
                return;

            var cppTypePrinter = new CppTypePrinter(Driver.TypeDatabase);
            var classCppType = @class.Visit(cppTypePrinter);

            block.Text.StringBuilder.Clear();
            block.WriteLine("return (({0}*)NativePtr)->{1}();",
                classCppType, hashcodeOverride.OriginalName);
        }
Example #45
0
        public override void CLIMarshalToNative(MarshalContext ctx)
        {
            var templateType = Type as TemplateSpecializationType;
            var type = templateType.Arguments[0].Type;

            var entryString = (ctx.Parameter != null) ? ctx.Parameter.Name : ctx.ArgName;

            var tmpVarName = "_tmp" + entryString;

            var cppTypePrinter = new CppTypePrinter(ctx.Driver.TypeDatabase);
            var nativeType = type.Type.Visit(cppTypePrinter);

            ctx.SupportBefore.WriteLine("auto {0} = Vector<{1}>();",
                tmpVarName, nativeType);
            ctx.SupportBefore.WriteLine("for each({0} _element in {1})",
                type.ToString(), entryString);
            ctx.SupportBefore.WriteStartBraceIndent();
            {
                var param = new Parameter
                {
                    Name = "_element",
                    QualifiedType = type
                };

                var elementCtx = new MarshalContext(ctx.Driver)
                {
                    Parameter = param,
                    ArgName = param.Name,
                };

                var marshal = new CLIMarshalManagedToNativePrinter(elementCtx);
                type.Type.Visit(marshal);

                if (!string.IsNullOrWhiteSpace(marshal.Context.SupportBefore))
                    ctx.SupportBefore.Write(marshal.Context.SupportBefore);

                ctx.SupportBefore.WriteLine("auto _marshalElement = {0};",
                    marshal.Context.Return);

                ctx.SupportBefore.WriteLine("{0}.Push(_marshalElement);", tmpVarName);
            }

            ctx.SupportBefore.WriteCloseBraceIndent();

            ctx.Return.Write(tmpVarName);
        }
Example #46
0
        public void GenerateClassEvents(Class @class)
        {
            foreach (var @event in @class.Events)
            {
                if ([email protected]) continue;

                var cppTypePrinter = new CppTypePrinter();
                var cppArgs = cppTypePrinter.VisitParameters(@event.Parameters, hasNames: true);

                WriteLine("private:");
                PushIndent();

                var delegateName = string.Format("_{0}Delegate", @event.Name);
                WriteLine("delegate void {0}({1});", delegateName, cppArgs);
                WriteLine("{0}^ {0}Instance;", delegateName);

                WriteLine("void _{0}Raise({1});", @event.Name, cppArgs);
                WriteLine("{0} _{1};", @event.Type, @event.Name);

                PopIndent();
                WriteLine("public:");
                PushIndent();

                WriteLine("event {0} {1}", @event.Type, @event.Name);
                WriteStartBraceIndent();

                WriteLine("void add({0} evt);", @event.Type);
                WriteLine("void remove({0} evt);", @event.Type);

                var cliTypePrinter = new CLITypePrinter(Driver);
                var cliArgs = cliTypePrinter.VisitParameters(@event.Parameters, hasNames: true);

                WriteLine("void raise({0});", cliArgs);
                WriteCloseBraceIndent();
                PopIndent();
            }
        }
Example #47
0
        public bool FindTypeMap(Type type, out TypeMap typeMap)
        {
            var typePrinter = new CppTypePrinter
            {
                PrintTypeQualifiers = false,
                PrintTypeModifiers = false,
                PrintLogicalNames = true
            };

            var template = type as TemplateSpecializationType;
            if (template != null)
            {
                var specialization = template.GetClassTemplateSpecialization();
                if (specialization != null && FindTypeMap(specialization, type, out typeMap))
                    return true;
                if (template.Template.TemplatedDecl != null)
                    return FindTypeMap(template.Template.TemplatedDecl, type,
                        out typeMap);
            }

            if (FindTypeMap(type.Visit(typePrinter), out typeMap))
            {
                typeMap.Type = type;
                return true;
            }

            if (FindTypeMap(type.Visit(typePrinter), out typeMap))
            {
                typeMap.Type = type;
                return true;
            }

            typePrinter.PrintScopeKind = CppTypePrintScopeKind.Qualified;
            if (FindTypeMap(type.Visit(typePrinter), out typeMap))
            {
                typeMap.Type = type;
                return true;
            }

            var typedef = type as TypedefType;
            return typedef != null && FindTypeMap(typedef.Declaration, type, out typeMap);
        }
Example #48
0
        public override bool VisitPointerType(PointerType pointer, TypeQualifiers quals)
        {
            if (!VisitType(pointer, quals))
                return false;

            var pointee = pointer.Pointee.Desugar();

            if ((pointee.IsPrimitiveType(PrimitiveType.Char) ||
                pointee.IsPrimitiveType(PrimitiveType.WideChar)) &&
                pointer.QualifiedPointee.Qualifiers.IsConst)
            {
                Context.SupportBefore.WriteLine(
                    "auto _{0} = clix::marshalString<clix::E_UTF8>({1});",
                    Context.ArgName, Context.Parameter.Name);

                Context.Return.Write("_{0}.c_str()", Context.ArgName);
                return true;
            }

            if (pointee is FunctionType)
            {
                var function = pointee as FunctionType;

                var cppTypePrinter = new CppTypePrinter(Context.Driver.TypeDatabase);
                var cppTypeName = pointer.Visit(cppTypePrinter, quals);

                return VisitDelegateType(function, cppTypeName);
            }

            Class @class;
            if (pointee.IsTagDecl(out @class) && @class.IsValueType)
            {
                if (Context.Function == null)
                    Context.Return.Write("&");
                return pointee.Visit(this, quals);
            }

            PrimitiveType primitive;
            if (pointee.IsPrimitiveType(out primitive))
            {
                var cppTypePrinter = new CppTypePrinter(Context.Driver.TypeDatabase);
                var cppTypeName = pointer.Visit(cppTypePrinter, quals);

                Context.Return.Write("({0})", cppTypeName);
                Context.Return.Write(Context.Parameter.Name);
                return true;
            }

            return pointer.Pointee.Visit(this, quals);
        }
Example #49
0
        private ParamMarshal GenerateFunctionParamMarshal(Parameter param, int paramIndex,
                                                          Function function = null)
        {
            var paramMarshal = new ParamMarshal {
                Name = param.Name, Param = param
            };

            if (param.Type is BuiltinType)
            {
                return(paramMarshal);
            }

            var argName = Generator.GeneratedIdentifier("arg") + paramIndex.ToString(CultureInfo.InvariantCulture);

            var isRef = param.IsOut || param.IsInOut;
            // Since both pointers and references to types are wrapped as CLI
            // tracking references when using in/out, we normalize them here to be able
            // to use the same code for marshaling.
            var paramType = param.Type;

            if (paramType is PointerType && isRef)
            {
                if (!paramType.IsReference())
                {
                    paramMarshal.Prefix = "&";
                }
                paramType = (paramType as PointerType).Pointee;
            }

            var effectiveParam = new Parameter(param)
            {
                QualifiedType = new QualifiedType(paramType)
            };

            var ctx = new MarshalContext(Context)
            {
                Parameter      = effectiveParam,
                ParameterIndex = paramIndex,
                ArgName        = argName,
                Function       = function
            };

            var marshal = new CLIMarshalManagedToNativePrinter(ctx);

            effectiveParam.Visit(marshal);

            if (string.IsNullOrEmpty(marshal.Context.Return))
            {
                throw new Exception(string.Format("Cannot marshal argument of function '{0}'",
                                                  function.QualifiedOriginalName));
            }

            if (isRef)
            {
                var typePrinter = new CppTypePrinter();
                var type        = paramType.Visit(typePrinter);

                if (param.IsInOut)
                {
                    if (!string.IsNullOrWhiteSpace(marshal.Context.Before))
                    {
                        Write(marshal.Context.Before);
                    }

                    WriteLine("{0} {1} = {2};", type, argName, marshal.Context.Return);
                }
                else
                {
                    WriteLine("{0} {1};", type, argName);
                }
            }
            else
            {
                if (!string.IsNullOrWhiteSpace(marshal.Context.Before))
                {
                    Write(marshal.Context.Before);
                }

                WriteLine("auto {0}{1} = {2};", marshal.VarPrefix, argName,
                          marshal.Context.Return);
                paramMarshal.Prefix = marshal.ArgumentPrefix;
            }

            paramMarshal.Name = argName;
            return(paramMarshal);
        }
Example #50
0
        public override void CLIMarshalToNative(MarshalContext ctx)
        {
            var templateType         = Type as TemplateSpecializationType;
            var type                 = templateType.Arguments[0].Type;
            var isPointerToPrimitive = type.Type.IsPointerToPrimitiveType();
            var managedType          = isPointerToPrimitive
                ? new CILType(typeof(System.IntPtr))
                : type.Type;

            var entryString = (ctx.Parameter != null) ? ctx.Parameter.Name
                : ctx.ArgName;

            var tmpVarName = "_tmp" + entryString;

            var cppTypePrinter = new CppTypePrinter();
            var nativeType     = type.Type.Visit(cppTypePrinter);

            ctx.Before.WriteLine("auto {0} = std::vector<{1}>();",
                                 tmpVarName, nativeType);
            ctx.Before.WriteLine("for each({0} _element in {1})",
                                 managedType, entryString);
            ctx.Before.WriteOpenBraceAndIndent();
            {
                var param = new Parameter
                {
                    Name          = "_element",
                    QualifiedType = type
                };

                var elementCtx = new MarshalContext(ctx.Context, ctx.Indentation)
                {
                    Parameter = param,
                    ArgName   = param.Name,
                };

                var marshal = new CLIMarshalManagedToNativePrinter(elementCtx);
                type.Type.Visit(marshal);

                if (!string.IsNullOrWhiteSpace(marshal.Context.Before))
                {
                    ctx.Before.Write(marshal.Context.Before);
                }

                if (isPointerToPrimitive)
                {
                    ctx.Before.WriteLine("auto _marshalElement = {0}.ToPointer();",
                                         marshal.Context.Return);
                }
                else
                {
                    ctx.Before.WriteLine("auto _marshalElement = {0};",
                                         marshal.Context.Return);
                }

                ctx.Before.WriteLine("{0}.push_back(_marshalElement);",
                                     tmpVarName);
            }

            ctx.Before.UnindentAndWriteCloseBrace();

            ctx.Return.Write(tmpVarName);
        }
Example #51
0
        private ParamMarshal GenerateFunctionParamMarshal(Parameter param, int paramIndex,
                                                          Function function = null)
        {
            var paramMarshal = new ParamMarshal {
                Name = param.Name, Param = param
            };

            if (param.Type is BuiltinType)
            {
                return(paramMarshal);
            }

            var argName = Generator.GeneratedIdentifier("arg") + paramIndex.ToString(CultureInfo.InvariantCulture);

            var isRef = param.IsOut || param.IsInOut;

            var paramType = param.Type;

            // Get actual type if the param type is a typedef but not a function type because function types have to be typedef.
            // We need to get the actual type this early before we visit any marshalling code to ensure we hit the marshalling
            // logic for the actual type and not the typedef.
            // This fixes issues where typedefs to primitive pointers are involved.
            FunctionType functionType;
            var          paramTypeAsTypedef = paramType as TypedefType;

            if (paramTypeAsTypedef != null && !paramTypeAsTypedef.Declaration.Type.IsPointerTo(out functionType))
            {
                paramType = param.Type.Desugar();
            }

            // Since both pointers and references to types are wrapped as CLI
            // tracking references when using in/out, we normalize them here to be able
            // to use the same code for marshaling.
            if (paramType is PointerType && isRef)
            {
                if (!paramType.IsReference())
                {
                    paramMarshal.Prefix = "&";
                }
                paramType = (paramType as PointerType).Pointee;
            }

            var effectiveParam = new Parameter(param)
            {
                QualifiedType = new QualifiedType(paramType)
            };

            var ctx = new MarshalContext(Context, CurrentIndentation)
            {
                Parameter      = effectiveParam,
                ParameterIndex = paramIndex,
                ArgName        = argName,
                Function       = function
            };

            var marshal = new CLIMarshalManagedToNativePrinter(ctx);

            effectiveParam.Visit(marshal);

            if (string.IsNullOrEmpty(marshal.Context.Return))
            {
                throw new Exception($"Cannot marshal argument of function '{function.QualifiedOriginalName}'");
            }

            if (isRef)
            {
                var typePrinter = new CppTypePrinter(Context)
                {
                    ResolveTypeMaps = false
                };
                var type = paramType.Visit(typePrinter);

                if (param.IsInOut)
                {
                    if (!string.IsNullOrWhiteSpace(marshal.Context.Before))
                    {
                        Write(marshal.Context.Before);
                    }

                    WriteLine("{0} {1} = {2};", type, argName, marshal.Context.Return);
                }
                else
                {
                    WriteLine("{0} {1};", type, argName);
                }
            }
            else
            {
                if (!string.IsNullOrWhiteSpace(marshal.Context.Before))
                {
                    Write(marshal.Context.Before);
                }

                WriteLine("auto {0}{1} = {2};", marshal.VarPrefix, argName,
                          marshal.Context.Return);
                paramMarshal.Prefix = marshal.ArgumentPrefix;
            }

            paramMarshal.Name = argName;
            return(paramMarshal);
        }
Example #52
0
 private void DocumentQtProperty(Property property)
 {
     string file = GetFileForDeclarationContext(property.Namespace);
     if (this.documentation.ContainsKey(file))
     {
         string docs = this.documentation[file];
         CppTypePrinter cppTypePrinter = new CppTypePrinter(new TypeMapDatabase());
         cppTypePrinter.PrintKind = CppTypePrintKind.Local;
         string type = property.Type.Visit(cppTypePrinter);
         Match match = Regex.Match(docs, "Property Documentation.*" + property.Name + @" : (const )?(\w+::)?" + type.Replace("*", @"\s*\*") +
                                   @"(\s+const)?\n(?<docs>.*?)\nAccess functions:", RegexOptions.Singleline | RegexOptions.ExplicitCapture);
         if (match.Success)
         {
             property.Comment = new RawComment();
             property.Comment.BriefText = match.Groups["docs"].Value;
         }
     }
 }
Example #53
0
        public override bool VisitPointerType(PointerType pointer, TypeQualifiers quals)
        {
            if (!VisitType(pointer, quals))
            {
                return(false);
            }

            var pointee = pointer.Pointee.Desugar();

            if (pointee.IsPrimitiveType(PrimitiveType.Void))
            {
                Context.Return.Write("::System::IntPtr({0})", Context.ReturnVarName);
                return(true);
            }

            if (CSharpTypePrinter.IsConstCharString(pointer))
            {
                Context.Return.Write(MarshalStringToManaged(Context.ReturnVarName,
                                                            pointer.Pointee.Desugar() as BuiltinType));
                return(true);
            }

            PrimitiveType primitive;
            var           param = Context.Parameter;

            if (param != null && (param.IsOut || param.IsInOut) &&
                pointee.IsPrimitiveType(out primitive))
            {
                Context.Return.Write(Context.ReturnVarName);
                return(true);
            }

            if (pointee.IsPrimitiveType(out primitive))
            {
                var returnVarName = Context.ReturnVarName;
                if (quals.IsConst != Context.ReturnType.Qualifiers.IsConst)
                {
                    var nativeTypePrinter = new CppTypePrinter(Context.Driver.TypeDatabase, false);
                    var returnType        = Context.ReturnType.Type.Desugar();
                    var constlessPointer  = new PointerType()
                    {
                        IsDependent      = pointer.IsDependent,
                        Modifier         = pointer.Modifier,
                        QualifiedPointee = new QualifiedType(returnType.GetPointee())
                    };
                    var nativeConstlessTypeName = constlessPointer.Visit(nativeTypePrinter, new TypeQualifiers());
                    returnVarName = string.Format("const_cast<{0}>({1})",
                                                  nativeConstlessTypeName, Context.ReturnVarName);
                }
                if (pointer.Pointee is TypedefType)
                {
                    var desugaredPointer = new PointerType()
                    {
                        IsDependent      = pointer.IsDependent,
                        Modifier         = pointer.Modifier,
                        QualifiedPointee = new QualifiedType(pointee)
                    };
                    var nativeTypePrinter = new CppTypePrinter(Context.Driver.TypeDatabase);
                    var nativeTypeName    = desugaredPointer.Visit(nativeTypePrinter, quals);
                    Context.Return.Write("reinterpret_cast<{0}>({1})", nativeTypeName,
                                         returnVarName);
                }
                else
                {
                    Context.Return.Write(returnVarName);
                }
                return(true);
            }

            TypeMap typeMap = null;

            Context.Driver.TypeDatabase.FindTypeMap(pointee, out typeMap);

            Class @class;

            if (pointee.TryGetClass(out @class) && typeMap == null)
            {
                var instance = (pointer.IsReference) ? "&" + Context.ReturnVarName
                    : Context.ReturnVarName;
                WriteClassInstance(@class, instance);
                return(true);
            }

            return(pointer.Pointee.Visit(this, quals));
        }
Example #54
0
        void GenerateEquals(Class @class, Block block, Method method)
        {
            var equalsOverride = @class.Methods.FirstOrDefault(m =>
            {
                var expansions = m.PreprocessedEntities.OfType<MacroExpansion>();
                return expansions.Any(e => e.Text == "FLD_EQUALS");
            });

            if (equalsOverride == null)
                return;

            var cliTypePrinter = new CLITypePrinter(Driver);
            var cppTypePrinter = new CppTypePrinter(Driver.TypeDatabase);
            var paramCppType = equalsOverride.Parameters[0].Visit(cppTypePrinter);
            var classCppType = @class.Visit(cppTypePrinter);
            var classCliType = @class.Visit(cliTypePrinter);

            block.Text.StringBuilder.Clear();
            block.WriteLine("if (!object) return false;");
            block.WriteLine("auto obj = dynamic_cast<{0}>({1});",
                classCliType, method.Parameters[0].Name);
            block.NewLine();

            block.WriteLine("if (!obj) return false;");
            block.WriteLine("auto param = ({0})obj->NativePtr;", paramCppType);
            block.WriteLine("return (({0}*)NativePtr)->{1}(param);",
                classCppType, equalsOverride.OriginalName);
        }