예제 #1
0
        internal CompilationVerifier CompileAndVerify(
            string[] sources,
            IEnumerable<MetadataReference> additionalRefs = null,
            IEnumerable<ModuleData> dependencies = null,
            Action<IModuleSymbol> sourceSymbolValidator = null,
            Action<PEAssembly> assemblyValidator = null,
            Action<IModuleSymbol> symbolValidator = null,
            SignatureDescription[] expectedSignatures = null,
            string expectedOutput = null,
            CompilationOptions options = null,
            ParseOptions parseOptions = null,
            EmitOptions emitOptions = null,
            bool verify = true)
        {
            if (options == null)
            {
                options = CompilationOptionsReleaseDll.WithOutputKind((expectedOutput != null) ? OutputKind.ConsoleApplication : OutputKind.DynamicallyLinkedLibrary);
            }

            var compilation = GetCompilationForEmit(sources, additionalRefs, options, parseOptions);

            return this.CompileAndVerify(
                compilation,
                null,
                dependencies,
                sourceSymbolValidator,
                assemblyValidator,
                symbolValidator,
                expectedSignatures,
                expectedOutput,
                emitOptions,
                verify);
        }
예제 #2
0
 internal CompilationVerifier CompileAndVerify(
     string source,
     IEnumerable<MetadataReference> additionalRefs = null,
     IEnumerable<ModuleData> dependencies = null,
     Action<IModuleSymbol> sourceSymbolValidator = null,
     Action<PEAssembly> assemblyValidator = null,
     Action<IModuleSymbol> symbolValidator = null,
     SignatureDescription[] expectedSignatures = null,
     string expectedOutput = null,
     CompilationOptions options = null,
     ParseOptions parseOptions = null,
     EmitOptions emitOptions = null,
     bool verify = true)
 {
     return CompileAndVerify(
         sources: new string[] { source },
         additionalRefs: additionalRefs,
         dependencies: dependencies,
         sourceSymbolValidator: sourceSymbolValidator,
         assemblyValidator: assemblyValidator,
         symbolValidator: symbolValidator,
         expectedSignatures: expectedSignatures,
         expectedOutput: expectedOutput,
         options: options,
         parseOptions: parseOptions,
         emitOptions: emitOptions,
         verify: verify);
 }
예제 #3
0
        public EEAssemblyBuilder(
            SourceAssemblySymbol sourceAssembly,
            EmitOptions emitOptions,
            ImmutableArray<MethodSymbol> methods,
            ModulePropertiesForSerialization serializationProperties,
            ImmutableArray<NamedTypeSymbol> additionalTypes,
            NamedTypeSymbol dynamicOperationContextType,
            CompilationTestData testData) :
            base(
                  sourceAssembly,
                  emitOptions,
                  outputKind: OutputKind.DynamicallyLinkedLibrary,
                  serializationProperties: serializationProperties,
                  manifestResources: SpecializedCollections.EmptyEnumerable<ResourceDescription>(),
                  additionalTypes: additionalTypes)
        {
            Methods = ImmutableHashSet.CreateRange(methods);
            _dynamicOperationContextType = dynamicOperationContextType;

            if (testData != null)
            {
                this.SetMethodTestData(testData.Methods);
                testData.Module = this;
            }
        }
예제 #4
0
        private CompilationVerifier CompileAndVerify(string source, string expectedOutput, IEnumerable<MetadataReference> references = null, EmitOptions emitOptions = EmitOptions.All, CSharpCompilationOptions compOptions = null)
        {
            SynchronizationContext.SetSynchronizationContext(null);

            var compilation = this.CreateCompilation(source, references: references, compOptions: compOptions);
            return base.CompileAndVerify(compilation, expectedOutput: expectedOutput, emitOptions: emitOptions);
        }
예제 #5
0
        internal static ImmutableArray<byte> EmitToArray(
            this Compilation compilation,
            EmitOptions options = null,
            CompilationTestData testData = null,
            DiagnosticDescription[] expectedWarnings = null)
        {
            var stream = new MemoryStream();
            MemoryStream pdbStream = 
                (compilation.Options.OptimizationLevel == OptimizationLevel.Debug) && !CLRHelpers.IsRunningOnMono() 
                ? new MemoryStream() 
                : null;

            var emitResult = compilation.Emit(
                peStream: stream,
                pdbStream: pdbStream,
                xmlDocumentationStream: null,
                win32Resources: null,
                manifestResources: null,
                options: options,
                testData: testData,
                getHostDiagnostics: null,
                cancellationToken: default(CancellationToken));

            Assert.True(emitResult.Success, "Diagnostics:\r\n" + string.Join("\r\n", emitResult.Diagnostics.Select(d => d.ToString())));

            if (expectedWarnings != null)
            {
                emitResult.Diagnostics.Verify(expectedWarnings);
            }

            return stream.ToImmutable();
        }
예제 #6
0
 internal PENetModuleBuilder(
     SourceModuleSymbol sourceModule,
     EmitOptions emitOptions,
     Cci.ModulePropertiesForSerialization serializationProperties,
     IEnumerable<ResourceDescription> manifestResources)
     : base(sourceModule, emitOptions, OutputKind.NetModule, serializationProperties, manifestResources)
 {
 }
예제 #7
0
 internal PENetModuleBuilder(
     PhpCompilation compilation,
     IModuleSymbol sourceModule,
     EmitOptions emitOptions,
     Microsoft.Cci.ModulePropertiesForSerialization serializationProperties,
     IEnumerable<ResourceDescription> manifestResources)
     : base(compilation, (Symbols.SourceModuleSymbol)sourceModule, serializationProperties, manifestResources, OutputKind.NetModule, emitOptions)
 {
 }
예제 #8
0
        public PEDeltaAssemblyBuilder(
            SourceAssemblySymbol sourceAssembly,
            EmitOptions emitOptions,
            OutputKind outputKind,
            Cci.ModulePropertiesForSerialization serializationProperties,
            IEnumerable<ResourceDescription> manifestResources,
            EmitBaseline previousGeneration,
            IEnumerable<SemanticEdit> edits,
            Func<ISymbol, bool> isAddedSymbol)
            : base(sourceAssembly, emitOptions, outputKind, serializationProperties, manifestResources, additionalTypes: ImmutableArray<NamedTypeSymbol>.Empty)
        {
            var initialBaseline = previousGeneration.InitialBaseline;
            var context = new EmitContext(this, null, new DiagnosticBag());

            // Hydrate symbols from initial metadata. Once we do so it is important to reuse these symbols across all generations,
            // in order for the symbol matcher to be able to use reference equality once it maps symbols to initial metadata.
            var metadataSymbols = GetOrCreateMetadataSymbols(initialBaseline, sourceAssembly.DeclaringCompilation);
            var metadataDecoder = (MetadataDecoder)metadataSymbols.MetadataDecoder;
            var metadataAssembly = (PEAssemblySymbol)metadataDecoder.ModuleSymbol.ContainingAssembly;

            var matchToMetadata = new CSharpSymbolMatcher(metadataSymbols.AnonymousTypes, sourceAssembly, context, metadataAssembly);

            CSharpSymbolMatcher matchToPrevious = null;
            if (previousGeneration.Ordinal > 0)
            {
                var previousAssembly = ((CSharpCompilation)previousGeneration.Compilation).SourceAssembly;
                var previousContext = new EmitContext((PEModuleBuilder)previousGeneration.PEModuleBuilder, null, new DiagnosticBag());

                matchToPrevious = new CSharpSymbolMatcher(
                    previousGeneration.AnonymousTypeMap,
                    sourceAssembly: sourceAssembly,
                    sourceContext: context,
                    otherAssembly: previousAssembly,
                    otherContext: previousContext,
                    otherSynthesizedMembersOpt: previousGeneration.SynthesizedMembers);
            }

            _previousDefinitions = new CSharpDefinitionMap(previousGeneration.OriginalMetadata.Module, edits, metadataDecoder, matchToMetadata, matchToPrevious);
            _previousGeneration = previousGeneration;
            _changes = new SymbolChanges(_previousDefinitions, edits, isAddedSymbol);

            // Workaround for https://github.com/dotnet/roslyn/issues/3192.
            // When compiling state machine we stash types of awaiters and state-machine hoisted variables,
            // so that next generation can look variables up and reuse their slots if possible.
            //
            // When we are about to allocate a slot for a lifted variable while compiling the next generation
            // we map its type to the previous generation and then check the slot types that we stashed earlier.
            // If the variable type matches we reuse it. In order to compare the previous variable type with the current one
            // both need to be completely lowered (translated). Standard translation only goes one level deep. 
            // Generic arguments are not translated until they are needed by metadata writer. 
            //
            // In order to get the fully lowered form we run the type symbols of stashed variables thru a deep translator
            // that translates the symbol recursively.
            _deepTranslator = new CSharpSymbolMatcher.DeepTranslator(sourceAssembly.GetSpecialType(SpecialType.System_Object));
        }
