示例#1
0
        public CodeGenerator(
            MethodSymbol method,
            BoundStatement boundBody,
            ILBuilder builder,
            PEModuleBuilder moduleBuilder,
            DiagnosticBag diagnostics,
            OptimizationLevel optimizations,
            bool emittingPdb)
        {
            Debug.Assert((object)method != null);
            Debug.Assert(boundBody != null);
            Debug.Assert(builder != null);
            Debug.Assert(moduleBuilder != null);
            Debug.Assert(diagnostics != null);

            _method = method;
            _boundBody = boundBody;
            _builder = builder;
            _module = moduleBuilder;
            _diagnostics = diagnostics;

            if (!method.GenerateDebugInfo)
            {
                // Always optimize synthesized methods that don't contain user code.
                // 
                // Specifically, always optimize synthesized explicit interface implementation methods
                // (aka bridge methods) with by-ref returns because peverify produces errors if we
                // return a ref local (which the return local will be in such cases).
                _ilEmitStyle = ILEmitStyle.Release;
            }
            else
            {
                if (optimizations == OptimizationLevel.Debug)
                {
                    _ilEmitStyle = ILEmitStyle.Debug;
                }
                else
                {
                    _ilEmitStyle = IsDebugPlus() ? 
                        ILEmitStyle.DebugFriendlyRelease : 
                        ILEmitStyle.Release;
                }
            }

            // Emit sequence points unless
            // - the PDBs are not being generated
            // - debug information for the method is not generated since the method does not contain
            //   user code that can be stepped through, or changed during EnC.
            // 
            // This setting only affects generating PDB sequence points, it shall not affect generated IL in any way.
            _emitPdbSequencePoints = emittingPdb && method.GenerateDebugInfo;

            _boundBody = Optimizer.Optimize(
                boundBody, 
                debugFriendly: _ilEmitStyle != ILEmitStyle.Release, 
                stackLocals: out _stackLocals);

            _methodBodySyntaxOpt = (method as SourceMethodSymbol)?.BodySyntax;
        }
        internal ModuleReference(PEModuleBuilder moduleBeingBuilt, ModuleSymbol underlyingModule)
        {
            Debug.Assert(moduleBeingBuilt != null);
            Debug.Assert((object)underlyingModule != null);

            this.moduleBeingBuilt = moduleBeingBuilt;
            this.underlyingModule = underlyingModule;
        }
        /// <summary>
        /// Traverse the symbol table and call Module.AddSynthesizedDefinition for each
        /// synthesized explicit implementation stub that has been generated (e.g. when the real
        /// implementation doesn't have the appropriate custom modifiers).
        /// </summary>
        public static void ProcessSynthesizedMembers(
            CSharpCompilation compilation,
            PEModuleBuilder moduleBeingBuilt,
            CancellationToken cancellationToken)
        {
            Debug.Assert(moduleBeingBuilt != null);

            var compiler = new SynthesizedMetadataCompiler(moduleBeingBuilt, cancellationToken);
            compiler.Visit(compilation.SourceModule.GlobalNamespace);
        }
        private Cci.IFieldDefinition ResolvedFieldImpl(PEModuleBuilder moduleBeingBuilt)
        {
            Debug.Assert(this.IsDefinitionOrDistinct());

            if (this.IsDefinition &&
                this.ContainingModule == moduleBeingBuilt.SourceModule)
            {
                return this;
            }

            return null;
        }
        /// <summary>
        /// Traverse the symbol table and call Module.AddSynthesizedDefinition for each
        /// synthesized explicit implementation stub that has been generated (e.g. when the real
        /// implementation doesn't have the appropriate custom modifiers).
        /// </summary>
        public static void ProcessSynthesizedMembers(
            CSharpCompilation compilation,
            PEModuleBuilder moduleBeingBuilt,
            CancellationToken cancellationToken)
        {
            Debug.Assert(moduleBeingBuilt != null);

            using (Logger.LogBlock(FunctionId.CSharp_Compiler_CompileSynthesizedMethodMetadata, message: compilation.AssemblyName, cancellationToken: cancellationToken))
            {
                var compiler = new SynthesizedMetadataCompiler(moduleBeingBuilt, cancellationToken);
                compiler.Visit(compilation.SourceModule.GlobalNamespace);
            }
        }
示例#6
0
        private CodeGenerator(MethodSymbol method,
            BoundStatement block,
            ILBuilder builder,
            PEModuleBuilder module,
            DiagnosticBag diagnostics,
            bool optimize,
            bool emitSequencePoints)
        {
            this.method = method;
            this.block = block;
            this.builder = builder;
            this.module = module;
            this.diagnostics = diagnostics;

            this.noOptimizations = !optimize;
            this.debugInformationKind = module.Compilation.Options.DebugInformationKind;

            if (!this.debugInformationKind.IsValid())
            {
                this.debugInformationKind = DebugInformationKind.None;
            }

            // Special case: always optimize synthesized explicit interface implementation methods
            // (aka bridge methods) with by-ref returns because peverify produces errors if we
            // return a ref local (which the return local will be in such cases).
            if (this.noOptimizations && method.ReturnType is ByRefReturnErrorTypeSymbol)
            {
                Debug.Assert(method is SynthesizedExplicitImplementationMethod);
                this.noOptimizations = false;
            }

            this.emitSequencePoints = emitSequencePoints;

            if (!this.noOptimizations)
            {
                this.block = Optimizer.Optimize(block, out stackLocals);
            }

            Debug.Assert((object)method != null);
            Debug.Assert(block != null);
            Debug.Assert(builder != null);
            Debug.Assert(module != null);

            var asSourceMethod = method as SourceMethodSymbol;
            if ((object)asSourceMethod != null)
            {
                methodBlockSyntax = asSourceMethod.BlockSyntax;
            }
        }
