private void BindPCallAndDelegate(InvocationExpressionSyntax node, ArrayBuilder <BoundExpression> args,
                                          DiagnosticBag diagnostics, TypeSyntax type)
        {
            var    XNode  = node.XNode as XP.MethodCallContext;
            string method = XNode?.Expr.GetText();

            if (string.IsNullOrEmpty(method))
            {
                method = "PCALL";
            }
            if (!ValidatePCallArguments(node, args, diagnostics, method))
            {
                return;
            }
            var kind = args[0].Kind;

            if (kind != BoundKind.Local && kind != BoundKind.FieldAccess)
            {
                Error(diagnostics, ErrorCode.ERR_PCallFirstArgument, node, method, "typed function pointer");
                return;
            }
            string methodName = null;
            // Note that this does not get the syntax of the argument itself
            // but the syntax of the place where the symbol (Global, Field or Local) that the argument points to was defined
            SyntaxReference syntaxref = null;

            if (kind == BoundKind.FieldAccess)
            {
                var bfa = args[0] as BoundFieldAccess;  // Global or Field
                if (bfa != null && bfa.ExpressionSymbol.DeclaringSyntaxReferences.Length > 0)
                {
                    syntaxref = bfa.ExpressionSymbol.DeclaringSyntaxReferences[0] as SyntaxReference;
                }
            }
            else if (kind == BoundKind.Local)
            {
                var bl = args[0] as BoundLocal;         // Local
                if (bl != null && bl.LocalSymbol?.DeclaringSyntaxReferences.Length > 0)
                {
                    syntaxref = bl.LocalSymbol.DeclaringSyntaxReferences[0] as SyntaxReference;
                }
            }
            if (syntaxref != null)
            {
                CSharpSyntaxNode syntaxnode = syntaxref.GetSyntax() as CSharpSyntaxNode;
                var xNode = syntaxnode?.XNode;
                methodName = GetTypedPtrName(xNode);
            }

            if (methodName == null)
            {
                // first argument for pcall must be typed ptr
                Error(diagnostics, ErrorCode.ERR_PCallFirstArgument, node, method, "typed function pointer");
                return;
            }
            var lookupResult = LookupResult.GetInstance();
            HashSet <DiagnosticInfo> useSiteDiagnostics = null;
            LookupOptions            options            = LookupOptions.AllMethodsOnArityZero;

            options |= LookupOptions.MustNotBeInstance;
            this.LookupSymbolsWithFallback(lookupResult, methodName, arity: 0, useSiteDiagnostics: ref useSiteDiagnostics, options: options);
            SourceMethodSymbol methodSym = null;

            if (lookupResult.IsClear)
            {
                // Cannot locate types pointer for pcall
                Error(diagnostics, ErrorCode.ERR_PCallTypedPointerName, node, method, methodName);
                methodSym = null;
            }
            else if (lookupResult.IsMultiViable)
            {
                foreach (var symbol in lookupResult.Symbols)
                {
                    if (symbol.DeclaringCompilation == this.Compilation && symbol is SourceMethodSymbol)
                    {
                        methodSym = (SourceMethodSymbol)symbol;
                        break;
                    }
                }
            }
            else
            {
                methodSym = (SourceMethodSymbol)lookupResult.Symbols[0];
            }
            if (methodSym != null)
            {
                lookupResult.Clear();
                var ts = FindPCallDelegateType(type as IdentifierNameSyntax);
                if (ts != null && ts.IsDelegateType())
                {
                    SourceDelegateMethodSymbol delmeth = ts.DelegateInvokeMethod() as SourceDelegateMethodSymbol;
                    // clone the parameters from the methodSym
                    var builder = ArrayBuilder <ParameterSymbol> .GetInstance();

                    foreach (var par in methodSym.Parameters)
                    {
                        var parameter = new SourceSimpleParameterSymbol(
                            delmeth,
                            par.Type,
                            par.Ordinal,
                            par.RefKind,
                            par.Name,
                            par.Locations);
                        builder.Add(parameter);
                    }
                    delmeth.InitializeParameters(builder.ToImmutableAndFree());
                    delmeth.SetReturnType(methodSym.ReturnType);
                }
                else
                {
                    Error(diagnostics, ErrorCode.ERR_PCallResolveGeneratedDelegate, node, method, type.ToString());
                }
            }
            return;
        }
        private void BindPCallNativeAndDelegate(InvocationExpressionSyntax node, ArrayBuilder <BoundExpression> args,
                                                DiagnosticBag diagnostics, TypeSyntax type)
        {
            var    XNode  = node.XNode as XP.MethodCallContext;
            string method = XNode?.Expr.GetText();

            if (string.IsNullOrEmpty(method))
            {
                method = "PCALLNATIVE";
            }
            if (!ValidatePCallArguments(node, args, diagnostics, method))
            {
                return;
            }
            // Our parent is the invocation expression of the delegate
            AnalyzedArguments analyzedArguments = AnalyzedArguments.GetInstance();

            try
            {
                var ts = FindPCallDelegateType(type as IdentifierNameSyntax);
                if (ts != null && ts.IsDelegateType())
                {
                    SourceDelegateMethodSymbol delmeth = ts.DelegateInvokeMethod() as SourceDelegateMethodSymbol;
                    // create new parameters based on the parameters from out parent call
                    var invoke    = node.Parent as InvocationExpressionSyntax;
                    var realargs  = invoke.ArgumentList;
                    var delparams = ts.DelegateParameters();
                    BindArgumentsAndNames(realargs, diagnostics, analyzedArguments);
                    var builder = ArrayBuilder <ParameterSymbol> .GetInstance();

                    int i = 0;
                    foreach (var expr in analyzedArguments.Arguments)
                    {
                        var ptype = expr.Type;
                        if (ptype == null)
                        {
                            ptype = new PointerTypeSymbol(Compilation.GetSpecialType(SpecialType.System_Void));
                        }
                        var parameter = new SourceSimpleParameterSymbol(
                            delmeth,
                            ptype,
                            i,
                            delparams[i].RefKind,
                            delparams[i].Name,
                            delparams[i].Locations);
                        builder.Add(parameter);
                        i++;
                    }
                    delmeth.InitializeParameters(builder.ToImmutableAndFree());
                }
                else
                {
                    Error(diagnostics, ErrorCode.ERR_PCallResolveGeneratedDelegate, node, method, type.ToString());
                }

                return;
            }
            finally
            {
                analyzedArguments.Free();
            }
        }