예제 #9
0
        public PEAssemblyBuilder(
            SourceAssemblySymbol sourceAssembly,
            Cci.ModulePropertiesForSerialization serializationProperties,
            IEnumerable<ResourceDescription> manifestResources,
            OutputKind outputKind,
            EmitOptions emitOptions)
            :base(sourceAssembly.DeclaringCompilation, (SourceModuleSymbol)sourceAssembly.Modules[0], serializationProperties, manifestResources, outputKind, emitOptions)
        {
            _sourceAssembly = sourceAssembly;
            _metadataName = (emitOptions.OutputNameOverride == null) ? sourceAssembly.MetadataName : FileNameUtilities.ChangeExtension(emitOptions.OutputNameOverride, extension: null);

            AssemblyOrModuleSymbolToModuleRefMap.Add(sourceAssembly, this);
        }
        public static MemoryStream EmitToStream(this Compilation compilation, EmitOptions options = null, DiagnosticDescription[] expectedWarnings = null)
        {
            var stream = new MemoryStream();
            var emitResult = compilation.Emit(stream, options: options);
            Assert.True(emitResult.Success, "Diagnostics: " + string.Join(", ", emitResult.Diagnostics.Select(d => d.ToString())));

            if (expectedWarnings != null)
            {
                emitResult.Diagnostics.Verify(expectedWarnings);
            }

            stream.Position = 0;
            return stream;
        }
 public static MetadataReference EmitToImageReference(
     this Compilation comp,
     EmitOptions options = null,
     bool embedInteropTypes = false,
     ImmutableArray<string> aliases = default(ImmutableArray<string>),
     DiagnosticDescription[] expectedWarnings = null)
 {
     var image = comp.EmitToArray(options, expectedWarnings: expectedWarnings);
     if (comp.Options.OutputKind == OutputKind.NetModule)
     {
         return ModuleMetadata.CreateFromImage(image).GetReference(display: comp.MakeSourceModuleName());
     }
     else
     {
         return AssemblyMetadata.CreateFromImage(image).GetReference(aliases: aliases, embedInteropTypes: embedInteropTypes, display: comp.MakeSourceAssemblySimpleName());
     }
 }
        public PEAssemblyBuilderBase(
            SourceAssemblySymbol sourceAssembly,
            EmitOptions emitOptions,
            OutputKind outputKind,
            Cci.ModulePropertiesForSerialization serializationProperties,
            IEnumerable<ResourceDescription> manifestResources,
            ImmutableArray<NamedTypeSymbol> additionalTypes)
            : base((SourceModuleSymbol)sourceAssembly.Modules[0], emitOptions, outputKind, serializationProperties, manifestResources)
        {
            Debug.Assert((object)sourceAssembly != null);

            _sourceAssembly = sourceAssembly;
            _additionalTypes = additionalTypes.NullToEmpty();
            _metadataName = (emitOptions.OutputNameOverride == null) ? sourceAssembly.MetadataName : FileNameUtilities.ChangeExtension(emitOptions.OutputNameOverride, extension: null);

            AssemblyOrModuleSymbolToModuleRefMap.Add(sourceAssembly, this);
        }
예제 #13
0
        internal static ImmutableArray<byte> EmitToArray(
            this Compilation compilation,
            EmitOptions options = null,
            CompilationTestData testData = null,
            DiagnosticDescription[] expectedWarnings = null,
            Stream pdbStream = null,
            IMethodSymbol debugEntryPoint = null,
            Stream sourceLinkStream = null,
            IEnumerable<EmbeddedText> embeddedTexts = null)
        {
            var peStream = new MemoryStream();

            if (pdbStream == null && compilation.Options.OptimizationLevel == OptimizationLevel.Debug && options?.DebugInformationFormat != DebugInformationFormat.Embedded)
            {
                if (MonoHelpers.IsRunningOnMono())
                {
                    options = (options ?? EmitOptions.Default).WithDebugInformationFormat(DebugInformationFormat.PortablePdb);
                }

                pdbStream = new MemoryStream();
            }

            var emitResult = compilation.Emit(
                peStream: peStream,
                pdbStream: pdbStream,
                xmlDocumentationStream: null,
                win32Resources: null,
                manifestResources: null,
                options: options,
                debugEntryPoint: debugEntryPoint,
                sourceLinkStream: sourceLinkStream,
                embeddedTexts: embeddedTexts,
                testData: testData,
                cancellationToken: default(CancellationToken));

            Assert.True(emitResult.Success, "Diagnostics:\r\n" + string.Join("\r\n", emitResult.Diagnostics.Select(d => d.ToString())));

            if (expectedWarnings != null)
            {
                emitResult.Diagnostics.Verify(expectedWarnings);
            }

            return peStream.ToImmutable();
        }
        protected override Assembly Load(AssemblyName assemblyName)
        {
            Assembly assembly;
            if (_assemblies.TryGetValue(assemblyName.Name, out assembly))
            {
                return assembly;
            }
            
            try
            {
                System.Console.WriteLine($"Load({assemblyName})");

                ProjectId projectId;
                if (_projects.TryGetValue(assemblyName.Name, out projectId))
                {
                    var project = _workspace.CurrentSolution.GetProject(projectId);
                    System.Console.WriteLine($"Found project {project.AssemblyName}({(project.Id)})");

                    using (var assemblySymbols = new MemoryStream())
                    using (var assemblyStream = new MemoryStream())
                    {
                        var emitOptions = new EmitOptions().WithDebugInformationFormat(DebugInformationFormat.PortablePdb);
                        var compilation = project.GetCompilationAsync().GetAwaiter().GetResult();
                        var emitResult = compilation.Emit(assemblyStream, assemblySymbols, options: emitOptions);

                        if (emitResult.Success)
                        {
                            assemblyStream.Position = 0;
                            assemblySymbols.Position = 0;

                            return LoadFromStream(assemblyStream, assemblySymbols);
                        }
                    }
                }
            }
            catch
            {
                return Default.LoadFromAssemblyName(assemblyName);
            }
            
            return null;
        }
예제 #15
0
        public PEDeltaAssemblyBuilder(
            SourceAssemblySymbol sourceAssembly,
            EmitOptions emitOptions,
            OutputKind outputKind,
            ModulePropertiesForSerialization serializationProperties,
            IEnumerable<ResourceDescription> manifestResources,
            EmitBaseline previousGeneration,
            IEnumerable<SemanticEdit> edits,
            Func<ISymbol, bool> isAddedSymbol)
            : base(sourceAssembly, emitOptions, outputKind, serializationProperties, manifestResources, assemblySymbolMapper: null, additionalTypes: ImmutableArray<NamedTypeSymbol>.Empty)
        {
            var context = new EmitContext(this, null, new DiagnosticBag());
            var module = previousGeneration.OriginalMetadata;
            var compilation = sourceAssembly.DeclaringCompilation;
            var metadataAssembly = compilation.GetBoundReferenceManager().CreatePEAssemblyForAssemblyMetadata(AssemblyMetadata.Create(module), MetadataImportOptions.All);
            var metadataDecoder = new Microsoft.CodeAnalysis.CSharp.Symbols.Metadata.PE.MetadataDecoder(metadataAssembly.PrimaryModule);

            previousGeneration = EnsureInitialized(previousGeneration, metadataDecoder);

            var matchToMetadata = new CSharpSymbolMatcher(previousGeneration.AnonymousTypeMap, sourceAssembly, context, metadataAssembly);

            CSharpSymbolMatcher matchToPrevious = null;
            if (previousGeneration.Ordinal > 0)
            {
                var previousAssembly = ((CSharpCompilation)previousGeneration.Compilation).SourceAssembly;
                var previousContext = new EmitContext((PEModuleBuilder)previousGeneration.PEModuleBuilder, null, new DiagnosticBag());

                matchToPrevious = new CSharpSymbolMatcher(
                    previousGeneration.AnonymousTypeMap,
                    sourceAssembly: sourceAssembly,
                    sourceContext: context,
                    otherAssembly: previousAssembly,
                    otherContext: previousContext,
                    otherSynthesizedMembersOpt: previousGeneration.SynthesizedMembers);
            }

            _previousDefinitions = new CSharpDefinitionMap(previousGeneration.OriginalMetadata.Module, edits, metadataDecoder, matchToMetadata, matchToPrevious);
            _previousGeneration = previousGeneration;
            _changes = new SymbolChanges(_previousDefinitions, edits, isAddedSymbol);
        }
예제 #16
0
        protected PEModuleBuilder(
            PhpCompilation compilation,
            SourceModuleSymbol sourceModule,
            Cci.ModulePropertiesForSerialization serializationProperties,
            IEnumerable<ResourceDescription> manifestResources,
            OutputKind outputKind,
            EmitOptions emitOptions)
        {
            Debug.Assert(sourceModule != null);
            Debug.Assert(serializationProperties != null);

            _compilation = compilation;
            _sourceModule = sourceModule;
            _serializationProperties = serializationProperties;
            this.ManifestResources = manifestResources;
            _outputKind = outputKind;
            _emitOptions = emitOptions;
            this.CompilationState = new CommonModuleCompilationState();
            _debugDocuments = new ConcurrentDictionary<string, Cci.DebugSourceDocument>(compilation.IsCaseSensitive ? StringComparer.Ordinal : StringComparer.OrdinalIgnoreCase);
            _synthesized = new SynthesizedManager(this);

            AssemblyOrModuleSymbolToModuleRefMap.Add(sourceModule, this);
        }
        public static EmitResult EmitWithMdb(this Compilation compilation, Stream peStream, Stream pdbStream = null,
            Stream xmlDocumentationStream = null, Stream win32Resources = null,
            IEnumerable<ResourceDescription> manifestResources = null, EmitOptions options = null,
            IMethodSymbol debugEntryPoint = null, CancellationToken cancellationToken = default(CancellationToken))
        {
            if (peStream == null)
            {
                throw new ArgumentNullException(nameof(peStream));
            }

            if (!peStream.CanWrite)
            {
                throw new ArgumentException(CodeAnalysisResources.StreamMustSupportWrite, nameof(peStream));
            }

            if (pdbStream != null && !pdbStream.CanWrite)
            {
                throw new ArgumentException(CodeAnalysisResources.StreamMustSupportWrite, nameof(pdbStream));
            }

            var testData = new CompilationTestData
            {
                SymWriterFactory = () => new MdbWriter()
            };

            return compilation.Emit(
                peStream,
                pdbStream,
                xmlDocumentationStream,
                win32Resources,
                manifestResources,
                options,
                debugEntryPoint,
                testData,
                null,
                cancellationToken);
        }