示例#7
0
        private CodeGenerator(
            MethodSymbol method,
            BoundStatement block,
            ILBuilder builder,
            PEModuleBuilder moduleBuilder,
            DiagnosticBag diagnostics,
            OptimizationLevel optimizations,
            bool emittingPdbs)
        {
            this.method = method;
            this.block = block;
            this.builder = builder;
            this.module = moduleBuilder;
            this.diagnostics = diagnostics;

            // Always optimize synthesized methods that don't contain user code.
            // 
            // Specifically, always optimize synthesized explicit interface implementation methods
            // (aka bridge methods) with by-ref returns because peverify produces errors if we
            // return a ref local (which the return local will be in such cases).

            this.optimizations = method.GenerateDebugInfo ? optimizations : OptimizationLevel.Release;

            // Emit sequence points unless
            // - the PDBs are not being generated
            // - debug information for the method is not generated since the method does not contain
            //   user code that can be stepped thru, or changed during EnC.
            // 
            // This setting only affects generating PDB sequence points, it shall not affect generated IL in any way.
            this.emitPdbSequencePoints = emittingPdbs && method.GenerateDebugInfo;

            if (this.optimizations == OptimizationLevel.Release)
            {
                this.block = Optimizer.Optimize(block, out stackLocals);
            }

            Debug.Assert((object)method != null);
            Debug.Assert(block != null);
            Debug.Assert(builder != null);
            Debug.Assert(moduleBuilder != null);

            var asSourceMethod = method as SourceMethodSymbol;
            if ((object)asSourceMethod != null)
            {
                methodBlockSyntax = asSourceMethod.BlockSyntax;
            }
        }
示例#8
0
        public static void CompileMethodBodies(
            CSharpCompilation compilation,
            PEModuleBuilder moduleBeingBuilt,
            bool generateDebugInfo,
            bool hasDeclarationErrors,
            Predicate<Symbol> filter,
            SyntaxTree filterTree,
            TextSpan? filterSpanWithinTree,
            DiagnosticBag diagnostics,
            CancellationToken cancellationToken)
        {
            using (Logger.LogBlock(FunctionId.CSharp_Compiler_CompileMethodBodies, message: compilation.AssemblyName, cancellationToken: cancellationToken))
            {
                Debug.Assert(filter == null || filterTree == null, "Cannot provide both a filter predicate and a filter tree.");

                if (filter == null && filterTree != null)
                {
                    filter = s => s.IsDefinedInSourceTree(filterTree, filterSpanWithinTree);
                }

                if (compilation.PreviousSubmission != null)
                {
                    // In case there is a previous submission, we should ensure 
                    // it has already created anonymous type/delegates templates

                    // NOTE: if there are any errors, we will pick up what was created anyway
                    compilation.PreviousSubmission.EnsureAnonymousTypeTemplates(cancellationToken);

                    // TODO: revise to use a loop instead of a recursion
                }

                MethodBodyCompiler.CompileMethodBodies(compilation, moduleBeingBuilt, generateDebugInfo, hasDeclarationErrors, diagnostics, filter, cancellationToken);

                MethodSymbol entryPoint = GetEntryPoint(compilation, moduleBeingBuilt, hasDeclarationErrors, diagnostics, cancellationToken);
                if (moduleBeingBuilt != null)
                {
                    moduleBeingBuilt.SetEntryPoint(entryPoint);
                }
            }
        }
示例#9
0
        Cci.IMethodReference Cci.ICustomAttribute.Constructor(EmitContext context)
        {
            PEModuleBuilder moduleBeingBuilt = (PEModuleBuilder)context.Module;

            return((Cci.IMethodReference)moduleBeingBuilt.Translate(this.AttributeConstructor, (CSharpSyntaxNode)context.SyntaxNodeOpt, context.Diagnostics));
        }
示例#10
0
        private Cci.INestedTypeDefinition AsNestedTypeDefinitionImpl(PEModuleBuilder moduleBeingBuilt)
        {
            Debug.Assert(this.IsDefinitionOrDistinct());

            if ((object)this.ContainingType != null &&
                this.IsDefinition &&
                this.ContainingModule == moduleBeingBuilt.SourceModule)
            {
                return this;
            }

            return null;
        }
示例#11
0
 protected override Cci.ITypeReference GetBaseClass(PEModuleBuilder moduleBuilder, CSharpSyntaxNode syntaxNodeOpt, DiagnosticBag diagnostics)
 {
     NamedTypeSymbol baseType = UnderlyingNamedType.BaseTypeNoUseSiteDiagnostics;
     return (object)baseType != null ? moduleBuilder.Translate(baseType, syntaxNodeOpt, diagnostics) : null;
 }
