internal TypeDefinition GetDelegateType(FunctionType functionType, string name) { var @delegate = new DelegateDefinition { Name = name + "_func", FunctionName = name, ReturnType = GetReturnTypeName(functionType.ReturnType.Type, name), Parameters = functionType.Parameters.Select(GetParameter).ToArray() }; _context.AddUnit(@delegate); return(@delegate); }
public override bool VisitMethodDecl(Method method) { if (!base.VisitMethodDecl(method) || !method.IsVirtual || method.Ignore) { return(false); } var @params = method.GatherInternalParams(Driver.Options.IsItaniumLikeAbi, true).ToList(); var delegateName = GenerateDelegateSignature(@params, method.ReturnType); var @delegate = new TypedefDecl { Name = delegateName, QualifiedType = new QualifiedType( new PointerType( new QualifiedType( new FunctionType { CallingConvention = method.CallingConvention, IsDependent = method.IsDependent, Parameters = @params, ReturnType = method.ReturnType }))), Namespace = namespaceDelegates }; var delegateString = @delegate.Visit(TypePrinter).Type; var existingDelegate = GetExistingDelegate(delegateString); if (existingDelegate != null) { Driver.Delegates.Add(method, existingDelegate); return(true); } existingDelegate = new DelegateDefinition(Driver.Options.OutputNamespace, delegateString); Driver.Delegates.Add(method, existingDelegate); foreach (var library in Driver.Options.Libraries) { libsDelegates[library].Add(delegateString, existingDelegate); } namespaceDelegates.Declarations.Add(@delegate); return(true); }
public override AstNode Visit(DelegateDefinition node) { // Use the base class for delegates. Structure building = node.GetStructure(); building.SetBase(currentModule.GetDelegateClass()); try { building.FixInheritance(); } catch (ModuleException error) { Error(node, error.Message); } return(node); }
private DelegateDefinition GetExistingDelegate(Module module, string delegateString) { if (module.Libraries.Count == 0) { return(Context.Delegates.Values.FirstOrDefault(t => t.Signature == delegateString)); } DelegateDefinition @delegate = null; if (new[] { module }.Union(module.Dependencies).Any( m => libsDelegates.ContainsKey(m) && libsDelegates[m].TryGetValue( delegateString, out @delegate))) { return(@delegate); } return(null); }
private DelegateDefinition GetExistingDelegate(string delegateString) { if (Driver.Options.Libraries.Count == 0) { return(Driver.Delegates.Values.FirstOrDefault(t => t.Signature == delegateString)); } DelegateDefinition @delegate = null; if (Driver.Options.Libraries.Union( Driver.Symbols.Libraries.SelectMany(l => l.Dependencies)).Any( l => libsDelegates.ContainsKey(l) && libsDelegates[l].TryGetValue(delegateString, out @delegate))) { return(@delegate); } return(null); }
public void Write(DelegateDefinition @delegate) { WriteSummary(@delegate); @delegate.Parameters.ToList().ForEach(x => WriteParam(x, x.Name)); WriteSummary(@delegate); var parameters = GetParameters(@delegate.Parameters); WriteLine("[UnmanagedFunctionPointer(CallingConvention.Cdecl)]"); WriteLine($"public unsafe delegate {@delegate.ReturnType.Name} {@delegate.FunctionName} ({parameters});"); WriteLine($"public unsafe struct {@delegate.Name}"); using (BeginBlock()) { WriteLine($"public IntPtr Pointer;"); Write($"public static implicit operator {@delegate.Name}({@delegate.FunctionName} func) => "); Write($"new {@delegate.Name} {{ Pointer = Marshal.GetFunctionPointerForDelegate(func) }};"); WriteLine(); } }
private DelegateDefinition GetExistingDelegate(IList <string> libraries, string delegateString) { if (libraries.Count == 0) { return(Context.Delegates.Values.FirstOrDefault(t => t.Signature == delegateString)); } DelegateDefinition @delegate = null; if (libraries.Union( Context.Symbols.Libraries.Where(l => libraries.Contains(l.FileName)).SelectMany( l => l.Dependencies)).Any(l => libsDelegates.ContainsKey(l) && libsDelegates[l].TryGetValue(delegateString, out @delegate))) { return(@delegate); } return(null); }
public override bool VisitMethodDecl(Method method) { if (!base.VisitMethodDecl(method) || !method.IsVirtual || method.Ignore) return false; var @params = method.GatherInternalParams(Context.ParserOptions.IsItaniumLikeAbi, true).ToList(); var delegateName = GenerateDelegateSignature(@params, method.ReturnType); var module = method.TranslationUnit.Module; Namespace namespaceDelegates; if (namespacesDelegates.ContainsKey(module)) { namespaceDelegates = namespacesDelegates[module]; } else { namespaceDelegates = new Namespace { Name = DelegatesNamespace, Namespace = module.Units.Last() }; namespacesDelegates.Add(module, namespaceDelegates); } var @delegate = new TypedefDecl { Name = delegateName, QualifiedType = new QualifiedType( new PointerType( new QualifiedType( new FunctionType { CallingConvention = method.CallingConvention, IsDependent = method.IsDependent, Parameters = @params, ReturnType = method.ReturnType }))), Namespace = namespaceDelegates, IsSynthetized = true }; Generator.CurrentOutputNamespace = module.OutputNamespace; var delegateString = @delegate.Visit(TypePrinter).Type; var existingDelegate = GetExistingDelegate( method.TranslationUnit.Module.Libraries, delegateString); if (existingDelegate != null) { Context.Delegates.Add(method, existingDelegate); return true; } existingDelegate = new DelegateDefinition(module.OutputNamespace, delegateString); Context.Delegates.Add(method, existingDelegate); foreach (var library in module.Libraries) libsDelegates[library].Add(delegateString, existingDelegate); namespaceDelegates.Declarations.Add(@delegate); return true; }
public override bool VisitMethodDecl(Method method) { if (!base.VisitMethodDecl(method) || !method.IsVirtual || method.Ignore) return false; var @params = method.GatherInternalParams(Driver.Options.IsItaniumLikeAbi, true).ToList(); var delegateName = GenerateDelegateSignature(@params, method.ReturnType); var @delegate = new TypedefDecl { Name = delegateName, QualifiedType = new QualifiedType( new PointerType( new QualifiedType( new FunctionType { CallingConvention = method.CallingConvention, IsDependent = method.IsDependent, Parameters = @params, ReturnType = method.ReturnType }))), Namespace = namespaceDelegates }; var delegateString = @delegate.Visit(TypePrinter).Type; var existingDelegate = GetExistingDelegate(delegateString); if (existingDelegate != null) { Driver.Delegates.Add(method, existingDelegate); return true; } existingDelegate = new DelegateDefinition(Driver.Options.OutputNamespace, delegateString); Driver.Delegates.Add(method, existingDelegate); foreach (var library in Driver.Options.Libraries) libsDelegates[library].Add(delegateString, existingDelegate); namespaceDelegates.Declarations.Add(@delegate); return true; }
private void AddDelegatesToDictionary(Declaration decl, Module module) { CallingConvention callingConvention; bool isDependent = false; QualifiedType returnType; List <Parameter> @params; if (decl is Method) { var method = (Method)decl; @params = method.GatherInternalParams(Context.ParserOptions.IsItaniumLikeAbi, true).ToList(); callingConvention = method.CallingConvention; isDependent = method.IsDependent; returnType = method.ReturnType; } else { var param = (Parameter)decl; var funcTypeParam = param.Type.Desugar().GetFinalPointee().Desugar() as FunctionType; @params = funcTypeParam.Parameters; callingConvention = funcTypeParam.CallingConvention; isDependent = funcTypeParam.IsDependent; returnType = funcTypeParam.ReturnType; } var delegateName = GenerateDelegateSignature(@params, returnType); Namespace namespaceDelegates; if (namespacesDelegates.ContainsKey(module)) { namespaceDelegates = namespacesDelegates[module]; } else { Namespace parent = null; if (string.IsNullOrEmpty(module.OutputNamespace)) { var group = module.Units.SelectMany(u => u.Declarations).OfType <Namespace>( ).GroupBy(d => d.Name).Where(g => g.Any(d => d.HasDeclarations)).ToList(); if (group.Count == 1) { parent = group.Last().Last(); } } if (parent == null) { parent = module.Units.Last(); } namespaceDelegates = new Namespace { Name = DelegatesNamespace, Namespace = parent }; namespacesDelegates.Add(module, namespaceDelegates); } var @delegate = new TypedefDecl { Name = delegateName, QualifiedType = new QualifiedType( new PointerType( new QualifiedType( new FunctionType { CallingConvention = callingConvention, IsDependent = isDependent, Parameters = @params, ReturnType = returnType }))), Namespace = namespaceDelegates, IsSynthetized = true, Access = decl is Method ? AccessSpecifier.Private : AccessSpecifier.Public }; var delegateString = @delegate.Visit(TypePrinter).Type; var existingDelegate = GetExistingDelegate( module, delegateString); if (existingDelegate != null) { Context.Delegates.Add(decl, existingDelegate); return; } existingDelegate = new DelegateDefinition(module.OutputNamespace, delegateString); Context.Delegates.Add(decl, existingDelegate); libsDelegates[module].Add(delegateString, existingDelegate); namespaceDelegates.Declarations.Add(@delegate); }
public override bool VisitMethodDecl(Method method) { if (!base.VisitMethodDecl(method) || !method.IsVirtual || method.Ignore) { return(false); } var @params = method.GatherInternalParams(Context.ParserOptions.IsItaniumLikeAbi, true).ToList(); var delegateName = GenerateDelegateSignature(@params, method.ReturnType); var module = method.TranslationUnit.Module; Namespace namespaceDelegates; if (namespacesDelegates.ContainsKey(module)) { namespaceDelegates = namespacesDelegates[module]; } else { namespaceDelegates = new Namespace { Name = DelegatesNamespace, Namespace = module.Units.Last() }; namespacesDelegates.Add(module, namespaceDelegates); } var @delegate = new TypedefDecl { Name = delegateName, QualifiedType = new QualifiedType( new PointerType( new QualifiedType( new FunctionType { CallingConvention = method.CallingConvention, IsDependent = method.IsDependent, Parameters = @params, ReturnType = method.ReturnType }))), Namespace = namespaceDelegates, IsSynthetized = true }; Generator.CurrentOutputNamespace = module.OutputNamespace; var delegateString = @delegate.Visit(TypePrinter).Type; var existingDelegate = GetExistingDelegate( method.TranslationUnit.Module.Libraries, delegateString); if (existingDelegate != null) { Context.Delegates.Add(method, existingDelegate); return(true); } existingDelegate = new DelegateDefinition(module.OutputNamespace, delegateString); Context.Delegates.Add(method, existingDelegate); foreach (var library in module.Libraries) { libsDelegates[library].Add(delegateString, existingDelegate); } namespaceDelegates.Declarations.Add(@delegate); return(true); }
public override bool VisitMethodDecl(Method method) { if (!base.VisitMethodDecl(method) || !method.IsVirtual || method.Ignore) { return(false); } var @params = method.GatherInternalParams(Context.ParserOptions.IsItaniumLikeAbi, true).ToList(); var delegateName = GenerateDelegateSignature(@params, method.ReturnType); var module = method.TranslationUnit.Module; Namespace namespaceDelegates; if (namespacesDelegates.ContainsKey(module)) { namespaceDelegates = namespacesDelegates[module]; } else { Namespace parent = null; if (string.IsNullOrEmpty(module.OutputNamespace)) { var group = module.Units.SelectMany(u => u.Declarations).OfType <Namespace>( ).GroupBy(d => d.Name).Where(g => g.Any(d => d.HasDeclarations)).ToList(); if (group.Count == 1) { parent = group.Last().Last(); } } if (parent == null) { parent = module.Units.Last(); } namespaceDelegates = new Namespace { Name = DelegatesNamespace, Namespace = parent }; namespacesDelegates.Add(module, namespaceDelegates); } var @delegate = new TypedefDecl { Name = delegateName, QualifiedType = new QualifiedType( new PointerType( new QualifiedType( new FunctionType { CallingConvention = method.CallingConvention, IsDependent = method.IsDependent, Parameters = @params, ReturnType = method.ReturnType }))), Namespace = namespaceDelegates, IsSynthetized = true, Access = AccessSpecifier.Private }; var delegateString = @delegate.Visit(TypePrinter).Type; var existingDelegate = GetExistingDelegate( method.TranslationUnit.Module, delegateString); if (existingDelegate != null) { Context.Delegates.Add(method, existingDelegate); return(true); } existingDelegate = new DelegateDefinition(module.OutputNamespace, delegateString); Context.Delegates.Add(method, existingDelegate); libsDelegates[module].Add(delegateString, existingDelegate); namespaceDelegates.Declarations.Add(@delegate); return(true); }
public override AstNode Visit(DelegateDefinition node) { // Parse the generic signature. GenericSignature genericSign = node.GetGenericSignature(); GenericPrototype genProto = GenericPrototype.Empty; PseudoScope protoScope = null; if (genericSign != null) { // Visit the generic signature. genericSign.Accept(this); // Connect the generic prototype. genProto = genericSign.GetPrototype(); // Create the placeholders scope. protoScope = new PseudoScope(currentScope, genProto); node.SetGenericScope(protoScope); } // Prevent redefinition. ScopeMember old = currentContainer.FindType(node.GetName(), GenericPrototype.Empty); if (old != null) { Error(node, "trying to redefine a delegate."); } // Create the structure MemberFlags flags = node.GetFlags(); // TODO: Check the flags. Class building = new Class(node.GetName(), flags, currentContainer); building.SetGenericPrototype(genProto); building.Position = node.GetPosition(); node.SetStructure(building); // Add into the current scope. if (currentContainer.IsNamespace()) { Namespace space = (Namespace)currentContainer; space.AddType(building); } else if (currentContainer.IsStructure() || currentContainer.IsInterface() || currentContainer.IsClass()) { Structure parent = (Structure)currentContainer; parent.AddType(building); } else { Error(node, "unexpected place for a delegate."); } // Register the compute binding delegate. if (building.GetFullName() == "Chela.Compute.ComputeBinding") { currentModule.RegisterComputeBindingDelegate(building); } return(node); }
protected override void VisitDelegateParam(DelegateDefinition @delegate, ParamDefinition param) { base.VisitDelegateParam(@delegate, param); VisitFunctionParam(@delegate, param); }
protected override void VisitDelegate(DelegateDefinition @delegate) { base.VisitDelegate(@delegate); VisitFunction(@delegate); }
public void Basics() { DelegateDefinition one = new DelegateDefinition(SomeArbitraryMethod); one += SomeOtherArbitraryMethod; one(1000); }