From 31d08582ea4fe2bc7e0927e45bc0488139895798 Mon Sep 17 00:00:00 2001 From: AlekseyTs Date: Tue, 17 Dec 2024 10:51:21 -0800 Subject: [PATCH 1/3] Propagate marked attributes from primary constructor parameters to backing fields. Related to #73920. --- .../Emitter/Model/MethodSymbolAdapter.cs | 2 +- .../Model/SourceAssemblySymbolAdapter.cs | 2 +- .../Portable/Emitter/Model/SymbolAdapter.cs | 6 +- .../IteratorRewriter/IteratorConstructor.cs | 2 +- .../Lowering/MethodToClassRewriter.cs | 2 +- .../StateMachineTypeSymbol.cs | 2 + .../SynthesizedStateMachineMethod.cs | 2 +- .../Lowering/SynthesizedMethodBaseSymbol.cs | 2 +- ...ymousManager.TypeOrDelegatePublicSymbol.cs | 2 + .../AnonymousType.DelegateTemplateSymbol.cs | 2 +- .../AnonymousType.FieldSymbol.cs | 2 +- .../AnonymousType.PropertyAccessorSymbol.cs | 2 +- .../AnonymousType.SynthesizedMethodBase.cs | 2 +- .../AnonymousType.TemplateSymbol.cs | 2 +- ...nymousType.TypeOrDelegateTemplateSymbol.cs | 2 + .../TypeWellKnownAttributeData.cs | 18 ++ .../Portable/Symbols/ErrorTypeSymbol.cs | 2 + .../Symbols/Metadata/PE/PEMethodSymbol.cs | 4 +- .../Symbols/Metadata/PE/PENamedTypeSymbol.cs | 20 ++ .../CSharp/Portable/Symbols/MethodSymbol.cs | 4 +- .../Portable/Symbols/NamedTypeSymbol.cs | 2 + .../Symbols/NativeIntegerTypeSymbol.cs | 2 + .../Retargeting/RetargetingNamedTypeSymbol.cs | 2 + .../FieldSymbolWithAttributesAndModifiers.cs | 2 +- .../Symbols/Source/ImplicitNamedTypeSymbol.cs | 2 + .../Symbols/Source/SourceAssemblySymbol.cs | 2 +- .../Source/SourceConstructorSymbolBase.cs | 2 +- .../Symbols/Source/SourceEventFieldSymbol.cs | 2 +- .../Symbols/Source/SourceEventSymbol.cs | 2 +- .../Symbols/Source/SourceFixedFieldSymbol.cs | 4 +- .../Source/SourceMemberContainerSymbol.cs | 2 +- .../Symbols/Source/SourceMemberFieldSymbol.cs | 2 +- .../Source/SourceMemberMethodSymbol.cs | 2 +- .../Symbols/Source/SourceModuleSymbol.cs | 2 +- .../Symbols/Source/SourceNamedTypeSymbol.cs | 15 +- .../Source/SourceOrdinaryMethodSymbolBase.cs | 2 +- .../Source/SourceParameterSymbolBase.cs | 2 +- .../Source/SourcePropertyAccessorSymbol.cs | 4 +- .../Source/SourcePropertySymbolBase.cs | 2 +- .../Source/SourceTypeParameterSymbol.cs | 2 +- .../Symbols/SubstitutedNamedTypeSymbol.cs | 2 + .../CSharp/Portable/Symbols/Symbol.cs | 6 +- ...hesizedReadOnlyListEnumeratorTypeSymbol.cs | 2 + .../SynthesizedReadOnlyListTypeSymbol.cs | 4 +- ...yConstructorParameterBackingFieldSymbol.cs | 16 ++ .../Records/SynthesizedRecordCopyCtor.cs | 2 +- ...nthesizedRecordEqualityContractProperty.cs | 4 +- .../SynthesizedRecordEqualityOperatorBase.cs | 2 +- .../SynthesizedRecordOrdinaryMethod.cs | 2 +- ...SynthesizedAccessorValueParameterSymbol.cs | 2 +- .../SynthesizedBackingFieldSymbol.cs | 2 +- .../Synthesized/SynthesizedContainer.cs | 4 +- .../SynthesizedEmbeddedAttributeSymbol.cs | 4 +- .../SynthesizedEntryPointSymbol.cs | 2 +- .../SynthesizedEnumValueFieldSymbol.cs | 2 +- .../SynthesizedEventAccessorSymbol.cs | 2 +- .../Synthesized/SynthesizedFieldSymbolBase.cs | 2 +- .../SynthesizedHotReloadExceptionSymbol.cs | 3 +- .../SynthesizedInlineArrayTypeSymbol.cs | 4 +- .../SynthesizedInstanceConstructor.cs | 2 +- .../Synthesized/SynthesizedParameterSymbol.cs | 2 +- ...hesizedPrivateImplementationDetailsType.cs | 2 + ...nthesizedSubstitutedTypeParameterSymbol.cs | 2 +- .../Symbols/Wrapped/WrappedParameterSymbol.cs | 2 +- .../Semantics/PrimaryConstructorTests.cs | 256 ++++++++++++++++++ .../Symbol/Symbols/MockNamedTypeSymbol.cs | 2 + .../Core/Portable/MetadataReader/PEModule.cs | 5 + .../Attributes/AttributeDescription.cs | 1 + .../Symbols/EENamedTypeSymbol.cs | 2 + 69 files changed, 423 insertions(+), 59 deletions(-) diff --git a/src/Compilers/CSharp/Portable/Emitter/Model/MethodSymbolAdapter.cs b/src/Compilers/CSharp/Portable/Emitter/Model/MethodSymbolAdapter.cs index 349edede8b243..5ec5fde9c5af4 100644 --- a/src/Compilers/CSharp/Portable/Emitter/Model/MethodSymbolAdapter.cs +++ b/src/Compilers/CSharp/Portable/Emitter/Model/MethodSymbolAdapter.cs @@ -510,7 +510,7 @@ bool Cci.IMethodDefinition.RequiresSecurityObject CheckDefinitionInvariant(); ImmutableArray userDefined = AdaptedMethodSymbol.GetReturnTypeAttributes(); - ArrayBuilder synthesized = null; + ArrayBuilder synthesized = null; AdaptedMethodSymbol.AddSynthesizedReturnTypeAttributes((PEModuleBuilder)context.Module, ref synthesized); // Note that callers of this method (CCI and ReflectionEmitter) have to enumerate diff --git a/src/Compilers/CSharp/Portable/Emitter/Model/SourceAssemblySymbolAdapter.cs b/src/Compilers/CSharp/Portable/Emitter/Model/SourceAssemblySymbolAdapter.cs index 66d7ad7888bef..a6e4bb2edeae3 100644 --- a/src/Compilers/CSharp/Portable/Emitter/Model/SourceAssemblySymbolAdapter.cs +++ b/src/Compilers/CSharp/Portable/Emitter/Model/SourceAssemblySymbolAdapter.cs @@ -18,7 +18,7 @@ internal IEnumerable GetCustomAttributesToEmit(PEModuleBuil CheckDefinitionInvariant(); ImmutableArray userDefined = this.GetAttributes(); - ArrayBuilder synthesized = null; + ArrayBuilder synthesized = null; this.AddSynthesizedAttributes(moduleBuilder, ref synthesized); if (emittingRefAssembly && !HasReferenceAssemblyAttribute) diff --git a/src/Compilers/CSharp/Portable/Emitter/Model/SymbolAdapter.cs b/src/Compilers/CSharp/Portable/Emitter/Model/SymbolAdapter.cs index 3f6099ccbc6b8..afd34feab5b3c 100644 --- a/src/Compilers/CSharp/Portable/Emitter/Model/SymbolAdapter.cs +++ b/src/Compilers/CSharp/Portable/Emitter/Model/SymbolAdapter.cs @@ -95,7 +95,7 @@ internal IEnumerable GetCustomAttributesToEmit(PEModuleBuil Debug.Assert(this.Kind != SymbolKind.Assembly); ImmutableArray userDefined; - ArrayBuilder synthesized = null; + ArrayBuilder synthesized = null; userDefined = this.GetAttributes(); this.AddSynthesizedAttributes(moduleBuilder, ref synthesized); @@ -110,7 +110,7 @@ internal IEnumerable GetCustomAttributesToEmit(PEModuleBuil /// internal IEnumerable GetCustomAttributesToEmit( ImmutableArray userDefined, - ArrayBuilder synthesized, + ArrayBuilder synthesized, bool isReturnType, bool emittingAssemblyAttributesInNetModule) { @@ -127,7 +127,7 @@ internal IEnumerable GetCustomAttributesToEmit( private IEnumerable GetCustomAttributesToEmitIterator( ImmutableArray userDefined, - ArrayBuilder synthesized, + ArrayBuilder synthesized, bool isReturnType, bool emittingAssemblyAttributesInNetModule) { diff --git a/src/Compilers/CSharp/Portable/Lowering/IteratorRewriter/IteratorConstructor.cs b/src/Compilers/CSharp/Portable/Lowering/IteratorRewriter/IteratorConstructor.cs index 78ed7749163e1..20a1202c90f0d 100644 --- a/src/Compilers/CSharp/Portable/Lowering/IteratorRewriter/IteratorConstructor.cs +++ b/src/Compilers/CSharp/Portable/Lowering/IteratorRewriter/IteratorConstructor.cs @@ -28,7 +28,7 @@ internal IteratorConstructor(StateMachineTypeSymbol container) SynthesizedParameterSymbol.Create(this, TypeWithAnnotations.Create(intType), 0, RefKind.None, GeneratedNames.MakeStateMachineStateFieldName())); } - internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, ref ArrayBuilder attributes) + internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, ref ArrayBuilder attributes) { base.AddSynthesizedAttributes(moduleBuilder, ref attributes); diff --git a/src/Compilers/CSharp/Portable/Lowering/MethodToClassRewriter.cs b/src/Compilers/CSharp/Portable/Lowering/MethodToClassRewriter.cs index 1f2fa70219430..de13dc92deff2 100644 --- a/src/Compilers/CSharp/Portable/Lowering/MethodToClassRewriter.cs +++ b/src/Compilers/CSharp/Portable/Lowering/MethodToClassRewriter.cs @@ -757,7 +757,7 @@ internal BaseMethodWrapperSymbol(NamedTypeSymbol containingType, MethodSymbol me AssignTypeMapAndTypeParameters(typeMap, typeParameters); } - internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, ref ArrayBuilder attributes) + internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, ref ArrayBuilder attributes) { base.AddSynthesizedAttributes(moduleBuilder, ref attributes); diff --git a/src/Compilers/CSharp/Portable/Lowering/StateMachineRewriter/StateMachineTypeSymbol.cs b/src/Compilers/CSharp/Portable/Lowering/StateMachineRewriter/StateMachineTypeSymbol.cs index 28f84d6e89cfe..1dbc00cef4295 100644 --- a/src/Compilers/CSharp/Portable/Lowering/StateMachineRewriter/StateMachineTypeSymbol.cs +++ b/src/Compilers/CSharp/Portable/Lowering/StateMachineRewriter/StateMachineTypeSymbol.cs @@ -85,5 +85,7 @@ public sealed override ImmutableArray GetAttributes() public sealed override bool AreLocalsZeroed => KickoffMethod.AreLocalsZeroed; internal override bool HasCodeAnalysisEmbeddedAttribute => false; + + internal override bool HasCompilerLoweringPreserveAttribute => false; } } diff --git a/src/Compilers/CSharp/Portable/Lowering/StateMachineRewriter/SynthesizedStateMachineMethod.cs b/src/Compilers/CSharp/Portable/Lowering/StateMachineRewriter/SynthesizedStateMachineMethod.cs index 1ee69d7210055..880f9759d86a2 100644 --- a/src/Compilers/CSharp/Portable/Lowering/StateMachineRewriter/SynthesizedStateMachineMethod.cs +++ b/src/Compilers/CSharp/Portable/Lowering/StateMachineRewriter/SynthesizedStateMachineMethod.cs @@ -118,7 +118,7 @@ public SynthesizedStateMachineDebuggerHiddenMethod( { } - internal sealed override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, ref ArrayBuilder attributes) + internal sealed override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, ref ArrayBuilder attributes) { var compilation = this.DeclaringCompilation; AddSynthesizedAttribute(ref attributes, compilation.TrySynthesizeAttribute(WellKnownMember.System_Diagnostics_DebuggerHiddenAttribute__ctor)); diff --git a/src/Compilers/CSharp/Portable/Lowering/SynthesizedMethodBaseSymbol.cs b/src/Compilers/CSharp/Portable/Lowering/SynthesizedMethodBaseSymbol.cs index 84656a69b0073..20589154af9bc 100644 --- a/src/Compilers/CSharp/Portable/Lowering/SynthesizedMethodBaseSymbol.cs +++ b/src/Compilers/CSharp/Portable/Lowering/SynthesizedMethodBaseSymbol.cs @@ -72,7 +72,7 @@ protected override void MethodChecks(BindingDiagnosticBag diagnostics) // TODO: move more functionality into here, making these symbols more lazy } - internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, ref ArrayBuilder attributes) + internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, ref ArrayBuilder attributes) { base.AddSynthesizedAttributes(moduleBuilder, ref attributes); diff --git a/src/Compilers/CSharp/Portable/Symbols/AnonymousTypes/PublicSymbols/AnonymousManager.TypeOrDelegatePublicSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/AnonymousTypes/PublicSymbols/AnonymousManager.TypeOrDelegatePublicSymbol.cs index e179edb4de88e..e2ed766e3be0e 100644 --- a/src/Compilers/CSharp/Portable/Symbols/AnonymousTypes/PublicSymbols/AnonymousManager.TypeOrDelegatePublicSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/AnonymousTypes/PublicSymbols/AnonymousManager.TypeOrDelegatePublicSymbol.cs @@ -42,6 +42,8 @@ internal sealed override IEnumerable GetFieldsToEmit() internal sealed override bool HasCodeAnalysisEmbeddedAttribute => false; + internal sealed override bool HasCompilerLoweringPreserveAttribute => false; + internal sealed override bool IsInterpolatedStringHandlerType => false; internal sealed override ImmutableArray GetEarlyAttributeDecodingMembers() diff --git a/src/Compilers/CSharp/Portable/Symbols/AnonymousTypes/SynthesizedSymbols/AnonymousType.DelegateTemplateSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/AnonymousTypes/SynthesizedSymbols/AnonymousType.DelegateTemplateSymbol.cs index b7749ddcd7867..9988175aaa0c5 100644 --- a/src/Compilers/CSharp/Portable/Symbols/AnonymousTypes/SynthesizedSymbols/AnonymousType.DelegateTemplateSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/AnonymousTypes/SynthesizedSymbols/AnonymousType.DelegateTemplateSymbol.cs @@ -243,7 +243,7 @@ private static ImmutableArray CreateMembers(MethodSymbol constructor, Me public override ImmutableArray TypeParameters { get; } - internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, ref ArrayBuilder attributes) + internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, ref ArrayBuilder attributes) { base.AddSynthesizedAttributes(moduleBuilder, ref attributes); diff --git a/src/Compilers/CSharp/Portable/Symbols/AnonymousTypes/SynthesizedSymbols/AnonymousType.FieldSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/AnonymousTypes/SynthesizedSymbols/AnonymousType.FieldSymbol.cs index 99541bb595a1d..d9bd6a604cebd 100644 --- a/src/Compilers/CSharp/Portable/Symbols/AnonymousTypes/SynthesizedSymbols/AnonymousType.FieldSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/AnonymousTypes/SynthesizedSymbols/AnonymousType.FieldSymbol.cs @@ -143,7 +143,7 @@ public override bool IsImplicitlyDeclared get { return true; } } - internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, ref ArrayBuilder attributes) + internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, ref ArrayBuilder attributes) { base.AddSynthesizedAttributes(moduleBuilder, ref attributes); diff --git a/src/Compilers/CSharp/Portable/Symbols/AnonymousTypes/SynthesizedSymbols/AnonymousType.PropertyAccessorSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/AnonymousTypes/SynthesizedSymbols/AnonymousType.PropertyAccessorSymbol.cs index afbca6b840301..a9f657366d425 100644 --- a/src/Compilers/CSharp/Portable/Symbols/AnonymousTypes/SynthesizedSymbols/AnonymousType.PropertyAccessorSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/AnonymousTypes/SynthesizedSymbols/AnonymousType.PropertyAccessorSymbol.cs @@ -83,7 +83,7 @@ internal override bool IsMetadataFinal } } - internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, ref ArrayBuilder attributes) + internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, ref ArrayBuilder attributes) { // Do not call base.AddSynthesizedAttributes. // Dev11 does not emit DebuggerHiddenAttribute in property accessors diff --git a/src/Compilers/CSharp/Portable/Symbols/AnonymousTypes/SynthesizedSymbols/AnonymousType.SynthesizedMethodBase.cs b/src/Compilers/CSharp/Portable/Symbols/AnonymousTypes/SynthesizedSymbols/AnonymousType.SynthesizedMethodBase.cs index 1e4730727af7a..425d6a2a363cd 100644 --- a/src/Compilers/CSharp/Portable/Symbols/AnonymousTypes/SynthesizedSymbols/AnonymousType.SynthesizedMethodBase.cs +++ b/src/Compilers/CSharp/Portable/Symbols/AnonymousTypes/SynthesizedSymbols/AnonymousType.SynthesizedMethodBase.cs @@ -165,7 +165,7 @@ internal sealed override bool IsMetadataNewSlot(bool ignoreInterfaceImplementati return false; } - internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, ref ArrayBuilder attributes) + internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, ref ArrayBuilder attributes) { base.AddSynthesizedAttributes(moduleBuilder, ref attributes); diff --git a/src/Compilers/CSharp/Portable/Symbols/AnonymousTypes/SynthesizedSymbols/AnonymousType.TemplateSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/AnonymousTypes/SynthesizedSymbols/AnonymousType.TemplateSymbol.cs index ce0f158b7a4a4..cf8174dac6733 100644 --- a/src/Compilers/CSharp/Portable/Symbols/AnonymousTypes/SynthesizedSymbols/AnonymousType.TemplateSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/AnonymousTypes/SynthesizedSymbols/AnonymousType.TemplateSymbol.cs @@ -157,7 +157,7 @@ public override IEnumerable MemberNames get { return _nameToSymbols.Keys; } } - internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, ref ArrayBuilder attributes) + internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, ref ArrayBuilder attributes) { base.AddSynthesizedAttributes(moduleBuilder, ref attributes); diff --git a/src/Compilers/CSharp/Portable/Symbols/AnonymousTypes/SynthesizedSymbols/AnonymousType.TypeOrDelegateTemplateSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/AnonymousTypes/SynthesizedSymbols/AnonymousType.TypeOrDelegateTemplateSymbol.cs index a0fd2af024250..9d601bda14ded 100644 --- a/src/Compilers/CSharp/Portable/Symbols/AnonymousTypes/SynthesizedSymbols/AnonymousType.TypeOrDelegateTemplateSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/AnonymousTypes/SynthesizedSymbols/AnonymousType.TypeOrDelegateTemplateSymbol.cs @@ -120,6 +120,8 @@ internal override bool GetGuidString(out string? guidString) internal sealed override bool HasCodeAnalysisEmbeddedAttribute => false; + internal sealed override bool HasCompilerLoweringPreserveAttribute => false; + internal sealed override bool IsInterpolatedStringHandlerType => false; internal sealed override ImmutableArray GetEarlyAttributeDecodingMembers() diff --git a/src/Compilers/CSharp/Portable/Symbols/Attributes/WellKnownAttributeData/TypeWellKnownAttributeData.cs b/src/Compilers/CSharp/Portable/Symbols/Attributes/WellKnownAttributeData/TypeWellKnownAttributeData.cs index 7e53e17e5e83e..7698bd8f41933 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Attributes/WellKnownAttributeData/TypeWellKnownAttributeData.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Attributes/WellKnownAttributeData/TypeWellKnownAttributeData.cs @@ -51,5 +51,23 @@ public bool HasSkipLocalsInitAttribute } } #endregion + + #region CompilerLoweringPreserveAttribute + private bool _hasCompilerLoweringPreserveAttribute; + public bool HasCompilerLoweringPreserveAttribute + { + get + { + VerifySealed(expected: true); + return _hasCompilerLoweringPreserveAttribute; + } + set + { + VerifySealed(expected: false); + _hasCompilerLoweringPreserveAttribute = value; + SetDataStored(); + } + } + #endregion } } diff --git a/src/Compilers/CSharp/Portable/Symbols/ErrorTypeSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/ErrorTypeSymbol.cs index 703f303fd2963..c6abc0310eddc 100644 --- a/src/Compilers/CSharp/Portable/Symbols/ErrorTypeSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/ErrorTypeSymbol.cs @@ -441,6 +441,8 @@ internal override bool GetGuidString(out string? guidString) internal override bool HasCodeAnalysisEmbeddedAttribute => false; + internal override bool HasCompilerLoweringPreserveAttribute => false; + internal override bool IsInterpolatedStringHandlerType => false; internal override ImmutableArray InterfacesNoUseSiteDiagnostics(ConsList? basesBeingResolved) diff --git a/src/Compilers/CSharp/Portable/Symbols/Metadata/PE/PEMethodSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Metadata/PE/PEMethodSymbol.cs index ef0db5c0a96c1..7594549773a9b 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Metadata/PE/PEMethodSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Metadata/PE/PEMethodSymbol.cs @@ -1653,12 +1653,12 @@ internal override OverriddenOrHiddenMembersResult OverriddenOrHiddenMembers } } - internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, ref ArrayBuilder attributes) + internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, ref ArrayBuilder attributes) { throw ExceptionUtilities.Unreachable(); } - internal override void AddSynthesizedReturnTypeAttributes(PEModuleBuilder moduleBuilder, ref ArrayBuilder attributes) + internal override void AddSynthesizedReturnTypeAttributes(PEModuleBuilder moduleBuilder, ref ArrayBuilder attributes) { throw ExceptionUtilities.Unreachable(); } diff --git a/src/Compilers/CSharp/Portable/Symbols/Metadata/PE/PENamedTypeSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Metadata/PE/PENamedTypeSymbol.cs index 97ccabb558fdb..60d770d5ad6b8 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Metadata/PE/PENamedTypeSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Metadata/PE/PENamedTypeSymbol.cs @@ -145,6 +145,7 @@ private sealed class UncommonProperties internal NamedTypeSymbol lazyComImportCoClassType = ErrorTypeSymbol.UnknownResultType; internal CollectionBuilderAttributeData lazyCollectionBuilderAttributeData = CollectionBuilderAttributeData.Uninitialized; internal ThreeState lazyHasEmbeddedAttribute = ThreeState.Unknown; + internal ThreeState lazyHasCompilerLoweringPreserveAttribute = ThreeState.Unknown; internal ThreeState lazyHasInterpolatedStringHandlerAttribute = ThreeState.Unknown; internal ThreeState lazyHasRequiredMembers = ThreeState.Unknown; @@ -468,6 +469,25 @@ internal override bool HasCodeAnalysisEmbeddedAttribute } } + internal override bool HasCompilerLoweringPreserveAttribute + { + get + { + var uncommon = GetUncommonProperties(); + if (uncommon == s_noUncommonProperties) + { + return false; + } + + if (!uncommon.lazyHasCompilerLoweringPreserveAttribute.HasValue()) + { + uncommon.lazyHasCompilerLoweringPreserveAttribute = ContainingPEModule.Module.HasCompilerLoweringPreserveAttribute(_handle).ToThreeState(); + } + + return uncommon.lazyHasCompilerLoweringPreserveAttribute.Value(); + } + } + internal override NamedTypeSymbol BaseTypeNoUseSiteDiagnostics { get diff --git a/src/Compilers/CSharp/Portable/Symbols/MethodSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/MethodSymbol.cs index ac078acaa6101..163e0f8ffb927 100644 --- a/src/Compilers/CSharp/Portable/Symbols/MethodSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/MethodSymbol.cs @@ -1148,7 +1148,7 @@ internal virtual bool SynthesizesLoweredBoundBody /// /// Build and add synthesized return type attributes for this method symbol. /// - internal virtual void AddSynthesizedReturnTypeAttributes(PEModuleBuilder moduleBuilder, ref ArrayBuilder attributes) + internal virtual void AddSynthesizedReturnTypeAttributes(PEModuleBuilder moduleBuilder, ref ArrayBuilder attributes) { if (this.ReturnsByRefReadonly) { @@ -1266,7 +1266,7 @@ public override int GetHashCode() } #nullable enable - protected static void AddRequiredMembersMarkerAttributes(ref ArrayBuilder attributes, MethodSymbol methodToAttribute) + protected static void AddRequiredMembersMarkerAttributes(ref ArrayBuilder attributes, MethodSymbol methodToAttribute) { if (methodToAttribute.ShouldCheckRequiredMembers() && methodToAttribute.ContainingType.HasAnyRequiredMembers) { diff --git a/src/Compilers/CSharp/Portable/Symbols/NamedTypeSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/NamedTypeSymbol.cs index 0a717650ddb41..86bffaf57f12a 100644 --- a/src/Compilers/CSharp/Portable/Symbols/NamedTypeSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/NamedTypeSymbol.cs @@ -1149,6 +1149,8 @@ internal NamedTypeSymbol GetUnboundGenericTypeOrSelf() internal abstract bool HasAsyncMethodBuilderAttribute(out TypeSymbol builderArgument); + internal abstract bool HasCompilerLoweringPreserveAttribute { get; } + /// /// Gets a value indicating whether this type has System.Runtime.CompilerServices.InterpolatedStringHandlerAttribute or not. /// diff --git a/src/Compilers/CSharp/Portable/Symbols/NativeIntegerTypeSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/NativeIntegerTypeSymbol.cs index 4bf3c91ad7608..b805e7b0319fb 100644 --- a/src/Compilers/CSharp/Portable/Symbols/NativeIntegerTypeSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/NativeIntegerTypeSymbol.cs @@ -205,6 +205,8 @@ internal override bool Equals(TypeSymbol? other, TypeCompareKind comparison) public override int GetHashCode() => _underlyingType.GetHashCode(); + internal override bool HasCompilerLoweringPreserveAttribute => false; + #if !DEBUG void Cci.IReference.Dispatch(Cci.MetadataVisitor visitor) { diff --git a/src/Compilers/CSharp/Portable/Symbols/Retargeting/RetargetingNamedTypeSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Retargeting/RetargetingNamedTypeSymbol.cs index 006c1447cb8dc..32a375a6e2eed 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Retargeting/RetargetingNamedTypeSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Retargeting/RetargetingNamedTypeSymbol.cs @@ -436,5 +436,7 @@ internal sealed override bool HasAsyncMethodBuilderAttribute(out TypeSymbol? bui builderArgument = null; return false; } + + internal override bool HasCompilerLoweringPreserveAttribute => _underlyingType.HasCompilerLoweringPreserveAttribute; } } diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/FieldSymbolWithAttributesAndModifiers.cs b/src/Compilers/CSharp/Portable/Symbols/Source/FieldSymbolWithAttributesAndModifiers.cs index bfec737594640..23835977ee21b 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/FieldSymbolWithAttributesAndModifiers.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/FieldSymbolWithAttributesAndModifiers.cs @@ -385,7 +385,7 @@ internal sealed override int? TypeLayoutOffset } } - internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, ref ArrayBuilder attributes) + internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, ref ArrayBuilder attributes) { base.AddSynthesizedAttributes(moduleBuilder, ref attributes); diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/ImplicitNamedTypeSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Source/ImplicitNamedTypeSymbol.cs index b18d9cbf6d5a5..b370e6423052a 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/ImplicitNamedTypeSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/ImplicitNamedTypeSymbol.cs @@ -171,6 +171,8 @@ internal override ObsoleteAttributeData ObsoleteAttributeData internal override bool HasCodeAnalysisEmbeddedAttribute => false; + internal override bool HasCompilerLoweringPreserveAttribute => false; + internal override bool IsInterpolatedStringHandlerType => false; internal sealed override NamedTypeSymbol AsNativeInteger() => throw ExceptionUtilities.Unreachable(); diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceAssemblySymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceAssemblySymbol.cs index 916a8a348eac2..b6c467e7338a2 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceAssemblySymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceAssemblySymbol.cs @@ -1935,7 +1935,7 @@ internal override bool GetGuidString(out string guidString) return guidString != null; } - internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, ref ArrayBuilder attributes) + internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, ref ArrayBuilder attributes) { base.AddSynthesizedAttributes(moduleBuilder, ref attributes); diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceConstructorSymbolBase.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceConstructorSymbolBase.cs index 33bf6d447922b..246b307c70ef8 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceConstructorSymbolBase.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceConstructorSymbolBase.cs @@ -260,7 +260,7 @@ internal override (CSharpAttributeData?, BoundAttribute?) EarlyDecodeWellKnownAt return base.EarlyDecodeWellKnownAttribute(ref arguments); } - internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, ref ArrayBuilder attributes) + internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, ref ArrayBuilder attributes) { base.AddSynthesizedAttributes(moduleBuilder, ref attributes); AddRequiredMembersMarkerAttributes(ref attributes, this); diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceEventFieldSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceEventFieldSymbol.cs index 6fbf7a12c38b4..b9ee725bb610f 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceEventFieldSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceEventFieldSymbol.cs @@ -56,7 +56,7 @@ public override Symbol AssociatedSymbol } } - internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, ref ArrayBuilder attributes) + internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, ref ArrayBuilder attributes) { base.AddSynthesizedAttributes(moduleBuilder, ref attributes); diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceEventSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceEventSymbol.cs index 0151e99ce3bab..f59aa15ba20fc 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceEventSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceEventSymbol.cs @@ -321,7 +321,7 @@ protected sealed override void DecodeWellKnownAttributeImpl(ref DecodeWellKnownA } } - internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, ref ArrayBuilder? attributes) + internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, ref ArrayBuilder? attributes) { base.AddSynthesizedAttributes(moduleBuilder, ref attributes); diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceFixedFieldSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceFixedFieldSymbol.cs index 9b8ba7104aaec..3f3943bc2c9b2 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceFixedFieldSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceFixedFieldSymbol.cs @@ -37,7 +37,7 @@ internal SourceFixedFieldSymbol( Debug.Assert(this.IsFixedSizeBuffer); } - internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, ref ArrayBuilder attributes) + internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, ref ArrayBuilder attributes) { base.AddSynthesizedAttributes(moduleBuilder, ref attributes); @@ -203,7 +203,7 @@ internal override FieldSymbol FixedElementField get { return _internalField; } } - internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, ref ArrayBuilder attributes) + internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, ref ArrayBuilder attributes) { base.AddSynthesizedAttributes(moduleBuilder, ref attributes); var compilation = ContainingSymbol.DeclaringCompilation; diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberContainerSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberContainerSymbol.cs index 84c2f6dea83fc..bb3ec749a0ffc 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberContainerSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberContainerSymbol.cs @@ -5327,7 +5327,7 @@ internal bool IsNullableEnabledForConstructorsAndInitializers(bool useStatic) membersAndInitializers.IsNullableEnabledForInstanceConstructorsAndFields; } - internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, ref ArrayBuilder attributes) + internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, ref ArrayBuilder attributes) { base.AddSynthesizedAttributes(moduleBuilder, ref attributes); diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberFieldSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberFieldSymbol.cs index c5366989a30bc..7d5bf84d04031 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberFieldSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberFieldSymbol.cs @@ -100,7 +100,7 @@ protected void TypeChecks(TypeSymbol type, BindingDiagnosticBag diagnostics) public abstract bool HasInitializer { get; } - internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, ref ArrayBuilder attributes) + internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, ref ArrayBuilder attributes) { base.AddSynthesizedAttributes(moduleBuilder, ref attributes); diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberMethodSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberMethodSymbol.cs index 92424e5eaffa4..fc43f0601c28c 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberMethodSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberMethodSymbol.cs @@ -1005,7 +1005,7 @@ internal override bool IsNullableAnalysisEnabled() return flags.IsNullableAnalysisEnabled; } - internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, ref ArrayBuilder attributes) + internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, ref ArrayBuilder attributes) { base.AddSynthesizedAttributes(moduleBuilder, ref attributes); diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceModuleSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceModuleSymbol.cs index 11a59bf87bafd..1018ea9ba532b 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceModuleSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceModuleSymbol.cs @@ -621,7 +621,7 @@ static bool namespaceIncludesTypeDeclarations(NamespaceSymbol ns) } } - internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, ref ArrayBuilder attributes) + internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, ref ArrayBuilder attributes) { base.AddSynthesizedAttributes(moduleBuilder, ref attributes); diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceNamedTypeSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceNamedTypeSymbol.cs index 9e4cca64413c5..5486b6320287f 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceNamedTypeSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceNamedTypeSymbol.cs @@ -1217,6 +1217,10 @@ protected sealed override void DecodeWellKnownAttributeImpl(ref DecodeWellKnownA diagnostics.Add(ErrorCode.ERR_InlineArrayAttributeOnRecord, arguments.AttributeSyntaxOpt.Name.Location); } } + else if (attribute.IsTargetAttribute(AttributeDescription.CompilerLoweringPreserveAttribute)) + { + arguments.GetOrCreateData().HasCompilerLoweringPreserveAttribute = true; + } else { var compilation = this.DeclaringCompilation; @@ -1418,6 +1422,15 @@ internal override bool HasCodeAnalysisEmbeddedAttribute } } + internal override bool HasCompilerLoweringPreserveAttribute + { + get + { + var data = GetDecodedWellKnownAttributeData(); + return data != null && data.HasCompilerLoweringPreserveAttribute; + } + } + #nullable enable internal sealed override bool IsInterpolatedStringHandlerType => GetEarlyDecodedWellKnownAttributeData()?.HasInterpolatedStringHandlerAttribute == true; @@ -1659,7 +1672,7 @@ internal override bool HasInlineArrayAttribute(out int length) /// These won't be returned by GetAttributes on source methods, but they /// will be returned by GetAttributes on metadata symbols. /// - internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, ref ArrayBuilder attributes) + internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, ref ArrayBuilder attributes) { base.AddSynthesizedAttributes(moduleBuilder, ref attributes); diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceOrdinaryMethodSymbolBase.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceOrdinaryMethodSymbolBase.cs index 158419141cdeb..ade24d4dcfefe 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceOrdinaryMethodSymbolBase.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceOrdinaryMethodSymbolBase.cs @@ -92,7 +92,7 @@ public override string Name internal abstract override OneOrMany> GetAttributeDeclarations(); - internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, ref ArrayBuilder attributes) + internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, ref ArrayBuilder attributes) { base.AddSynthesizedAttributes(moduleBuilder, ref attributes); diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceParameterSymbolBase.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceParameterSymbolBase.cs index a8a1d2f81f362..dddd8387261ef 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceParameterSymbolBase.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceParameterSymbolBase.cs @@ -66,7 +66,7 @@ public sealed override AssemblySymbol ContainingAssembly internal abstract ConstantValue DefaultValueFromAttributes { get; } - internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, ref ArrayBuilder attributes) + internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, ref ArrayBuilder attributes) { base.AddSynthesizedAttributes(moduleBuilder, ref attributes); diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourcePropertyAccessorSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourcePropertyAccessorSymbol.cs index d57ad4859e972..4c7a1dd16a416 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourcePropertyAccessorSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourcePropertyAccessorSymbol.cs @@ -786,7 +786,7 @@ private ImmutableArray ComputeParameters() return parameters.ToImmutableAndFree(); } - internal sealed override void AddSynthesizedReturnTypeAttributes(PEModuleBuilder moduleBuilder, ref ArrayBuilder attributes) + internal sealed override void AddSynthesizedReturnTypeAttributes(PEModuleBuilder moduleBuilder, ref ArrayBuilder attributes) { base.AddSynthesizedReturnTypeAttributes(moduleBuilder, ref attributes); @@ -801,7 +801,7 @@ internal sealed override void AddSynthesizedReturnTypeAttributes(PEModuleBuilder } } - internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, ref ArrayBuilder attributes) + internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, ref ArrayBuilder attributes) { base.AddSynthesizedAttributes(moduleBuilder, ref attributes); diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourcePropertySymbolBase.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourcePropertySymbolBase.cs index b9db8eceb84eb..6ab9c97d1be7f 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourcePropertySymbolBase.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourcePropertySymbolBase.cs @@ -1360,7 +1360,7 @@ internal PropertyEarlyWellKnownAttributeData GetEarlyDecodedWellKnownAttributeDa return (PropertyEarlyWellKnownAttributeData)attributesBag.EarlyDecodedWellKnownAttributeData; } - internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, ref ArrayBuilder attributes) + internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, ref ArrayBuilder attributes) { base.AddSynthesizedAttributes(moduleBuilder, ref attributes); diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceTypeParameterSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceTypeParameterSymbol.cs index b4f70d7b9dc34..c402d52b987f4 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceTypeParameterSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceTypeParameterSymbol.cs @@ -382,7 +382,7 @@ internal override void ForceComplete(SourceLocation locationOpt, Predicate attributes) + internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, ref ArrayBuilder attributes) { base.AddSynthesizedAttributes(moduleBuilder, ref attributes); diff --git a/src/Compilers/CSharp/Portable/Symbols/SubstitutedNamedTypeSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/SubstitutedNamedTypeSymbol.cs index 914ab75c586a0..379aae474eb7e 100644 --- a/src/Compilers/CSharp/Portable/Symbols/SubstitutedNamedTypeSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/SubstitutedNamedTypeSymbol.cs @@ -485,5 +485,7 @@ internal sealed override bool HasInlineArrayAttribute(out int length) { return _underlyingType.HasInlineArrayAttribute(out length); } + + internal sealed override bool HasCompilerLoweringPreserveAttribute => _underlyingType.HasCompilerLoweringPreserveAttribute; } } diff --git a/src/Compilers/CSharp/Portable/Symbols/Symbol.cs b/src/Compilers/CSharp/Portable/Symbols/Symbol.cs index 3af10fed130ca..8aa95a4dfdf11 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Symbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Symbol.cs @@ -870,20 +870,20 @@ internal Symbol() /// /// Build and add synthesized attributes for this symbol. /// - internal virtual void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, ref ArrayBuilder attributes) + internal virtual void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, ref ArrayBuilder attributes) { } /// /// Convenience helper called by subclasses to add a synthesized attribute to a collection of attributes. /// - internal static void AddSynthesizedAttribute(ref ArrayBuilder attributes, SynthesizedAttributeData attribute) + internal static void AddSynthesizedAttribute(ref ArrayBuilder attributes, CSharpAttributeData attribute) { if (attribute != null) { if (attributes == null) { - attributes = new ArrayBuilder(1); + attributes = new ArrayBuilder(1); } attributes.Add(attribute); diff --git a/src/Compilers/CSharp/Portable/Symbols/Synthesized/ReadOnlyListType/SynthesizedReadOnlyListEnumeratorTypeSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Synthesized/ReadOnlyListType/SynthesizedReadOnlyListEnumeratorTypeSymbol.cs index a52e934731662..927c1d23d5931 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Synthesized/ReadOnlyListType/SynthesizedReadOnlyListEnumeratorTypeSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Synthesized/ReadOnlyListType/SynthesizedReadOnlyListEnumeratorTypeSymbol.cs @@ -169,6 +169,8 @@ static void addProperty(ArrayBuilder builder, PropertySymbol property) internal override bool HasCodeAnalysisEmbeddedAttribute => false; + internal override bool HasCompilerLoweringPreserveAttribute => false; + internal override bool IsInterpolatedStringHandlerType => false; internal override bool HasSpecialName => false; diff --git a/src/Compilers/CSharp/Portable/Symbols/Synthesized/ReadOnlyListType/SynthesizedReadOnlyListTypeSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Synthesized/ReadOnlyListType/SynthesizedReadOnlyListTypeSymbol.cs index 3b55781ebc14a..43b5765ed7076 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Synthesized/ReadOnlyListType/SynthesizedReadOnlyListTypeSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Synthesized/ReadOnlyListType/SynthesizedReadOnlyListTypeSymbol.cs @@ -846,6 +846,8 @@ public static bool CanCreateSingleElement(CSharpCompilation compilation) internal override bool HasCodeAnalysisEmbeddedAttribute => false; + internal override bool HasCompilerLoweringPreserveAttribute => false; + internal override bool IsInterpolatedStringHandlerType => false; internal override bool HasSpecialName => false; @@ -917,7 +919,7 @@ internal override bool GetGuidString(out string? guidString) return false; } - internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, ref ArrayBuilder attributes) + internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, ref ArrayBuilder attributes) { base.AddSynthesizedAttributes(moduleBuilder, ref attributes); AddSynthesizedAttribute(ref attributes, DeclaringCompilation.TrySynthesizeAttribute(WellKnownMember.System_Runtime_CompilerServices_CompilerGeneratedAttribute__ctor)); diff --git a/src/Compilers/CSharp/Portable/Symbols/Synthesized/Records/SynthesizedPrimaryConstructorParameterBackingFieldSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Synthesized/Records/SynthesizedPrimaryConstructorParameterBackingFieldSymbol.cs index 5f3d127451425..f373c80aade14 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Synthesized/Records/SynthesizedPrimaryConstructorParameterBackingFieldSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Synthesized/Records/SynthesizedPrimaryConstructorParameterBackingFieldSymbol.cs @@ -4,7 +4,9 @@ using System.Collections.Immutable; using System.Linq; +using Microsoft.CodeAnalysis.CSharp.Emit; using Microsoft.CodeAnalysis.CSharp.Syntax; +using Microsoft.CodeAnalysis.PooledObjects; using Roslyn.Utilities; namespace Microsoft.CodeAnalysis.CSharp.Symbols @@ -64,5 +66,19 @@ public override Symbol ContainingSymbol public override NamedTypeSymbol ContainingType => ParameterSymbol.ContainingSymbol.ContainingType; + + internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, ref ArrayBuilder attributes) + { + foreach (CSharpAttributeData attr in ParameterSymbol.GetAttributes()) + { + if (attr.AttributeClass is { HasCompilerLoweringPreserveAttribute: true } attributeType && + (attributeType.GetAttributeUsageInfo().ValidTargets & System.AttributeTargets.Field) != 0) + { + AddSynthesizedAttribute(ref attributes, attr); + } + } + + base.AddSynthesizedAttributes(moduleBuilder, ref attributes); + } } } diff --git a/src/Compilers/CSharp/Portable/Symbols/Synthesized/Records/SynthesizedRecordCopyCtor.cs b/src/Compilers/CSharp/Portable/Symbols/Synthesized/Records/SynthesizedRecordCopyCtor.cs index 382f69fbb0e21..6b355c31c0d4c 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Synthesized/Records/SynthesizedRecordCopyCtor.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Synthesized/Records/SynthesizedRecordCopyCtor.cs @@ -72,7 +72,7 @@ internal override void GenerateMethodBodyStatements(SyntheticBoundNodeFactory F, TextSpan.FromBounds(recordDeclaration.Identifier.Span.Start, recordDeclaration.TypeParameterList.Span.End))); } - internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, ref ArrayBuilder attributes) + internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, ref ArrayBuilder attributes) { base.AddSynthesizedAttributes(moduleBuilder, ref attributes); Debug.Assert(IsImplicitlyDeclared); diff --git a/src/Compilers/CSharp/Portable/Symbols/Synthesized/Records/SynthesizedRecordEqualityContractProperty.cs b/src/Compilers/CSharp/Portable/Symbols/Synthesized/Records/SynthesizedRecordEqualityContractProperty.cs index 260dc11f240ce..b99b4283207fc 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Synthesized/Records/SynthesizedRecordEqualityContractProperty.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Synthesized/Records/SynthesizedRecordEqualityContractProperty.cs @@ -89,7 +89,7 @@ protected override void ValidatePropertyType(BindingDiagnosticBag diagnostics) VerifyOverridesEqualityContractFromBase(this, diagnostics); } - internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, ref ArrayBuilder attributes) + internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, ref ArrayBuilder attributes) { base.AddSynthesizedAttributes(moduleBuilder, ref attributes); @@ -155,7 +155,7 @@ internal GetAccessorSymbol( { } - internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, ref ArrayBuilder attributes) + internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, ref ArrayBuilder attributes) { base.AddSynthesizedAttributes(moduleBuilder, ref attributes); diff --git a/src/Compilers/CSharp/Portable/Symbols/Synthesized/Records/SynthesizedRecordEqualityOperatorBase.cs b/src/Compilers/CSharp/Portable/Symbols/Synthesized/Records/SynthesizedRecordEqualityOperatorBase.cs index 3a0ec1fa8abe8..9b1f67f53bcd3 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Synthesized/Records/SynthesizedRecordEqualityOperatorBase.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Synthesized/Records/SynthesizedRecordEqualityOperatorBase.cs @@ -78,7 +78,7 @@ protected sealed override (TypeWithAnnotations ReturnType, ImmutableArray 2; - internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, ref ArrayBuilder attributes) + internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, ref ArrayBuilder attributes) { base.AddSynthesizedAttributes(moduleBuilder, ref attributes); Debug.Assert(IsImplicitlyDeclared); diff --git a/src/Compilers/CSharp/Portable/Symbols/Synthesized/Records/SynthesizedRecordOrdinaryMethod.cs b/src/Compilers/CSharp/Portable/Symbols/Synthesized/Records/SynthesizedRecordOrdinaryMethod.cs index 3bcc164df94a6..404ed77cadab1 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Synthesized/Records/SynthesizedRecordOrdinaryMethod.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Synthesized/Records/SynthesizedRecordOrdinaryMethod.cs @@ -72,7 +72,7 @@ protected sealed override void CheckConstraintsForExplicitInterfaceType(Conversi { } - internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, ref ArrayBuilder attributes) + internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, ref ArrayBuilder attributes) { base.AddSynthesizedAttributes(moduleBuilder, ref attributes); Debug.Assert(IsImplicitlyDeclared); diff --git a/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedAccessorValueParameterSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedAccessorValueParameterSymbol.cs index 7252c0fee9068..4e606bf4edcbe 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedAccessorValueParameterSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedAccessorValueParameterSymbol.cs @@ -77,7 +77,7 @@ internal override OneOrMany> GetAttributeDeclara return accessor.GetAttributeDeclarations(); } - internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, ref ArrayBuilder attributes) + internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, ref ArrayBuilder attributes) { base.AddSynthesizedAttributes(moduleBuilder, ref attributes); diff --git a/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedBackingFieldSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedBackingFieldSymbol.cs index ba0d9afc70e4b..851b7d1f214d2 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedBackingFieldSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedBackingFieldSymbol.cs @@ -37,7 +37,7 @@ public SynthesizedBackingFieldSymbolBase( (isStatic ? DeclarationModifiers.Static : DeclarationModifiers.None); } - internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, ref ArrayBuilder attributes) + internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, ref ArrayBuilder attributes) { base.AddSynthesizedAttributes(moduleBuilder, ref attributes); diff --git a/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedContainer.cs b/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedContainer.cs index cf72b7d487782..1ebb62c711944 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedContainer.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedContainer.cs @@ -55,7 +55,7 @@ protected SynthesizedContainer(string name, ImmutableArray internal sealed override bool IsInterface => this.TypeKind == TypeKind.Interface; - internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, ref ArrayBuilder attributes) + internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, ref ArrayBuilder attributes) { base.AddSynthesizedAttributes(moduleBuilder, ref attributes); @@ -102,6 +102,8 @@ internal override ImmutableArray TypeArgumentsWithAnnotatio internal override bool HasCodeAnalysisEmbeddedAttribute => false; + internal override bool HasCompilerLoweringPreserveAttribute => false; + internal sealed override bool IsInterpolatedStringHandlerType => false; internal sealed override bool HasDeclaredRequiredMembers => false; diff --git a/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedEmbeddedAttributeSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedEmbeddedAttributeSymbol.cs index f753cfbdbec6d..b3a57c3c7e1c7 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedEmbeddedAttributeSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedEmbeddedAttributeSymbol.cs @@ -110,6 +110,8 @@ internal override bool GetGuidString(out string guidString) internal override bool HasCodeAnalysisEmbeddedAttribute => true; + internal override bool HasCompilerLoweringPreserveAttribute => false; + internal override bool IsInterpolatedStringHandlerType => false; internal override bool HasSpecialName => false; @@ -172,7 +174,7 @@ internal override bool GetGuidString(out string guidString) internal sealed override bool IsRecordStruct => false; internal sealed override bool HasPossibleWellKnownCloneMethod() => false; - internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, ref ArrayBuilder attributes) + internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, ref ArrayBuilder attributes) { base.AddSynthesizedAttributes(moduleBuilder, ref attributes); diff --git a/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedEntryPointSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedEntryPointSymbol.cs index 62f5a6a4969a3..fc86c841ab206 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedEntryPointSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedEntryPointSymbol.cs @@ -378,7 +378,7 @@ internal AsyncForwardEntryPoint(CSharpCompilation compilation, NamedTypeSymbol c ReturnType.SpecialType == SpecialType.System_Int32); } - internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, ref ArrayBuilder attributes) + internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, ref ArrayBuilder attributes) { base.AddSynthesizedAttributes(moduleBuilder, ref attributes); diff --git a/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedEnumValueFieldSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedEnumValueFieldSymbol.cs index 1d123c6be164d..ab2d76a36fdf8 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedEnumValueFieldSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedEnumValueFieldSymbol.cs @@ -35,7 +35,7 @@ internal override TypeWithAnnotations GetFieldType(ConsList fieldsB return TypeWithAnnotations.Create(((SourceNamedTypeSymbol)ContainingType).EnumUnderlyingType); } - internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, ref ArrayBuilder attributes) + internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, ref ArrayBuilder attributes) { // no attributes should be emitted } diff --git a/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedEventAccessorSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedEventAccessorSymbol.cs index 3c5407381199a..9c37841206071 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedEventAccessorSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedEventAccessorSymbol.cs @@ -70,7 +70,7 @@ internal override OneOrMany> GetAttributeDeclara return OneOrMany.Create(this.AssociatedEvent.AttributeDeclarationSyntaxList); } - internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, ref ArrayBuilder attributes) + internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, ref ArrayBuilder attributes) { base.AddSynthesizedAttributes(moduleBuilder, ref attributes); diff --git a/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedFieldSymbolBase.cs b/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedFieldSymbolBase.cs index 09a9100ffbd56..99833d8908a80 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedFieldSymbolBase.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedFieldSymbolBase.cs @@ -43,7 +43,7 @@ internal abstract bool SuppressDynamicAttribute get; } - internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, ref ArrayBuilder attributes) + internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, ref ArrayBuilder attributes) { base.AddSynthesizedAttributes(moduleBuilder, ref attributes); diff --git a/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedHotReloadExceptionSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedHotReloadExceptionSymbol.cs index c98708ef4cd6a..30bcbb683b475 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedHotReloadExceptionSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedHotReloadExceptionSymbol.cs @@ -71,7 +71,7 @@ internal override IEnumerable GetFieldsToEmit() public override ImmutableArray GetTypeMembers(ReadOnlyMemory name) => []; public override ImmutableArray GetTypeMembers(ReadOnlyMemory name, int arity) => []; - internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, ref ArrayBuilder attributes) + internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, ref ArrayBuilder attributes) { base.AddSynthesizedAttributes(moduleBuilder, ref attributes); @@ -104,6 +104,7 @@ internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, r internal sealed override bool IsFileLocal => false; internal sealed override FileIdentifier? AssociatedFileIdentifier => null; internal override bool HasCodeAnalysisEmbeddedAttribute => true; + internal override bool HasCompilerLoweringPreserveAttribute => false; internal override bool IsInterpolatedStringHandlerType => false; internal override bool HasSpecialName => false; internal override bool IsComImport => false; diff --git a/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedInlineArrayTypeSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedInlineArrayTypeSymbol.cs index 05dca7980687e..014d0e9005941 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedInlineArrayTypeSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedInlineArrayTypeSymbol.cs @@ -94,6 +94,8 @@ internal SynthesizedInlineArrayTypeSymbol(SourceModuleSymbol containingModule, s internal override bool HasCodeAnalysisEmbeddedAttribute => false; + internal override bool HasCompilerLoweringPreserveAttribute => false; + internal override bool GetGuidString(out string? guidString) { guidString = null; @@ -185,7 +187,7 @@ internal sealed override bool HasAsyncMethodBuilderAttribute(out TypeSymbol? bui internal override IEnumerable<(MethodSymbol Body, MethodSymbol Implemented)> SynthesizedInterfaceMethodImpls() => SpecializedCollections.EmptyEnumerable<(MethodSymbol Body, MethodSymbol Implemented)>(); - internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, ref ArrayBuilder attributes) + internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, ref ArrayBuilder attributes) { base.AddSynthesizedAttributes(moduleBuilder, ref attributes); diff --git a/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedInstanceConstructor.cs b/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedInstanceConstructor.cs index e173fa2d011ef..70ea99af74714 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedInstanceConstructor.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedInstanceConstructor.cs @@ -319,7 +319,7 @@ internal virtual void GenerateMethodBodyStatements(SyntheticBoundNodeFactory fac protected override bool HasSetsRequiredMembersImpl => false; - internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, ref ArrayBuilder attributes) + internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, ref ArrayBuilder attributes) { base.AddSynthesizedAttributes(moduleBuilder, ref attributes); AddRequiredMembersMarkerAttributes(ref attributes, this); diff --git a/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedParameterSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedParameterSymbol.cs index 87045c0165364..479ad310a97a8 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedParameterSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedParameterSymbol.cs @@ -145,7 +145,7 @@ public override ImmutableArray DeclaringSyntaxReferences } } - internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, ref ArrayBuilder attributes) + internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, ref ArrayBuilder attributes) { // Emit [Dynamic] on synthesized parameter symbols when the original parameter was dynamic // in order to facilitate debugging. In the case the necessary attributes are missing diff --git a/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedPrivateImplementationDetailsType.cs b/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedPrivateImplementationDetailsType.cs index fbb5c68b07696..7436082c596fe 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedPrivateImplementationDetailsType.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedPrivateImplementationDetailsType.cs @@ -83,6 +83,8 @@ public SynthesizedPrivateImplementationDetailsType(PrivateImplementationDetails internal override bool HasCodeAnalysisEmbeddedAttribute => false; + internal override bool HasCompilerLoweringPreserveAttribute => false; + internal override bool IsInterpolatedStringHandlerType => false; internal override bool HasSpecialName => _privateImplementationDetails.IsSpecialName; diff --git a/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedSubstitutedTypeParameterSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedSubstitutedTypeParameterSymbol.cs index 56979139e7487..29d619d53c3a4 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedSubstitutedTypeParameterSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedSubstitutedTypeParameterSymbol.cs @@ -32,7 +32,7 @@ public override bool IsImplicitlyDeclared public override TypeParameterKind TypeParameterKind => ContainingSymbol is MethodSymbol ? TypeParameterKind.Method : TypeParameterKind.Type; - internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, ref ArrayBuilder attributes) + internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, ref ArrayBuilder attributes) { base.AddSynthesizedAttributes(moduleBuilder, ref attributes); diff --git a/src/Compilers/CSharp/Portable/Symbols/Wrapped/WrappedParameterSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Wrapped/WrappedParameterSymbol.cs index c15838b1daea2..ca61e1f1b142e 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Wrapped/WrappedParameterSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Wrapped/WrappedParameterSymbol.cs @@ -71,7 +71,7 @@ public override ImmutableArray GetAttributes() return _underlyingParameter.GetAttributes(); } - internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, ref ArrayBuilder attributes) + internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, ref ArrayBuilder attributes) { _underlyingParameter.AddSynthesizedAttributes(moduleBuilder, ref attributes); } diff --git a/src/Compilers/CSharp/Test/Emit3/Semantics/PrimaryConstructorTests.cs b/src/Compilers/CSharp/Test/Emit3/Semantics/PrimaryConstructorTests.cs index 364be8b47f381..6d823626ffacc 100644 --- a/src/Compilers/CSharp/Test/Emit3/Semantics/PrimaryConstructorTests.cs +++ b/src/Compilers/CSharp/Test/Emit3/Semantics/PrimaryConstructorTests.cs @@ -10,6 +10,7 @@ using System.Linq; using System.Threading; using Microsoft.CodeAnalysis.CSharp.Symbols; +using Microsoft.CodeAnalysis.CSharp.Symbols.Retargeting; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.CSharp.Test.Utilities; using Microsoft.CodeAnalysis.Diagnostics; @@ -25,6 +26,20 @@ namespace Microsoft.CodeAnalysis.CSharp.UnitTests.Semantics public class PrimaryConstructorTests : CompilingTestBase { + /// + /// The shape of the attribute comes from https://github.com/dotnet/runtime/issues/103430 + /// + private const string CompilerLoweringPreserveAttributeDefinition = @" +namespace System.Runtime.CompilerServices +{ + [AttributeUsage(AttributeTargets.Class, Inherited = false)] + public class CompilerLoweringPreserveAttribute : Attribute + { + public CompilerLoweringPreserveAttribute() { } + } +} +"; + [Flags] public enum TestFlags { @@ -22360,5 +22375,246 @@ public record {{typeKind}} C4 Diagnostic(ErrorCode.WRN_UninitializedNonNullableField, "C2").WithArguments("property", "Text").WithLocation(12, 12) ); } + + [Theory] + [CombinatorialData] + public void CompilerLoweringPreserveAttribute_01([CombinatorialValues("class ", "struct")] string keyword) + { + string source1 = @" +using System; +using System.Runtime.CompilerServices; + +[CompilerLoweringPreserve] +[AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter)] +public class Preserve1Attribute : Attribute { } + +[CompilerLoweringPreserve] +[AttributeUsage(AttributeTargets.Parameter)] +public class Preserve2Attribute : Attribute { } +"; + + string source2 = @" +public " + keyword + @" Test1( + [Preserve1] + [Preserve2] + int P1) +{ + int M1() => P1; +} +"; + var comp1 = CreateCompilation( + [source1, source2, CompilerLoweringPreserveAttributeDefinition], + options: TestOptions.DebugDll.WithMetadataImportOptions(MetadataImportOptions.All)); + CompileAndVerify(comp1, symbolValidator: validate).VerifyDiagnostics(); + + var comp2 = CreateCompilation([source2], references: [comp1.ToMetadataReference()], options: TestOptions.DebugDll.WithMetadataImportOptions(MetadataImportOptions.All)); + CompileAndVerify(comp2, symbolValidator: validate).VerifyDiagnostics(); + + var comp3 = CreateCompilation([source2], references: [comp1.EmitToImageReference()], options: TestOptions.DebugDll.WithMetadataImportOptions(MetadataImportOptions.All)); + CompileAndVerify(comp3, symbolValidator: validate).VerifyDiagnostics(); + + static void validate(ModuleSymbol m) + { + AssertEx.SequenceEqual( + [ + "Preserve1Attribute", + "System.Runtime.CompilerServices.CompilerGeneratedAttribute", + "System.Diagnostics.DebuggerBrowsableAttribute(System.Diagnostics.DebuggerBrowsableState.Never)" + ], + m.GlobalNamespace.GetMember("Test1.P").GetAttributes().Select(a => a.ToString())); + } + } + + [Theory] + [CombinatorialData] + public void CompilerLoweringPreserveAttribute_02([CombinatorialValues("class ", "struct")] string keyword) + { + string source1 = @" +using System; +using System.Runtime.CompilerServices; + +[CompilerLoweringPreserve] +[AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter)] +public class Preserve1Attribute : Attribute { } + +[CompilerLoweringPreserve] +[AttributeUsage(AttributeTargets.Parameter)] +public class Preserve2Attribute : Attribute { } +"; + + string source2 = @" +public record " + keyword + @" Test1( + [Preserve1] + [Preserve2] + int P1) +{ + int M1() => P1; +} +"; + var comp1 = CreateCompilation( + [source1, source2, CompilerLoweringPreserveAttributeDefinition, IsExternalInitTypeDefinition], + options: TestOptions.DebugDll.WithMetadataImportOptions(MetadataImportOptions.All)); + CompileAndVerify(comp1, symbolValidator: validate).VerifyDiagnostics(); + + var comp2 = CreateCompilation([source2, IsExternalInitTypeDefinition], references: [comp1.ToMetadataReference()], options: TestOptions.DebugDll.WithMetadataImportOptions(MetadataImportOptions.All)); + CompileAndVerify(comp2, symbolValidator: validate).VerifyDiagnostics(); + + var comp3 = CreateCompilation([source2, IsExternalInitTypeDefinition], references: [comp1.EmitToImageReference()], options: TestOptions.DebugDll.WithMetadataImportOptions(MetadataImportOptions.All)); + CompileAndVerify(comp3, symbolValidator: validate).VerifyDiagnostics(); + + static void validate(ModuleSymbol m) + { + AssertEx.SequenceEqual( + [ + "System.Runtime.CompilerServices.CompilerGeneratedAttribute", + "System.Diagnostics.DebuggerBrowsableAttribute(System.Diagnostics.DebuggerBrowsableState.Never)" + ], + m.GlobalNamespace.GetMember("Test1.k__BackingField").GetAttributes().Select(a => a.ToString())); + } + } + + [Theory] + [CombinatorialData] + public void CompilerLoweringPreserveAttribute_03([CombinatorialValues("class ", "struct")] string keyword) + { + string source1 = @" +using System; + +[AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter)] +public class Preserve1Attribute : Attribute { } +"; + + string source2 = @" +public record " + keyword + @" Test1( + [field: Preserve1] + int P1) +{ + int M1() => P1; +} +"; + var comp1 = CreateCompilation( + [source1, source2, IsExternalInitTypeDefinition], + options: TestOptions.DebugDll.WithMetadataImportOptions(MetadataImportOptions.All)); + CompileAndVerify(comp1, symbolValidator: validate).VerifyDiagnostics(); + + static void validate(ModuleSymbol m) + { + AssertEx.SequenceEqual( + [ + "System.Runtime.CompilerServices.CompilerGeneratedAttribute", + "System.Diagnostics.DebuggerBrowsableAttribute(System.Diagnostics.DebuggerBrowsableState.Never)", + "Preserve1Attribute" + ], + m.GlobalNamespace.GetMember("Test1.k__BackingField").GetAttributes().Select(a => a.ToString())); + } + } + + [Theory] + [CombinatorialData] + public void CompilerLoweringPreserveAttribute_04_Retargeting([CombinatorialValues("class ", "struct")] string keyword) + { + string source0 = @" +public class Test0 {} +"; + + var comp0 = CreateCompilation(source0); + + string source1 = @" +using System; +using System.Runtime.CompilerServices; + +[CompilerLoweringPreserve] +[AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter)] +public class Preserve1Attribute : Attribute { } + +[CompilerLoweringPreserve] +[AttributeUsage(AttributeTargets.Parameter)] +public class Preserve2Attribute : Attribute { } +"; + + string source2 = @" +public " + keyword + @" Test1( + [Preserve1] + [Preserve2] + int P1) +{ + int M1() => P1; +} +"; + var comp1 = CreateCompilation( + [source1, CompilerLoweringPreserveAttributeDefinition], + references: [comp0.ToMetadataReference()], + options: TestOptions.DebugDll.WithMetadataImportOptions(MetadataImportOptions.All)); + + var comp2 = CreateCompilation([source2], references: [comp1.ToMetadataReference()], options: TestOptions.DebugDll.WithMetadataImportOptions(MetadataImportOptions.All)); + + Assert.IsType(comp2.GetTypeByMetadataName("Preserve1Attribute")); + + CompileAndVerify(comp2, symbolValidator: validate).VerifyDiagnostics(); + + static void validate(ModuleSymbol m) + { + AssertEx.SequenceEqual( + [ + "Preserve1Attribute", + "System.Runtime.CompilerServices.CompilerGeneratedAttribute", + "System.Diagnostics.DebuggerBrowsableAttribute(System.Diagnostics.DebuggerBrowsableState.Never)" + ], + m.GlobalNamespace.GetMember("Test1.P").GetAttributes().Select(a => a.ToString())); + } + } + + [Theory] + [CombinatorialData] + public void CompilerLoweringPreserveAttribute_05_Generic([CombinatorialValues("class ", "struct")] string keyword) + { + string source0 = @" +public class Test0 {} +"; + + var comp0 = CreateCompilation(source0); + + string source1 = @" +using System; +using System.Runtime.CompilerServices; + +[CompilerLoweringPreserve] +[AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter)] +public class Preserve1Attribute : Attribute { } + +[CompilerLoweringPreserve] +[AttributeUsage(AttributeTargets.Parameter)] +public class Preserve2Attribute : Attribute { } +"; + + string source2 = @" +public " + keyword + @" Test1( + [Preserve1] + [Preserve2] + int P1) +{ + int M1() => P1; +} +"; + var comp1 = CreateCompilation( + [source1, CompilerLoweringPreserveAttributeDefinition], + references: [comp0.ToMetadataReference()], + options: TestOptions.DebugDll.WithMetadataImportOptions(MetadataImportOptions.All)); + + var comp2 = CreateCompilation([source2], references: [comp1.ToMetadataReference()], options: TestOptions.DebugDll.WithMetadataImportOptions(MetadataImportOptions.All)); + + CompileAndVerify(comp2, symbolValidator: validate).VerifyDiagnostics(); + + static void validate(ModuleSymbol m) + { + AssertEx.SequenceEqual( + [ + "Preserve1Attribute", + "System.Runtime.CompilerServices.CompilerGeneratedAttribute", + "System.Diagnostics.DebuggerBrowsableAttribute(System.Diagnostics.DebuggerBrowsableState.Never)" + ], + m.GlobalNamespace.GetMember("Test1.P").GetAttributes().Select(a => a.ToString())); + } + } } } diff --git a/src/Compilers/CSharp/Test/Symbol/Symbols/MockNamedTypeSymbol.cs b/src/Compilers/CSharp/Test/Symbol/Symbols/MockNamedTypeSymbol.cs index d4b933a157acd..854eed416473e 100644 --- a/src/Compilers/CSharp/Test/Symbol/Symbols/MockNamedTypeSymbol.cs +++ b/src/Compilers/CSharp/Test/Symbol/Symbols/MockNamedTypeSymbol.cs @@ -265,6 +265,8 @@ internal override ImmutableArray GetDeclaredInterfaces(ConsList internal override bool HasCodeAnalysisEmbeddedAttribute => false; + internal override bool HasCompilerLoweringPreserveAttribute => false; + internal sealed override ManagedKind GetManagedKind(ref CompoundUseSiteInfo useSiteInfo) => ManagedKind.Managed; internal override bool ShouldAddWinRTMembers diff --git a/src/Compilers/Core/Portable/MetadataReader/PEModule.cs b/src/Compilers/Core/Portable/MetadataReader/PEModule.cs index cd20e4b23798f..7e2c6a5eae7f6 100644 --- a/src/Compilers/Core/Portable/MetadataReader/PEModule.cs +++ b/src/Compilers/Core/Portable/MetadataReader/PEModule.cs @@ -1022,6 +1022,11 @@ internal bool HasCodeAnalysisEmbeddedAttribute(EntityHandle token) return FindTargetAttribute(token, AttributeDescription.CodeAnalysisEmbeddedAttribute).HasValue; } + internal bool HasCompilerLoweringPreserveAttribute(EntityHandle token) + { + return FindTargetAttribute(token, AttributeDescription.CompilerLoweringPreserveAttribute).HasValue; + } + internal bool HasInterpolatedStringHandlerAttribute(EntityHandle token) { return FindTargetAttribute(token, AttributeDescription.InterpolatedStringHandlerAttribute).HasValue; diff --git a/src/Compilers/Core/Portable/Symbols/Attributes/AttributeDescription.cs b/src/Compilers/Core/Portable/Symbols/Attributes/AttributeDescription.cs index 7a6618dcf3f05..6b16eac1db4e2 100644 --- a/src/Compilers/Core/Portable/Symbols/Attributes/AttributeDescription.cs +++ b/src/Compilers/Core/Portable/Symbols/Attributes/AttributeDescription.cs @@ -490,5 +490,6 @@ static AttributeDescription() internal static readonly AttributeDescription InlineArrayAttribute = new AttributeDescription("System.Runtime.CompilerServices", "InlineArrayAttribute", s_signatures_HasThis_Void_Int32_Only); internal static readonly AttributeDescription CollectionBuilderAttribute = new AttributeDescription("System.Runtime.CompilerServices", "CollectionBuilderAttribute", s_signaturesOfCollectionBuilderAttribute); internal static readonly AttributeDescription OverloadResolutionPriorityAttribute = new AttributeDescription("System.Runtime.CompilerServices", "OverloadResolutionPriorityAttribute", s_signatures_HasThis_Void_Int32_Only); + internal static readonly AttributeDescription CompilerLoweringPreserveAttribute = new AttributeDescription("System.Runtime.CompilerServices", "CompilerLoweringPreserveAttribute", s_signatures_HasThis_Void_Only); } } diff --git a/src/ExpressionEvaluator/CSharp/Source/ExpressionCompiler/Symbols/EENamedTypeSymbol.cs b/src/ExpressionEvaluator/CSharp/Source/ExpressionCompiler/Symbols/EENamedTypeSymbol.cs index 5b36032734e10..c0ae503882254 100644 --- a/src/ExpressionEvaluator/CSharp/Source/ExpressionCompiler/Symbols/EENamedTypeSymbol.cs +++ b/src/ExpressionEvaluator/CSharp/Source/ExpressionCompiler/Symbols/EENamedTypeSymbol.cs @@ -345,6 +345,8 @@ internal override bool IsInterface internal override bool HasCodeAnalysisEmbeddedAttribute => false; + internal override bool HasCompilerLoweringPreserveAttribute => false; + internal sealed override NamedTypeSymbol AsNativeInteger() => throw ExceptionUtilities.Unreachable(); internal sealed override NamedTypeSymbol NativeIntegerUnderlyingType => null; From f9f18b9a66e332623a1499bb5448be45dacfa5f1 Mon Sep 17 00:00:00 2001 From: AlekseyTs Date: Tue, 17 Dec 2024 11:57:33 -0800 Subject: [PATCH 2/3] Fixup tests --- .../Test/Emit3/Semantics/PrimaryConstructorTests.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Compilers/CSharp/Test/Emit3/Semantics/PrimaryConstructorTests.cs b/src/Compilers/CSharp/Test/Emit3/Semantics/PrimaryConstructorTests.cs index 6d823626ffacc..a0c5bc414dcc2 100644 --- a/src/Compilers/CSharp/Test/Emit3/Semantics/PrimaryConstructorTests.cs +++ b/src/Compilers/CSharp/Test/Emit3/Semantics/PrimaryConstructorTests.cs @@ -22454,13 +22454,13 @@ public record " + keyword + @" Test1( var comp1 = CreateCompilation( [source1, source2, CompilerLoweringPreserveAttributeDefinition, IsExternalInitTypeDefinition], options: TestOptions.DebugDll.WithMetadataImportOptions(MetadataImportOptions.All)); - CompileAndVerify(comp1, symbolValidator: validate).VerifyDiagnostics(); + CompileAndVerify(comp1, symbolValidator: validate, verify: Verification.Skipped).VerifyDiagnostics(); var comp2 = CreateCompilation([source2, IsExternalInitTypeDefinition], references: [comp1.ToMetadataReference()], options: TestOptions.DebugDll.WithMetadataImportOptions(MetadataImportOptions.All)); - CompileAndVerify(comp2, symbolValidator: validate).VerifyDiagnostics(); + CompileAndVerify(comp2, symbolValidator: validate, verify: Verification.Skipped).VerifyDiagnostics(); var comp3 = CreateCompilation([source2, IsExternalInitTypeDefinition], references: [comp1.EmitToImageReference()], options: TestOptions.DebugDll.WithMetadataImportOptions(MetadataImportOptions.All)); - CompileAndVerify(comp3, symbolValidator: validate).VerifyDiagnostics(); + CompileAndVerify(comp3, symbolValidator: validate, verify: Verification.Skipped).VerifyDiagnostics(); static void validate(ModuleSymbol m) { @@ -22495,7 +22495,7 @@ public record " + keyword + @" Test1( var comp1 = CreateCompilation( [source1, source2, IsExternalInitTypeDefinition], options: TestOptions.DebugDll.WithMetadataImportOptions(MetadataImportOptions.All)); - CompileAndVerify(comp1, symbolValidator: validate).VerifyDiagnostics(); + CompileAndVerify(comp1, symbolValidator: validate, verify: Verification.Skipped).VerifyDiagnostics(); static void validate(ModuleSymbol m) { From 91637e156893188c34b901dcaf69833856a36ee6 Mon Sep 17 00:00:00 2001 From: AlekseyTs Date: Tue, 17 Dec 2024 16:36:28 -0800 Subject: [PATCH 3/3] Add test scenarios --- .../Semantics/PrimaryConstructorTests.cs | 26 +++++++++---------- .../Test/Utilities/CSharp/CSharpTestBase.cs | 14 ++++++++++ 2 files changed, 26 insertions(+), 14 deletions(-) diff --git a/src/Compilers/CSharp/Test/Emit3/Semantics/PrimaryConstructorTests.cs b/src/Compilers/CSharp/Test/Emit3/Semantics/PrimaryConstructorTests.cs index a0c5bc414dcc2..623a2f0f15f6b 100644 --- a/src/Compilers/CSharp/Test/Emit3/Semantics/PrimaryConstructorTests.cs +++ b/src/Compilers/CSharp/Test/Emit3/Semantics/PrimaryConstructorTests.cs @@ -26,20 +26,6 @@ namespace Microsoft.CodeAnalysis.CSharp.UnitTests.Semantics public class PrimaryConstructorTests : CompilingTestBase { - /// - /// The shape of the attribute comes from https://github.com/dotnet/runtime/issues/103430 - /// - private const string CompilerLoweringPreserveAttributeDefinition = @" -namespace System.Runtime.CompilerServices -{ - [AttributeUsage(AttributeTargets.Class, Inherited = false)] - public class CompilerLoweringPreserveAttribute : Attribute - { - public CompilerLoweringPreserveAttribute() { } - } -} -"; - [Flags] public enum TestFlags { @@ -22391,12 +22377,16 @@ public class Preserve1Attribute : Attribute { } [CompilerLoweringPreserve] [AttributeUsage(AttributeTargets.Parameter)] public class Preserve2Attribute : Attribute { } + +[AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter)] +public class Preserve3Attribute : Attribute { } "; string source2 = @" public " + keyword + @" Test1( [Preserve1] [Preserve2] + [Preserve3] int P1) { int M1() => P1; @@ -22530,12 +22520,16 @@ public class Preserve1Attribute : Attribute { } [CompilerLoweringPreserve] [AttributeUsage(AttributeTargets.Parameter)] public class Preserve2Attribute : Attribute { } + +[AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter)] +public class Preserve3Attribute : Attribute { } "; string source2 = @" public " + keyword + @" Test1( [Preserve1] [Preserve2] + [Preserve3] int P1) { int M1() => P1; @@ -22585,12 +22579,16 @@ public class Preserve1Attribute : Attribute { } [CompilerLoweringPreserve] [AttributeUsage(AttributeTargets.Parameter)] public class Preserve2Attribute : Attribute { } + +[AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter)] +public class Preserve3Attribute : Attribute { } "; string source2 = @" public " + keyword + @" Test1( [Preserve1] [Preserve2] + [Preserve3] int P1) { int M1() => P1; diff --git a/src/Compilers/Test/Utilities/CSharp/CSharpTestBase.cs b/src/Compilers/Test/Utilities/CSharp/CSharpTestBase.cs index a2d5397815847..166457fffd27e 100644 --- a/src/Compilers/Test/Utilities/CSharp/CSharpTestBase.cs +++ b/src/Compilers/Test/Utilities/CSharp/CSharpTestBase.cs @@ -764,6 +764,20 @@ .property instance int32 Priority() } """; + /// + /// The shape of the attribute comes from https://github.com/dotnet/runtime/issues/103430 + /// + internal const string CompilerLoweringPreserveAttributeDefinition = """ + namespace System.Runtime.CompilerServices + { + [AttributeUsage(AttributeTargets.Class, Inherited = false)] + public class CompilerLoweringPreserveAttribute : Attribute + { + public CompilerLoweringPreserveAttribute() { } + } + } + """; + protected static T GetSyntax(SyntaxTree tree, string text) { return GetSyntaxes(tree, text).Single();