示例#12
0
 public TypeCompilationState(NamedTypeSymbol typeOpt, CSharpCompilation compilation, PEModuleBuilder moduleBuilderOpt)
 {
     this.Compilation      = compilation;
     _typeOpt              = typeOpt;
     this.ModuleBuilderOpt = moduleBuilderOpt;
 }
        Cci.IDefinition Cci.IReference.AsDefinition(EmitContext context)
        {
            PEModuleBuilder moduleBeingBuilt = (PEModuleBuilder)context.Module;

            return(AsTypeDefinitionImpl(moduleBeingBuilt));
        }
        Cci.ITypeDefinition Cci.ITypeReference.GetResolvedType(EmitContext context)
        {
            PEModuleBuilder moduleBeingBuilt = (PEModuleBuilder)context.Module;

            return(AsTypeDefinitionImpl(moduleBeingBuilt));
        }
示例#15
0
 internal override NamedTypeSymbol FixedImplementationType(PEModuleBuilder emitModule)
 {
     EnsureSignatureIsLoaded();
     return(_lazyFixedImplementationType);
 }
示例#16
0
 internal virtual NamedTypeSymbol FixedImplementationType(PEModuleBuilder emitModule)
 {
     return(null);
 }
示例#17
0
 internal override NamedTypeSymbol FixedImplementationType(PEModuleBuilder emitModule)
 {
     return emitModule.SetFixedImplementationType(this);
 }
示例#18
0
        public CodeGenerator(
            MethodSymbol method,
            BoundStatement boundBody,
            ILBuilder builder,
            PEModuleBuilder moduleBuilder,
            DiagnosticBag diagnostics,
            OptimizationLevel optimizations,
            bool emittingPdb)
        {
            Debug.Assert((object)method != null);
            Debug.Assert(boundBody != null);
            Debug.Assert(builder != null);
            Debug.Assert(moduleBuilder != null);
            Debug.Assert(diagnostics != null);

            _method      = method;
            _boundBody   = boundBody;
            _builder     = builder;
            _module      = moduleBuilder;
            _diagnostics = diagnostics;

            if (!method.GenerateDebugInfo)
            {
                // Always optimize synthesized methods that don't contain user code.
                //
                // Specifically, always optimize synthesized explicit interface implementation methods
                // (aka bridge methods) with by-ref returns because peverify produces errors if we
                // return a ref local (which the return local will be in such cases).
                _ilEmitStyle = ILEmitStyle.Release;
            }
            else
            {
                if (optimizations == OptimizationLevel.Debug)
                {
                    _ilEmitStyle = ILEmitStyle.Debug;
                }
                else
                {
                    _ilEmitStyle = IsDebugPlus() ?
                                   ILEmitStyle.DebugFriendlyRelease :
                                   ILEmitStyle.Release;
                }
            }

            // Emit sequence points unless
            // - the PDBs are not being generated
            // - debug information for the method is not generated since the method does not contain
            //   user code that can be stepped through, or changed during EnC.
            //
            // This setting only affects generating PDB sequence points, it shall not affect generated IL in any way.
            _emitPdbSequencePoints = emittingPdb && method.GenerateDebugInfo;

            try
            {
                _boundBody = Optimizer.Optimize(
                    boundBody,
                    debugFriendly: _ilEmitStyle != ILEmitStyle.Release,
                    stackLocals: out _stackLocals);
            }
            catch (BoundTreeVisitor.CancelledByStackGuardException ex)
            {
                ex.AddAnError(diagnostics);
                _boundBody = boundBody;
            }

            var sourceMethod = method as SourceMemberMethodSymbol;

            (BlockSyntax blockBody, ArrowExpressionClauseSyntax expressionBody) = sourceMethod?.Bodies ?? default;
            _methodBodySyntaxOpt = (SyntaxNode)blockBody ?? expressionBody ?? sourceMethod?.SyntaxNode;
        }
        Cci.IMethodReference Cci.ICustomAttribute.Constructor(EmitContext context, bool reportDiagnostics)
        {
            PEModuleBuilder moduleBeingBuilt = (PEModuleBuilder)context.Module;

            return((Cci.IMethodReference)moduleBeingBuilt.Translate(this.AttributeConstructor, /*context.SyntaxNodeOpt, */ context.Diagnostics, false));
        }
示例#20
0
        protected override Cci.ITypeReference GetBaseClass(PEModuleBuilder moduleBuilder, SyntaxNode syntaxNodeOpt, DiagnosticBag diagnostics)
        {
            NamedTypeSymbol baseType = UnderlyingNamedType.BaseTypeNoUseSiteDiagnostics;

            return((object)baseType != null?moduleBuilder.Translate(baseType, syntaxNodeOpt, diagnostics) : null);
        }
示例#21
0
 internal override NamedTypeSymbol FixedImplementationType(PEModuleBuilder emitModule)
 {
     return(emitModule.SetFixedImplementationType(this));
 }
示例#22
0
 internal override NamedTypeSymbol FixedImplementationType(PEModuleBuilder emitModule)
 {
     Debug.Assert(!this.IsFixedSizeBuffer, "Subclasses representing fixed fields must override");
     return(null);
 }