예제 #18
0
        public void Emit(Compilation mainCompilation, IEnumerable<ResourceDescription> manifestResources, EmitOptions emitOptions, bool usePdbForDebugging = false)
        {
            _testData.Methods.Clear();
            var diagnostics = DiagnosticBag.GetInstance();
            var dependencies = new List<ModuleData>();
            var mainOutput = RuntimeUtilities.EmitCompilation(mainCompilation, manifestResources, dependencies, diagnostics, _testData, emitOptions);

            if (mainOutput.HasValue)
            {
                _diagnostics = diagnostics.ToReadOnly();
                _mainImage = mainOutput.Value.Assembly;
                _pdb = mainOutput.Value.Pdb;
            }
            else
            {
                _mainImage = default(ImmutableArray<byte>);
                _pdb = default(ImmutableArray<byte>);
                _diagnostics = default(ImmutableArray<Diagnostic>);

                string dumpDir;
                DumpAssemblyData(dependencies, out dumpDir);
                throw new EmitException(diagnostics.ToReadOnly(), dumpDir);
            }
        }
예제 #19
0
        public CompilerInstruction(Compiler compiler, InstructionCode code, Operand[] operands)
            : base(compiler)
        {
            Contract.Requires(compiler != null);
            Contract.Requires(operands != null);

            _code = code;
            _emitOptions = compiler.EmitOptions;
            // Each created instruction takes emit options and clears it.
            compiler.EmitOptions = EmitOptions.None;

            _operands = operands;
            _memoryOperand = null;

            _variables = null;

            for (int i = 0; i < operands.Length; i++)
            {
                if (operands[i].IsMem)
                {
                    _memoryOperand = (Mem)operands[i];
                    break;
                }
            }

            InstructionDescription id = InstructionDescription.FromInstruction(_code);
            _isSpecial = id.IsSpecial;
            _isFPU = id.IsFPU;
            _isGPBHiUsed = false;
            _isGPBLoUsed = false;

            if (_isSpecial)
            {
                // ${SPECIAL_INSTRUCTION_HANDLING_BEGIN}
                switch (_code)
                {
                case InstructionCode.Cpuid:
                    // Special...
                    break;

                case InstructionCode.Cbw:
                case InstructionCode.Cdqe:
                case InstructionCode.Cwde:
                    // Special...
                    break;

                case InstructionCode.Cdq:
                case InstructionCode.Cqo:
                case InstructionCode.Cwd:
                    // Special...
                    break;

                case InstructionCode.Cmpxchg:
                case InstructionCode.Cmpxchg8b:
                case InstructionCode.Cmpxchg16b:
                    // Special...
                    if (_code == InstructionCode.Cmpxchg16b && !Util.IsX64)
                        throw new NotSupportedException(string.Format("The '{0}' instruction is only supported on X64.", _code));

                    break;

                case InstructionCode.Daa:
                case InstructionCode.Das:
                    // Special...
                    if (!Util.IsX86)
                        throw new NotSupportedException(string.Format("The '{0}' instruction is only supported on X86.", _code));

                    break;

                case InstructionCode.Imul:
                    switch (operands.Length)
                    {
                    case 2:
                        // IMUL dst, src is not special instruction.
                        _isSpecial = false;
                        break;
                    case 3:
                        if (!(_operands[0].IsVar && _operands[1].IsVar && _operands[2].IsVarMem))
                        {
                            // Only IMUL dst_hi, dst_lo, reg/mem is special, all others don't.
                            _isSpecial = false;
                        }
                        break;
                    }
                    break;
                case InstructionCode.Mul:
                case InstructionCode.Idiv:
                case InstructionCode.Div:
                    // Special...
                    break;

                case InstructionCode.MovPtr:
                    // Special...
                    break;

                case InstructionCode.Lahf:
                case InstructionCode.Sahf:
                    // Special...
                    break;

                case InstructionCode.Maskmovdqu:
                case InstructionCode.Maskmovq:
                    // Special...
                    break;

                case InstructionCode.Enter:
                case InstructionCode.Leave:
                    // Special...
                    break;

                case InstructionCode.Ret:
                    // Special...
                    break;

                case InstructionCode.Monitor:
                case InstructionCode.Mwait:
                    // Special...
                    break;

                case InstructionCode.Pop:
                case InstructionCode.Popad:
                case InstructionCode.Popfd:
                case InstructionCode.Popfq:
                    // Special...
                    break;

                case InstructionCode.Push:
                case InstructionCode.Pushad:
                case InstructionCode.Pushfd:
                case InstructionCode.Pushfq:
                    // Special...
                    break;

                case InstructionCode.Rcl:
                case InstructionCode.Rcr:
                case InstructionCode.Rol:
                case InstructionCode.Ror:
                case InstructionCode.Sal:
                case InstructionCode.Sar:
                case InstructionCode.Shl:
                case InstructionCode.Shr:
                    // Rot instruction is special only if last operand is variable (register).
                    _isSpecial = _operands[1].IsVar;
                    break;

                case InstructionCode.Shld:
                case InstructionCode.Shrd:
                    // Shld/Shrd instruction is special only if last operand is variable (register).
                    _isSpecial = _operands[2].IsVar;
                    break;

                case InstructionCode.Rdtsc:
                case InstructionCode.Rdtscp:
                    // Special...
                    break;

                case InstructionCode.RepLodsb:
                case InstructionCode.RepLodsd:
                case InstructionCode.RepLodsq:
                case InstructionCode.RepLodsw:
                case InstructionCode.RepMovsb:
                case InstructionCode.RepMovsd:
                case InstructionCode.RepMovsq:
                case InstructionCode.RepMovsw:
                case InstructionCode.RepStosb:
                case InstructionCode.RepStosd:
                case InstructionCode.RepStosq:
                case InstructionCode.RepStosw:
                case InstructionCode.RepeCmpsb:
                case InstructionCode.RepeCmpsd:
                case InstructionCode.RepeCmpsq:
                case InstructionCode.RepeCmpsw:
                case InstructionCode.RepeScasb:
                case InstructionCode.RepeScasd:
                case InstructionCode.RepeScasq:
                case InstructionCode.RepeScasw:
                case InstructionCode.RepneCmpsb:
                case InstructionCode.RepneCmpsd:
                case InstructionCode.RepneCmpsq:
                case InstructionCode.RepneCmpsw:
                case InstructionCode.RepneScasb:
                case InstructionCode.RepneScasd:
                case InstructionCode.RepneScasq:
                case InstructionCode.RepneScasw:
                    // Special...
                    break;

                default:
                    throw new CompilerException("Instruction is marked as special but handling for it is not present.");
                }
                // ${SPECIAL_INSTRUCTION_HANDLING_END}
            }
        }
예제 #20
0
        public void PlatformMismatch_08()
        {
            var emitOptions = new EmitOptions(runtimeMetadataVersion: "v1234");

            string refSource = @"
public interface ITestPlatform
{}
";
            var refCompilation = CreateCompilation(refSource, options: TestOptions.ReleaseModule.WithPlatform(Platform.Itanium), assemblyName: "PlatformMismatch");

            refCompilation.VerifyEmitDiagnostics(emitOptions);
            var imageRef = refCompilation.EmitToImageReference();

            string useSource = @"
public interface IUsePlatform
{
    ITestPlatform M();
}
";

            var useCompilation = CreateCompilation(useSource,
                new MetadataReference[] { imageRef },
                options: TestOptions.ReleaseDll.WithPlatform(Platform.Itanium));

            useCompilation.VerifyEmitDiagnostics(emitOptions);
        }
예제 #21
0
        public void PlatformMismatch_04()
        {
            var emitOptions = new EmitOptions(runtimeMetadataVersion: "v1234");

            string refSource = @"
public interface ITestPlatform
{}
";
            var refCompilation = CreateCompilation(refSource, options: TestOptions.ReleaseModule.WithPlatform(Platform.X86), assemblyName: "PlatformMismatch");

            refCompilation.VerifyEmitDiagnostics(emitOptions);
            var imageRef = refCompilation.EmitToImageReference();

            string useSource = @"
public interface IUsePlatform
{
    ITestPlatform M();
}
";

            var useCompilation = CreateCompilation(useSource,
                new MetadataReference[] { imageRef },
                options: TestOptions.ReleaseDll.WithPlatform(Platform.Itanium));

            useCompilation.VerifyEmitDiagnostics(emitOptions,
                // error CS8011: Assembly and module 'PlatformMismatch.netmodule' cannot target different processors.
                Diagnostic(ErrorCode.ERR_ConflictingMachineModule).WithArguments("PlatformMismatch.netmodule"));
        }
예제 #22
0
        public void PlatformMismatch_03()
        {
            var emitOptions = new EmitOptions(runtimeMetadataVersion: "v1234");

            string refSource = @"
public interface ITestPlatform
{}
";
            var refCompilation = CreateCompilation(refSource, options: TestOptions.ReleaseDll.WithPlatform(Platform.X86), assemblyName: "PlatformMismatch");

            refCompilation.VerifyEmitDiagnostics(emitOptions);
            var compRef = new CSharpCompilationReference(refCompilation);
            var imageRef = refCompilation.EmitToImageReference();

            string useSource = @"
public interface IUsePlatform
{
    ITestPlatform M();
}
";

            var useCompilation = CreateCompilation(useSource,
                new MetadataReference[] { compRef },
                options: TestOptions.ReleaseDll.WithPlatform(Platform.Itanium));

            useCompilation.VerifyEmitDiagnostics(emitOptions,
                // warning CS8012: Referenced assembly 'PlatformMismatch, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' targets a different processor.
                Diagnostic(ErrorCode.WRN_ConflictingMachineAssembly).WithArguments("PlatformMismatch, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null"));

            useCompilation = CreateCompilation(useSource,
                new MetadataReference[] { imageRef },
                options: TestOptions.ReleaseDll.WithPlatform(Platform.Itanium));

            useCompilation.VerifyEmitDiagnostics(emitOptions,
                // warning CS8012: Referenced assembly 'PlatformMismatch, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' targets a different processor.
                Diagnostic(ErrorCode.WRN_ConflictingMachineAssembly).WithArguments("PlatformMismatch, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null"));

            useCompilation = CreateCompilation(useSource,
                new MetadataReference[] { compRef },
                options: TestOptions.ReleaseModule.WithPlatform(Platform.Itanium));

            useCompilation.VerifyEmitDiagnostics(emitOptions,
                // warning CS8012: Referenced assembly 'PlatformMismatch, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' targets a different processor.
                Diagnostic(ErrorCode.WRN_ConflictingMachineAssembly).WithArguments("PlatformMismatch, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null"));

            useCompilation = CreateCompilation(useSource,
                new MetadataReference[] { imageRef },
                options: TestOptions.ReleaseModule.WithPlatform(Platform.Itanium));

            useCompilation.VerifyEmitDiagnostics(emitOptions,
                // warning CS8012: Referenced assembly 'PlatformMismatch, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' targets a different processor.
                Diagnostic(ErrorCode.WRN_ConflictingMachineAssembly).WithArguments("PlatformMismatch, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null"));
        }
