// Process the given well known attribute applied to the given ownerSymbol
        private void ProcessWellKnownAttribute(SourceAttributeData attribute, Symbol ownerSymbol, AttributeSyntax node, DiagnosticBag diagnostics, bool validTarget)
        {
            var wellKnownAttribute = attribute.WellKnownAttribute;
            Debug.Assert(WellKnownTypes.IsWellKnownAttribute(wellKnownAttribute));

            switch (wellKnownAttribute)
            {
                case WellKnownType.System_AttributeUsageAttribute:
                    ProcessAttributeUsageAttribute(attribute, ownerSymbol, node, diagnostics);
                    return;

                case WellKnownType.System_Runtime_CompilerServices_ExtensionAttribute:
                    ProcessExtensionAttribute(attribute, ownerSymbol, node, diagnostics, validTarget);
                    return;

                case WellKnownType.System_Reflection_DefaultMemberAttribute:
                    ProcessDefaultMemberAttribute(ownerSymbol, node, diagnostics, validTarget);
                    return;

                case WellKnownType.System_Runtime_CompilerServices_DateTimeConstantAttribute:
                case WellKnownType.System_Runtime_CompilerServices_DecimalConstantAttribute:
                case WellKnownType.System_Runtime_CompilerServices_InternalsVisibleToAttribute:
                    // TODO semantic analysis of well known attributes
                    return;
            }
        }
        // Process the given well known attribute applied to the given ownerSymbol
        private void ProcessWellKnownAttribute(SourceAttributeData attribute, Symbol ownerSymbol, AttributeSyntax node, DiagnosticBag diagnostics, bool validTarget)
        {
            var wellKnownAttribute = attribute.WellKnownAttribute;

            Debug.Assert(WellKnownTypes.IsWellKnownAttribute(wellKnownAttribute));

            switch (wellKnownAttribute)
            {
            case WellKnownType.System_AttributeUsageAttribute:
                ProcessAttributeUsageAttribute(attribute, ownerSymbol, node, diagnostics);
                return;

            case WellKnownType.System_Runtime_CompilerServices_ExtensionAttribute:
                ProcessExtensionAttribute(attribute, ownerSymbol, node, diagnostics, validTarget);
                return;

            case WellKnownType.System_Reflection_DefaultMemberAttribute:
                ProcessDefaultMemberAttribute(ownerSymbol, node, diagnostics, validTarget);
                return;

            case WellKnownType.System_Runtime_CompilerServices_DateTimeConstantAttribute:
            case WellKnownType.System_Runtime_CompilerServices_DecimalConstantAttribute:
            case WellKnownType.System_Runtime_CompilerServices_InternalsVisibleToAttribute:
                // TODO semantic analysis of well known attributes
                return;
            }
        }
        private void ProcessExtensionAttribute(SourceAttributeData attributeUsageAttribute, Symbol ownerSymbol, AttributeSyntax node, DiagnosticBag diagnostics, bool validTarget)
        {
            if (!validTarget)
            {
                return;
            }

            // [Extension] attribute should not be set explicitly.
            Error(diagnostics, ErrorCode.ERR_ExplicitExtension, node, WellKnownType.System_Runtime_CompilerServices_ExtensionAttribute.GetMetadataName());
        }
        // Process the specified AttributeUsage attribute on the given ownerSymbol
        private void ProcessAttributeUsageAttribute(SourceAttributeData attributeUsageAttribute, Symbol ownerSymbol, AttributeSyntax node, DiagnosticBag diagnostics)
        {
            // Validate first ctor argument for AtributeUsage specification is a valid AttributeTargets enum member
            Debug.Assert(attributeUsageAttribute.AttributeConstructor == GetWellKnownTypeMember(WellKnownMember.System_AttributeUsageAttribute__ctor, diagnostics, node));
            var targetArgument = (int)attributeUsageAttribute.PositionalArguments[0].Value;
            if (!AttributeUsageInfo.IsValidValueForAttributeTargets(targetArgument))
            {
                // invalid attribute target
                Error(diagnostics, ErrorCode.ERR_InvalidAttributeArgument, node.ArgumentList.Arguments[0], GetAttributeNameFromSyntax(node));
            }

            // AttributeUsage can only be specified for attribute classes
            if (ownerSymbol.Kind == SymbolKind.NamedType &&
                !((NamedTypeSymbol)ownerSymbol).IsAttributeType(Compilation))
            {
                Error(diagnostics, ErrorCode.ERR_AttributeUsageOnNonAttributeClass, node, GetAttributeNameFromSyntax(node));
            }
        }
        // Process the specified AttributeUsage attribute on the given ownerSymbol
        private void ProcessAttributeUsageAttribute(SourceAttributeData attributeUsageAttribute, Symbol ownerSymbol, AttributeSyntax node, DiagnosticBag diagnostics)
        {
            // Validate first ctor argument for AtributeUsage specification is a valid AttributeTargets enum member
            Debug.Assert(attributeUsageAttribute.AttributeConstructor == GetWellKnownTypeMember(WellKnownMember.System_AttributeUsageAttribute__ctor, diagnostics, node));
            var targetArgument = (int)attributeUsageAttribute.PositionalArguments[0].Value;

            if (!AttributeUsageInfo.IsValidValueForAttributeTargets(targetArgument))
            {
                // invalid attribute target
                Error(diagnostics, ErrorCode.ERR_InvalidAttributeArgument, node.ArgumentList.Arguments[0], GetAttributeNameFromSyntax(node));
            }

            // AttributeUsage can only be specified for attribute classes
            if (ownerSymbol.Kind == SymbolKind.NamedType &&
                !((NamedTypeSymbol)ownerSymbol).IsAttributeType(Compilation))
            {
                Error(diagnostics, ErrorCode.ERR_AttributeUsageOnNonAttributeClass, node, GetAttributeNameFromSyntax(node));
            }
        }
        private void ProcessExtensionAttribute(SourceAttributeData attributeUsageAttribute, Symbol ownerSymbol, AttributeSyntax node, DiagnosticBag diagnostics, bool validTarget)
        {
            if (!validTarget)
            {
                return;
            }

            // [Extension] attribute should not be set explicitly.
            Error(diagnostics, ErrorCode.ERR_ExplicitExtension, node, WellKnownType.System_Runtime_CompilerServices_ExtensionAttribute.GetMetadataName());
        }