示例#23
0
        public void AssignTemplatesNamesAndCompile(MethodCompiler compiler, PEModuleBuilder moduleBeingBuilt, BindingDiagnosticBag diagnostics)
        {
            // Ensure all previous anonymous type templates are included so the
            // types are available for subsequent edit and continue generations.
            foreach (var key in moduleBeingBuilt.GetPreviousAnonymousTypes())
            {
                var templateKey = AnonymousTypeDescriptor.ComputeKey(key.Fields, f => f.Name);
                this.AnonymousTypeTemplates.GetOrAdd(templateKey, k => this.CreatePlaceholderTemplate(key));
            }

            // Get all anonymous types owned by this manager
            var builder = ArrayBuilder <AnonymousTypeTemplateSymbol> .GetInstance();

            GetCreatedAnonymousTypeTemplates(builder);

            // If the collection is not sealed yet we should assign
            // new indexes to the created anonymous type templates
            if (!this.AreTemplatesSealed)
            {
                // If we are emitting .NET module, include module's name into type's name to ensure
                // uniqueness across added modules.
                string moduleId;

                if (moduleBeingBuilt.OutputKind == OutputKind.NetModule)
                {
                    moduleId = moduleBeingBuilt.Name;

                    string extension = OutputKind.NetModule.GetDefaultExtension();

                    if (moduleId.EndsWith(extension, StringComparison.OrdinalIgnoreCase))
                    {
                        moduleId = moduleId.Substring(0, moduleId.Length - extension.Length);
                    }

                    moduleId = MetadataHelpers.MangleForTypeNameIfNeeded(moduleId);
                }
                else
                {
                    moduleId = string.Empty;
                }

                int nextIndex = moduleBeingBuilt.GetNextAnonymousTypeIndex();
                foreach (var template in builder)
                {
                    string name;
                    int    index;
                    if (!moduleBeingBuilt.TryGetAnonymousTypeName(template, out name, out index))
                    {
                        index = nextIndex++;
                        name  = GeneratedNames.MakeAnonymousTypeTemplateName(index, this.Compilation.GetSubmissionSlotIndex(), moduleId);
                    }
                    // normally it should only happen once, but in case there is a race
                    // NameAndIndex.set has an assert which guarantees that the
                    // template name provided is the same as the one already assigned
                    template.NameAndIndex = new NameAndIndex(name, index);
                }

                this.SealTemplates();
            }

            if (builder.Count > 0 && !ReportMissingOrErroneousSymbols(diagnostics))
            {
                // Process all the templates
                foreach (var template in builder)
                {
                    foreach (var method in template.SpecialMembers)
                    {
                        moduleBeingBuilt.AddSynthesizedDefinition(template, method.GetCciAdapter());
                    }

                    compiler.Visit(template, null);
                }
            }

            builder.Free();

            var synthesizedDelegates = ArrayBuilder <SynthesizedDelegateSymbol> .GetInstance();

            GetCreatedSynthesizedDelegates(synthesizedDelegates);
            foreach (var synthesizedDelegate in synthesizedDelegates)
            {
                compiler.Visit(synthesizedDelegate, null);
            }
            synthesizedDelegates.Free();
        }
        private static void AddDebugSourceDocumentsForChecksumDirectives(
            PEModuleBuilder moduleBeingBuilt,
            SyntaxTree tree,
            DiagnosticBag diagnostics)
        {
            var checksumDirectives = tree.GetRoot().GetDirectives(d => d.Kind == SyntaxKind.PragmaChecksumDirectiveTrivia &&
                                                                 !d.ContainsDiagnostics);

            foreach (var directive in checksumDirectives)
            {
                var checkSumDirective = (PragmaChecksumDirectiveTriviaSyntax)directive;
                var path = checkSumDirective.File.ValueText;

                var checkSumText = checkSumDirective.Bytes.ValueText;
                var normalizedPath = moduleBeingBuilt.NormalizeDebugDocumentPath(path, basePath: tree.FilePath);
                var existingDoc = moduleBeingBuilt.TryGetDebugDocumentForNormalizedPath(normalizedPath);

                // duplicate checksum pragmas are valid as long as values match
                // if we have seen this document already, check for matching values.
                if (existingDoc != null)
                {
                    // pragma matches a file path on an actual tree.
                    // Dev12 compiler just ignores the pragma in this case which means that
                    // checksum of the actual tree always wins and no warning is given.
                    // We will continue doing the same.
                    if (existingDoc.IsComputedChecksum)
                    {
                        continue;
                    }

                    if (CheckSumMatches(checkSumText, existingDoc.SourceHash))
                    {
                        var guid = Guid.Parse(checkSumDirective.Guid.ValueText);
                        if (guid == existingDoc.SourceHashKind)
                        {
                            // all parts match, nothing to do
                            continue;
                        }
                    }

                    // did not match to an existing document
                    // produce a warning and ignore the pragma
                    diagnostics.Add(ErrorCode.WRN_ConflictingChecksum, new SourceLocation(checkSumDirective), path);
                }
                else
                {
                    var newDocument = new Cci.DebugSourceDocument(
                        normalizedPath,
                        Cci.DebugSourceDocument.CorSymLanguageTypeCSharp,
                        MakeCheckSumBytes(checkSumDirective.Bytes.ValueText),
                        Guid.Parse(checkSumDirective.Guid.ValueText));

                    moduleBeingBuilt.AddDebugDocument(newDocument);
                }
            }
        }