예제 #23
0
        public void PlatformMismatch_01()
        {
            var emitOptions = new EmitOptions(runtimeMetadataVersion: "v1234");

            string refSource = @"
public interface ITestPlatform
{}
";
            var refCompilation = CreateCompilation(refSource, options: TestOptions.ReleaseDll.WithPlatform(Platform.Itanium), assemblyName: "PlatformMismatch");

            refCompilation.VerifyEmitDiagnostics(emitOptions);
            var compRef = new CSharpCompilationReference(refCompilation);
            var imageRef = refCompilation.EmitToImageReference();

            string useSource = @"
public interface IUsePlatform
{
    ITestPlatform M();
}
";
            var useCompilation = CreateCompilation(useSource,
                new MetadataReference[] { compRef },
                options: TestOptions.ReleaseDll.WithPlatform(Platform.AnyCpu));

            useCompilation.VerifyEmitDiagnostics(emitOptions);

            useCompilation = CreateCompilation(useSource,
                new MetadataReference[] { imageRef },
                options: TestOptions.ReleaseDll.WithPlatform(Platform.AnyCpu));

            useCompilation.VerifyEmitDiagnostics(emitOptions);

            useCompilation = CreateCompilation(useSource,
                new MetadataReference[] { compRef },
                options: TestOptions.ReleaseModule.WithPlatform(Platform.AnyCpu));

            useCompilation.VerifyEmitDiagnostics(emitOptions);

            useCompilation = CreateCompilation(useSource,
                new MetadataReference[] { imageRef },
                options: TestOptions.ReleaseModule.WithPlatform(Platform.AnyCpu));

            useCompilation.VerifyEmitDiagnostics(emitOptions);

            useCompilation = CreateCompilation(useSource,
                new MetadataReference[] { compRef },
                options: TestOptions.ReleaseDll.WithPlatform(Platform.X86));

            useCompilation.VerifyEmitDiagnostics(emitOptions,
                // warning CS8012: Referenced assembly 'PlatformMismatch, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' targets a different processor.
                Diagnostic(ErrorCode.WRN_ConflictingMachineAssembly).WithArguments("PlatformMismatch, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null"));

            useCompilation = CreateCompilation(useSource,
                new MetadataReference[] { imageRef },
                options: TestOptions.ReleaseDll.WithPlatform(Platform.X86));

            useCompilation.VerifyEmitDiagnostics(emitOptions,
                // warning CS8012: Referenced assembly 'PlatformMismatch, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' targets a different processor.
                Diagnostic(ErrorCode.WRN_ConflictingMachineAssembly).WithArguments("PlatformMismatch, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null"));

            useCompilation = CreateCompilation(useSource,
                new MetadataReference[] { compRef },
                options: TestOptions.ReleaseModule.WithPlatform(Platform.X86));

            useCompilation.VerifyEmitDiagnostics(emitOptions,
                // warning CS8012: Referenced assembly 'PlatformMismatch, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' targets a different processor.
                Diagnostic(ErrorCode.WRN_ConflictingMachineAssembly).WithArguments("PlatformMismatch, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null"));

            useCompilation = CreateCompilation(useSource,
                new MetadataReference[] { imageRef },
                options: TestOptions.ReleaseModule.WithPlatform(Platform.X86));

            useCompilation.VerifyEmitDiagnostics(emitOptions,
                // warning CS8012: Referenced assembly 'PlatformMismatch, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' targets a different processor.
                Diagnostic(ErrorCode.WRN_ConflictingMachineAssembly).WithArguments("PlatformMismatch, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null"));

            // Confirm that suppressing the old alink warning 1607 shuts off WRN_ConflictingMachineAssembly
            var warnings = new System.Collections.Generic.Dictionary<string, ReportDiagnostic>();
            warnings.Add(MessageProvider.Instance.GetIdForErrorCode((int)ErrorCode.WRN_ALinkWarn), ReportDiagnostic.Suppress);
            useCompilation = useCompilation.WithOptions(useCompilation.Options.WithSpecificDiagnosticOptions(warnings));
            useCompilation.VerifyEmitDiagnostics(emitOptions);
        }
예제 #24
0
        private static EEAssemblyBuilder CreateModuleBuilder(
            CSharpCompilation compilation,
            ImmutableArray<MethodSymbol> methods,
            ImmutableArray<NamedTypeSymbol> additionalTypes,
            EENamedTypeSymbol synthesizedType,
            Microsoft.CodeAnalysis.CodeGen.CompilationTestData testData,
            DiagnosticBag diagnostics)
        {
            // Each assembly must have a unique name.
            var emitOptions = new EmitOptions(outputNameOverride: ExpressionCompilerUtilities.GenerateUniqueName());

            var dynamicOperationContextType = GetNonDisplayClassContainer(synthesizedType.SubstitutedSourceType);

            string runtimeMetadataVersion = compilation.GetRuntimeMetadataVersion(emitOptions, diagnostics);
            var serializationProperties = compilation.ConstructModuleSerializationProperties(emitOptions, runtimeMetadataVersion);
            return new EEAssemblyBuilder(compilation.SourceAssembly, emitOptions, methods, serializationProperties, additionalTypes, dynamicOperationContextType, testData);
        }
예제 #25
0
        internal static EmitOutput? EmitCompilationCore(
            Compilation compilation,
            IEnumerable<ResourceDescription> manifestResources,
            DiagnosticBag diagnostics,
            CompilationTestData testData,
            EmitOptions emitOptions
        )
        {
            using (var executableStream = new MemoryStream())
            {
                var pdb = default(ImmutableArray<byte>);
                var assembly = default(ImmutableArray<byte>);
                var pdbStream = MonoHelpers.IsRunningOnMono()
                    ? null
                    : new MemoryStream();

                EmitResult result;
                try
                {
                    result = compilation.Emit(
                        executableStream,
                        pdbStream: pdbStream,
                        xmlDocumentationStream: null,
                        win32Resources: null,
                        manifestResources: manifestResources,
                        options: emitOptions ?? EmitOptions.Default,
                        debugEntryPoint: null,
                        sourceLinkStream: null,
                        testData: testData,
                        cancellationToken: default(CancellationToken));
                }
                finally
                {
                    if (pdbStream != null)
                    {
                        pdb = pdbStream.ToImmutable();
                        pdbStream.Dispose();
                    }
                }

                diagnostics.AddRange(result.Diagnostics);
                assembly = executableStream.ToImmutable();

                if (result.Success)
                {
                    return new EmitOutput(assembly, pdb);
                }

                return null;
            }
        }
예제 #26
0
        public void EmitOptionsDiagnostics()
        {
            var c = CreateCompilationWithMscorlib("class C {}");
            var stream = new MemoryStream();

            var options = new EmitOptions(
                debugInformationFormat: (DebugInformationFormat)(-1),
                outputNameOverride: " ",
                fileAlignment: 513,
                subsystemVersion: SubsystemVersion.Create(1000000, -1000000));

            EmitResult result = c.Emit(stream, options: options);

            result.Diagnostics.Verify(
                // error CS2042: Invalid debug information format: -1
                Diagnostic(ErrorCode.ERR_InvalidDebugInformationFormat).WithArguments("-1"),
                // error CS2041: Invalid output name: Name cannot start with whitespace.
                Diagnostic(ErrorCode.ERR_InvalidOutputName).WithArguments(CodeAnalysisResources.NameCannotStartWithWhitespace),
                // error CS2024: Invalid file section alignment '513'
                Diagnostic(ErrorCode.ERR_InvalidFileAlignment).WithArguments("513"),
                // error CS1773: Invalid version 1000000.-1000000 for /subsystemversion. The version must be 6.02 or greater for ARM or AppContainerExe, and 4.00 or greater otherwise
                Diagnostic(ErrorCode.ERR_InvalidSubsystemVersion).WithArguments("1000000.-1000000"));

            Assert.False(result.Success);
        }
 public PEAssemblyBuilder(
     SourceAssemblySymbol sourceAssembly,
     EmitOptions emitOptions,
     OutputKind outputKind,
     Cci.ModulePropertiesForSerialization serializationProperties,
     IEnumerable<ResourceDescription> manifestResources)
     : base(sourceAssembly, emitOptions, outputKind, serializationProperties, manifestResources, ImmutableArray<NamedTypeSymbol>.Empty)
 {
 }
