internal static AggregateSymbol InitializePredefinedType(AggregateSymbol sym, PredefinedType pt) { sym.SetPredefined(true); sym.SetPredefType(pt); sym.SetSkipUDOps(pt <= PredefinedType.PT_ENUM && pt != PredefinedType.PT_INTPTR && pt != PredefinedType.PT_UINTPTR && pt != PredefinedType.PT_TYPE); return sym; }
public MethodSymbol LookupInvokeMeth(AggregateSymbol pAggDel) { Debug.Assert(pAggDel.AggKind() == AggKindEnum.Delegate); for (Symbol pSym = LookupAggMember(GetNameManager().GetPredefName(PredefinedName.PN_INVOKE), pAggDel, symbmask_t.MASK_ALL); pSym != null; pSym = LookupNextSym(pSym, pAggDel, symbmask_t.MASK_ALL)) { if (pSym.IsMethodSymbol() && pSym.AsMethodSymbol().isInvoke()) { return pSym.AsMethodSymbol(); } } return null; }
// Aggregate public AggregateType CreateAggregateType( Name name, AggregateSymbol parent, TypeArray typeArgsThis, AggregateType outerType) { AggregateType type = new AggregateType(); type.outerType = outerType; type.SetOwningAggregate(parent); type.SetTypeArgsThis(typeArgsThis); type.SetName(name); type.SetTypeKind(TypeKind.TK_AggregateType); return type; }
public AggregateDeclaration CreateAggregateDecl(AggregateSymbol agg, Declaration declOuter) { Debug.Assert(agg != null); //Debug.Assert(declOuter == null || declOuter.Bag() == agg.Parent); // DECLSYMs are not parented like named symbols. AggregateDeclaration sym = newBasicSym(SYMKIND.SK_AggregateDeclaration, agg.name, null).AsAggregateDeclaration(); if (declOuter != null) { declOuter.AddToChildList(sym); } agg.AddDecl(sym); Debug.Assert(sym != null); return (sym); }
private MethodSymbol LoadMethod( AggregateSymbol type, int[] signature, int cMethodTyVars, Name methodName, ACCESS methodAccess, bool isStatic, bool isVirtual ) { Debug.Assert(signature != null); Debug.Assert(cMethodTyVars >= 0); Debug.Assert(methodName != null); if (type == null) { return null; } TypeArray classTyVars = type.GetTypeVarsAll(); int index = 0; CType returnType = LoadTypeFromSignature(signature, ref index, classTyVars); if (returnType == null) { return null; } TypeArray argumentTypes = LoadTypeArrayFromSignature(signature, ref index, classTyVars); if (argumentTypes == null) { return null; } TypeArray standardMethodTyVars = GetTypeManager().GetStdMethTyVarArray(cMethodTyVars); MethodSymbol ret = LookupMethodWhileLoading(type, cMethodTyVars, methodName, methodAccess, isStatic, isVirtual, returnType, argumentTypes); if (ret == null) { RuntimeBinderSymbolTable.AddPredefinedMethodToSymbolTable(type, methodName); ret = LookupMethodWhileLoading(type, cMethodTyVars, methodName, methodAccess, isStatic, isVirtual, returnType, argumentTypes); } return ret; }
private MethodSymbol FindDelegateConstructor(AggregateSymbol delegateType) { Debug.Assert(delegateType != null && delegateType.IsDelegate()); MethodSymbol ctor = FindDelegateConstructor(delegateType, s_DelegateCtorSignature1); if (ctor == null) { ctor = FindDelegateConstructor(delegateType, s_DelegateCtorSignature2); } return ctor; }
private bool bindImplicitConversionBetweenSimpleTypes(AggregateType aggTypeSrc) { AggregateSymbol aggSrc = aggTypeSrc.getAggregate(); Debug.Assert(aggSrc.getThisType().isSimpleType()); Debug.Assert(_typeDest.isSimpleType()); Debug.Assert(aggSrc.IsPredefined() && _typeDest.isPredefined()); PredefinedType ptSrc = aggSrc.GetPredefType(); PredefinedType ptDest = _typeDest.getPredefType(); ConvKind convertKind; bool fConstShrinkCast = false; Debug.Assert((int)ptSrc < NUM_SIMPLE_TYPES && (int)ptDest < NUM_SIMPLE_TYPES); // 13.1.7 Implicit constant expression conversions // // An implicit constant expression conversion permits the following conversions: // * A constant-expression (14.16) of type int can be converted to type sbyte, byte, short, // ushort, uint, or ulong, provided the value of the constant-expression is within the range // of the destination type. // * A constant-expression of type long can be converted to type ulong, provided the value of // the constant-expression is not negative. // Note: Don't use GetConst here since the conversion only applies to bona-fide compile time constants. if (_exprSrc != null && _exprSrc.isCONSTANT_OK() && ((ptSrc == PredefinedType.PT_INT && ptDest != PredefinedType.PT_BOOL && ptDest != PredefinedType.PT_CHAR) || (ptSrc == PredefinedType.PT_LONG && ptDest == PredefinedType.PT_ULONG)) && isConstantInRange(_exprSrc.asCONSTANT(), _typeDest)) { // Special case (CLR 6.1.6): if integral constant is in range, the conversion is a legal implicit conversion. convertKind = ConvKind.Implicit; fConstShrinkCast = _needsExprDest && (GetConvKind(ptSrc, ptDest) != ConvKind.Implicit); } else if (ptSrc == ptDest) { // Special case: precision limiting casts to float or double Debug.Assert(ptSrc == PredefinedType.PT_FLOAT || ptSrc == PredefinedType.PT_DOUBLE); Debug.Assert(0 != (_flags & CONVERTTYPE.ISEXPLICIT)); convertKind = ConvKind.Implicit; } else { convertKind = GetConvKind(ptSrc, ptDest); Debug.Assert(convertKind != ConvKind.Identity); // identity conversion should have been handled at first. } if (convertKind != ConvKind.Implicit) { return(false); } // An implicit conversion exists. Do the conversion. if (_exprSrc.GetConst() != null) { // Fold the constant cast if possible. ConstCastResult result = _binder.bindConstantCast(_exprSrc, _exprTypeDest, _needsExprDest, out _exprDest, false); if (result == ConstCastResult.Success) { return(true); // else, don't fold and use a regular cast, below. } } if (isUserDefinedConversion(ptSrc, ptDest)) { if (!_needsExprDest) { return(true); } // According the language, this is a standard conversion, but it is implemented // through a user-defined conversion. Because it's a standard conversion, we don't // test the NOUDC flag here. return(_binder.bindUserDefinedConversion(_exprSrc, aggTypeSrc, _typeDest, _needsExprDest, out _exprDest, true)); } if (_needsExprDest) { _binder.bindSimpleCast(_exprSrc, _exprTypeDest, out _exprDest); } return(true); }
private AggregateSymbol FindPredefinedTypeCore(Name name, NamespaceOrAggregateSymbol bag, KAID aid, AggKindEnum aggKind, int arity, out AggregateSymbol paggAmbig, out AggregateSymbol paggBad) { AggregateSymbol aggFound = null; paggAmbig = null; paggBad = null; for (AggregateSymbol aggCur = _pBSymmgr.LookupGlobalSymCore(name, bag, symbmask_t.MASK_AggregateSymbol).AsAggregateSymbol(); aggCur != null; aggCur = BSYMMGR.LookupNextSym(aggCur, bag, symbmask_t.MASK_AggregateSymbol).AsAggregateSymbol()) { if (!aggCur.InAlias(aid) || aggCur.GetTypeVarsAll().size != arity) { continue; } if (aggCur.AggKind() != aggKind) { if (paggBad == null) { paggBad = aggCur; } continue; } if (aggFound != null) { Debug.Assert(paggAmbig == null); paggAmbig = aggCur; break; } aggFound = aggCur; if (paggAmbig == null) { break; } } return aggFound; }
public TypeParameterSymbol CreateClassTypeParameter(Name pName, AggregateSymbol pParent, int index, int indexTotal) { TypeParameterSymbol pResult = newBasicSym(SYMKIND.SK_TypeParameterSymbol, pName, pParent).AsTypeParameterSymbol(); pResult.SetIndexInOwnParameters(index); pResult.SetIndexInTotalParameters(indexTotal); pResult.SetIsMethodTypeParameter(false); pResult.SetAccess(ACCESS.ACC_PRIVATE); // Always private - not accessible anywhere except their own type. return pResult; }
///////////////////////////////////////////////////////////////////////////////// private CType GetConstructedType(Type type, AggregateSymbol agg) { // We've found the one we want, so return it. if (type.GetTypeInfo().IsGenericType) { // If we're a generic type, then we need to add the type arguments. List<CType> types = new List<CType>(); foreach (Type argument in type.GetGenericArguments()) { types.Add(GetCTypeFromType(argument)); } TypeArray typeArray = _bsymmgr.AllocParams(types.ToArray()); AggregateType aggType = _typeManager.GetAggregate(agg, typeArray); return aggType; } CType ctype = agg.getThisType(); return ctype; }
public void InsertAggregate( AggregateSymbol aggregate, AggregateType outer, TypeArray args, AggregateType pAggregate) { Debug.Assert(LookupAggregate(aggregate, outer, args) == null); _aggregateTable.Add(MakeKey(aggregate, MakeKey(outer, args)), pAggregate); }
public CMethodIterator(Name name, TypeArray containingTypes, CType qualifyingType, AggregateSymbol context, int arity, EXPRFLAG flags, symbmask_t mask, ArgInfos nonTrailingNamedArguments) { Debug.Assert(name != null); Debug.Assert(containingTypes != null); Debug.Assert(containingTypes.Count != 0); _name = name; _containingTypes = containingTypes; _qualifyingType = qualifyingType; _context = context; _arity = arity; _flags = flags; _mask = mask; _nonTrailingNamedArguments = nonTrailingNamedArguments; }
// // SymbolLoader forwarders (end) ///////////////////////////////////////////////////////////////////////////////// // // Utility methods // private ACCESSERROR CheckAccessCore(Symbol symCheck, AggregateType atsCheck, Symbol symWhere, CType typeThru) { Debug.Assert(symCheck != null); Debug.Assert(atsCheck == null || symCheck.parent == atsCheck.getAggregate()); Debug.Assert(typeThru == null || typeThru is AggregateType || typeThru is TypeParameterType || typeThru is ArrayType || typeThru is NullableType || typeThru is ErrorType); switch (symCheck.GetAccess()) { default: throw Error.InternalCompilerError(); //return ACCESSERROR.ACCESSERROR_NOACCESS; case ACCESS.ACC_UNKNOWN: return(ACCESSERROR.ACCESSERROR_NOACCESS); case ACCESS.ACC_PUBLIC: return(ACCESSERROR.ACCESSERROR_NOERROR); case ACCESS.ACC_PRIVATE: case ACCESS.ACC_PROTECTED: if (symWhere == null) { return(ACCESSERROR.ACCESSERROR_NOACCESS); } break; case ACCESS.ACC_INTERNAL: case ACCESS.ACC_INTERNALPROTECTED: // Check internal, then protected. if (symWhere == null) { return(ACCESSERROR.ACCESSERROR_NOACCESS); } if (symWhere.SameAssemOrFriend(symCheck)) { return(ACCESSERROR.ACCESSERROR_NOERROR); } if (symCheck.GetAccess() == ACCESS.ACC_INTERNAL) { return(ACCESSERROR.ACCESSERROR_NOACCESS); } break; } // Find the inner-most enclosing AggregateSymbol. AggregateSymbol aggWhere = null; for (Symbol symT = symWhere; symT != null; symT = symT.parent) { if (symT is AggregateSymbol aggSym) { aggWhere = aggSym; break; } if (symT is AggregateDeclaration aggDec) { aggWhere = aggDec.Agg(); break; } } if (aggWhere == null) { return(ACCESSERROR.ACCESSERROR_NOACCESS); } // Should always have atsCheck for private and protected access check. // We currently don't need it since access doesn't respect instantiation. // We just use symWhere.parent as AggregateSymbol instead. AggregateSymbol aggCheck = symCheck.parent as AggregateSymbol; // First check for private access. for (AggregateSymbol agg = aggWhere; agg != null; agg = agg.GetOuterAgg()) { if (agg == aggCheck) { return(ACCESSERROR.ACCESSERROR_NOERROR); } } if (symCheck.GetAccess() == ACCESS.ACC_PRIVATE) { return(ACCESSERROR.ACCESSERROR_NOACCESS); } // Handle the protected case - which is the only real complicated one. Debug.Assert(symCheck.GetAccess() == ACCESS.ACC_PROTECTED || symCheck.GetAccess() == ACCESS.ACC_INTERNALPROTECTED); // Check if symCheck is in aggWhere or a base of aggWhere, // or in an outer agg of aggWhere or a base of an outer agg of aggWhere. AggregateType atsThru = null; if (typeThru != null && !symCheck.isStatic) { atsThru = SymbolLoader.GetAggTypeSym(typeThru); } // Look for aggCheck among the base classes of aggWhere and outer aggs. bool found = false; for (AggregateSymbol agg = aggWhere; agg != null; agg = agg.GetOuterAgg()) { Debug.Assert(agg != aggCheck); // We checked for this above. // Look for aggCheck among the base classes of agg. if (agg.FindBaseAgg(aggCheck)) { found = true; // aggCheck is a base class of agg. Check atsThru. // For non-static protected access to be legal, atsThru must be an instantiation of // agg or a CType derived from an instantiation of agg. In this case // all that matters is that agg is in the base AggregateSymbol chain of atsThru. The // actual AGGTYPESYMs involved don't matter. if (atsThru == null || atsThru.getAggregate().FindBaseAgg(agg)) { return(ACCESSERROR.ACCESSERROR_NOERROR); } } } // the CType in which the method is being called has no relationship with the // CType on which the method is defined surely this is NOACCESS and not NOACCESSTHRU if (found == false) { return(ACCESSERROR.ACCESSERROR_NOACCESS); } return((atsThru == null) ? ACCESSERROR.ACCESSERROR_NOACCESS : ACCESSERROR.ACCESSERROR_NOACCESSTHRU); }
public Symbol LookupAggMember(Name name, AggregateSymbol agg, symbmask_t mask) { return(getBSymmgr().LookupAggMember(name, agg, mask)); }
private AggregateSymbol GetOptPredefAgg(PredefinedType pt, bool fEnsureState) { AggregateSymbol agg = GetTypeManager().GetOptPredefAgg(pt); return(agg); }
protected Symbol newBasicSym( SYMKIND kind, Name name, ParentSymbol parent) { // The parser creates names with PN_MISSING when attempting to recover from errors // To prevent spurious errors, we create SYMs with a different name (PN_MISSINGSYM) // so that they are never found when doing lookup. if (name == m_pMissingNameNode) { name = m_pMissingNameSym; } Symbol sym; switch (kind) { case SYMKIND.SK_NamespaceSymbol: sym = new NamespaceSymbol(); sym.name = name; break; case SYMKIND.SK_NamespaceDeclaration: sym = new NamespaceDeclaration(); sym.name = name; break; case SYMKIND.SK_AssemblyQualifiedNamespaceSymbol: sym = new AssemblyQualifiedNamespaceSymbol(); sym.name = name; break; case SYMKIND.SK_AggregateSymbol: sym = new AggregateSymbol(); sym.name = name; break; case SYMKIND.SK_AggregateDeclaration: sym = new AggregateDeclaration(); sym.name = name; break; case SYMKIND.SK_TypeParameterSymbol: sym = new TypeParameterSymbol(); sym.name = name; break; case SYMKIND.SK_FieldSymbol: sym = new FieldSymbol(); sym.name = name; break; case SYMKIND.SK_LocalVariableSymbol: sym = new LocalVariableSymbol(); sym.name = name; break; case SYMKIND.SK_MethodSymbol: sym = new MethodSymbol(); sym.name = name; break; case SYMKIND.SK_PropertySymbol: sym = new PropertySymbol(); sym.name = name; break; case SYMKIND.SK_EventSymbol: sym = new EventSymbol(); sym.name = name; break; case SYMKIND.SK_TransparentIdentifierMemberSymbol: sym = new TransparentIdentifierMemberSymbol(); sym.name = name; break; case SYMKIND.SK_Scope: sym = new Scope(); sym.name = name; break; case SYMKIND.SK_LabelSymbol: sym = new LabelSymbol(); sym.name = name; break; case SYMKIND.SK_GlobalAttributeDeclaration: sym = new GlobalAttributeDeclaration(); sym.name = name; break; case SYMKIND.SK_UnresolvedAggregateSymbol: sym = new UnresolvedAggregateSymbol(); sym.name = name; break; case SYMKIND.SK_InterfaceImplementationMethodSymbol: sym = new InterfaceImplementationMethodSymbol(); sym.name = name; break; case SYMKIND.SK_IndexerSymbol: sym = new IndexerSymbol(); sym.name = name; break; case SYMKIND.SK_ParentSymbol: sym = new ParentSymbol(); sym.name = name; break; case SYMKIND.SK_IteratorFinallyMethodSymbol: sym = new IteratorFinallyMethodSymbol(); sym.name = name; break; default: throw Error.InternalCompilerError(); } sym.setKind(kind); if (parent != null) { // Set the parent element of the child symbol. parent.AddToChildList(sym); m_pSymTable.InsertChild(parent, sym); } return(sym); }
/*************************************************************************************************** * Determine whether there is an explicit or implicit reference conversion (or identity conversion) * from typeSrc to typeDst. This is when: * * 13.2.3 Explicit reference conversions * * The explicit reference conversions are: * From object to any reference-type. * From any class-type S to any class-type T, provided S is a base class of T. * From any class-type S to any interface-type T, provided S is not sealed and provided S does not implement T. * From any interface-type S to any class-type T, provided T is not sealed or provided T implements S. * From any interface-type S to any interface-type T, provided S is not derived from T. * From an array-type S with an element type SE to an array-type T with an element type TE, provided all of the following are true: * o S and T differ only in element type. (In other words, S and T have the same number of dimensions.) * o An explicit reference conversion exists from SE to TE. * From System.Array and the interfaces it implements, to any array-type. * From System.Delegate and the interfaces it implements, to any delegate-type. * From a one-dimensional array-type S[] to System.Collections.Generic.IList<T>, System.Collections.Generic.IReadOnlyList<T> and their base interfaces, provided there is an explicit reference conversion from S to T. * From a generic delegate type S to generic delegate type T, provided all of the follow are true: * o Both types are constructed generic types of the same generic delegate type, D<X1,... Xk>.That is, * S is D<S1,... Sk> and T is D<T1,... Tk>. * o S is not compatible with or identical to T. * o If type parameter Xi is declared to be invariant then Si must be identical to Ti. * o If type parameter Xi is declared to be covariant ("out") then Si must be convertible * to Ti via an identify conversion, implicit reference conversion, or explicit reference conversion. * o If type parameter Xi is declared to be contravariant ("in") then either Si must be identical to Ti, * or Si and Ti must both be reference types. * From System.Collections.Generic.IList<T>, System.Collections.Generic.IReadOnlyList<T> and their base interfaces to a one-dimensional array-type S[], provided there is an implicit or explicit reference conversion from S[] to System.Collections.Generic.IList<T> or System.Collections.Generic.IReadOnlyList<T>. This is precisely when either S and T are the same type or there is an implicit or explicit reference conversion from S to T. * * For a type-parameter T that is known to be a reference type (§25.7), the following explicit reference conversions exist: * From the effective base class C of T to T and from any base class of C to T. * From any interface-type to T. * From T to any interface-type I provided there isn’t already an implicit reference conversion from T to I. * From a type-parameter U to T provided that T depends on U (§25.7). [Note: Since T is known to be a reference type, within the scope of T, the run-time type of U will always be a reference type, even if U is not known to be a reference type at compile-time. end note] * * Both src and dst are reference types and there is a builtin explicit conversion from * src to dst. * Or src is a reference type and dst is a base type of src (in which case the conversion is * implicit as well). * Or dst is a reference type and src is a base type of dst. * * The latter two cases can happen with type variables even though the other type variable is not * a reference type. ***************************************************************************************************/ public static bool FExpRefConv(SymbolLoader loader, CType typeSrc, CType typeDst) { Debug.Assert(typeSrc != null); Debug.Assert(typeDst != null); if (typeSrc.IsRefType() && typeDst.IsRefType()) { // is there an implicit reference conversion in either direction? // this handles the bulk of the cases ... if (loader.HasIdentityOrImplicitReferenceConversion(typeSrc, typeDst) || loader.HasIdentityOrImplicitReferenceConversion(typeDst, typeSrc)) { return(true); } // For a type-parameter T that is known to be a reference type (§25.7), the following explicit reference conversions exist: // • From any interface-type to T. // • From T to any interface-type I provided there isn’t already an implicit reference conversion from T to I. if (typeSrc.isInterfaceType() && typeDst.IsTypeParameterType()) { return(true); } if (typeSrc.IsTypeParameterType() && typeDst.isInterfaceType()) { return(true); } // * From any class-type S to any interface-type T, provided S is not sealed // * From any interface-type S to any class-type T, provided T is not sealed // * From any interface-type S to any interface-type T, provided S is not derived from T. if (typeSrc.IsAggregateType() && typeDst.IsAggregateType()) { AggregateSymbol aggSrc = typeSrc.AsAggregateType().getAggregate(); AggregateSymbol aggDest = typeDst.AsAggregateType().getAggregate(); if ((aggSrc.IsClass() && !aggSrc.IsSealed() && aggDest.IsInterface()) || (aggSrc.IsInterface() && aggDest.IsClass() && !aggDest.IsSealed()) || (aggSrc.IsInterface() && aggDest.IsInterface())) { return(true); } } // * From an array-type S with an element type SE to an array-type T with an element type TE, provided all of the following are true: // o S and T differ only in element type. (In other words, S and T have the same number of dimensions.) // o An explicit reference conversion exists from SE to TE. if (typeSrc.IsArrayType() && typeDst.IsArrayType()) { return(typeSrc.AsArrayType().rank == typeDst.AsArrayType().rank&& FExpRefConv(loader, typeSrc.AsArrayType().GetElementType(), typeDst.AsArrayType().GetElementType())); } // * From a one-dimensional array-type S[] to System.Collections.Generic.IList<T>, System.Collections.Generic.IReadOnlyList<T> // and their base interfaces, provided there is an explicit reference conversion from S to T. if (typeSrc.IsArrayType()) { if (typeSrc.AsArrayType().rank != 1 || !typeDst.isInterfaceType() || typeDst.AsAggregateType().GetTypeArgsAll().Size != 1) { return(false); } AggregateSymbol aggIList = loader.GetOptPredefAgg(PredefinedType.PT_G_ILIST); AggregateSymbol aggIReadOnlyList = loader.GetOptPredefAgg(PredefinedType.PT_G_IREADONLYLIST); if ((aggIList == null || !loader.IsBaseAggregate(aggIList, typeDst.AsAggregateType().getAggregate())) && (aggIReadOnlyList == null || !loader.IsBaseAggregate(aggIReadOnlyList, typeDst.AsAggregateType().getAggregate()))) { return(false); } return(FExpRefConv(loader, typeSrc.AsArrayType().GetElementType(), typeDst.AsAggregateType().GetTypeArgsAll().Item(0))); } if (typeDst.IsArrayType() && typeSrc.IsAggregateType()) { // * From System.Array and the interfaces it implements, to any array-type. if (loader.HasIdentityOrImplicitReferenceConversion(loader.GetReqPredefType(PredefinedType.PT_ARRAY), typeSrc)) { return(true); } // * From System.Collections.Generic.IList<T>, System.Collections.Generic.IReadOnlyList<T> and their base interfaces to a // one-dimensional array-type S[], provided there is an implicit or explicit reference conversion from S[] to // System.Collections.Generic.IList<T> or System.Collections.Generic.IReadOnlyList<T>. This is precisely when either S and T // are the same type or there is an implicit or explicit reference conversion from S to T. ArrayType arrayDest = typeDst.AsArrayType(); AggregateType aggtypeSrc = typeSrc.AsAggregateType(); if (arrayDest.rank != 1 || !typeSrc.isInterfaceType() || aggtypeSrc.GetTypeArgsAll().Size != 1) { return(false); } AggregateSymbol aggIList = loader.GetOptPredefAgg(PredefinedType.PT_G_ILIST); AggregateSymbol aggIReadOnlyList = loader.GetOptPredefAgg(PredefinedType.PT_G_IREADONLYLIST); if ((aggIList == null || !loader.IsBaseAggregate(aggIList, aggtypeSrc.getAggregate())) && (aggIReadOnlyList == null || !loader.IsBaseAggregate(aggIReadOnlyList, aggtypeSrc.getAggregate()))) { return(false); } CType typeArr = arrayDest.GetElementType(); CType typeLst = aggtypeSrc.GetTypeArgsAll().Item(0); Debug.Assert(!typeArr.IsNeverSameType()); return(typeArr == typeLst || FExpRefConv(loader, typeArr, typeLst)); } if (HasGenericDelegateExplicitReferenceConversion(loader, typeSrc, typeDst)) { return(true); } } else if (typeSrc.IsRefType()) { // conversion of T . U, where T : class, U // .. these constraints implies where U : class return(loader.HasIdentityOrImplicitReferenceConversion(typeSrc, typeDst)); } else if (typeDst.IsRefType()) { // conversion of T . U, where U : class, T // .. these constraints implies where T : class return(loader.HasIdentityOrImplicitReferenceConversion(typeDst, typeSrc)); } return(false); }
public bool computeManagedType(SymbolLoader symbolLoader) { if (IsVoidType()) { return(false); } switch (fundType()) { case FUNDTYPE.FT_NONE: case FUNDTYPE.FT_REF: case FUNDTYPE.FT_VAR: return(true); case FUNDTYPE.FT_STRUCT: if (IsNullableType()) { return(true); } else { AggregateSymbol aggT = getAggregate(); // See if we already know. if (aggT.IsKnownManagedStructStatus()) { return(aggT.IsManagedStruct()); } // Generics are always managed. if (aggT.GetTypeVarsAll().Count > 0) { aggT.SetManagedStruct(true); return(true); } // If the struct layout has an error, don't recurse its children. if (aggT.IsLayoutError()) { aggT.SetUnmanagedStruct(true); return(false); } // at this point we can only determine the managed status // if we have members defined, otherwise we don't know the result if (symbolLoader != null) { for (Symbol ps = aggT.firstChild; ps != null; ps = ps.nextChild) { if (ps.IsFieldSymbol() && !ps.AsFieldSymbol().isStatic) { CType type = ps.AsFieldSymbol().GetType(); if (type.computeManagedType(symbolLoader)) { aggT.SetManagedStruct(true); return(true); } } } aggT.SetUnmanagedStruct(true); } return(false); } default: return(false); } }
///////////////////////////////////////////////////////////////////////////////// private void SetInterfacesOnAggregate(AggregateSymbol aggregate, Type type) { Type[] interfaces; if (type.GetTypeInfo().IsGenericType) { type = type.GetTypeInfo().GetGenericTypeDefinition(); } interfaces = type.GetTypeInfo().ImplementedInterfaces.ToArray(); // We wont be able to find the difference between Ifaces and // IfacesAll anymore - at runtime, the class implements all of its // Ifaces and IfacesAll, so theres no way to differentiate. // // This actually doesn't matter though - for conversions and methodcalls, // we don't really care where they've come from as long as we know the overall // set of IfacesAll. aggregate.SetIfaces(_bsymmgr.AllocParams(interfaces.Length, GetCTypeArrayFromTypes(interfaces))); aggregate.SetIfacesAll(aggregate.GetIfaces()); }
private EventSymbol AddEventToSymbolTable(EventInfo eventInfo, AggregateSymbol aggregate, FieldSymbol addedField) { EventSymbol ev = _symbolTable.LookupSym( GetName(eventInfo.Name), aggregate, symbmask_t.MASK_EventSymbol) as EventSymbol; if (ev != null) { Debug.Assert(ev.AssociatedEventInfo == eventInfo); return ev; } ev = _symFactory.CreateEvent(GetName(eventInfo.Name), aggregate, null); ev.AssociatedEventInfo = eventInfo; // EventSymbol ACCESS access = ACCESS.ACC_PRIVATE; if (eventInfo.AddMethod != null) { ev.methAdd = AddMethodToSymbolTable(eventInfo.AddMethod, aggregate, MethodKindEnum.EventAccessor); ev.methAdd.SetEvent(ev); ev.isOverride = ev.methAdd.IsOverride(); access = ev.methAdd.GetAccess(); } if (eventInfo.RemoveMethod != null) { ev.methRemove = AddMethodToSymbolTable(eventInfo.RemoveMethod, aggregate, MethodKindEnum.EventAccessor); ev.methRemove.SetEvent(ev); ev.isOverride = ev.methRemove.IsOverride(); access = ev.methRemove.GetAccess(); } Debug.Assert(ev.methAdd != null || ev.methRemove != null); ev.isStatic = false; ev.type = GetCTypeFromType(eventInfo.EventHandlerType); // Symbol ev.SetAccess(access); Type eventRegistrationTokenType = EventRegistrationTokenType; if ((object)eventRegistrationTokenType != null && (object)WindowsRuntimeMarshalType != null && ev.methAdd.RetType.AssociatedSystemType == eventRegistrationTokenType && ev.methRemove.Params.Item(0).AssociatedSystemType == eventRegistrationTokenType) { ev.IsWindowsRuntimeEvent = true; } // If we imported a field on the same aggregate, with the same name, and it also // has the same type, then that field is the backing field for this event, and // we mark it as such. This is used for the CSharpIsEventBinder. // In the case of a WindowsRuntime event, the field will be of type // EventRegistrationTokenTable<delegateType>. Type eventRegistrationTokenTableType; if (addedField != null && addedField.GetType() != null && (addedField.GetType() == ev.type || ( addedField.GetType().AssociatedSystemType.IsConstructedGenericType && (object)(eventRegistrationTokenTableType = EventRegistrationTokenTableType) != null && addedField.GetType().AssociatedSystemType.GetGenericTypeDefinition() == eventRegistrationTokenTableType && addedField.GetType().AssociatedSystemType.GenericTypeArguments[0] == ev.type.AssociatedSystemType) )) { addedField.isEvent = true; } return ev; }
private AggCastResult bindExplicitConversionBetweenSimpleTypes(AggregateType aggTypeDest) { // 13.2.1 // // Because the explicit conversions include all implicit and explicit numeric conversions, // it is always possible to convert from any numeric-type to any other numeric-type using // a cast expression (14.6.6). Debug.Assert(_typeSrc != null); Debug.Assert(aggTypeDest != null); if (!_typeSrc.isSimpleType() || !aggTypeDest.isSimpleType()) { return(AggCastResult.Failure); } AggregateSymbol aggDest = aggTypeDest.getAggregate(); Debug.Assert(_typeSrc.isPredefined() && aggDest.IsPredefined()); PredefinedType ptSrc = _typeSrc.getPredefType(); PredefinedType ptDest = aggDest.GetPredefType(); Debug.Assert((int)ptSrc < NUM_SIMPLE_TYPES && (int)ptDest < NUM_SIMPLE_TYPES); ConvKind convertKind = GetConvKind(ptSrc, ptDest); // Identity and implicit conversions should already have been handled. Debug.Assert(convertKind != ConvKind.Implicit); Debug.Assert(convertKind != ConvKind.Identity); if (convertKind != ConvKind.Explicit) { return(AggCastResult.Failure); } if (_exprSrc.GetConst() != null) { // Fold the constant cast if possible. ConstCastResult result = _binder.bindConstantCast(_exprSrc, _exprTypeDest, _needsExprDest, out _exprDest, true); if (result == ConstCastResult.Success) { return(AggCastResult.Success); // else, don't fold and use a regular cast, below. } if (result == ConstCastResult.CheckFailure && 0 == (_flags & CONVERTTYPE.CHECKOVERFLOW)) { return(AggCastResult.Abort); } } bool bConversionOk = true; if (_needsExprDest) { // Explicit conversions involving decimals are bound as user-defined conversions. if (isUserDefinedConversion(ptSrc, ptDest)) { // According the language, this is a standard conversion, but it is implemented // through a user-defined conversion. Because it's a standard conversion, we don't // test the CONVERTTYPE.NOUDC flag here. bConversionOk = _binder.bindUserDefinedConversion(_exprSrc, _typeSrc, aggTypeDest, _needsExprDest, out _exprDest, false); } else { _binder.bindSimpleCast(_exprSrc, _exprTypeDest, out _exprDest, (_flags & CONVERTTYPE.CHECKOVERFLOW) != 0 ? EXPRFLAG.EXF_CHECKOVERFLOW : 0); } } return(bConversionOk ? AggCastResult.Success : AggCastResult.Failure); }
///////////////////////////////////////////////////////////////////////////////// private TypeParameterType AddTypeParameterToSymbolTable( AggregateSymbol agg, MethodSymbol meth, Type t, bool bIsAggregate) { Debug.Assert((agg != null && bIsAggregate) || (meth != null && !bIsAggregate)); TypeParameterSymbol typeParam; if (bIsAggregate) { typeParam = _symFactory.CreateClassTypeParameter( GetName(t), agg, t.GenericParameterPosition, t.GenericParameterPosition); } else { typeParam = _symFactory.CreateMethodTypeParameter( GetName(t), meth, t.GenericParameterPosition, t.GenericParameterPosition); } if ((t.GetTypeInfo().GenericParameterAttributes & GenericParameterAttributes.Covariant) != 0) { typeParam.Covariant = true; } if ((t.GetTypeInfo().GenericParameterAttributes & GenericParameterAttributes.Contravariant) != 0) { typeParam.Contravariant = true; } SpecCons cons = SpecCons.None; if ((t.GetTypeInfo().GenericParameterAttributes & GenericParameterAttributes.DefaultConstructorConstraint) != 0) { cons |= SpecCons.New; } if ((t.GetTypeInfo().GenericParameterAttributes & GenericParameterAttributes.ReferenceTypeConstraint) != 0) { cons |= SpecCons.Ref; } if ((t.GetTypeInfo().GenericParameterAttributes & GenericParameterAttributes.NotNullableValueTypeConstraint) != 0) { cons |= SpecCons.Val; } typeParam.SetConstraints(cons); typeParam.SetAccess(ACCESS.ACC_PUBLIC); TypeParameterType typeParamType = _typeManager.GetTypeParameter(typeParam); return typeParamType; }
public static string GetNiceName(AggregateSymbol type) => type.IsPredefined() ? GetNiceName(type.GetPredefType()) : null;
private AggregateSymbol FindPredefinedTypeCore(Name name, NamespaceOrAggregateSymbol bag, KAID aid, AggKindEnum aggKind, int arity, out AggregateSymbol paggAmbig, out AggregateSymbol paggBad) { AggregateSymbol aggFound = null; paggAmbig = null; paggBad = null; for (AggregateSymbol aggCur = _pBSymmgr.LookupGlobalSymCore(name, bag, symbmask_t.MASK_AggregateSymbol).AsAggregateSymbol(); aggCur != null; aggCur = BSYMMGR.LookupNextSym(aggCur, bag, symbmask_t.MASK_AggregateSymbol).AsAggregateSymbol()) { if (!aggCur.InAlias(aid) || aggCur.GetTypeVarsAll().size != arity) { continue; } if (aggCur.AggKind() != aggKind) { if (paggBad == null) { paggBad = aggCur; } continue; } if (aggFound != null) { Debug.Assert(paggAmbig == null); paggAmbig = aggCur; break; } aggFound = aggCur; if (paggAmbig == null) { break; } } return(aggFound); }
public static Symbol LookupAggMember(Name name, AggregateSymbol agg, symbmask_t mask) => SymbolStore.LookupSym(name, agg, mask);
public Symbol LookupAggMember(Name name, AggregateSymbol agg, symbmask_t mask) { return(tableGlobal.LookupSym(name, agg, mask)); }
/* * returns the inputfile where a symbol was declared. * * returns null for namespaces because they can be declared * in multiple files. */ public InputFile getInputFile() { switch (kind) { case SYMKIND.SK_NamespaceSymbol: case SYMKIND.SK_AssemblyQualifiedNamespaceSymbol: // namespaces don't have input files // call with a NamespaceDeclaration instead Debug.Assert(false); return(null); case SYMKIND.SK_NamespaceDeclaration: return(null); case SYMKIND.SK_AggregateSymbol: { #if !CSEE AggregateSymbol AggregateSymbol = this.AsAggregateSymbol(); if (!AggregateSymbol.IsSource()) { return(AggregateSymbol.DeclOnly().getInputFile()); } // Because an AggregateSymbol that isn't metadata can be defined across multiple // files, getInputFile isn't a reasonable operation. Debug.Assert(false); return(null); #endif } /* * case SK_AggregateType: * return ((Symbol)this.AsAggregateType().getAggregate()).getInputFile(); */ case SYMKIND.SK_AggregateDeclaration: return(this.AsAggregateDeclaration().getInputFile()); /* * case SK_TypeParameterType: * if (this.AsTypeParameterType().GetOwningSymbol().IsAggregateSymbol()) * { * ASSERT(0); * return null; * } * else * { * ASSERT(this.AsTypeParameterType().GetOwningSymbol().IsMethodSymbol()); * return AsTypeParameterType().GetOwningSymbol().AsMethodSymbol().getInputFile(); * } */ case SYMKIND.SK_TypeParameterSymbol: if (this.parent.IsAggregateSymbol()) { // Because an AggregateSymbol that isn't metadata can be defined across multiple // files, getInputFile isn't a reasonable operation. Debug.Assert(false); return(null); } else if (this.parent.IsMethodSymbol()) { return(this.parent.AsMethodSymbol().getInputFile()); } Debug.Assert(false); break; case SYMKIND.SK_FieldSymbol: return(this.AsFieldSymbol().containingDeclaration().getInputFile()); case SYMKIND.SK_MethodSymbol: return(this.AsMethodSymbol().containingDeclaration().getInputFile()); case SYMKIND.SK_PropertySymbol: return(this.AsPropertySymbol().containingDeclaration().getInputFile()); case SYMKIND.SK_EventSymbol: return(this.AsEventSymbol().containingDeclaration().getInputFile()); /* * case SK_PointerType: * case SK_NullableType: * case SK_ArrayType: * case SK_PinnedType: * case SK_ParameterModifierType: * case SK_OptionalModifierType: * return AsType().GetBaseOrParameterOrElementType().getInputFile(); */ case SYMKIND.SK_GlobalAttributeDeclaration: return(parent.getInputFile()); /* * case SK_NullType: * case SK_VoidType: * return null; */ default: Debug.Assert(false); break; } return(null); }
public static string GetNiceName(AggregateSymbol type) { if (type.IsPredefined()) return GetNiceName(type.GetPredefType()); else return null; }
private bool TryVarianceAdjustmentToGetAccessibleType(CSemanticChecker semanticChecker, BindingContext bindingContext, AggregateType typeSrc, out CType typeDst) { Debug.Assert(typeSrc != null); Debug.Assert(typeSrc.isInterfaceType() || typeSrc.isDelegateType()); typeDst = null; AggregateSymbol aggSym = typeSrc.GetOwningAggregate(); AggregateType aggOpenType = aggSym.getThisType(); if (!semanticChecker.CheckTypeAccess(aggOpenType, bindingContext.ContextForMemberLookup)) { // if the aggregate symbol itself is not accessible, then forget it, there is no // variance that will help us arrive at an accessible type. return(false); } TypeArray typeArgs = typeSrc.GetTypeArgsThis(); TypeArray typeParams = aggOpenType.GetTypeArgsThis(); CType[] newTypeArgsTemp = new CType[typeArgs.Count]; for (int i = 0; i < typeArgs.Count; i++) { if (semanticChecker.CheckTypeAccess(typeArgs[i], bindingContext.ContextForMemberLookup)) { // we have an accessible argument, this position is not a problem. newTypeArgsTemp[i] = typeArgs[i]; continue; } if (!typeArgs[i].IsRefType() || !((TypeParameterType)typeParams[i]).Covariant) { // This guy is inaccessible, and we are not going to be able to vary him, so we need to fail. return(false); } CType intermediateTypeArg; if (GetBestAccessibleType(semanticChecker, bindingContext, typeArgs[i], out intermediateTypeArg)) { // now we either have a value type (which must be accessible due to the above // check, OR we have an inaccessible type (which must be a ref type). In either // case, the recursion worked out and we are OK to vary this argument. newTypeArgsTemp[i] = intermediateTypeArg; continue; } else { Debug.Assert(false, "GetBestAccessibleType unexpectedly failed on a type that was used as a type parameter"); return(false); } } TypeArray newTypeArgs = semanticChecker.getBSymmgr().AllocParams(typeArgs.Count, newTypeArgsTemp); CType intermediateType = this.GetAggregate(aggSym, typeSrc.outerType, newTypeArgs); // All type arguments were varied successfully, which means now we must be accessible. But we could // have violated constraints. Let's check that out. if (!TypeBind.CheckConstraints(semanticChecker, null /*ErrorHandling*/, intermediateType, CheckConstraintsFlags.NoErrors)) { return(false); } typeDst = intermediateType; Debug.Assert(semanticChecker.CheckTypeAccess(typeDst, bindingContext.ContextForMemberLookup)); return(true); }
// delegate specific helpers private MethodSymbol FindDelegateConstructor(AggregateSymbol delegateType, int[] signature) { Debug.Assert(delegateType != null && delegateType.IsDelegate()); Debug.Assert(signature != null); return LoadMethod( delegateType, signature, 0, // meth ty vars GetPredefName(PredefinedName.PN_CTOR), ACCESS.ACC_PUBLIC, false, // MethodCallingConventionEnum.Static false); // MethodCallingConventionEnum.Virtual }
public AggregateType GetAggregate(AggregateSymbol agg, AggregateType atsOuter, TypeArray typeArgs) { Debug.Assert(agg.GetTypeManager() == this); Debug.Assert(atsOuter == null || atsOuter.getAggregate() == agg.Parent, ""); if (typeArgs == null) { typeArgs = BSYMMGR.EmptyTypeArray(); } Debug.Assert(agg.GetTypeVars().Count == typeArgs.Count); Name name = _BSymmgr.GetNameFromPtrs(typeArgs, atsOuter); Debug.Assert(name != null); AggregateType pAggregate = _typeTable.LookupAggregate(name, agg); if (pAggregate == null) { pAggregate = _typeFactory.CreateAggregateType( name, agg, typeArgs, atsOuter ); Debug.Assert(!pAggregate.fConstraintsChecked && !pAggregate.fConstraintError); pAggregate.SetErrors(false); _typeTable.InsertAggregate(name, agg, pAggregate); // If we have a generic type definition, then we need to set the // base class to be our current base type, and use that to calculate // our agg type and its base, then set it to be the generic version of the // base type. This is because: // // Suppose we have Foo<T> : IFoo<T> // // Initially, the BaseType will be IFoo<Foo.T>, which gives us the substitution // that we want to use for our agg type's base type. However, in the Symbol chain, // we want the base type to be IFoo<IFoo.T>. Thats why we need to do this little trick. // // If we don't have a generic type definition, then we just need to set our base // class. This is so that if we have a base type that's generic, we'll be // getting the correctly instantiated base type. var baseType = pAggregate.AssociatedSystemType?.BaseType; if (baseType != null) { // Store the old base class. AggregateType oldBaseType = agg.GetBaseClass(); agg.SetBaseClass(_symbolTable.GetCTypeFromType(baseType) as AggregateType); pAggregate.GetBaseClass(); // Get the base type for the new agg type we're making. agg.SetBaseClass(oldBaseType); } } else { Debug.Assert(!pAggregate.HasErrors()); } Debug.Assert(pAggregate.getAggregate() == agg); Debug.Assert(pAggregate.GetTypeArgsThis() != null && pAggregate.GetTypeArgsAll() != null); Debug.Assert(pAggregate.GetTypeArgsThis() == typeArgs); return(pAggregate); }
public MethodSymbol FindDelegateConstructor(AggregateSymbol delegateType, bool fReportErrors) { MethodSymbol ctor = FindDelegateConstructor(delegateType); if (ctor == null && fReportErrors) { GetErrorContext().Error(ErrorCode.ERR_BadDelegateConstructor, delegateType); } return ctor; throw Error.InternalCompilerError(); }
///////////////////////////////////////////////////////////////////////////////// private PropertySymbol AddPropertyToSymbolTable(PropertyInfo property, AggregateSymbol aggregate) { Name name; bool isIndexer = property.GetIndexParameters() != null && property.GetIndexParameters().Length != 0; if (isIndexer) { name = GetName(SpecialNames.Indexer); } else { name = GetName(property.Name); } PropertySymbol prop = _symbolTable.LookupSym( name, aggregate, symbmask_t.MASK_PropertySymbol) as PropertySymbol; // If we already had one, see if it matches. if (prop != null) { PropertySymbol prevProp = null; // We'll have multiple properties with the same name if we have indexers. // In that case, we need to look at every indexer to see if we find one with // the matching associated sym that we want. while (prop != null) { if (prop.AssociatedPropertyInfo.IsEquivalentTo(property)) { return prop; } prevProp = prop; prop = _semanticChecker.SymbolLoader.LookupNextSym(prop, prop.parent, symbmask_t.MASK_PropertySymbol).AsPropertySymbol(); } prop = prevProp; if (isIndexer) { // We have an indexer for a different property info, so // create a new symbol for it. prop = null; } } // If we already had a property but its associated info doesn't match, // then we repurpose the property that we've found. This can happen // in the case of generic instantiations. // // Note that this is a bit of a hack - the best way to fix this is // by not depending on the instantiated properties at all, but rather depending // on their non-instantiated generic form, which can be gotten from the // parent's generic type definition's member. From there, we'll also need to // keep track of the instantiation as we move along, so that when we need the // associated property, we can instantiate it correctly. // // This seems far too heavyweight - since we know we will never bind to more // than one property per payload, lets just blast it each time. if (prop == null) { if (isIndexer) { prop = _semanticChecker.GetSymbolLoader().GetGlobalMiscSymFactory().CreateIndexer(name, aggregate, GetName(property.Name), null); prop.Params = CreateParameterArray(null, property.GetIndexParameters()); } else { prop = _symFactory.CreateProperty(GetName(property.Name), aggregate, null); prop.Params = BSYMMGR.EmptyTypeArray(); } } prop.AssociatedPropertyInfo = property; prop.isStatic = property.GetGetMethod(true) != null ? property.GetGetMethod(true).IsStatic : property.GetSetMethod(true).IsStatic; prop.isParamArray = DoesMethodHaveParameterArray(property.GetIndexParameters()); prop.swtSlot = null; prop.RetType = GetCTypeFromType(property.PropertyType); prop.isOperator = isIndexer; // Determine if its an override. We should always have an accessor, unless // the metadata was bogus. if (property.GetMethod != null || property.SetMethod != null) { MethodInfo accessor = property.GetMethod ?? property.SetMethod; // Must have at least one. prop.isOverride = accessor.IsVirtual && accessor.IsHideBySig && accessor.GetRuntimeBaseDefinition() != accessor; prop.isHideByName = !accessor.IsHideBySig; } SetParameterDataForMethProp(prop, property.GetIndexParameters()); // Get and set. MethodInfo methGet = property.GetMethod; MethodInfo methSet = property.SetMethod; ACCESS access = ACCESS.ACC_PRIVATE; if (methGet != null) { prop.methGet = AddMethodToSymbolTable(methGet, aggregate, MethodKindEnum.PropAccessor); // If we have an indexed property, leave the method as a method we can call, // and mark the property as bogus. if (isIndexer || prop.methGet.Params.size == 0) { prop.methGet.SetProperty(prop); } else { prop.setBogus(true); prop.methGet.SetMethKind(MethodKindEnum.Actual); } if (prop.methGet.GetAccess() > access) { access = prop.methGet.GetAccess(); } } if (methSet != null) { prop.methSet = AddMethodToSymbolTable(methSet, aggregate, MethodKindEnum.PropAccessor); // If we have an indexed property, leave the method as a method we can call, // and mark the property as bogus. if (isIndexer || prop.methSet.Params.size == 1) { prop.methSet.SetProperty(prop); } else { prop.setBogus(true); prop.methSet.SetMethKind(MethodKindEnum.Actual); } if (prop.methSet.GetAccess() > access) { access = prop.methSet.GetAccess(); } } // The access of the property is the least restrictive access of its getter/setter. prop.SetAccess(access); return prop; }
private MethodSymbol LookupMethodWhileLoading(AggregateSymbol type, int cMethodTyVars, Name methodName, ACCESS methodAccess, bool isStatic, bool isVirtual, CType returnType, TypeArray argumentTypes) { for (Symbol sym = GetSymbolLoader().LookupAggMember(methodName, type, symbmask_t.MASK_ALL); sym != null; sym = GetSymbolLoader().LookupNextSym(sym, type, symbmask_t.MASK_ALL)) { if (sym.IsMethodSymbol()) { MethodSymbol methsym = sym.AsMethodSymbol(); if ((methsym.GetAccess() == methodAccess || methodAccess == ACCESS.ACC_UNKNOWN) && methsym.isStatic == isStatic && methsym.isVirtual == isVirtual && methsym.typeVars.size == cMethodTyVars && GetTypeManager().SubstEqualTypes(methsym.RetType, returnType, null, methsym.typeVars, SubstTypeFlags.DenormMeth) && GetTypeManager().SubstEqualTypeArrays(methsym.Params, argumentTypes, (TypeArray)null, methsym.typeVars, SubstTypeFlags.DenormMeth) && !methsym.getBogus()) { return methsym; } } } return null; }
///////////////////////////////////////////////////////////////////////////////// private MethodSymbol AddMethodToSymbolTable(MemberInfo member, AggregateSymbol callingAggregate, MethodKindEnum kind) { MethodInfo method = member as MethodInfo; ConstructorInfo ctor = member as ConstructorInfo; Debug.Assert(method != null || ctor != null); #if UNSUPPORTEDAPI Debug.Assert(member.DeclaringType == member.ReflectedType); #endif // If we are trying to add an actual method via MethodKindEnum.Actual, and // the memberinfo is a special name, and its not static, then return null. // We'll re-add the thing later with some other method kind. // // This will happen for things like indexers and properties. The ones that have // special names that we DO want to allow adding are things like operators, which // are static and will not be added again later. if (kind == MethodKindEnum.Actual && // MethKindEnum.Actual (method == null || // Not a ConstructorInfo (!method.IsStatic && method.IsSpecialName))) // Not static and is a special name { return null; } MethodSymbol methodSymbol = FindMatchingMethod(member, callingAggregate); if (methodSymbol != null) { return methodSymbol; } ParameterInfo[] parameters = method != null ? method.GetParameters() : ctor.GetParameters(); // First create the method. methodSymbol = _symFactory.CreateMethod(GetName(member.Name), callingAggregate, null); methodSymbol.AssociatedMemberInfo = member; methodSymbol.SetMethKind(kind); if (kind == MethodKindEnum.ExplicitConv || kind == MethodKindEnum.ImplicitConv) { callingAggregate.SetHasConversion(); methodSymbol.SetConvNext(callingAggregate.GetFirstUDConversion()); callingAggregate.SetFirstUDConversion(methodSymbol); } ACCESS access; if (method != null) { if (method.IsPublic) { access = ACCESS.ACC_PUBLIC; } else if (method.IsPrivate) { access = ACCESS.ACC_PRIVATE; } else if (method.IsFamily) { access = ACCESS.ACC_PROTECTED; } else if (method.IsAssembly || method.IsFamilyAndAssembly) { access = ACCESS.ACC_INTERNAL; } else { Debug.Assert(method.IsFamilyOrAssembly); access = ACCESS.ACC_INTERNALPROTECTED; } } else { Debug.Assert(ctor != null); if (ctor.IsPublic) { access = ACCESS.ACC_PUBLIC; } else if (ctor.IsPrivate) { access = ACCESS.ACC_PRIVATE; } else if (ctor.IsFamily) { access = ACCESS.ACC_PROTECTED; } else if (ctor.IsAssembly || ctor.IsFamilyAndAssembly) { access = ACCESS.ACC_INTERNAL; } else { Debug.Assert(ctor.IsFamilyOrAssembly); access = ACCESS.ACC_INTERNALPROTECTED; } } methodSymbol.SetAccess(access); methodSymbol.isExtension = false; // We don't support extension methods. methodSymbol.isExternal = false; if (method != null) { methodSymbol.typeVars = GetMethodTypeParameters(method, methodSymbol); methodSymbol.isVirtual = method.IsVirtual; methodSymbol.isAbstract = method.IsAbstract; methodSymbol.isStatic = method.IsStatic; methodSymbol.isOverride = method.IsVirtual && method.IsHideBySig && method.GetRuntimeBaseDefinition() != method; methodSymbol.isOperator = IsOperator(method); methodSymbol.swtSlot = GetSlotForOverride(method); methodSymbol.isVarargs = (method.CallingConvention & CallingConventions.VarArgs) == CallingConventions.VarArgs; methodSymbol.RetType = GetCTypeFromType(method.ReturnType); } else { methodSymbol.typeVars = BSYMMGR.EmptyTypeArray(); methodSymbol.isVirtual = ctor.IsVirtual; methodSymbol.isAbstract = ctor.IsAbstract; methodSymbol.isStatic = ctor.IsStatic; methodSymbol.isOverride = false; methodSymbol.isOperator = false; methodSymbol.swtSlot = null; methodSymbol.isVarargs = false; methodSymbol.RetType = _typeManager.GetVoid(); } methodSymbol.modOptCount = GetCountOfModOpts(parameters); methodSymbol.useMethInstead = false; methodSymbol.isParamArray = DoesMethodHaveParameterArray(parameters); methodSymbol.isHideByName = false; methodSymbol.errExpImpl = null; methodSymbol.Params = CreateParameterArray(methodSymbol.AssociatedMemberInfo, parameters); methodSymbol.declaration = null; SetParameterDataForMethProp(methodSymbol, parameters); return methodSymbol; }
///////////////////////////////////////////////////////////////////////////////// private FieldSymbol AddFieldToSymbolTable(FieldInfo fieldInfo, AggregateSymbol aggregate) { FieldSymbol field = _symbolTable.LookupSym( GetName(fieldInfo.Name), aggregate, symbmask_t.MASK_FieldSymbol) as FieldSymbol; if (field != null) { return field; } field = _symFactory.CreateMemberVar(GetName(fieldInfo.Name), aggregate, null, 0); field.AssociatedFieldInfo = fieldInfo; field.isStatic = fieldInfo.IsStatic; ACCESS access; if (fieldInfo.IsPublic) { access = ACCESS.ACC_PUBLIC; } else if (fieldInfo.IsPrivate) { access = ACCESS.ACC_PRIVATE; } else if (fieldInfo.IsFamily) { access = ACCESS.ACC_PROTECTED; } else if (fieldInfo.IsAssembly || fieldInfo.IsFamilyAndAssembly) { access = ACCESS.ACC_INTERNAL; } else { Debug.Assert(fieldInfo.IsFamilyOrAssembly); access = ACCESS.ACC_INTERNALPROTECTED; } field.SetAccess(access); field.isReadOnly = fieldInfo.IsInitOnly; field.isEvent = false; field.isAssigned = true; field.SetType(GetCTypeFromType(fieldInfo.FieldType)); return field; }
///////////////////////////////////////////////////////////////////////////////// private TypeArray GetAggregateTypeParameters(Type type, AggregateSymbol agg) { if (type.GetTypeInfo().IsGenericType) { Type genericDefinition = type.GetTypeInfo().GetGenericTypeDefinition(); Type[] genericArguments = genericDefinition.GetGenericArguments(); List<CType> ctypes = new List<CType>(); int outerParameters = agg.isNested() ? agg.GetOuterAgg().GetTypeVarsAll().size : 0; for (int i = 0; i < genericArguments.Length; i++) { // Suppose we have the following: // // class A<A1, A2, ..., An> // { // class B<B1, B2, ..., Bm> // { // } // } // // B will have m+n generic arguments - { A1, A2, ..., An, B1, B2, ..., Bn }. // As we enumerate these, we need to skip type parameters whose GenericParameterPosition // is less than n, since the first n type parameters are { A1, A2, ..., An }. Type t = genericArguments[i]; if (t.GenericParameterPosition < outerParameters) { continue; } CType ctype = null; if (t.IsGenericParameter && t.DeclaringType == genericDefinition) { ctype = LoadClassTypeParameter(agg, t); } else { ctype = GetCTypeFromType(t); } // We check to make sure we own the type parameter - this is because we're // currently calculating TypeArgsThis, NOT TypeArgsAll. if (ctype.AsTypeParameterType().GetOwningSymbol() == agg) { ctypes.Add(ctype); } } return _bsymmgr.AllocParams(ctypes.Count, ctypes.ToArray()); } return BSYMMGR.EmptyTypeArray(); }
///////////////////////////////////////////////////////////////////////////////// internal void AddPredefinedPropertyToSymbolTable(AggregateSymbol type, Name property) { AggregateType aggtype = type.getThisType(); Type t = aggtype.AssociatedSystemType; var props = Enumerable.Where(t.GetRuntimeProperties(), x => x.Name == property.Text); foreach (PropertyInfo pi in props) { AddPropertyToSymbolTable(pi, type); } }
public AggregateType LookupAggregate(AggregateSymbol aggregate, AggregateType outer, TypeArray args) { _aggregateTable.TryGetValue(MakeKey(aggregate, MakeKey(outer, args)), out AggregateType result); return(result); }
///////////////////////////////////////////////////////////////////////////////// internal void AddPredefinedMethodToSymbolTable(AggregateSymbol type, Name methodName) { Type t = type.getThisType().AssociatedSystemType; // If we got here, it means we couldn't find it in our initial lookup. Means we haven't loaded it from reflection yet. // Lets go and do that now. // Check if we have constructors or not. if (methodName == _nameManager.GetPredefinedName(PredefinedName.PN_CTOR)) { var ctors = Enumerable.Where(t.GetConstructors(), m => m.Name == methodName.Text); foreach (ConstructorInfo c in ctors) { AddMethodToSymbolTable( c, type, MethodKindEnum.Constructor); } } else { var methods = Enumerable.Where(t.GetRuntimeMethods(), m => m.Name == methodName.Text && m.DeclaringType == t); foreach (MethodInfo m in methods) { AddMethodToSymbolTable( m, type, m.Name == SpecialNames.Invoke ? MethodKindEnum.Invoke : MethodKindEnum.Actual); } } }
public AggregateType GetAggregate(AggregateSymbol agg, AggregateType atsOuter, TypeArray typeArgs) { Debug.Assert(agg.GetTypeManager() == this); Debug.Assert(atsOuter == null || atsOuter.getAggregate() == agg.Parent, ""); if (typeArgs == null) { typeArgs = BSYMMGR.EmptyTypeArray(); } Debug.Assert(agg.GetTypeVars().Size == typeArgs.Size); Name name = _BSymmgr.GetNameFromPtrs(typeArgs, atsOuter); Debug.Assert(name != null); AggregateType pAggregate = _typeTable.LookupAggregate(name, agg); if (pAggregate == null) { pAggregate = _typeFactory.CreateAggregateType( name, agg, typeArgs, atsOuter ); Debug.Assert(!pAggregate.fConstraintsChecked && !pAggregate.fConstraintError); pAggregate.SetErrors(pAggregate.GetTypeArgsAll().HasErrors()); #if CSEE SpecializedSymbolCreationEE* pSymCreate = static_cast<SpecializedSymbolCreationEE*>(m_BSymmgr.GetSymFactory().m_pSpecializedSymbolCreation); AggregateSymbolExtra* pExtra = pSymCreate.GetHashTable().GetElement(agg).AsAggregateSymbolExtra(); pAggregate.typeRes = pAggregate; if (!pAggregate.IsUnresolved()) { pAggregate.tsRes = ktsImportMax; } pAggregate.fDirty = pExtra.IsDirty() || pAggregate.IsUnresolved(); pAggregate.tsDirty = pExtra.GetLastComputedDirtyBit(); #endif // CSEE _typeTable.InsertAggregate(name, agg, pAggregate); // If we have a generic type definition, then we need to set the // base class to be our current base type, and use that to calculate // our agg type and its base, then set it to be the generic version of the // base type. This is because: // // Suppose we have Foo<T> : IFoo<T> // // Initially, the BaseType will be IFoo<Foo.T>, which gives us the substitution // that we want to use for our agg type's base type. However, in the Symbol chain, // we want the base type to be IFoo<IFoo.T>. Thats why we need to do this little trick. // // If we don't have a generic type definition, then we just need to set our base // class. This is so that if we have a base type that's generic, we'll be // getting the correctly instantiated base type. if (pAggregate.AssociatedSystemType != null && pAggregate.AssociatedSystemType.GetTypeInfo().BaseType != null) { // Store the old base class. AggregateType oldBaseType = agg.GetBaseClass(); agg.SetBaseClass(_symbolTable.GetCTypeFromType(pAggregate.AssociatedSystemType.GetTypeInfo().BaseType).AsAggregateType()); pAggregate.GetBaseClass(); // Get the base type for the new agg type we're making. agg.SetBaseClass(oldBaseType); } } else { Debug.Assert(pAggregate.HasErrors() == pAggregate.GetTypeArgsAll().HasErrors()); } Debug.Assert(pAggregate.getAggregate() == agg); Debug.Assert(pAggregate.GetTypeArgsThis() != null && pAggregate.GetTypeArgsAll() != null); Debug.Assert(pAggregate.GetTypeArgsThis() == typeArgs); return pAggregate; }
///////////////////////////////////////////////////////////////////////////////// internal bool AggregateContainsMethod(AggregateSymbol agg, string szName, symbmask_t mask) { return _semanticChecker.SymbolLoader.LookupAggMember(GetName(szName), agg, mask) != null; }
public AggregateType GetAggregate(AggregateSymbol agg, TypeArray typeArgsAll) { Debug.Assert(typeArgsAll != null && typeArgsAll.Size == agg.GetTypeVarsAll().Size); if (typeArgsAll.size == 0) return agg.getThisType(); AggregateSymbol aggOuter = agg.GetOuterAgg(); if (aggOuter == null) return GetAggregate(agg, null, typeArgsAll); int cvarOuter = aggOuter.GetTypeVarsAll().Size; Debug.Assert(cvarOuter <= typeArgsAll.Size); TypeArray typeArgsOuter = _BSymmgr.AllocParams(cvarOuter, typeArgsAll, 0); TypeArray typeArgsInner = _BSymmgr.AllocParams(agg.GetTypeVars().Size, typeArgsAll, cvarOuter); AggregateType atsOuter = GetAggregate(aggOuter, typeArgsOuter); return GetAggregate(agg, atsOuter, typeArgsInner); }
///////////////////////////////////////////////////////////////////////////////// private TypeParameterType LoadClassTypeParameter(AggregateSymbol parent, Type t) { for (AggregateSymbol p = parent; p != null; p = p.parent.IsAggregateSymbol() ? p.parent.AsAggregateSymbol() : null) { for (TypeParameterSymbol typeParam = _bsymmgr.LookupAggMember( GetName(t), p, symbmask_t.MASK_TypeParameterSymbol) as TypeParameterSymbol; typeParam != null; typeParam = BSYMMGR.LookupNextSym(typeParam, p, symbmask_t.MASK_TypeParameterSymbol) as TypeParameterSymbol) { if (AreTypeParametersEquivalent(typeParam.GetTypeParameterType().AssociatedSystemType, t)) { return typeParam.GetTypeParameterType(); } } } return AddTypeParameterToSymbolTable(parent, null, t, true); }
public AggregateType outerType; // the outer type if this is a nested type public void SetOwningAggregate(AggregateSymbol agg) { _pOwningAggregate = agg; }
///////////////////////////////////////////////////////////////////////////////// private TypeParameterType ProcessMethodTypeParameter(MethodInfo methinfo, Type t, AggregateSymbol parent) { MethodSymbol meth = FindMatchingMethod(methinfo, parent); if (meth == null) { meth = AddMethodToSymbolTable(methinfo, parent, MethodKindEnum.Actual); // Because we return null from AddMethodToSymbolTable when we have a MethodKindEnum.Actual // and the method that we're trying to add is a special name, we need to assert that // we indeed have added a method. This is because no special name should have a method // type parameter on it. Debug.Assert(meth != null); } return LoadMethodTypeParameter(meth, t); }
public bool FindBaseAgg(AggregateSymbol agg) { for (AggregateSymbol aggT = this; aggT != null; aggT = aggT.GetBaseAgg()) { if (aggT == agg) return true; } return false; }
///////////////////////////////////////////////////////////////////////////////// private AggregateSymbol FindSymWithMatchingArity(AggregateSymbol aggregateSymbol, Type type) { for (AggregateSymbol agg = aggregateSymbol; agg != null; agg = BSYMMGR.LookupNextSym(agg, agg.Parent, symbmask_t.MASK_AggregateSymbol) as AggregateSymbol) { if (agg.GetTypeVarsAll().size == type.GetGenericArguments().Length) { return agg; } } return null; }
private AggregateSymbol FindPredefinedType(ErrorHandling errorContext, string pszType, KAID aid, AggKindEnum aggKind, int arity, bool isRequired) { Debug.Assert(!string.IsNullOrEmpty(pszType)); // Shouldn't be the empty string! NamespaceOrAggregateSymbol bagCur = _pBSymmgr.GetRootNS(); Name name = null; string[] nameParts = pszType.Split(s_nameSeparators); for (int i = 0, n = nameParts.Length; i < n; i++) { name = _pBSymmgr.GetNameManager().Add(nameParts[i]); if (i == n - 1) { // This is the last component. Handle it special below. break; } // first search for an outer type which is also predefined // this must be first because we always create a namespace for // outer names, even for nested types AggregateSymbol aggNext = _pBSymmgr.LookupGlobalSymCore(name, bagCur, symbmask_t.MASK_AggregateSymbol).AsAggregateSymbol(); if (aggNext != null && aggNext.InAlias(aid) && aggNext.IsPredefined()) { bagCur = aggNext; } else { // ... if no outer type, then search for namespaces NamespaceSymbol nsNext = _pBSymmgr.LookupGlobalSymCore(name, bagCur, symbmask_t.MASK_NamespaceSymbol).AsNamespaceSymbol(); bool bIsInAlias = true; if (nsNext == null) { bIsInAlias = false; } else { bIsInAlias = nsNext.InAlias(aid); } if (!bIsInAlias) { // Didn't find the namespace in this aid. if (isRequired) { errorContext.Error(ErrorCode.ERR_PredefinedTypeNotFound, pszType); } return(null); } bagCur = nsNext; } } AggregateSymbol aggAmbig; AggregateSymbol aggBad; AggregateSymbol aggFound = FindPredefinedTypeCore(name, bagCur, aid, aggKind, arity, out aggAmbig, out aggBad); if (aggFound == null) { // Didn't find the AggregateSymbol. if (aggBad != null && (isRequired || aid == KAID.kaidGlobal && aggBad.IsSource())) { errorContext.ErrorRef(ErrorCode.ERR_PredefinedTypeBadType, aggBad); } else if (isRequired) { errorContext.Error(ErrorCode.ERR_PredefinedTypeNotFound, pszType); } return(null); } if (aggAmbig == null && aid != KAID.kaidGlobal) { // Look in kaidGlobal to make sure there isn't a conflicting one. AggregateSymbol tmp; AggregateSymbol agg2 = FindPredefinedTypeCore(name, bagCur, KAID.kaidGlobal, aggKind, arity, out aggAmbig, out tmp); Debug.Assert(agg2 != null); if (agg2 != aggFound) { aggAmbig = agg2; } } return(aggFound); }