示例#25
0
 internal override IEnumerable <CSharpAttributeData> GetCustomAttributesToEmit(PEModuleBuilder moduleBuilder)
 {
     return(GetAttributes());
 }
        IEnumerable <Cci.MethodImplementation> Cci.ITypeDefinition.GetExplicitImplementationOverrides(EmitContext context)
        {
            CheckDefinitionInvariant();

            PEModuleBuilder moduleBeingBuilt = (PEModuleBuilder)context.Module;

            foreach (var member in this.GetMembers())
            {
                if (member.Kind == SymbolKind.Method)
                {
                    var method = (MethodSymbol)member;
                    Debug.Assert((object)method.PartialDefinitionPart == null); // must be definition

                    var explicitImplementations = method.ExplicitInterfaceImplementations;
                    if (explicitImplementations.Length != 0)
                    {
                        foreach (var implemented in method.ExplicitInterfaceImplementations)
                        {
                            yield return(new Microsoft.Cci.MethodImplementation(method, moduleBeingBuilt.TranslateOverriddenMethodReference(implemented, (CSharpSyntaxNode)context.SyntaxNodeOpt, context.Diagnostics)));
                        }
                    }

                    if (this.IsInterface)
                    {
                        continue;
                    }

                    if (method.RequiresExplicitOverride())
                    {
                        // If C# and the runtime don't agree on the overridden method, then
                        // we will mark the method as newslot (see MethodSymbolAdapter) and
                        // specify the override explicitly.
                        // This mostly affects accessors - C# ignores method interactions
                        // between accessors and non-accessors, whereas the runtime does not.
                        yield return(new Microsoft.Cci.MethodImplementation(method, moduleBeingBuilt.TranslateOverriddenMethodReference(method.OverriddenMethod, (CSharpSyntaxNode)context.SyntaxNodeOpt, context.Diagnostics)));
                    }
                    else if (method.MethodKind == MethodKind.Destructor && this.SpecialType != SpecialType.System_Object)
                    {
                        // New in Roslyn: all destructors explicitly override (or are) System.Object.Finalize so that
                        // they are guaranteed to be runtime finalizers.  As a result, it is no longer possible to create
                        // a destructor that will never be invoked by the runtime.
                        // NOTE: If System.Object doesn't contain a destructor, you're on your own - this destructor may
                        // or not be called by the runtime.
                        TypeSymbol objectType = this.DeclaringCompilation.GetSpecialType(CodeAnalysis.SpecialType.System_Object);
                        foreach (Symbol objectMember in objectType.GetMembers(WellKnownMemberNames.DestructorName))
                        {
                            MethodSymbol objectMethod = objectMember as MethodSymbol;
                            if ((object)objectMethod != null && objectMethod.MethodKind == MethodKind.Destructor)
                            {
                                yield return(new Microsoft.Cci.MethodImplementation(method, moduleBeingBuilt.TranslateOverriddenMethodReference(objectMethod, (CSharpSyntaxNode)context.SyntaxNodeOpt, context.Diagnostics)));
                            }
                        }
                    }
                }
            }

            if (this.IsInterface)
            {
                yield break;
            }

            var syntheticMethods = moduleBeingBuilt.GetSynthesizedMethods(this);

            if (syntheticMethods != null)
            {
                foreach (var m in syntheticMethods)
                {
                    var method = m as MethodSymbol;
                    if ((object)method != null)
                    {
                        Debug.Assert((object)method.PartialDefinitionPart == null); // must be definition

                        foreach (var implemented in method.ExplicitInterfaceImplementations)
                        {
                            yield return(new Microsoft.Cci.MethodImplementation(method, moduleBeingBuilt.TranslateOverriddenMethodReference(implemented, (CSharpSyntaxNode)context.SyntaxNodeOpt, context.Diagnostics)));
                        }

                        Debug.Assert(!method.RequiresExplicitOverride());
                    }
                }
            }
        }
 protected override Cci.ITypeReference GetType(PEModuleBuilder moduleBuilder, CSharpSyntaxNode syntaxNodeOpt, DiagnosticBag diagnostics)
 {
     return moduleBuilder.Translate(UnderlyingProperty.Type, syntaxNodeOpt, diagnostics);
 }
示例#28
0
        /// <summary>
        /// Creates ghost stub that calls method.
        /// </summary>
        public static void CreateGhostOverload(this MethodSymbol method, NamedTypeSymbol containingtype, PEModuleBuilder module, DiagnosticBag diagnostic,
                                               TypeSymbol ghostreturn, IEnumerable <ParameterSymbol> ghostparams,
                                               MethodSymbol explicitOverride = null)
        {
            string prefix = (explicitOverride != null && explicitOverride.ContainingType.IsInterface)
                ? (explicitOverride.ContainingType.GetFullName() + ".")   // explicit interface override
                : null;

            var ghost = new SynthesizedMethodSymbol(
                containingtype, prefix + method.Name, method.IsStatic, explicitOverride != null, ghostreturn, method.DeclaredAccessibility)
            {
                ExplicitOverride = explicitOverride,
                ForwardedCall    = method,
            };

            ghost.SetParameters(ghostparams.Select(p => SynthesizedParameterSymbol.Create(ghost, p)).ToArray());

            // save method symbol to module
            module.SynthesizedManager.AddMethod(containingtype, ghost);

            // generate method body
            GenerateGhostBody(module, diagnostic, method, ghost);
        }
示例#29
0
 internal override NamedTypeSymbol FixedImplementationType(PEModuleBuilder emitModule)
 {
     EnsureSignatureIsLoaded();
     return _lazyFixedImplementationType;
 }
        internal void AddToType(NamedTypeSymbol containingType, PEModuleBuilder moduleBeingBuilt)
        {
            foreach (var field in FieldSymbols)
            {
                moduleBeingBuilt.AddSynthesizedDefinition(containingType, field);
            }

            FieldSymbol hostObjectField = GetHostObjectField();
            if ((object)hostObjectField != null)
            {
                moduleBeingBuilt.AddSynthesizedDefinition(containingType, hostObjectField);
            }
        }