예제 #28
0
        public IDiagnosticResult EmitAssembly(string outputPath)
        {
            IList<ResourceDescription> resources = CompilationContext.Resources;

            var assemblyPath = Path.Combine(outputPath, Name + ".dll");
            var pdbPath = Path.Combine(outputPath, Name + ".pdb");
            var xmlDocPath = Path.Combine(outputPath, Name + ".xml");

            // REVIEW: Memory bloat?

            using (var xmlDocStream = new MemoryStream())
            using (var pdbStream = new MemoryStream())
            using (var assemblyStream = new MemoryStream())
            using (var win32resStream = CompilationContext.Compilation.CreateDefaultWin32Resources(
                versionResource: true,
                noManifest: false,
                manifestContents: null,
                iconInIcoFormat: null))
            {
                // The default win32resStream extracted from compilation represents a Win32 applicaiton manifest.
                // It enables the assmebly information to be viewed in Windows Explorer.

                Logger.TraceInformation("[{0}]: Emitting assembly for {1}", GetType().Name, Name);

                var sw = Stopwatch.StartNew();

                EmitResult emitResult = null;

                if (_supportsPdbGeneration.Value)
                {
                    var options = new EmitOptions(pdbFilePath: pdbPath);
                    emitResult = CompilationContext.Compilation.Emit(
                        assemblyStream,
                        pdbStream: pdbStream,
                        xmlDocumentationStream: xmlDocStream,
                        win32Resources: win32resStream,
                        manifestResources: resources,
                        options: options);
                }
                else
                {
                    Logger.TraceWarning("PDB generation is not supported on this platform");
                    emitResult = CompilationContext.Compilation.Emit(
                        assemblyStream,
                        xmlDocumentationStream: xmlDocStream,
                        manifestResources: resources,
                        win32Resources: win32resStream);
                }

                sw.Stop();

                Logger.TraceInformation("[{0}]: Emitted {1} in {2}ms", GetType().Name, Name, sw.ElapsedMilliseconds);

                var afterCompileContext = new AfterCompileContext(CompilationContext, emitResult.Diagnostics)
                {
                    AssemblyStream = assemblyStream,
                    SymbolStream = pdbStream,
                    XmlDocStream = xmlDocStream
                };

                foreach (var m in CompilationContext.Modules)
                {
                    m.AfterCompile(afterCompileContext);
                }

                if (!emitResult.Success ||
                    afterCompileContext.Diagnostics.Any(RoslynDiagnosticUtilities.IsError))
                {
                    return CreateDiagnosticResult(emitResult.Success, afterCompileContext.Diagnostics);
                }

                // Ensure there's an output directory
                Directory.CreateDirectory(outputPath);

                if (afterCompileContext.AssemblyStream != null)
                {
                    afterCompileContext.AssemblyStream.Position = 0;

                    using (var assemblyFileStream = File.Create(assemblyPath))
                    {
                        afterCompileContext.AssemblyStream.CopyTo(assemblyFileStream);
                    }
                }

                if (afterCompileContext.XmlDocStream != null)
                {
                    afterCompileContext.XmlDocStream.Position = 0;
                    using (var xmlDocFileStream = File.Create(xmlDocPath))
                    {
                        afterCompileContext.XmlDocStream.CopyTo(xmlDocFileStream);
                    }
                }

                if (_supportsPdbGeneration.Value)
                {
                    if (afterCompileContext.SymbolStream != null)
                    {
                        afterCompileContext.SymbolStream.Position = 0;

                        using (var pdbFileStream = File.Create(pdbPath))
                        {
                            afterCompileContext.SymbolStream.CopyTo(pdbFileStream);
                        }
                    }
                }

                return CreateDiagnosticResult(emitResult.Success, afterCompileContext.Diagnostics);
            }
        }
