private ImmutableArray <TAttributeData> GetAttributes(TModuleCompilationState compilationState, TSyntaxNode syntaxNodeOpt, DiagnosticBag diagnostics) { ArrayBuilder <TAttributeData> builder = ArrayBuilder <TAttributeData> .GetInstance(); // Copy some of the attributes. // Note, when porting attributes, we are not using constructors from original symbol. // The constructors might be missing (for example, in metadata case) and doing lookup // will ensure that we report appropriate errors. foreach (TAttributeData attrData in GetCustomAttributesToEmit(compilationState)) { if (IsTargetAttribute(attrData, AttributeDescription.ParamArrayAttribute)) { if (attrData.CommonConstructorArguments.Length == 0) { builder.AddOptional(TypeManager.CreateSynthesizedAttribute(WellKnownMember.System_ParamArrayAttribute__ctor, attrData, syntaxNodeOpt, diagnostics)); } } else if (IsTargetAttribute(attrData, AttributeDescription.DateTimeConstantAttribute)) { if (attrData.CommonConstructorArguments.Length == 1) { builder.AddOptional(TypeManager.CreateSynthesizedAttribute(WellKnownMember.System_Runtime_CompilerServices_DateTimeConstantAttribute__ctor, attrData, syntaxNodeOpt, diagnostics)); } } else { int signatureIndex = TypeManager.GetTargetAttributeSignatureIndex(UnderlyingParameter, attrData, AttributeDescription.DecimalConstantAttribute); if (signatureIndex != -1) { Debug.Assert(signatureIndex == 0 || signatureIndex == 1); if (attrData.CommonConstructorArguments.Length == 5) { builder.AddOptional(TypeManager.CreateSynthesizedAttribute( signatureIndex == 0 ? WellKnownMember.System_Runtime_CompilerServices_DecimalConstantAttribute__ctor : WellKnownMember.System_Runtime_CompilerServices_DecimalConstantAttribute__ctorByteByteInt32Int32Int32, attrData, syntaxNodeOpt, diagnostics)); } } else if (IsTargetAttribute(attrData, AttributeDescription.DefaultParameterValueAttribute)) { if (attrData.CommonConstructorArguments.Length == 1) { builder.AddOptional(TypeManager.CreateSynthesizedAttribute(WellKnownMember.System_Runtime_InteropServices_DefaultParameterValueAttribute__ctor, attrData, syntaxNodeOpt, diagnostics)); } } } } return(builder.ToImmutableAndFree()); }
private BoundStatement MakeLoweredForm(BoundPatternSwitchStatement node) { var expression = _localRewriter.VisitExpression(node.Expression); var result = ArrayBuilder <BoundStatement> .GetInstance(); // if the expression is "too complex", we copy it to a temp. LocalSymbol initialTemp = null; if (expression.ConstantValue == null) { initialTemp = _factory.SynthesizedLocal(expression.Type, expression.Syntax); result.Add(_factory.Assignment(_factory.Local(initialTemp), expression)); expression = _factory.Local(initialTemp); // EnC: We need to insert a hidden sequence point to handle function remapping in case // the containing method is edited while methods invoked in the expression are being executed. if (!node.WasCompilerGenerated && _localRewriter.Instrument) { expression = _localRewriter._instrumenter.InstrumentSwitchStatementExpression(node, expression, _factory); } } // output the decision tree part LowerPatternSwitch(expression, node, result); // if the endpoint is reachable, we exit the switch if (!node.IsComplete) { result.Add(_factory.Goto(node.BreakLabel)); } // at this point the end of result is unreachable. _declaredTemps.AddOptional(initialTemp); _declaredTemps.AddRange(node.InnerLocals); // output the sections of code foreach (var section in node.SwitchSections) { // Lifetime of these locals is expanded to the entire switch body. _declaredTemps.AddRange(section.Locals); // Start with the part of the decision tree that is in scope of the section variables. // Its endpoint is not reachable (it jumps back into the decision tree code). var sectionSyntax = (SyntaxNode)section.Syntax; var sectionBuilder = _switchSections[sectionSyntax]; // Add labels corresponding to the labels of the switch section. foreach (var label in section.SwitchLabels) { sectionBuilder.Add(_factory.Label(label.Label)); } // Add the translated body of the switch section sectionBuilder.AddRange(_localRewriter.VisitList(section.Statements)); sectionBuilder.Add(_factory.Goto(node.BreakLabel)); ImmutableArray <BoundStatement> statements = sectionBuilder.ToImmutableAndFree(); if (section.Locals.IsEmpty) { result.Add(_factory.StatementList(statements)); } else { result.Add(new BoundScope(section.Syntax, section.Locals, statements)); } // at this point the end of result is unreachable. } result.Add(_factory.Label(node.BreakLabel)); BoundStatement translatedSwitch = _factory.Block(_declaredTemps.ToImmutableArray(), node.InnerLocalFunctions, result.ToImmutableAndFree()); // Only add instrumentation (such as a sequence point) if the node is not compiler-generated. if (!node.WasCompilerGenerated && _localRewriter.Instrument) { translatedSwitch = _localRewriter._instrumenter.InstrumentPatternSwitchStatement(node, translatedSwitch); } return(translatedSwitch); }
private ImmutableArray <TAttributeData> GetAttributes(TModuleCompilationState compilationState, TSyntaxNode syntaxNodeOpt, DiagnosticBag diagnostics) { ArrayBuilder <TAttributeData> builder = ArrayBuilder <TAttributeData> .GetInstance(); // Put the CompilerGenerated attribute on the NoPIA types we define so that // static analysis tools (e.g. fxcop) know that they can be skipped builder.AddOptional(TypeManager.CreateCompilerGeneratedAttribute()); // Copy some of the attributes. bool hasGuid = false; bool hasComEventInterfaceAttribute = false; // Note, when porting attributes, we are not using constructors from original symbol. // The constructors might be missing (for example, in metadata case) and doing lookup // will ensure that we report appropriate errors. foreach (TAttributeData attrData in GetCustomAttributesToEmit(compilationState)) { if (IsTargetAttribute(attrData, AttributeDescription.GuidAttribute)) { if (attrData.TryGetGuidAttributeValue(out string guidString)) { // If this type has a GuidAttribute, we should emit it. hasGuid = true; builder.AddOptional(TypeManager.CreateSynthesizedAttribute(WellKnownMember.System_Runtime_InteropServices_GuidAttribute__ctor, attrData, syntaxNodeOpt, diagnostics)); } } else if (IsTargetAttribute(attrData, AttributeDescription.ComEventInterfaceAttribute)) { if (attrData.CommonConstructorArguments.Length == 2) { hasComEventInterfaceAttribute = true; builder.AddOptional(TypeManager.CreateSynthesizedAttribute(WellKnownMember.System_Runtime_InteropServices_ComEventInterfaceAttribute__ctor, attrData, syntaxNodeOpt, diagnostics)); } } else { int signatureIndex = TypeManager.GetTargetAttributeSignatureIndex(UnderlyingNamedType, attrData, AttributeDescription.InterfaceTypeAttribute); if (signatureIndex != -1) { Debug.Assert(signatureIndex == 0 || signatureIndex == 1); if (attrData.CommonConstructorArguments.Length == 1) { builder.AddOptional(TypeManager.CreateSynthesizedAttribute(signatureIndex == 0 ? WellKnownMember.System_Runtime_InteropServices_InterfaceTypeAttribute__ctorInt16 : WellKnownMember.System_Runtime_InteropServices_InterfaceTypeAttribute__ctorComInterfaceType, attrData, syntaxNodeOpt, diagnostics)); } } else if (IsTargetAttribute(attrData, AttributeDescription.BestFitMappingAttribute)) { if (attrData.CommonConstructorArguments.Length == 1) { builder.AddOptional(TypeManager.CreateSynthesizedAttribute(WellKnownMember.System_Runtime_InteropServices_BestFitMappingAttribute__ctor, attrData, syntaxNodeOpt, diagnostics)); } } else if (IsTargetAttribute(attrData, AttributeDescription.CoClassAttribute)) { if (attrData.CommonConstructorArguments.Length == 1) { builder.AddOptional(TypeManager.CreateSynthesizedAttribute(WellKnownMember.System_Runtime_InteropServices_CoClassAttribute__ctor, attrData, syntaxNodeOpt, diagnostics)); } } else if (IsTargetAttribute(attrData, AttributeDescription.FlagsAttribute)) { if (attrData.CommonConstructorArguments.Length == 0 && UnderlyingNamedType.IsEnum) { builder.AddOptional(TypeManager.CreateSynthesizedAttribute(WellKnownMember.System_FlagsAttribute__ctor, attrData, syntaxNodeOpt, diagnostics)); } } else if (IsTargetAttribute(attrData, AttributeDescription.DefaultMemberAttribute)) { if (attrData.CommonConstructorArguments.Length == 1) { builder.AddOptional(TypeManager.CreateSynthesizedAttribute(WellKnownMember.System_Reflection_DefaultMemberAttribute__ctor, attrData, syntaxNodeOpt, diagnostics)); // Embed members matching default member name. string defaultMember = attrData.CommonConstructorArguments[0].Value as string; if (defaultMember != null) { EmbedDefaultMembers(defaultMember, syntaxNodeOpt, diagnostics); } } } else if (IsTargetAttribute(attrData, AttributeDescription.UnmanagedFunctionPointerAttribute)) { if (attrData.CommonConstructorArguments.Length == 1) { builder.AddOptional(TypeManager.CreateSynthesizedAttribute(WellKnownMember.System_Runtime_InteropServices_UnmanagedFunctionPointerAttribute__ctor, attrData, syntaxNodeOpt, diagnostics)); } } } } // We must emit a TypeIdentifier attribute which connects this local type with the canonical type. // Interfaces usually have a guid attribute, in which case the TypeIdentifier attribute we emit will // not need any additional parameters. For interfaces which lack a guid and all other types, we must // emit a TypeIdentifier that has parameters identifying the scope and name of the original type. We // will use the Assembly GUID as the scope identifier. if (IsInterface && !hasComEventInterfaceAttribute) { if (!IsComImport) { // If we have an interface not marked ComImport, but the assembly is linked, then // we need to give an error. We allow event interfaces to not have ComImport marked on them. // ERRID_NoPIAAttributeMissing2/ERR_InteropTypeMissingAttribute ReportMissingAttribute(AttributeDescription.ComImportAttribute, syntaxNodeOpt, diagnostics); } else if (!hasGuid) { // Interfaces used with No-PIA ought to have a guid attribute, or the CLR cannot do type unification. // This interface lacks a guid, so unification probably won't work. We allow event interfaces to not have a Guid. // ERRID_NoPIAAttributeMissing2/ERR_InteropTypeMissingAttribute ReportMissingAttribute(AttributeDescription.GuidAttribute, syntaxNodeOpt, diagnostics); } } // Note, this logic should match the one in RetargetingSymbolTranslator.RetargetNoPiaLocalType // when we try to predict what attributes we will emit on embedded type, which corresponds the // type we are retargeting. builder.AddOptional(CreateTypeIdentifierAttribute(hasGuid && IsInterface, syntaxNodeOpt, diagnostics)); return(builder.ToImmutableAndFree()); }