示例#31
0
        internal override IEnumerable <CSharpAttributeData> GetCustomAttributesToEmit(PEModuleBuilder moduleBuilder)
        {
            foreach (CSharpAttributeData attribute in GetAttributes())
            {
                yield return(attribute);
            }

            // Yield hidden attributes last, order might be important.
            if (FilterOutDecimalConstantAttribute())
            {
                var containingPEModuleSymbol = _containingType.ContainingPEModule;
                yield return(new PEAttributeData(containingPEModuleSymbol,
                                                 containingPEModuleSymbol.Module.FindLastTargetAttribute(_handle, AttributeDescription.DecimalConstantAttribute).Handle));
            }
        }
示例#32
0
        public static void Run(MethodSymbol method, BoundStatement block, ILBuilder builder, PEModuleBuilder module, DiagnosticBag diagnostics, bool optimize, bool emitSequencePoints)
        {
            CodeGenerator generator = new CodeGenerator(method, block, builder, module, diagnostics, optimize, emitSequencePoints);
            generator.Generate();
            Debug.Assert(generator.asyncCatchHandlerOffset < 0);
            Debug.Assert(generator.asyncYieldPoints == null);
            Debug.Assert(generator.asyncResumePoints == null);

            if (!diagnostics.HasAnyErrors())
            {
                builder.Realize();
            }
        }
示例#33
0
 internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, ref ArrayBuilder <SynthesizedAttributeData> attributes)
 {
     // Do not call base.AddSynthesizedAttributes.
     // Dev11 does not emit DebuggerHiddenAttribute in property accessors
 }
示例#34
0
 public SpecializedGenericMethodInstanceReference(MethodSymbol underlyingMethod)
     : base(underlyingMethod)
 {
     Debug.Assert(PEModuleBuilder.IsGenericType(underlyingMethod.ContainingType) && underlyingMethod.ContainingType.IsDefinition);
     genericMethod = new SpecializedMethodReference(underlyingMethod);
 }
示例#35
0
 internal override NamedTypeSymbol FixedImplementationType(PEModuleBuilder emitModule)
 {
     // This occurs rarely, if ever.  The scenario would be a generic struct
     // containing a fixed-size buffer.  Given the rarity there would be little
     // benefit to "optimizing" the performance of this by cacheing the
     // translated implementation type.
     return (NamedTypeSymbol)_containingType.TypeSubstitution.SubstituteType(_originalDefinition.FixedImplementationType(emitModule));
 }
示例#36
0
            internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, ref ArrayBuilder <SynthesizedAttributeData> attributes)
            {
                base.AddSynthesizedAttributes(moduleBuilder, ref attributes);

                AddSynthesizedAttribute(ref attributes, this.DeclaringCompilation.TrySynthesizeAttribute(WellKnownMember.System_Diagnostics_DebuggerHiddenAttribute__ctor));
            }
 public SynthesizedMethodMetadataCompiler(PEModuleBuilder moduleBeingBuilt, CancellationToken cancellationToken)
 {
     Debug.Assert(moduleBeingBuilt != null);
     this.moduleBeingBuilt = moduleBeingBuilt;
     this.cancellationToken = cancellationToken;
 }
示例#38
0
 internal override IEnumerable <CSharpAttributeData> GetCustomAttributesToEmit(
     PEModuleBuilder moduleBuilder
     )
 {
     throw ExceptionUtilities.Unreachable;
 }
示例#39
0
        Cci.IDefinition Cci.IReference.AsDefinition(EmitContext context)
        {
            PEModuleBuilder moduleBeingBuilt = (PEModuleBuilder)context.Module;

            return(ResolvedFieldImpl(moduleBeingBuilt));
        }
示例#40
0
        private static MetadataConstant CreateMetadataConstant(ITypeSymbolInternal type, object value, EmitContext context)
        {
            PEModuleBuilder moduleBeingBuilt = (PEModuleBuilder)context.Module;

            return(moduleBeingBuilt.CreateConstant((TypeSymbol)type, value, syntaxNodeOpt: (CSharpSyntaxNode)context.SyntaxNodeOpt, diagnostics: context.Diagnostics));
        }
