void CLSComplianceChecker::VerifyConstraintsAreCLSCompliant(BCSYM_NamedRoot * ContainerOrProc)
{
    VSASSERT(ContainerOrProc->IsContainer() || ContainerOrProc->IsProc(),
                "Symbol kind unexpected during generic constraint CLS compliance checking!!!");

    // Check the Generic parameter constraint types too for CLS Compliance.
    // If not a generic type or method, it will not have any generic
    // parameters.

    for(BCSYM_GenericParam *GenericParam = ContainerOrProc->GetFirstGenericParam();
        GenericParam;
        GenericParam = GenericParam->GetNextParam())
    {
        for (BCSYM_GenericTypeConstraint *Constraint = GenericParam->GetTypeConstraints();
             Constraint;
             Constraint = Constraint->Next())
        {
            BCSYM *ConstraintType = Constraint->GetRawType();

            if (IsTypeCLSCompliant(ConstraintType, GenericParam))
            {
                continue;
            }

            ReportErrorOnSymbol(
                WRNID_GenericConstraintNotCLSCompliant1,
                Constraint,
                GenericParam,
                ConstraintType->ChaseToType()->GetErrorName(m_Compiler));
        }
    }
}
Esempio n. 2
0
BCSYM*
Bindable::BasesIter::GetFirst()
{
    BCSYM *Base = NULL;
    m_LinkToCurrentBase = NULL;

    if (m_ClassOrInterface->IsClass())
    {
        Base = m_ClassOrInterface->PClass()->GetBaseClass();

        if (Base &&
            (Base->IsBad() || !Base->IsClass()))
        {
            Base = NULL;
        }
    }
    else if (m_ClassOrInterface->IsInterface())
    {
        m_LinkToCurrentBase = m_ClassOrInterface->PInterface()->GetFirstImplements();

        Base = GetBaseInterface(m_LinkToCurrentBase);
    }

    return Base;
}
Esempio n. 3
0
BCSYM_Container*
Bindable::BasesIter::GetNextBase
(
    BCSYM_GenericTypeBinding **BaseGenericBinding
)
{
    BCSYM *Base;

    if (!m_IteratorStarted)
    {
        m_IteratorStarted = true;
        Base = GetFirst();
    }
    else
    {
        Base = GetNext();
    }

    if (BaseGenericBinding)
    {
        if (Base && Base->IsGenericTypeBinding())
        {
            *BaseGenericBinding = Base->PGenericTypeBinding();
        }
        else
        {
            *BaseGenericBinding = NULL;
        }
    }

    return Base->PContainer();
}
void CLSComplianceChecker::VerifyBasesForCLSCompliance(BCSYM_Container * Container)
{
    VSASSERT( Container->IsCLSCompliant(),
                    "Non-CLS compliant container unexpected!!!");

    if (Container->IsClass())
    {
        BCSYM *RawBaseType = Container->PClass()->GetRawBase();

        // Report an error if this inherited class is not compliant.
        //
        if (!IsTypeCLSCompliant(RawBaseType, Container))
        {
            ReportErrorOnSymbol(
                WRNID_BaseClassNotCLSCompliant2,
                Container,
                Container->GetName(),
                RawBaseType->ChaseToType()->GetErrorName(m_Compiler));
        }
    }
    else if (Container->IsInterface())
    {
        for (BCSYM_Implements *Impl =
                Container->PInterface()->GetFirstImplements();
             Impl;
             Impl = Impl->GetNext())
        {
            if (Impl->IsBad())
            {
                continue;
            }

            BCSYM *RawBaseType = Impl->GetRawRoot();

            // Report an error if this inherited interface is not compliant.
            //
            if (!IsTypeCLSCompliant(RawBaseType, Container))
            {
                ReportErrorOnSymbol(
                    WRNID_InheritedInterfaceNotCLSCompliant2,
                    Container,
                    Container->GetName(),
                    RawBaseType->ChaseToType()->GetErrorName(m_Compiler));
            }
        }
    }
}
Esempio n. 5
0
bool TypeExtensionIterator::MoveNext()
{
    BCSYM_NamedRoot * pNamed = NULL;
    do
    {
        pNamed = m_childIterator.GetNext();
        if (pNamed && pNamed->IsContainer())
        {
            BCSYM_Container *pContainer = pNamed->PContainer();

            // Perf: We are only interested in looking at types marked as containing extension methods.  So only load the 
            // type's children if the type says it contains extension methods.

            BCSYM *pContainerAfterDiggingThroughAlias = pContainer->DigThroughAlias();

            if (pContainerAfterDiggingThroughAlias->IsClass())
            {
                if (pContainerAfterDiggingThroughAlias->PClass()->ContainsExtensionMethods())
                {
                    pContainer->EnsureChildrenLoaded();
                }
            }
            else if (!pContainer->GetCompilerFile() ||
                (pContainer->GetCompilerFile()->IsMetaDataFile() && pContainer->GetCompilerFile()->ContainsExtensionMethods()))
            {
                pContainer->EnsureChildrenLoaded();
            }
        }
    }
    while (pNamed && ! pNamed->IsTypeExtension());

    if (pNamed)
    {
        m_pCurrent = pNamed->PClass();
    }
    else
    {
        m_pCurrent = NULL;
    }

    return m_pCurrent;
}
void CLSComplianceChecker::VerifyEnumUnderlyingTypeForCLSCompliance(BCSYM_Container * PossibleEnum)
{
    VSASSERT( PossibleEnum->IsCLSCompliant(),
                    "Non-CLS compliant container unexpected!!!");

    if (!PossibleEnum->IsEnum())
    {
        return;
    }

    BCSYM *UnderlyingType = PossibleEnum->PClass()->GetUnderlyingTypeForEnum();

    if (!IsTypeCLSCompliant(UnderlyingType, PossibleEnum))
    {
        // Underlying type '|1' of enum is not CLS Compliant.

        ReportErrorOnSymbol(
            WRNID_EnumUnderlyingTypeNotCLS1,
            PossibleEnum,
            UnderlyingType->GetErrorName(m_Compiler));
    }
}
Esempio n. 7
0
BCSYM*
Bindable::BasesIter::GetBaseInterface
(
    BCSYM_Implements *&LinkToBase
)
{
    BCSYM *Base = NULL;

    do
    {
        do
        {
            if (!LinkToBase)
            {
                return NULL;
            }

            if (!LinkToBase->IsBad())
            {
                break;
            }

            LinkToBase = LinkToBase->GetNext();

        } while(true);

        Base = LinkToBase->GetInterfaceIfExists();

        if (Base && !Base->IsBad())
        {
            break;
        }

        LinkToBase = LinkToBase->GetNext();

    } while(true);

    return Base;
}
Esempio n. 8
0
/*****************************************************************************
;ValidateHandlesLists

Given Method() Handles X1.SomeEvent

    1. verify that X1 is a valid WithEvents variable
    2. verify that X1 sources SomeEvent()
*****************************************************************************/
void
Bindable::ValidateAndHookUpHandles
(
    BCSYM_HandlesList *HandlesEntry,
    BCSYM_MethodImpl *HandlingMethod
)
{
    VSASSERT( !HandlesEntry->IsBad(), "Bad handles unexpected here!!");
    VSASSERT( CurrentContainer()->IsClass(),
                    "Non-classes/non-structures/non-modules cannot have handles clauses!!");

    // Dev10#489103: if the handling method is bad, then we can't really tell whether it handles the event:
    if (HandlingMethod->IsBadParamTypeOrReturnType())
    {
        HandlesEntry->SetIsBad();
        return;
    }

    Symbols
        SymbolFactory(
            CurrentCompilerInstance(),
            CurrentAllocator(),
            NULL,
            CurrentGenericBindingCache());

    BCSYM_Class *ContainerOfHandlingMethod = CurrentContainer()->PClass();

    BCSYM *TypeToFindEventIn;
    BCSYM_Property *EventSourceProperty = NULL;
    BCSYM_Property *WithEventsProperty;
    BCSYM *InstanceTypeThroughWhichEventIsAccessed;

    if (HandlesEntry->IsMyBase())
    {
        TypeToFindEventIn = TypeHelpers::GetBaseClass(ContainerOfHandlingMethod, SymbolFactory);

        // A bad base is no base
        if (!TypeToFindEventIn)
        {
            HandlesEntry->SetIsBad();
            return;
        }

        InstanceTypeThroughWhichEventIsAccessed = ContainerOfHandlingMethod;
    }
    else if (HandlesEntry->IsEventFromMeOrMyClass())
    {
        if (ContainerOfHandlingMethod->IsGeneric())
        {
            TypeToFindEventIn =
                SynthesizeOpenGenericBinding(
                    ContainerOfHandlingMethod,
                    SymbolFactory);
        }
        else
        {
            TypeToFindEventIn = ContainerOfHandlingMethod;
        }

        InstanceTypeThroughWhichEventIsAccessed = ContainerOfHandlingMethod;
    }
    else
    {
        WithEventsProperty = HandlesEntry->GetWithEventsProperty();

        VSASSERT( WithEventsProperty,
                        "How can a non-bad handles entry not have a withevents property ?");

        BCSYM_Variable *WithEventsVar = WithEventsProperty->CreatedByWithEventsDecl();

        VSASSERT( WithEventsVar,
                        "How can a non-bad handles entry not refer to a withevents var ?");

        if (WithEventsVar->IsBad() ||
            WithEventsVar->IsBadVariableType())
        {
            HandlesEntry->SetIsBad();
            return;
        }

        BCSYM *TypeOfWithEventsVar = WithEventsProperty->GetType();

        VSASSERT( TypeOfWithEventsVar->IsContainer() ||
                  (TypeOfWithEventsVar->IsGenericParam() &&
                        TypeOfWithEventsVar->PGenericParam()->IsReferenceType()),
                            "What else can the type of a withevents variable be ?");

        if (HandlesEntry->GetEventSourcePropertyName())
        {
            // If withevents variable type is type parameter, then search in its class constraint,
            // else search in the withevents variable type itself.
            //
            EventSourceProperty =
                GetEventSourceProperty(
                    TypeOfWithEventsVar,
                    HandlesEntry->GetEventSourcePropertyName());

            if (!EventSourceProperty)
            {
                // "'Handles' must specify a 'WithEvents' variable or 'MyBase' qualified with a single identifier."

                ReportErrorOnSymbol(
                    IsStdModule(CurrentContainer()) ?
                        ERRID_HandlesSyntaxInModule :
                        ERRID_HandlesSyntaxInClass,
                    CurrentErrorLog(HandlingMethod),
                    HandlesEntry);

                HandlesEntry->SetIsBad();
                return;
            }

            // 






            HandlesEntry->SetEventSourceProperty(EventSourceProperty);

            // 


            VSASSERT( EventSourceProperty->GetType()->IsContainer(),
                            "Referring Property - What else can a type that is not a named type be ?");

            TypeToFindEventIn = EventSourceProperty->GetType();
        }
        else
        {
            TypeToFindEventIn = TypeOfWithEventsVar;
        }

        InstanceTypeThroughWhichEventIsAccessed = TypeToFindEventIn;
    }

    VSASSERT( TypeToFindEventIn, "No type to find the event in ?");

    bool IsBadName;
    BCSYM_NamedRoot *EventDecl =
        Semantics::EnsureNamedRoot
        (
            Semantics::InterpretName
            (
                HandlesEntry->GetEventName(),
                *(HandlesEntry->GetLocationOfEvent()),
                TypeToFindEventIn->IsContainer() ?
                    TypeToFindEventIn->PContainer()->GetHash() :
                    NULL,
                TypeToFindEventIn->IsGenericParam() ?
                    TypeToFindEventIn->PGenericParam() :
                    NULL,
                NameSearchIgnoreParent | NameSearchEventReference | NameSearchIgnoreExtensionMethods,
                InstanceTypeThroughWhichEventIsAccessed,
                ContainerOfHandlingMethod->GetHash(),     // Current Context
                CurrentErrorLog(HandlingMethod),
                CurrentCompilerInstance(),
                CurrentCompilerHost(),
                m_CompilationCaches,
                CurrentSourceFile(HandlingMethod),
                false,                                    // don't perform obsolete checks
                IsBadName,
                NULL,   // the binding context is not required here since the synthesized
                        // code has the withevents variable from which the type binding
                        // information is obtained
                NULL,
                -1
            )
        );


    if (IsBadName)
    {
        HandlesEntry->SetIsBad();
        return;
    }

    if (!EventDecl || !EventDecl->IsEventDecl())
    {
        ReportErrorAtLocation(
            ERRID_EventNotFound1,
            CurrentErrorLog(HandlingMethod),
            HandlesEntry->GetLocationOfEvent(),
            HandlesEntry->GetEventName());

        HandlesEntry->SetIsBad();
        return;
    }

    if (EventDecl->IsBad())
    {
        HandlesEntry->SetIsBad();
        return;
    }


    BCSYM_EventDecl *Event = EventDecl->PEventDecl();
    HandlesEntry->SetEvent(Event);

    // [....] - 11/17/2005
    // See Bug # 544269
    // The call to ResolveAllNamedTypesForContainer needed to be replaced with a call
    // to ResolveShadowingOverloadingAndOverridingForContainer because event signatures
    // are not necessarily setup untill after ResolveShadowingOverloadingAndOverriding
    // has been called.

    // Go and bind the event we are comparing against up to the state we need for
    // validating handles.
    ResolveShadowingOverloadingOverridingAndCheckGenericsForContainer(Event->GetContainer(), m_CompilationCaches);


    // Check for bad param types here (VSW#172753).
    if (Event->GetDelegate() &&
        Event->GetDelegate()->IsContainer() &&
        DefinedInMetaData(Event->GetDelegate()->PContainer()))
    {
        for (BCSYM_Param *Param = Event->GetFirstParam();
             Param;
             Param = Param->GetNext())
        {
            if (Param->GetType()->IsBad())
            {
                Param->GetType()->PNamedRoot()->ReportError(
                    CurrentCompilerInstance(),
                    CurrentErrorLog(HandlingMethod),
                    HandlesEntry->GetLocationOfEvent());

                HandlesEntry->SetIsBad();
                return;
            }
        }
    }

    BCSYM_GenericBinding *EventGenericBindingContext =
        DeriveGenericBindingForMemberReference(TypeToFindEventIn, Event, SymbolFactory, CurrentCompilerHost());

   MethodConversionClass MethodConversion = Semantics::ClassifyMethodConversion(
            HandlingMethod,
            GenericBindingInfo(),
            Event,
            EventGenericBindingContext,
            false, //IgnoreReturnValueErrorsForInference
            &SymbolFactory,
            CurrentCompilerHost());

    SourceFile * SourceFile = HandlingMethod->GetSourceFile();

    if (!Semantics::IsSupportedMethodConversion(
            SourceFile->GetOptionFlags() & OPTION_OptionStrict,
            MethodConversion))
    {
        // "Method '|1' cannot handle Event '|2' because they do not have the same signature."

        StringBuffer HandlingMethodRepresentation;
        HandlingMethod->GetBasicRep(CurrentCompilerInstance(), NULL, &HandlingMethodRepresentation);

        StringBuffer EventRepresentation;
        Event->GetBasicRep(CurrentCompilerInstance(), NULL, &EventRepresentation, EventGenericBindingContext);

        ReportErrorAtLocation(
            ERRID_EventHandlerSignatureIncompatible2,
            CurrentErrorLog(HandlingMethod),
            HandlesEntry->GetLocationOfEvent(),
            HandlingMethodRepresentation.GetString(),
            EventRepresentation.GetString());

        HandlesEntry->SetIsBad();
        return;
    }

    // Hook up handlers to the events they specify in their handles clauses

    if (HandlesEntry->IsMyBase() ||
        HandlesEntry->IsEventFromMeOrMyClass())
    {
        // For these cases, we search for valid MyBase, Me, MyClass handles clauses and set up the
        // addhandlers in all constructors that directly call a base constructor. This is done in
        // semantics in initializefields because that is when the information whether it directly
        // calls the base constructor is known.
        //

        const bool BuildSharedConstructor = true;

        if (HandlesEntry->GetEvent()->IsShared() &&
            HandlingMethod->IsShared())
        {
            // Make sure a shared constructor is present, else synthesize one

            if (!ContainerOfHandlingMethod->GetSharedConstructor(CurrentCompilerInstance()))
            {
                // Synthesize one
                SynthesizeConstructor(BuildSharedConstructor);
            }
        }
        else
        {
            // Make sure an Instance constructor is present, else synthesize one

            if (!ContainerOfHandlingMethod->GetFirstInstanceConstructor(CurrentCompilerInstance()))
            {
                // Synthesize one
                SynthesizeConstructor(!BuildSharedConstructor);
            }
        }
    }
    else
    {
        VSASSERT( WithEventsProperty->SetProperty(),
                        "How can there be no set accessor for a withevents property ?");


        if (WithEventsProperty->IsShared() &&
            !HandlingMethod->IsShared())
        {
            // "Events of shared WithEvents variables cannot be handled by non-shared methods."

            ReportErrorAtLocation(
                ERRID_SharedEventNeedsSharedHandler,
                CurrentErrorLog(HandlingMethod),
                HandlesEntry->GetLocationOfWithEventsVar());

            HandlesEntry->SetIsBad();
            return;
        }

        // 

        // hookup the handler list info for the above handles entry on to the WithEvents_Set.
        // GenWithEventsSetCode() will write synthetic code for these later
        //
        WithEventsProperty->SetProperty()->AddToHandlerList(
            HandlingMethod,
            Event,
            EventGenericBindingContext,
            EventSourceProperty,
            CurrentAllocator());

    }
}
Esempio n. 9
0
bool // true - there are events defined on the WithEvents variable AND they are visible to ContainerOfWithEventsVar
Bindable::CheckForAccessibleEvents
(
    BCSYM *TypeOfWithEventsVar,
    bool ConsiderEventSourcePropertiesToo,
    bool &AnyEventDefined
)
{
    // Note: the calling function is expected to initialize AnyEventDefine to false.
    // We don't do this here because the function is recursive.

    if (TypeOfWithEventsVar->IsBad())
    {
        // This has the effect of sometimes missing an event def we could have found had we not punted.
        // But does it make sense to dig into an interface that is junk?

        return false;
    }

    BCSYM *TypePossiblyContainingEvents;

    if (TypeOfWithEventsVar->IsGenericParam())
    {
        TypePossiblyContainingEvents =
            GetClassConstraint(
                TypeOfWithEventsVar->PGenericParam(),
                CurrentCompilerHost(),
                CurrentAllocator(),
                true,   // ReturnArraysAs"System.Array"
                true    // ReturnValuesAs"System.ValueType"or"System.Enum"
                );

        // See if there are any events in the class constraint
        //
        // Note that the class constraint needs to be checked separately to
        // preserve the shadowing semantics for the events found.
        //
        if (TypePossiblyContainingEvents &&
            !TypePossiblyContainingEvents->IsBad() &&
            CheckForAccessibleEventsInContainer(
                TypePossiblyContainingEvents,
                TypeOfWithEventsVar,
                ConsiderEventSourcePropertiesToo,
                AnyEventDefined))
        {
            return true;
        }

        VSASSERT(TypePossiblyContainingEvents ||
                 TypeOfWithEventsVar->PGenericParam()->IsReferenceType(), "Unexpected withevents type!!!");

        // See if there are any events in the Interface constraints

        BCITER_Constraints ConstraintsIter(TypeOfWithEventsVar->PGenericParam(), true, CurrentCompilerInstance());

        while (BCSYM_GenericConstraint *Constraint = ConstraintsIter.Next())
        {
            VSASSERT(!Constraint->IsBadConstraint(), "Bad constraint unexpected!!!");

            if (!Constraint->IsGenericTypeConstraint())
            {
                continue;
            }

            TypePossiblyContainingEvents = Constraint->PGenericTypeConstraint()->GetType();

            if (!TypePossiblyContainingEvents ||
                TypePossiblyContainingEvents->IsBad() ||
                !TypePossiblyContainingEvents->IsInterface())
            {
                continue;
            }

            if (CheckForAccessibleEventsInContainer(
                    TypePossiblyContainingEvents,
                    TypeOfWithEventsVar,
                    ConsiderEventSourcePropertiesToo,
                    AnyEventDefined))
            {
                return true;
            }
        }

        return false;
    }
    else
    {
        TypePossiblyContainingEvents = TypeOfWithEventsVar;

        return
            CheckForAccessibleEventsInContainer(
                TypePossiblyContainingEvents,
                TypeOfWithEventsVar,
                ConsiderEventSourcePropertiesToo,
                AnyEventDefined);
    }

    return false;
}
Esempio n. 10
0
BCSYM_Property*
Bindable::GetEventSourceProperty
(
    BCSYM *TypeOfWithEventsVar,
    _In_z_ STRING *PropertyName
)
{
    // Need to find a property that sources an event

    // To handle events on subobjects, (internal use only), you must supply a Class
    // type for the WithEvents variable. But for completeness with respect to generics,
    // adding support type parameters with class constraints too.

    BCSYM *TypeToFindEventSourcePropertyIn;

    if (TypeOfWithEventsVar->IsGenericParam())
    {
        // 
        TypeToFindEventSourcePropertyIn =
            GetClassConstraint(
                TypeOfWithEventsVar->PGenericParam(),
                CurrentCompilerHost(),
                CurrentAllocator(),
                false, // don't ReturnArraysAs"System.Array"
                true   // ReturnValuesAs"System.ValueType"or"System.Enum"
                );
    }
    else
    {
        TypeToFindEventSourcePropertyIn = TypeOfWithEventsVar;
    }

    if (!TypeToFindEventSourcePropertyIn ||
        !TypeToFindEventSourcePropertyIn->IsClass())
    {
        return NULL;
    }

    // ---- attributes on all symbols in the TypeOfWithEventsVar container. This is needed
    // in order to verify if a property is an EventSource which is determined by
    // an attribute on the property.
    //
    ----AttributesOnAllSymbolsInContainer(TypeToFindEventSourcePropertyIn->PClass(), m_CompilationCaches);

    BCSYM_NamedRoot *Property =
        TypeToFindEventSourcePropertyIn->PClass()->SimpleBind(NULL, PropertyName);

    while (Property && Property->IsProperty())
    {
        if (ValidEventSourceProperty(Property->PProperty()) &&
            IsAccessible(
                Property->PProperty()->GetProperty(),
                TypeToFindEventSourcePropertyIn->IsGenericBinding() ?
                    TypeToFindEventSourcePropertyIn->PGenericBinding() :
                    NULL,
                CurrentContainer(),
                TypeOfWithEventsVar))
        {
            return Property->PProperty(); // found it
        }

        Property = Property->GetNextOfSameName();

        // Note:
        // - we don't support finding the Property if it is overloaded
        // across classes.
        // - Also note that we don't support digging into bases. This was
        // how the previous impl. was.
        // Given that this is not a user feature, we don't bother doing
        // this extra work.

    }

    return NULL;
}
Esempio n. 11
0
/**************************************************************************************************
;ValidateWithEventsVar

Makes sure the WithEvents var sources at least one visible non-shared event.
Also checks to make sure the type behind the WithEvents var is a class/interface
***************************************************************************************************/
bool // true - WithEvents var is good
Bindable::ValidateWithEventsVar
(
    BCSYM_Variable *WithEventsVar
)
{
    // We don't want to mark withevents variables in references assemblies as bad
    // because we want users to be able to use these withevents variables at least
    // in non-withevents context

    if (WithEventsVar->IsBad())
    {
        return false;
    }

    VSASSERT( WithEventsVar->GetType(),
                    "How can a withevents variable not have atleast a bad type ?");

    if (WithEventsVar->GetType()->IsBad())
    {
        WithEventsVar->SetIsBad();

        // Also, indicate that the problem here is with a type of the with events variable.
        //
        WithEventsVar->PVariable()->SetIsBadVariableType(true);
        return false;
    }

    BCSYM *TypeOfWithEventsVar = WithEventsVar->GetType();

    // The type of a WITHEVENTS variable must be either a
    // - a type parameter with a class constraint or
    // - class or an interface,
    //
    if (!IsClassOrInterface(TypeOfWithEventsVar) &&
        !(TypeOfWithEventsVar->IsGenericParam() &&
            TypeOfWithEventsVar->PGenericParam()->IsReferenceType()))
    {
        ReportErrorOnSymbol(
            ERRID_WithEventsAsStruct,
            CurrentErrorLog(WithEventsVar),
            // Intrinsic types don't have locations, so report error on the withevents var itself
            //
            WithEventsVar->GetRawType()->IsNamedType()?
                WithEventsVar->GetRawType() :
                WithEventsVar);

        // Indicate that the problem here is with the type of the withevents variable, but don't
        // mark the variable itself as completely bad because we still want the user to be able
        // to use it like a normal variable.
        //
        WithEventsVar->PVariable()->SetIsBadVariableType(true);
        return false;
    }

    // The WithEvents variable must source at least one non-shared event that is visible
    // to the container in which it is defined.
    //
    // Errors are no longer reported for this scenario. - see bug VSWhidbey 542456.
    // Because of this CheckForAccessibleEvents is no longer required, but this indirectly/subtly
    // results in calls to ResolveShadowingOverloadingAndOverridingForContainer,
    // ----AttributesOnAllSymbolsInContainer and other such tasks in bindable which later consumers
    // of these withevent variable might be dependent on. So to minimize code churn and risk for
    // whidbey, not removing this call. ----AttributesOnAllSymbolsInContainer is infact known to
    // be required for withevents of interfaces with the CoClass attributes.
    //
    // 




    bool AccessibilityIssue = false;
    CheckForAccessibleEvents(
        TypeOfWithEventsVar,
        // Consider EventSource properties too as being accessible events
        true,
        AccessibilityIssue);

    return true;
}
bool CLSComplianceChecker::IsTypeCLSCompliant(
    BCSYM * RawType,
    BCSYM_NamedRoot * NamedContext)
{
    BCSYM *ActualType = RawType->ChaseToType();

    if (!ActualType ||
        (ActualType->IsNamedRoot() &&
         ActualType->PNamedRoot()->IsBadNamedRoot()))
    {
        return true;
    }

    // Return true for generic params because its constraints are anyway verified separately
    //
    if (ActualType->IsGenericParam())
    {
        return true;
    }

    VSASSERT( ActualType->IsContainer(),
                    "What else can a chased type be ?");

    if (ActualType->IsGenericBinding())
    {
        NameTypeArguments **RawTypeArgumentsSets =
            RawType->IsNamedType() ? RawType->PNamedType()->GetArgumentsArray() : NULL;

        unsigned CountOfRawTypeArgumentsSets =
            RawType->IsNamedType() ? RawType->PNamedType()->GetNameCount() : 0;

        NameTypeArguments *CurrentRawTypeArgumentsSet = NULL;
        unsigned CurrentRawTypeArgumentsSetIndex = CountOfRawTypeArgumentsSets;

        for(BCSYM_GenericTypeBinding *GenericBinding = ActualType->PGenericTypeBinding();
            GenericBinding;
            GenericBinding = GenericBinding->GetParentBinding())
        {
            if (RawTypeArgumentsSets && CurrentRawTypeArgumentsSetIndex > 0)
            {
                CurrentRawTypeArgumentsSet = RawTypeArgumentsSets[--CurrentRawTypeArgumentsSetIndex];

                if (CurrentRawTypeArgumentsSet &&
                    CurrentRawTypeArgumentsSet->m_BoundGenericBinding != GenericBinding)
                {
                    // Lost the one to one mapping between actual type and raw type, so
                    // invalidate and do not use the raw type argument locations.

                    CurrentRawTypeArgumentsSet = NULL;
                }
            }

            unsigned GenericArgumentCount = GenericBinding->GetArgumentCount();
            for(unsigned Index = 0; Index < GenericArgumentCount; Index++)
            {
                BCSYM *ArgumentType = GenericBinding->GetArgument(Index);

                if (!IsTypeCLSCompliant(ArgumentType, NamedContext))
                {
                    Location *ErrorLocation = NULL;

                    if (CurrentRawTypeArgumentsSet &&
                        CurrentRawTypeArgumentsSet->m_ArgumentCount > 0)
                    {
                        ErrorLocation = CurrentRawTypeArgumentsSet->GetArgumentLocation(Index);
                    }

                    if (!ErrorLocation)
                    {
                        ErrorLocation =
                            RawType->IsNamedType() ?
                                RawType->GetLocation() :
                                NamedContext->GetLocation();
                    }

                    ReportErrorAtLocation(
                        WRNID_TypeNotCLSCompliant1,
                        ErrorLocation,
                        NamedContext,
                        ArgumentType->ChaseToType()->GetErrorName(m_Compiler));
                }
            }
        }

        return IsTypeCLSCompliant(ActualType->PGenericTypeBinding()->GetGeneric(), NamedContext);
    }

    return ActualType->PContainer()->IsCLSCompliant();
}
void CLSComplianceChecker::VerifyProcForCLSCompliance(
    BCSYM_Proc * Proc,
    BCSYM_Container * ParentOfProc)
{
    // We won't do CLS Compliance checking on BeginInvoke or EndInvoke (only Invoke) to avoid
    // duplicating our efforts.
    //
    if (ParentOfProc->IsDelegate() &&
        (ParentOfProc->SimpleBind(NULL, STRING_CONST(m_Compiler, DelegateBeginInvoke)) == Proc ||
         ParentOfProc->SimpleBind(NULL, STRING_CONST(m_Compiler, DelegateEndInvoke)) == Proc))
    {
        return;
    }

    // Event specific validation
    //
    if (Proc->IsEventDecl())
    {
        BCSYM_EventDecl *Event = Proc->PEventDecl();
        BCSYM *RawDelegate = Event->GetRawDelegate();
        BCSYM *Delegate = Event->GetDelegate();

        VSASSERT(!(Event->AreParametersObtainedFromDelegate() && Event->IsDelegateFromImplements()),
                        "Event parameters obtained from the implemented event's delegate - unexpected!!!");

        // The event's delegate also needs to be validated, but only when it is not the implicitly
        // generated delegate of this event.
        //
        if (Delegate &&
            Delegate->IsDelegate() &&
            Delegate->PClass()->CreatedByEventDecl() != Event)
        {
            // If this asserts fails, this can possibly cause duplicate errors for type arguments
            // of the delegate and also for errors to be reported at the wrong locations.
            //
            VSASSERT(RawDelegate->IsNamedType() || Event->IsDelegateFromImplements(),
                        "Event delegate should not be the raw delegate type of the implemented event!!!");

            if (!IsTypeCLSCompliant(RawDelegate, Event))
            {
                ReportErrorOnSymbol(
                    WRNID_EventDelegateTypeNotCLSCompliant2,
                    RawDelegate->IsNamedType() ?
                        RawDelegate :
                        Event,
                    Event,
                    Delegate->PClass()->GetQualifiedName(true, ParentOfProc),
                    Event->GetName());
            }
        }

        // If the event's parameters are obtained from its delegate, then its parameters should not
        // be checked here because they will be validated when the delegate itself is checked.
        //
        if (Event->AreParametersObtainedFromDelegate())
        {
            return;
        }
    }


    // Check the return type.
    //
    if (!IsTypeCLSCompliant(Proc->GetRawType(), Proc))
    {
        ReportErrorOnSymbol(
            WRNID_ProcTypeNotCLSCompliant1,
            Proc,
            Proc->GetName());
    }

    // Check the parameters.
    //
    for(BCSYM_Param *Param = Proc->GetFirstParam();
        Param;
        Param = Param->GetNext())
    {
        if (!IsTypeCLSCompliant(Param->GetRawType(), Proc))
        {
            ReportErrorOnSymbol(
                WRNID_ParamNotCLSCompliant1,
                Param,
                Proc,
                Param->GetName());
        }
        else if (Param->IsOptional() && Param->IsParamWithValue())
        {
            BCSYM_Expression *OptionalValue =
                Param->PParamWithValue()->GetExpression();

            if (OptionalValue &&
                // SByte, UInt16, Uint32, Uint64 constants are not CLS compliant
                //
                (OptionalValue->GetValue().TypeCode == t_i1 ||
                    OptionalValue->GetValue().TypeCode == t_ui2 ||
                    OptionalValue->GetValue().TypeCode == t_ui4 ||
                    OptionalValue->GetValue().TypeCode == t_ui8))

            {
                ReportErrorOnSymbol(
                    WRNID_OptionalValueNotCLSCompliant1,
                    Param->PParamWithValue()->GetExpression()->HasLocation() ?
                        (BCSYM *)Param->PParamWithValue()->GetExpression() :
                        Param,
                    Proc,
                    Param->GetName());
            }
        }
    }

    VerifyOverloadsForCLSCompliance(Proc);
    VerifyConstraintsAreCLSCompliant(Proc);

}