예제 #29
0
        /// <summary>
        /// Parses a command line.
        /// </summary>
        /// <param name="args">A collection of strings representing the command line arguments.</param>
        /// <param name="baseDirectory">The base directory used for qualifying file locations.</param>
        /// <param name="sdkDirectory">The directory to search for mscorlib.</param>
        /// <param name="additionalReferenceDirectories">A string representing additional reference paths.</param>
        /// <returns>a commandlinearguments object representing the parsed command line.</returns>
        public new CSharpCommandLineArguments Parse(IEnumerable<string> args, string baseDirectory, string sdkDirectory, string additionalReferenceDirectories = null)
        {
            List<Diagnostic> diagnostics = new List<Diagnostic>();
            List<string> flattenedArgs = new List<string>();
            List<string> scriptArgs = IsInteractive ? new List<string>() : null;
            FlattenArgs(args, diagnostics, flattenedArgs, scriptArgs, baseDirectory);

            string appConfigPath = null;
            bool displayLogo = true;
            bool displayHelp = false;
            bool optimize = false;
            bool checkOverflow = false;
            bool allowUnsafe = false;
            bool concurrentBuild = true;
            bool emitPdb = false;
            string pdbPath = null;
            bool noStdLib = false;
            string outputDirectory = baseDirectory;
            string outputFileName = null;
            string documentationPath = null;
            string errorLogPath = null;
            bool parseDocumentationComments = false; //Don't just null check documentationFileName because we want to do this even if the file name is invalid.
            bool utf8output = false;
            OutputKind outputKind = OutputKind.ConsoleApplication;
            SubsystemVersion subsystemVersion = SubsystemVersion.None;
            LanguageVersion languageVersion = CSharpParseOptions.Default.LanguageVersion;
            string mainTypeName = null;
            string win32ManifestFile = null;
            string win32ResourceFile = null;
            string win32IconFile = null;
            bool noWin32Manifest = false;
            Platform platform = Platform.AnyCpu;
            ulong baseAddress = 0;
            int fileAlignment = 0;
            bool? delaySignSetting = null;
            string keyFileSetting = null;
            string keyContainerSetting = null;
            List<ResourceDescription> managedResources = new List<ResourceDescription>();
            List<CommandLineSourceFile> sourceFiles = new List<CommandLineSourceFile>();
            List<CommandLineSourceFile> additionalFiles = new List<CommandLineSourceFile>();
            bool sourceFilesSpecified = false;
            bool resourcesOrModulesSpecified = false;
            Encoding codepage = null;
            var checksumAlgorithm = SourceHashAlgorithm.Sha1;
            var defines = ArrayBuilder<string>.GetInstance();
            List<CommandLineReference> metadataReferences = new List<CommandLineReference>();
            List<CommandLineAnalyzerReference> analyzers = new List<CommandLineAnalyzerReference>();
            List<string> libPaths = new List<string>();
            List<string> keyFileSearchPaths = new List<string>();
            List<string> usings = new List<string>();
            var generalDiagnosticOption = ReportDiagnostic.Default;
            var diagnosticOptions = new Dictionary<string, ReportDiagnostic>();
            var noWarns = new Dictionary<string, ReportDiagnostic>();
            var warnAsErrors = new Dictionary<string, ReportDiagnostic>();
            int warningLevel = 4;
            bool highEntropyVA = false;
            bool printFullPaths = false;
            string moduleAssemblyName = null;
            string moduleName = null;
            List<string> features = new List<string>();
            string runtimeMetadataVersion = null;
            bool errorEndLocation = false;
            bool reportAnalyzer = false;
            CultureInfo preferredUILang = null;
            string touchedFilesPath = null;
            var sqmSessionGuid = Guid.Empty;

            // Process ruleset files first so that diagnostic severity settings specified on the command line via
            // /nowarn and /warnaserror can override diagnostic severity settings specified in the ruleset file.
            if (!IsInteractive)
            {
                foreach (string arg in flattenedArgs)
                {
                    string name, value;
                    if (TryParseOption(arg, out name, out value) && (name == "ruleset"))
                    {
                        var unquoted = RemoveAllQuotes(value);

                        if (string.IsNullOrEmpty(unquoted))
                        {
                            AddDiagnostic(diagnostics, ErrorCode.ERR_SwitchNeedsString, "<text>", name);
                        }
                        else
                        {
                            generalDiagnosticOption = GetDiagnosticOptionsFromRulesetFile(diagnosticOptions, diagnostics, unquoted, baseDirectory);
                        }
                    }
                }
            }

            foreach (string arg in flattenedArgs)
            {
                Debug.Assert(!arg.StartsWith("@", StringComparison.Ordinal));

                string name, value;
                if (!TryParseOption(arg, out name, out value))
                {
                    sourceFiles.AddRange(ParseFileArgument(arg, baseDirectory, diagnostics));
                    sourceFilesSpecified = true;
                    continue;
                }

                switch (name)
                {
                    case "?":
                    case "help":
                        displayHelp = true;
                        continue;

                    case "r":
                    case "reference":
                        metadataReferences.AddRange(ParseAssemblyReferences(arg, value, diagnostics, embedInteropTypes: false));
                        continue;

                    case "a":
                    case "analyzer":
                        analyzers.AddRange(ParseAnalyzers(arg, value, diagnostics));
                        continue;

                    case "d":
                    case "define":
                        if (string.IsNullOrEmpty(value))
                        {
                            AddDiagnostic(diagnostics, ErrorCode.ERR_SwitchNeedsString, "<text>", arg);
                            continue;
                        }

                        IEnumerable<Diagnostic> defineDiagnostics;
                        defines.AddRange(ParseConditionalCompilationSymbols(value, out defineDiagnostics));
                        diagnostics.AddRange(defineDiagnostics);
                        continue;

                    case "codepage":
                        if (value == null)
                        {
                            AddDiagnostic(diagnostics, ErrorCode.ERR_SwitchNeedsString, "<text>", name);
                            continue;
                        }

                        var encoding = TryParseEncodingName(value);
                        if (encoding == null)
                        {
                            AddDiagnostic(diagnostics, ErrorCode.FTL_BadCodepage, value);
                            continue;
                        }

                        codepage = encoding;
                        continue;

                    case "checksumalgorithm":
                        if (string.IsNullOrEmpty(value))
                        {
                            AddDiagnostic(diagnostics, ErrorCode.ERR_SwitchNeedsString, "<text>", name);
                            continue;
                        }

                        var newChecksumAlgorithm = TryParseHashAlgorithmName(value);
                        if (newChecksumAlgorithm == SourceHashAlgorithm.None)
                        {
                            AddDiagnostic(diagnostics, ErrorCode.FTL_BadChecksumAlgorithm, value);
                            continue;
                        }

                        checksumAlgorithm = newChecksumAlgorithm;
                        continue;

                    case "checked":
                    case "checked+":
                        if (value != null)
                        {
                            break;
                        }

                        checkOverflow = true;
                        continue;

                    case "checked-":
                        if (value != null)
                            break;

                        checkOverflow = false;
                        continue;

                    case "features":
                        if (value == null)
                        {
                            features.Clear();
                        }
                        else
                        {
                            features.Add(value);
                        }
                        continue;

                    case "noconfig":
                        // It is already handled (see CommonCommandLineCompiler.cs).
                        continue;

                    case "sqmsessionguid":
                        if (value == null)
                        {
                            AddDiagnostic(diagnostics, ErrorCode.ERR_MissingGuidForOption, "<text>", name);
                        }
                        else
                        {
                            if (!Guid.TryParse(value, out sqmSessionGuid))
                            {
                                AddDiagnostic(diagnostics, ErrorCode.ERR_InvalidFormatForGuidForOption, value, name);
                            }
                        }
                        continue;

                    case "preferreduilang":
                        if (string.IsNullOrEmpty(value))
                        {
                            AddDiagnostic(diagnostics, ErrorCode.ERR_SwitchNeedsString, "<text>", arg);
                            continue;
                        }

                        try
                        {
                            preferredUILang = new CultureInfo(value);
                            if (CorLightup.Desktop.IsUserCustomCulture(preferredUILang) ?? false)
                            {
                                // Do not use user custom cultures.
                                preferredUILang = null;
                            }
                        }
                        catch (CultureNotFoundException)
                        {
                        }

                        if (preferredUILang == null)
                        {
                            AddDiagnostic(diagnostics, ErrorCode.WRN_BadUILang, value);
                        }

                        continue;

#if DEBUG
                    case "attachdebugger":
                        Debugger.Launch();
                        continue;
#endif
                }

                if (IsInteractive)
                {
                    switch (name)
                    {
                        // interactive:
                        case "rp":
                        case "referencepath":
                            // TODO: should it really go to libPaths?
                            ParseAndResolveReferencePaths(name, value, baseDirectory, libPaths, MessageID.IDS_REFERENCEPATH_OPTION, diagnostics);
                            continue;

                        case "u":
                        case "using":
                            usings.AddRange(ParseUsings(arg, value, diagnostics));
                            continue;
                    }
                }
                else
                {
                    switch (name)
                    {
                        case "out":
                            if (string.IsNullOrWhiteSpace(value))
                            {
                                AddDiagnostic(diagnostics, ErrorCode.ERR_NoFileSpec, arg);
                            }
                            else
                            {
                                ParseOutputFile(value, diagnostics, baseDirectory, out outputFileName, out outputDirectory);
                            }

                            continue;

                        case "t":
                        case "target":
                            if (value == null)
                            {
                                break; // force 'unrecognized option'
                            }

                            if (string.IsNullOrEmpty(value))
                            {
                                AddDiagnostic(diagnostics, ErrorCode.FTL_InvalidTarget);
                            }
                            else
                            {
                                outputKind = ParseTarget(value, diagnostics);
                            }

                            continue;

                        case "moduleassemblyname":
                            value = value != null ? value.Unquote() : null;

                            if (string.IsNullOrEmpty(value))
                            {
                                AddDiagnostic(diagnostics, ErrorCode.ERR_SwitchNeedsString, "<text>", arg);
                            }
                            else if (!MetadataHelpers.IsValidAssemblyOrModuleName(value))
                            {
                                // Dev11 C# doesn't check the name (VB does)
                                AddDiagnostic(diagnostics, ErrorCode.ERR_InvalidAssemblyName, "<text>", arg);
                            }
                            else
                            {
                                moduleAssemblyName = value;
                            }

                            continue;

                        case "modulename":
                            var unquotedModuleName = RemoveAllQuotes(value);
                            if (string.IsNullOrEmpty(unquotedModuleName))
                            {
                                AddDiagnostic(diagnostics, ErrorCode.ERR_SwitchNeedsString, MessageID.IDS_Text.Localize(), "modulename");
                                continue;
                            }
                            else
                            {
                                moduleName = unquotedModuleName;
                            }

                            continue;

                        case "platform":
                            if (string.IsNullOrEmpty(value))
                            {
                                AddDiagnostic(diagnostics, ErrorCode.ERR_SwitchNeedsString, "<string>", arg);
                            }
                            else
                            {
                                platform = ParsePlatform(value, diagnostics);
                            }
                            continue;

                        case "recurse":
                            if (value == null)
                            {
                                break; // force 'unrecognized option'
                            }
                            else if (string.IsNullOrEmpty(value))
                            {
                                AddDiagnostic(diagnostics, ErrorCode.ERR_NoFileSpec, arg);
                            }
                            else
                            {
                                int before = sourceFiles.Count;
                                sourceFiles.AddRange(ParseRecurseArgument(value, baseDirectory, diagnostics));
                                if (sourceFiles.Count > before)
                                {
                                    sourceFilesSpecified = true;
                                }
                            }
                            continue;

                        case "doc":
                            parseDocumentationComments = true;
                            if (string.IsNullOrEmpty(value))
                            {
                                AddDiagnostic(diagnostics, ErrorCode.ERR_SwitchNeedsString, MessageID.IDS_Text.Localize(), arg);
                                continue;
                            }
                            string unquoted = RemoveAllQuotes(value);
                            if (string.IsNullOrEmpty(unquoted))
                            {
                                // CONSIDER: This diagnostic exactly matches dev11, but it would be simpler (and more consistent with /out)
                                // if we just let the next case handle /doc:"".
                                AddDiagnostic(diagnostics, ErrorCode.ERR_SwitchNeedsString, MessageID.IDS_Text.Localize(), "/doc:"); // Different argument.
                            }
                            else
                            {
                                documentationPath = ParseGenericPathToFile(unquoted, diagnostics, baseDirectory);
                            }
                            continue;

                        case "addmodule":
                            if (value == null)
                            {
                                AddDiagnostic(diagnostics, ErrorCode.ERR_SwitchNeedsString, MessageID.IDS_Text.Localize(), "/addmodule:");
                            }
                            else if (string.IsNullOrEmpty(value))
                            {
                                AddDiagnostic(diagnostics, ErrorCode.ERR_NoFileSpec, arg);
                            }
                            else
                            {
                                // NOTE(tomat): Dev10 used to report CS1541: ERR_CantIncludeDirectory if the path was a directory.
                                // Since we now support /referencePaths option we would need to search them to see if the resolved path is a directory.
                                // An error will be reported by the assembly manager anyways.
                                metadataReferences.AddRange(ParseSeparatedPaths(value).Select(path => new CommandLineReference(path, MetadataReferenceProperties.Module)));
                                resourcesOrModulesSpecified = true;
                            }
                            continue;

                        case "l":
                        case "link":
                            metadataReferences.AddRange(ParseAssemblyReferences(arg, value, diagnostics, embedInteropTypes: true));
                            continue;

                        case "win32res":
                            win32ResourceFile = GetWin32Setting(arg, value, diagnostics);
                            continue;

                        case "win32icon":
                            win32IconFile = GetWin32Setting(arg, value, diagnostics);
                            continue;

                        case "win32manifest":
                            win32ManifestFile = GetWin32Setting(arg, value, diagnostics);
                            noWin32Manifest = false;
                            continue;

                        case "nowin32manifest":
                            noWin32Manifest = true;
                            win32ManifestFile = null;
                            continue;

                        case "res":
                        case "resource":
                            if (value == null)
                            {
                                break; // Dev11 reports unrecognized option
                            }

                            var embeddedResource = ParseResourceDescription(arg, value, baseDirectory, diagnostics, embedded: true);
                            if (embeddedResource != null)
                            {
                                managedResources.Add(embeddedResource);
                                resourcesOrModulesSpecified = true;
                            }

                            continue;

                        case "linkres":
                        case "linkresource":
                            if (value == null)
                            {
                                break; // Dev11 reports unrecognized option
                            }

                            var linkedResource = ParseResourceDescription(arg, value, baseDirectory, diagnostics, embedded: false);
                            if (linkedResource != null)
                            {
                                managedResources.Add(linkedResource);
                                resourcesOrModulesSpecified = true;
                            }

                            continue;

                        case "debug":
                            emitPdb = true;

                            // unused, parsed for backward compat only
                            if (value != null)
                            {
                                if (value.IsEmpty())
                                {
                                    AddDiagnostic(diagnostics, ErrorCode.ERR_SwitchNeedsString, MessageID.IDS_Text.Localize(), name);
                                }
                                else if (!string.Equals(value, "full", StringComparison.OrdinalIgnoreCase) &&
                                         !string.Equals(value, "pdbonly", StringComparison.OrdinalIgnoreCase))
                                {
                                    AddDiagnostic(diagnostics, ErrorCode.ERR_BadDebugType, value);
                                }
                            }
                            continue;

                        case "debug+":
                            //guard against "debug+:xx"
                            if (value != null)
                                break;

                            emitPdb = true;
                            continue;

                        case "debug-":
                            if (value != null)
                                break;

                            emitPdb = false;
                            continue;

                        case "o":
                        case "optimize":
                        case "o+":
                        case "optimize+":
                            if (value != null)
                                break;

                            optimize = true;
                            continue;

                        case "o-":
                        case "optimize-":
                            if (value != null)
                                break;

                            optimize = false;
                            continue;

                        case "p":
                        case "parallel":
                        case "p+":
                        case "parallel+":
                            if (value != null)
                                break;

                            concurrentBuild = true;
                            continue;

                        case "p-":
                        case "parallel-":
                            if (value != null)
                                break;

                            concurrentBuild = false;
                            continue;

                        case "warnaserror":
                        case "warnaserror+":
                            if (value == null)
                            {
                                generalDiagnosticOption = ReportDiagnostic.Error;

                                // Reset specific warnaserror options (since last /warnaserror flag on the command line always wins),
                                // and bump warnings to errors.
                                warnAsErrors.Clear();
                                foreach (var key in diagnosticOptions.Keys)
                                {
                                    if (diagnosticOptions[key] == ReportDiagnostic.Warn)
                                    {
                                        warnAsErrors[key] = ReportDiagnostic.Error;
                                    }
                                }

                                continue;
                            }

                            if (string.IsNullOrEmpty(value))
                            {
                                AddDiagnostic(diagnostics, ErrorCode.ERR_SwitchNeedsNumber, name);
                            }
                            else
                            {
                                AddWarnings(warnAsErrors, ReportDiagnostic.Error, ParseWarnings(value));
                            }
                            continue;

                        case "warnaserror-":
                            if (value == null)
                            {
                                generalDiagnosticOption = ReportDiagnostic.Default;

                                // Clear specific warnaserror options (since last /warnaserror flag on the command line always wins).
                                warnAsErrors.Clear();

                                continue;
                            }

                            if (string.IsNullOrEmpty(value))
                            {
                                AddDiagnostic(diagnostics, ErrorCode.ERR_SwitchNeedsNumber, name);
                            }
                            else
                            {
                                foreach (var id in ParseWarnings(value))
                                {
                                    ReportDiagnostic ruleSetValue;
                                    if (diagnosticOptions.TryGetValue(id, out ruleSetValue))
                                    {
                                        warnAsErrors[id] = ruleSetValue;
                                    }
                                    else
                                    {
                                        warnAsErrors[id] = ReportDiagnostic.Default;
                                    }
                                }
                            }
                            continue;

                        case "w":
                        case "warn":
                            if (value == null)
                            {
                                AddDiagnostic(diagnostics, ErrorCode.ERR_SwitchNeedsNumber, name);
                                continue;
                            }

                            int newWarningLevel;
                            if (string.IsNullOrEmpty(value) ||
                                !int.TryParse(value, NumberStyles.Integer, CultureInfo.InvariantCulture, out newWarningLevel))
                            {
                                AddDiagnostic(diagnostics, ErrorCode.ERR_SwitchNeedsNumber, name);
                            }
                            else if (newWarningLevel < 0 || newWarningLevel > 4)
                            {
                                AddDiagnostic(diagnostics, ErrorCode.ERR_BadWarningLevel, name);
                            }
                            else
                            {
                                warningLevel = newWarningLevel;
                            }
                            continue;

                        case "nowarn":
                            if (value == null)
                            {
                                AddDiagnostic(diagnostics, ErrorCode.ERR_SwitchNeedsNumber, name);
                                continue;
                            }

                            if (string.IsNullOrEmpty(value))
                            {
                                AddDiagnostic(diagnostics, ErrorCode.ERR_SwitchNeedsNumber, name);
                            }
                            else
                            {
                                AddWarnings(noWarns, ReportDiagnostic.Suppress, ParseWarnings(value));
                            }
                            continue;

                        case "unsafe":
                        case "unsafe+":
                            if (value != null)
                                break;

                            allowUnsafe = true;
                            continue;

                        case "unsafe-":
                            if (value != null)
                                break;

                            allowUnsafe = false;
                            continue;

                        case "langversion":
                            if (string.IsNullOrEmpty(value))
                            {
                                AddDiagnostic(diagnostics, ErrorCode.ERR_SwitchNeedsString, MessageID.IDS_Text.Localize(), "/langversion:");
                            }
                            else if (!TryParseLanguageVersion(value, CSharpParseOptions.Default.LanguageVersion, out languageVersion))
                            {
                                AddDiagnostic(diagnostics, ErrorCode.ERR_BadCompatMode, value);
                            }
                            continue;

                        case "delaysign":
                        case "delaysign+":
                            if (value != null)
                            {
                                break;
                            }

                            delaySignSetting = true;
                            continue;

                        case "delaysign-":
                            if (value != null)
                            {
                                break;
                            }

                            delaySignSetting = false;
                            continue;

                        case "keyfile":
                            if (string.IsNullOrEmpty(value))
                            {
                                AddDiagnostic(diagnostics, ErrorCode.ERR_NoFileSpec, "keyfile");
                            }
                            else
                            {
                                keyFileSetting = RemoveAllQuotes(value);
                            }
                            // NOTE: Dev11/VB also clears "keycontainer", see also:
                            //
                            // MSDN: In case both /keyfile and /keycontainer are specified (either by command line option or by 
                            // MSDN: custom attribute) in the same compilation, the compiler will first try the key container. 
                            // MSDN: If that succeeds, then the assembly is signed with the information in the key container. 
                            // MSDN: If the compiler does not find the key container, it will try the file specified with /keyfile. 
                            // MSDN: If that succeeds, the assembly is signed with the information in the key file and the key 
                            // MSDN: information will be installed in the key container (similar to sn -i) so that on the next 
                            // MSDN: compilation, the key container will be valid.
                            continue;

                        case "keycontainer":
                            if (string.IsNullOrEmpty(value))
                            {
                                AddDiagnostic(diagnostics, ErrorCode.ERR_SwitchNeedsString, MessageID.IDS_Text.Localize(), "keycontainer");
                            }
                            else
                            {
                                keyContainerSetting = value;
                            }
                            // NOTE: Dev11/VB also clears "keyfile", see also:
                            //
                            // MSDN: In case both /keyfile and /keycontainer are specified (either by command line option or by 
                            // MSDN: custom attribute) in the same compilation, the compiler will first try the key container. 
                            // MSDN: If that succeeds, then the assembly is signed with the information in the key container. 
                            // MSDN: If the compiler does not find the key container, it will try the file specified with /keyfile. 
                            // MSDN: If that succeeds, the assembly is signed with the information in the key file and the key 
                            // MSDN: information will be installed in the key container (similar to sn -i) so that on the next 
                            // MSDN: compilation, the key container will be valid.
                            continue;

                        case "highentropyva":
                        case "highentropyva+":
                            if (value != null)
                                break;

                            highEntropyVA = true;
                            continue;

                        case "highentropyva-":
                            if (value != null)
                                break;

                            highEntropyVA = false;
                            continue;

                        case "nologo":
                            displayLogo = false;
                            continue;

                        case "baseaddress":
                            ulong newBaseAddress;
                            if (string.IsNullOrEmpty(value) || !TryParseUInt64(value, out newBaseAddress))
                            {
                                if (string.IsNullOrEmpty(value))
                                {
                                    AddDiagnostic(diagnostics, ErrorCode.ERR_SwitchNeedsNumber, name);
                                }
                                else
                                {
                                    AddDiagnostic(diagnostics, ErrorCode.ERR_BadBaseNumber, value);
                                }
                            }
                            else
                            {
                                baseAddress = newBaseAddress;
                            }

                            continue;

                        case "subsystemversion":
                            if (string.IsNullOrEmpty(value))
                            {
                                AddDiagnostic(diagnostics, ErrorCode.ERR_SwitchNeedsString, MessageID.IDS_Text.Localize(), "subsystemversion");
                                continue;
                            }

                            // It seems VS 2012 just silently corrects invalid values and suppresses the error message
                            SubsystemVersion version = SubsystemVersion.None;
                            if (SubsystemVersion.TryParse(value, out version))
                            {
                                subsystemVersion = version;
                            }
                            else
                            {
                                AddDiagnostic(diagnostics, ErrorCode.ERR_InvalidSubsystemVersion, value);
                            }

                            continue;

                        case "touchedfiles":
                            unquoted = RemoveAllQuotes(value);
                            if (string.IsNullOrEmpty(unquoted))
                            {
                                AddDiagnostic(diagnostics, ErrorCode.ERR_SwitchNeedsString, MessageID.IDS_Text.Localize(), "touchedfiles");
                                continue;
                            }
                            else
                            {
                                touchedFilesPath = unquoted;
                            }

                            continue;

                        case "bugreport":
                            UnimplementedSwitch(diagnostics, name);
                            continue;

                        case "utf8output":
                            if (value != null)
                                break;

                            utf8output = true;
                            continue;

                        case "m":
                        case "main":
                            // Remove any quotes for consistent behaviour as MSBuild can return quoted or 
                            // unquoted main.    
                            unquoted = RemoveAllQuotes(value);
                            if (string.IsNullOrEmpty(unquoted))
                            {
                                AddDiagnostic(diagnostics, ErrorCode.ERR_SwitchNeedsString, "<text>", name);
                                continue;
                            }

                            mainTypeName = unquoted;
                            continue;

                        case "fullpaths":
                            if (value != null)
                                break;

                            printFullPaths = true;
                            continue;

                        case "filealign":
                            ushort newAlignment;
                            if (string.IsNullOrEmpty(value))
                            {
                                AddDiagnostic(diagnostics, ErrorCode.ERR_SwitchNeedsNumber, name);
                            }
                            else if (!TryParseUInt16(value, out newAlignment))
                            {
                                AddDiagnostic(diagnostics, ErrorCode.ERR_InvalidFileAlignment, value);
                            }
                            else if (!CompilationOptions.IsValidFileAlignment(newAlignment))
                            {
                                AddDiagnostic(diagnostics, ErrorCode.ERR_InvalidFileAlignment, value);
                            }
                            else
                            {
                                fileAlignment = newAlignment;
                            }
                            continue;

                        case "pdb":
                            if (string.IsNullOrEmpty(value))
                            {
                                AddDiagnostic(diagnostics, ErrorCode.ERR_NoFileSpec, arg);
                            }
                            else
                            {
                                pdbPath = ParsePdbPath(value, diagnostics, baseDirectory);
                            }
                            continue;

                        case "errorendlocation":
                            errorEndLocation = true;
                            continue;

                        case "reportanalyzer":
                            reportAnalyzer = true;
                            continue;

                        case "nostdlib":
                        case "nostdlib+":
                            if (value != null)
                                break;

                            noStdLib = true;
                            continue;

                        case "lib":
                            ParseAndResolveReferencePaths(name, value, baseDirectory, libPaths, MessageID.IDS_LIB_OPTION, diagnostics);
                            continue;

                        case "nostdlib-":
                            if (value != null)
                                break;

                            noStdLib = false;
                            continue;

                        case "errorreport":
                            continue;

                        case "errorlog":
                            unquoted = RemoveAllQuotes(value);
                            if (string.IsNullOrEmpty(unquoted))
                            {
                                AddDiagnostic(diagnostics, ErrorCode.ERR_SwitchNeedsString, ":<file>", RemoveAllQuotes(arg));
                            }
                            else
                            {
                                errorLogPath = ParseGenericPathToFile(unquoted, diagnostics, baseDirectory);
                            }
                            continue;

                        case "appconfig":
                            unquoted = RemoveAllQuotes(value);
                            if (string.IsNullOrEmpty(unquoted))
                            {
                                AddDiagnostic(diagnostics, ErrorCode.ERR_SwitchNeedsString, ":<text>", RemoveAllQuotes(arg));
                            }
                            else
                            {
                                appConfigPath = ParseGenericPathToFile(unquoted, diagnostics, baseDirectory);
                            }
                            continue;

                        case "runtimemetadataversion":
                            unquoted = RemoveAllQuotes(value);
                            if (string.IsNullOrEmpty(unquoted))
                            {
                                AddDiagnostic(diagnostics, ErrorCode.ERR_SwitchNeedsString, "<text>", name);
                                continue;
                            }

                            runtimeMetadataVersion = unquoted;
                            continue;

                        case "ruleset":
                            // The ruleset arg has already been processed in a separate pass above.
                            continue;

                        case "additionalfile":
                            if (string.IsNullOrEmpty(value))
                            {
                                AddDiagnostic(diagnostics, ErrorCode.ERR_SwitchNeedsString, "<file list>", name);
                                continue;
                            }

                            additionalFiles.AddRange(ParseAdditionalFileArgument(value, baseDirectory, diagnostics));
                            continue;
                    }
                }

                AddDiagnostic(diagnostics, ErrorCode.ERR_BadSwitch, arg);
            }

            foreach (var o in warnAsErrors)
            {
                diagnosticOptions[o.Key] = o.Value;
            }

            // Specific nowarn options always override specific warnaserror options.
            foreach (var o in noWarns)
            {
                diagnosticOptions[o.Key] = o.Value;
            }

            if (!IsInteractive && !sourceFilesSpecified && (outputKind.IsNetModule() || !resourcesOrModulesSpecified))
            {
                AddDiagnostic(diagnostics, diagnosticOptions, ErrorCode.WRN_NoSources);
            }

            if (!noStdLib)
            {
                metadataReferences.Insert(0, new CommandLineReference(Path.Combine(sdkDirectory, "mscorlib.dll"), MetadataReferenceProperties.Assembly));
            }

            if (!platform.Requires64Bit())
            {
                if (baseAddress > uint.MaxValue - 0x8000)
                {
                    AddDiagnostic(diagnostics, ErrorCode.ERR_BadBaseNumber, string.Format("0x{0:X}", baseAddress));
                    baseAddress = 0;
                }
            }

            // add additional reference paths if specified
            if (!string.IsNullOrWhiteSpace(additionalReferenceDirectories))
            {
                ParseAndResolveReferencePaths(null, additionalReferenceDirectories, baseDirectory, libPaths, MessageID.IDS_LIB_ENV, diagnostics);
            }

            ImmutableArray<string> referencePaths = BuildSearchPaths(sdkDirectory, libPaths);

            ValidateWin32Settings(win32ResourceFile, win32IconFile, win32ManifestFile, outputKind, diagnostics);

            // Dev11 searches for the key file in the current directory and assembly output directory.
            // We always look to base directory and then examine the search paths.
            keyFileSearchPaths.Add(baseDirectory);
            if (baseDirectory != outputDirectory)
            {
                keyFileSearchPaths.Add(outputDirectory);
            }

            if (!emitPdb)
            {
                if (pdbPath != null)
                {
                    // Can't give a PDB file name and turn off debug information
                    AddDiagnostic(diagnostics, ErrorCode.ERR_MissingDebugSwitch);
                }
            }

            string compilationName;
            GetCompilationAndModuleNames(diagnostics, outputKind, sourceFiles, sourceFilesSpecified, moduleAssemblyName, ref outputFileName, ref moduleName, out compilationName);

            var parseOptions = new CSharpParseOptions
            (
                languageVersion: languageVersion,
                preprocessorSymbols: defines.ToImmutableAndFree(),
                documentationMode: parseDocumentationComments ? DocumentationMode.Diagnose : DocumentationMode.None,
                kind: SourceCodeKind.Regular,
                features: CompilerOptionParseUtilities.ParseFeatures(features)
            );

            var scriptParseOptions = parseOptions.WithKind(SourceCodeKind.Script);

            var options = new CSharpCompilationOptions
            (
                outputKind: outputKind,
                moduleName: moduleName,
                mainTypeName: mainTypeName,
                scriptClassName: WellKnownMemberNames.DefaultScriptClassName,
                usings: usings,
                optimizationLevel: optimize ? OptimizationLevel.Release : OptimizationLevel.Debug,
                checkOverflow: checkOverflow,
                allowUnsafe: allowUnsafe,
                concurrentBuild: concurrentBuild,
                cryptoKeyContainer: keyContainerSetting,
                cryptoKeyFile: keyFileSetting,
                delaySign: delaySignSetting,
                platform: platform,
                generalDiagnosticOption: generalDiagnosticOption,
                warningLevel: warningLevel,
                specificDiagnosticOptions: diagnosticOptions
            );

            var emitOptions = new EmitOptions
            (
                metadataOnly: false,
                debugInformationFormat: DebugInformationFormat.Pdb,
                pdbFilePath: null, // to be determined later
                outputNameOverride: null, // to be determined later
                baseAddress: baseAddress,
                highEntropyVirtualAddressSpace: highEntropyVA,
                fileAlignment: fileAlignment,
                subsystemVersion: subsystemVersion,
                runtimeMetadataVersion: runtimeMetadataVersion
            );

            // add option incompatibility errors if any
            diagnostics.AddRange(options.Errors);

            return new CSharpCommandLineArguments
            {
                IsInteractive = IsInteractive,
                BaseDirectory = baseDirectory,
                Errors = diagnostics.AsImmutable(),
                Utf8Output = utf8output,
                CompilationName = compilationName,
                OutputFileName = outputFileName,
                PdbPath = pdbPath,
                EmitPdb = emitPdb,
                OutputDirectory = outputDirectory,
                DocumentationPath = documentationPath,
                ErrorLogPath = errorLogPath,
                AppConfigPath = appConfigPath,
                SourceFiles = sourceFiles.AsImmutable(),
                Encoding = codepage,
                ChecksumAlgorithm = checksumAlgorithm,
                MetadataReferences = metadataReferences.AsImmutable(),
                AnalyzerReferences = analyzers.AsImmutable(),
                AdditionalFiles = additionalFiles.AsImmutable(),
                ReferencePaths = referencePaths,
                KeyFileSearchPaths = keyFileSearchPaths.AsImmutable(),
                Win32ResourceFile = win32ResourceFile,
                Win32Icon = win32IconFile,
                Win32Manifest = win32ManifestFile,
                NoWin32Manifest = noWin32Manifest,
                DisplayLogo = displayLogo,
                DisplayHelp = displayHelp,
                ManifestResources = managedResources.AsImmutable(),
                CompilationOptions = options,
                ParseOptions = IsInteractive ? scriptParseOptions : parseOptions,
                EmitOptions = emitOptions,
                ScriptArguments = scriptArgs.AsImmutableOrEmpty(),
                TouchedFilesPath = touchedFilesPath,
                PrintFullPaths = printFullPaths,
                ShouldIncludeErrorEndLocation = errorEndLocation,
                PreferredUILang = preferredUILang,
                SqmSessionGuid = sqmSessionGuid,
                ReportAnalyzer = reportAnalyzer
            };
        }