示例#41
0
        public static void Run(MethodSymbol method, BoundStatement block, ILBuilder builder, PEModuleBuilder module, DiagnosticBag diagnostics, bool optimize, bool emitSequencePoints,
            out int asyncCatchHandlerOffset, out ImmutableArray<int> asyncYieldPoints, out ImmutableArray<int> asyncResumePoints)
        {
            CodeGenerator generator = new CodeGenerator(method, block, builder, module, diagnostics, optimize, emitSequencePoints);
            generator.Generate();

            if (!diagnostics.HasAnyErrors())
            {
                builder.Realize();
            }

            asyncCatchHandlerOffset = (generator.asyncCatchHandlerOffset < 0)
                ? -1
                : generator.builder.GetILOffsetFromMarker(generator.asyncCatchHandlerOffset);

            ArrayBuilder<int> yieldPoints = generator.asyncYieldPoints;
            ArrayBuilder<int> resumePoints = generator.asyncResumePoints;
            if (yieldPoints == null)
            {
                asyncYieldPoints = ImmutableArray<int>.Empty;
                asyncResumePoints = ImmutableArray<int>.Empty;
            }
            else
            {
                var yieldPointBuilder = ArrayBuilder<int>.GetInstance();
                var resumePointBuilder = ArrayBuilder<int>.GetInstance();
                int n = yieldPoints.Count;
                for (int i = 0; i < n; i++)
                {
                    int yieldOffset = generator.builder.GetILOffsetFromMarker(yieldPoints[i]);
                    int resumeOffset = generator.builder.GetILOffsetFromMarker(resumePoints[i]);
                    Debug.Assert(resumeOffset >= 0); // resume marker should always be reachable from dispatch

                    // yield point may not be reachable if the whole 
                    // await is not reachable; we just ignore such awaits
                    if (yieldOffset > 0)
                    {
                        yieldPointBuilder.Add(yieldOffset);
                        resumePointBuilder.Add(resumeOffset);
                    }
                }

                asyncYieldPoints = yieldPointBuilder.ToImmutableAndFree();
                asyncResumePoints = resumePointBuilder.ToImmutableAndFree();
                yieldPoints.Free();
                resumePoints.Free();
            }
        }
示例#42
0
        Cci.ITypeReference Cci.ICustomAttribute.GetType(EmitContext context)
        {
            PEModuleBuilder moduleBeingBuilt = (PEModuleBuilder)context.Module;

            return(moduleBeingBuilt.Translate(this.AttributeClass, syntaxNodeOpt: (CSharpSyntaxNode)context.SyntaxNodeOpt, diagnostics: context.Diagnostics));
        }
示例#43
0
        private Cci.ITypeDefinition AsTypeDefinitionImpl(PEModuleBuilder moduleBeingBuilt)
        {
            Debug.Assert(this.IsDefinitionOrDistinct());

            if (this.IsDefinition && // can't be generic instantiation
                this.ContainingModule == moduleBeingBuilt.SourceModule) // must be declared in the module we are building
            {
                return this;
            }

            return null;
        }
示例#44
0
 protected override IEnumerable <CSharpAttributeData> GetCustomAttributesToEmit(PEModuleBuilder moduleBuilder)
 {
     return(UnderlyingEvent.GetCustomAttributesToEmit(moduleBuilder));
 }
 private SynthesizedMetadataCompiler(PEModuleBuilder moduleBeingBuilt, CancellationToken cancellationToken)
 {
     Debug.Assert(moduleBeingBuilt != null);
     _moduleBeingBuilt = moduleBeingBuilt;
     _cancellationToken = cancellationToken;
 }
示例#46
0
 protected override Cci.ITypeReference GetType(PEModuleBuilder moduleBuilder, SyntaxNode syntaxNodeOpt, DiagnosticBag diagnostics)
 {
     return(moduleBuilder.Translate(UnderlyingEvent.Type, syntaxNodeOpt, diagnostics));
 }
示例#47
0
 public TypeCompilationState(NamedTypeSymbol typeOpt, CSharpCompilation compilation, PEModuleBuilder moduleBuilderOpt)
 {
     this.Compilation = compilation;
     _typeOpt = typeOpt;
     this.ModuleBuilderOpt = moduleBuilderOpt;
 }
示例#48
0
 internal override IEnumerable <CSharpAttributeData> GetCustomAttributesToEmit(PEModuleBuilder moduleBuilder)
 {
     return(this.RetargetingTranslator.RetargetAttributes(_underlyingField.GetCustomAttributesToEmit(moduleBuilder)));
 }
示例#49
0
        internal static MethodSymbol GetEntryPoint(CSharpCompilation compilation, PEModuleBuilder moduleBeingBuilt, bool hasDeclarationErrors, DiagnosticBag diagnostics, CancellationToken cancellationToken)
        {
            CSharpCompilationOptions options = compilation.Options;
            if (!options.OutputKind.IsApplication())
            {
                Debug.Assert(compilation.GetEntryPointAndDiagnostics(cancellationToken) == null);
                return compilation.IsSubmission
                    ? DefineScriptEntryPoint(compilation, moduleBeingBuilt, compilation.GetSubmissionReturnType(), hasDeclarationErrors, diagnostics)
                    : null;
            }

            Debug.Assert(!compilation.IsSubmission);
            Debug.Assert(options.OutputKind.IsApplication());

            CSharpCompilation.EntryPoint entryPoint = compilation.GetEntryPointAndDiagnostics(cancellationToken);
            Debug.Assert(entryPoint != null);
            Debug.Assert(!entryPoint.Diagnostics.IsDefault);

            diagnostics.AddRange(entryPoint.Diagnostics);

            if ((object)compilation.ScriptClass != null)
            {
                Debug.Assert((object)entryPoint.MethodSymbol == null);
                return DefineScriptEntryPoint(compilation, moduleBeingBuilt, compilation.GetSpecialType(SpecialType.System_Void), hasDeclarationErrors, diagnostics);
            }

            Debug.Assert((object)entryPoint.MethodSymbol != null || entryPoint.Diagnostics.HasAnyErrors() || !compilation.Options.Errors.IsDefaultOrEmpty);
            return entryPoint.MethodSymbol;
        }
 private SynthesizedMetadataCompiler(PEModuleBuilder moduleBeingBuilt, CancellationToken cancellationToken)
 {
     Debug.Assert(moduleBeingBuilt != null);
     _moduleBeingBuilt  = moduleBeingBuilt;
     _cancellationToken = cancellationToken;
 }
示例#51
0
        internal static MethodSymbol DefineScriptEntryPoint(CSharpCompilation compilation, PEModuleBuilder moduleBeingBuilt, TypeSymbol returnType, bool hasDeclarationErrors, DiagnosticBag diagnostics)
        {
            var scriptEntryPoint = new SynthesizedEntryPointSymbol(compilation.ScriptClass, returnType, diagnostics);
            if (moduleBeingBuilt != null && !hasDeclarationErrors && !diagnostics.HasAnyErrors())
            {
                var compilationState = new TypeCompilationState(compilation.ScriptClass, moduleBeingBuilt);
                var body = scriptEntryPoint.CreateBody();

                var emittedBody = GenerateMethodBody(
                    compilationState,
                    scriptEntryPoint,
                    body,
                    diagnostics,
                    compilation.Options.Optimize,
                    debugDocumentProvider: null,
                    namespaceScopes: default(ImmutableArray<NamespaceScope>));

                moduleBeingBuilt.SetMethodBody(scriptEntryPoint, emittedBody);
                moduleBeingBuilt.AddCompilerGeneratedDefinition(compilation.ScriptClass, scriptEntryPoint);
            }

            return scriptEntryPoint;
        }
示例#52
0
            internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, ref ArrayBuilder <SynthesizedAttributeData> attributes)
            {
                base.AddSynthesizedAttributes(moduleBuilder, ref attributes);

                AddSynthesizedAttribute(ref attributes, this.DeclaringCompilation.SynthesizeDebuggerStepThroughAttribute());
            }
 internal override NamedTypeSymbol FixedImplementationType(PEModuleBuilder emitModule)
 {
     Debug.Assert(!this.IsFixed, "Subclasses representing fixed fields must override");
     return null;
 }
示例#54
0
 void CreateGhostOverload(PEModuleBuilder module, DiagnosticBag diagnostic, int pcount)
 {
     Debug.Assert(this.Parameters.Length > pcount);
     GhostMethodBuilder.CreateGhostOverload(this, this.ContainingType, module, diagnostic, this.ReturnType, this.Parameters.Take(pcount), null);
 }
        // TODO: consider unifying with VB
        private bool StartSourceChecksumCalculation(PEModuleBuilder moduleBeingBuilt, DiagnosticBag diagnostics)
        {
            // Check that all syntax trees are debuggable:
            bool allTreesDebuggable = true;
            foreach (var tree in this.syntaxTrees)
            {
                if (!string.IsNullOrEmpty(tree.FilePath) && tree.GetText().Encoding == null)
                {
                    diagnostics.Add(ErrorCode.ERR_EncodinglessSyntaxTree, tree.GetRoot().GetLocation());
                    allTreesDebuggable = false;
                }
            }

            if (!allTreesDebuggable)
            {
                return false;
            }

            // Add debug documents for all trees with distinct paths.
            foreach (var tree in this.syntaxTrees)
            {
                if (!string.IsNullOrEmpty(tree.FilePath))
                {
                    // compilation does not guarantee that all trees will have distinct paths.
                    // Do not attempt adding a document for a particular path if we already added one.
                    string normalizedPath = moduleBeingBuilt.NormalizeDebugDocumentPath(tree.FilePath, basePath: null);
                    var existingDoc = moduleBeingBuilt.TryGetDebugDocumentForNormalizedPath(normalizedPath);
                    if (existingDoc == null)
                    {
                        moduleBeingBuilt.AddDebugDocument(MakeDebugSourceDocumentForTree(normalizedPath, tree));
                    }
                }
            }

            // Add debug documents for all pragmas. 
            // If there are clashes with already processed directives, report warnings.
            // If there are clashes with debug documents that came from actual trees, ignore the pragma.
            foreach (var tree in this.syntaxTrees)
            {
                AddDebugSourceDocumentsForChecksumDirectives(moduleBeingBuilt, tree, diagnostics);
            }

            return true;
        }
示例#56
0
 /// <summary>
 /// Creates ghost stubs,
 /// i.e. methods with a different signature calling this routine to comply with CLR standards.
 /// </summary>
 internal virtual void SynthesizeStubs(PEModuleBuilder module, DiagnosticBag diagnostic)
 {
     SynthesizeOverloadsWithOptionalParameters(module, diagnostic);
 }
        private void SetupWin32Resources(PEModuleBuilder moduleBeingBuilt, Stream win32Resources, DiagnosticBag diagnostics)
        {
            if (win32Resources == null)
                return;

            switch (DetectWin32ResourceForm(win32Resources))
            {
                case Win32ResourceForm.COFF:
                    moduleBeingBuilt.Win32ResourceSection = MakeWin32ResourcesFromCOFF(win32Resources, diagnostics);
                    break;
                case Win32ResourceForm.RES:
                    moduleBeingBuilt.Win32Resources = MakeWin32ResourceList(win32Resources, diagnostics);
                    break;
                default:
                    diagnostics.Add(ErrorCode.ERR_BadWin32Res, NoLocation.Singleton, "Unrecognized file format.");
                    break;
            }
        }
示例#58
0
 public TypeCompilationState(NamedTypeSymbol type, PEModuleBuilder moduleBuilder)
 {
     this.type = type;
     this.ModuleBuilder = moduleBuilder;
 }