예제 #30
0
        internal static EmitOutput? EmitCompilation(
            Compilation compilation,
            IEnumerable<ResourceDescription> manifestResources,
            List<ModuleData> dependencies,
            DiagnosticBag diagnostics,
            CompilationTestData testData,
            EmitOptions emitOptions
        )
        {
            // A Compilation can appear multiple times in a depnedency graph as both a Compilation and as a MetadataReference
            // value.  Iterate the Compilations eagerly so they are always emitted directly and later references can re-use 
            // the value.  This gives better, and consistent, diagostic information.
            var referencedCompilations = FindReferencedCompilations(compilation);
            var fullNameSet = new HashSet<string>(StringComparer.OrdinalIgnoreCase);

            foreach (var referencedCompilation in referencedCompilations)
            {
                var emitData = EmitCompilationCore(referencedCompilation, null, diagnostics, null, emitOptions);
                if (emitData.HasValue)
                {
                    var moduleData = new ModuleData(referencedCompilation.Assembly.Identity,
                                                    OutputKind.DynamicallyLinkedLibrary,
                                                    emitData.Value.Assembly,
                                                    pdb: default(ImmutableArray<byte>),
                                                    inMemoryModule: true);
                    fullNameSet.Add(moduleData.Id.FullName);
                    dependencies.Add(moduleData);
                }
            }

            // Now that the Compilation values have been emitted, emit the non-compilation references
            foreach (var current in (new[] { compilation }).Concat(referencedCompilations))
            {
                EmitReferences(current, fullNameSet, dependencies, diagnostics);
            }

            return EmitCompilationCore(compilation, manifestResources, diagnostics, testData, emitOptions);
        }