public PointerTypeReference(Module moduleBeingBuilt, PointerTypeSymbol underlyingPointerType)
            : base(moduleBeingBuilt)
        {
            Contract.ThrowIfNull(underlyingPointerType);

            this.underlyingPointerType = underlyingPointerType;
        }
        protected internal override object VisitPointerType(PointerTypeSymbol symbol, ArrayBuilder<SymbolDescriptionPart> builder)
        {
            VisitType(symbol.PointedAtType, builder);
            AddPunctuation(SyntaxKind.AsteriskToken, builder);

            return null;
        }
        public void Test2()
        {
            var oldMsCorLib = TestReferences.NetFx.v4_0_21006.mscorlib;
            var newMsCorLib = MscorlibRef;

            var source = @"
public class Modifiers
{
    public volatile int volatileFld;

    void F1(System.DateTime* p)
    {
    }
}
";

            CSharpCompilation c1 = CSharpCompilation.Create("C1", new[] { Parse(source) }, new[] { oldMsCorLib });

            var c1Assembly = c1.Assembly;

            var r1 = new CSharpCompilationReference(c1);
            CSharpCompilation c2 = CSharpCompilation.Create("C2", references: new[] { newMsCorLib, r1 });
            var c1AsmRef         = c2.GetReferencedAssemblySymbol(r1);

            Assert.NotSame(c1Assembly, c1AsmRef);

            var mscorlibAssembly = c2.GetReferencedAssemblySymbol(newMsCorLib);

            Assert.NotSame(mscorlibAssembly, c1.GetReferencedAssemblySymbol(oldMsCorLib));

            var modifiers = c2.GlobalNamespace.GetTypeMembers("Modifiers").Single();

            Assert.IsType <RetargetingNamedTypeSymbol>(modifiers);

            FieldSymbol volatileFld = modifiers.GetMembers("volatileFld").OfType <FieldSymbol>().Single();

            Assert.Equal(1, volatileFld.TypeWithAnnotations.CustomModifiers.Length);

            var volatileFldMod = volatileFld.TypeWithAnnotations.CustomModifiers[0];

            Assert.False(volatileFldMod.IsOptional);
            Assert.Equal("System.Runtime.CompilerServices.IsVolatile", volatileFldMod.Modifier.ToTestDisplayString());
            Assert.Equal(SpecialType.System_Int32, volatileFld.Type.SpecialType);
            Assert.Same(mscorlibAssembly, ((CSharpCustomModifier)volatileFldMod).ModifierSymbol.ContainingAssembly);

            Assert.Equal("volatileFld", volatileFld.Name);
            Assert.True(volatileFld.IsVolatile);
            Assert.Same(volatileFld, volatileFld.OriginalDefinition);
            Assert.Null(volatileFld.GetConstantValue(ConstantFieldsInProgress.Empty, earlyDecodingWellKnownAttributes: false));
            Assert.Null(volatileFld.ConstantValue);
            Assert.Null(volatileFld.AssociatedSymbol);
            Assert.Same(c1AsmRef, volatileFld.ContainingAssembly);
            Assert.Same(c1AsmRef.Modules[0], volatileFld.ContainingModule);
            Assert.Same(modifiers, volatileFld.ContainingSymbol);
            Assert.Equal(Accessibility.Public, volatileFld.DeclaredAccessibility);
            Assert.False(volatileFld.IsConst);
            Assert.False(volatileFld.IsReadOnly);
            Assert.False(volatileFld.IsStatic);
            Assert.Same(volatileFld.ContainingModule, ((RetargetingFieldSymbol)volatileFld).RetargetingModule);
            Assert.Same(c1Assembly, ((RetargetingFieldSymbol)volatileFld).UnderlyingField.ContainingAssembly);

            MethodSymbol m1 = modifiers.GetMembers("F1").OfType <MethodSymbol>().Single();

            Assert.Equal(0, m1.ReturnTypeWithAnnotations.CustomModifiers.Length);
            Assert.True(!m1.ExplicitInterfaceImplementations.IsDefault);
            Assert.Equal(0, m1.ExplicitInterfaceImplementations.Length);
            Assert.False(m1.HidesBaseMethodsByName);
            Assert.False(m1.IsExtensionMethod);
            Assert.Equal(((RetargetingMethodSymbol)m1).UnderlyingMethod.CallingConvention, m1.CallingConvention);
            Assert.Null(m1.AssociatedSymbol);
            Assert.Same(c1AsmRef.Modules[0], m1.ContainingModule);

            ParameterSymbol p1 = m1.Parameters[0];

            Assert.Equal(0, p1.TypeWithAnnotations.CustomModifiers.Length);
            Assert.Same(c1AsmRef.Modules[0], p1.ContainingModule);
            Assert.False(p1.HasExplicitDefaultValue, "Parameter has default value");
            Assert.Equal(0, p1.Ordinal);

            PointerTypeSymbol p1Type = (PointerTypeSymbol)p1.Type;

            Assert.Null(p1Type.ContainingAssembly);
            Assert.Same(mscorlibAssembly, p1Type.PointedAtType.ContainingAssembly);
            Assert.Equal(SpecialType.System_DateTime, p1Type.PointedAtType.SpecialType);
            Assert.Equal(0, p1.TypeWithAnnotations.CustomModifiers.Length);
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Determine whether there is any substitution of type parameters that will
        /// make two types identical.
        /// </summary>
        /// <param name="t1">LHS</param>
        /// <param name="t2">RHS</param>
        /// <param name="substitution">
        /// Substitutions performed so far (or null for none).
        /// Keys are type parameters, values are types (possibly type parameters).
        /// Will be updated with new subsitutions by the callee.
        /// Should be ignored when false is returned.
        /// </param>
        /// <returns>True if there exists a type map such that Map(LHS) == Map(RHS).</returns>
        /// <remarks>
        /// Derived from Dev10's BSYMMGR::UnifyTypes.
        /// Two types will not unify if they have different custom modifiers.
        /// </remarks>
        private static bool CanUnifyHelper(TypeSymbol t1, TypeSymbol t2, ref MutableTypeMap substitution)
        {
            if (ReferenceEquals(t1, t2))
            {
                return(true);
            }
            else if ((object)t1 == null || (object)t2 == null)
            {
                // Can't both be null or they would have been ReferenceEquals
                return(false);
            }

            if (substitution != null)
            {
                t1 = substitution.SubstituteType(t1);
                t2 = substitution.SubstituteType(t2);
            }

            // If one of the types is a type parameter, then the substitution could make them ReferenceEquals.
            if (ReferenceEquals(t1, t2))
            {
                return(true);
            }

            // We can avoid a lot of redundant checks if we ensure that we only have to check
            // for type parameters on the LHS
            if (!t1.IsTypeParameter() && t2.IsTypeParameter())
            {
                TypeSymbol tmp = t1;
                t1 = t2;
                t2 = tmp;
            }

            // If t1 is not a type parameter, then neither is t2
            Debug.Assert(t1.IsTypeParameter() || !t2.IsTypeParameter());

            switch (t1.Kind)
            {
            case SymbolKind.ArrayType:
            {
                if (t2.TypeKind != t1.TypeKind)
                {
                    return(false);
                }

                ArrayTypeSymbol at1 = (ArrayTypeSymbol)t1;
                ArrayTypeSymbol at2 = (ArrayTypeSymbol)t2;

                if (at1.Rank != at2.Rank || !at1.CustomModifiers.SequenceEqual(at2.CustomModifiers))
                {
                    return(false);
                }

                return(CanUnifyHelper(at1.ElementType, at2.ElementType, ref substitution));
            }

            case SymbolKind.PointerType:
            {
                if (t2.TypeKind != t1.TypeKind)
                {
                    return(false);
                }

                PointerTypeSymbol pt1 = (PointerTypeSymbol)t1;
                PointerTypeSymbol pt2 = (PointerTypeSymbol)t2;

                if (!pt1.CustomModifiers.SequenceEqual(pt2.CustomModifiers))
                {
                    return(false);
                }

                return(CanUnifyHelper(pt1.PointedAtType, pt2.PointedAtType, ref substitution));
            }

            case SymbolKind.NamedType:
            case SymbolKind.ErrorType:
            {
                if (t2.TypeKind != t1.TypeKind)
                {
                    return(false);
                }

                NamedTypeSymbol nt1 = (NamedTypeSymbol)t1;
                NamedTypeSymbol nt2 = (NamedTypeSymbol)t2;

                if (!nt1.IsGenericType)
                {
                    return(!nt2.IsGenericType && nt1 == nt2);
                }
                else if (!nt2.IsGenericType)
                {
                    return(false);
                }

                int arity = nt1.Arity;

                if (nt2.Arity != arity || nt2.OriginalDefinition != nt1.OriginalDefinition)
                {
                    return(false);
                }

                for (int i = 0; i < arity; i++)
                {
                    if (!CanUnifyHelper(nt1.TypeArgumentsNoUseSiteDiagnostics[i], nt2.TypeArgumentsNoUseSiteDiagnostics[i], ref substitution))
                    {
                        return(false);
                    }
                }

                // Note: Dev10 folds this into the loop since GetTypeArgsAll includes type args for containing types
                return((object)nt1.ContainingType == null || CanUnifyHelper(nt1.ContainingType, nt2.ContainingType, ref substitution));
            }

            case SymbolKind.TypeParameter:
            {
                // These substitutions are not allowed in C#
                if (t2.TypeKind == TypeKind.Pointer || t2.SpecialType == SpecialType.System_Void)
                {
                    return(false);
                }

                TypeParameterSymbol tp1 = (TypeParameterSymbol)t1;

                // Perform the "occurs check" - i.e. ensure that t2 doesn't contain t1 to avoid recursive types
                // Note: t2 can't be the same type param - we would have caught that with ReferenceEquals above
                if (Contains(t2, tp1))
                {
                    return(false);
                }

                if (substitution == null)
                {
                    substitution = new MutableTypeMap();
                }

                // MutableTypeMap.Add will throw if the key has already been added.  However,
                // if t1 was already in the substitution, it would have been substituted at the
                // start of this method and we wouldn't be here.
                substitution.Add(tp1, t2);

                return(true);
            }

            default:
            {
                return(t1 == t2);
            }
            }
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Determine whether there is any substitution of type parameters that will
        /// make two types identical.
        /// </summary>
        /// <param name="t1">LHS</param>
        /// <param name="t2">RHS</param>
        /// <param name="substitution">
        /// Substitutions performed so far (or null for none).
        /// Keys are type parameters, values are types (possibly type parameters).
        /// Will be updated with new substitutions by the callee.
        /// Should be ignored when false is returned.
        /// </param>
        /// <param name="untouchables">
        /// Set of type symbols that cannot be replaced by substitution.
        /// </param>
        /// <returns>True if there exists a type map such that Map(LHS) == Map(RHS).</returns>
        /// <remarks>
        /// Derived from Dev10's BSYMMGR::UnifyTypes.
        /// Two types will not unify if they have different custom modifiers.
        /// </remarks>
        private static bool CanUnifyHelper(TypeWithModifiers t1, TypeWithModifiers t2, ref MutableTypeMap substitution, ImmutableHashSet <TypeParameterSymbol> untouchables)
        {
            if (t1 == t2)
            {
                return(true);
            }
            else if ((object)t1.Type == null || (object)t2.Type == null)
            {
                // Can't both be null or they would have been equal
                return(false);
            }

            if (substitution != null)
            {
                t1 = t1.SubstituteType(substitution);
                t2 = t2.SubstituteType(substitution);
            }

            // If one of the types is a type parameter, then the substitution could make them equal.
            if (t1 == t2)
            {
                return(true);
            }

            // We can avoid a lot of redundant checks if we ensure that we only have to check
            // for type parameters on the LHS
            if (!t1.Type.IsTypeParameter() && t2.Type.IsTypeParameter())
            {
                TypeWithModifiers tmp = t1;
                t1 = t2;
                t2 = tmp;
            }

            // If t1 is not a type parameter, then neither is t2
            Debug.Assert(t1.Type.IsTypeParameter() || !t2.Type.IsTypeParameter());

            switch (t1.Type.Kind)
            {
            case SymbolKind.ArrayType:
            {
                if (t2.Type.TypeKind != t1.Type.TypeKind || !t2.CustomModifiers.SequenceEqual(t1.CustomModifiers))
                {
                    return(false);
                }

                ArrayTypeSymbol at1 = (ArrayTypeSymbol)t1.Type;
                ArrayTypeSymbol at2 = (ArrayTypeSymbol)t2.Type;

                if (!at1.HasSameShapeAs(at2))
                {
                    return(false);
                }

                return(CanUnifyHelper(new TypeWithModifiers(at1.ElementType, at1.CustomModifiers), new TypeWithModifiers(at2.ElementType, at2.CustomModifiers), ref substitution, untouchables));
            }

            case SymbolKind.PointerType:
            {
                if (t2.Type.TypeKind != t1.Type.TypeKind || !t2.CustomModifiers.SequenceEqual(t1.CustomModifiers))
                {
                    return(false);
                }

                PointerTypeSymbol pt1 = (PointerTypeSymbol)t1.Type;
                PointerTypeSymbol pt2 = (PointerTypeSymbol)t2.Type;

                return(CanUnifyHelper(new TypeWithModifiers(pt1.PointedAtType, pt1.CustomModifiers), new TypeWithModifiers(pt2.PointedAtType, pt2.CustomModifiers), ref substitution, untouchables));
            }

            case SymbolKind.NamedType:
            case SymbolKind.ErrorType:
            {
                if (t2.Type.TypeKind != t1.Type.TypeKind || !t2.CustomModifiers.SequenceEqual(t1.CustomModifiers))
                {
                    return(false);
                }

                NamedTypeSymbol nt1 = (NamedTypeSymbol)t1.Type;
                NamedTypeSymbol nt2 = (NamedTypeSymbol)t2.Type;

                if (nt1.IsTupleType)
                {
                    if (!nt2.IsTupleType)
                    {
                        return(false);
                    }

                    return(CanUnifyHelper(new TypeWithModifiers(nt1.TupleUnderlyingType), new TypeWithModifiers(nt2.TupleUnderlyingType), ref substitution, untouchables));
                }

                if (!nt1.IsGenericType)
                {
                    return(!nt2.IsGenericType && nt1 == nt2);
                }
                else if (!nt2.IsGenericType)
                {
                    return(false);
                }

                int arity = nt1.Arity;

                if (nt2.Arity != arity || nt2.OriginalDefinition != nt1.OriginalDefinition)
                {
                    return(false);
                }

                var nt1Arguments = nt1.TypeArgumentsNoUseSiteDiagnostics;
                var nt2Arguments = nt2.TypeArgumentsNoUseSiteDiagnostics;

                var nt1HasModifiers = nt1.HasTypeArgumentsCustomModifiers;
                var nt2HasModifiers = nt2.HasTypeArgumentsCustomModifiers;

                for (int i = 0; i < arity; i++)
                {
                    if (!CanUnifyHelper(new TypeWithModifiers(nt1Arguments[i], nt1HasModifiers ? nt1.GetTypeArgumentCustomModifiers(i) : default(ImmutableArray <CustomModifier>)),
                                        new TypeWithModifiers(nt2Arguments[i], nt2HasModifiers ? nt2.GetTypeArgumentCustomModifiers(i) : default(ImmutableArray <CustomModifier>)),
                                        ref substitution,
                                        untouchables))
                    {
                        return(false);
                    }
                }

                // Note: Dev10 folds this into the loop since GetTypeArgsAll includes type args for containing types
                // TODO: Calling CanUnifyHelper for the containing type is an overkill, we simply need to go through type arguments for all containers.
                return((object)nt1.ContainingType == null || CanUnifyHelper(new TypeWithModifiers(nt1.ContainingType), new TypeWithModifiers(nt2.ContainingType), ref substitution, untouchables));
            }

            case SymbolKind.TypeParameter:
            {
                // These substitutions are not allowed in C#
                if (t2.Type.TypeKind == TypeKind.Pointer || t2.Type.SpecialType == SpecialType.System_Void)
                {
                    return(false);
                }

                TypeParameterSymbol tp1 = (TypeParameterSymbol)t1.Type;

                // Perform the "occurs check" - i.e. ensure that t2 doesn't contain t1 to avoid recursive types
                // Note: t2 can't be the same type param - we would have caught that with ReferenceEquals above
                if (Contains(t2.Type, tp1))
                {
                    return(false);
                }

                // @MattWindsor91 (Concept-C# 2017)
                // Quickfix to make sure that, when there are two TPs
                // to be unified, and both are associated, we
                //var isAssocFlowingInwards =
                //    t2.Type.IsTypeParameter()
                //    && ((TypeParameterSymbol)t2.Type).IsAssociatedType
                //    && tp1.IsAssociatedType;

                if (!untouchables.Contains(tp1))        // && !isAssocFlowingInwards)
                {
                    if (t1.CustomModifiers.IsDefaultOrEmpty)
                    {
                        AddSubstitution(ref substitution, tp1, t2);
                        return(true);
                    }

                    if (t1.CustomModifiers.SequenceEqual(t2.CustomModifiers))
                    {
                        AddSubstitution(ref substitution, tp1, new TypeWithModifiers(t2.Type));
                        return(true);
                    }

                    if (t1.CustomModifiers.Length < t2.CustomModifiers.Length &&
                        t1.CustomModifiers.SequenceEqual(t2.CustomModifiers.Take(t1.CustomModifiers.Length)))
                    {
                        AddSubstitution(ref substitution, tp1,
                                        new TypeWithModifiers(t2.Type,
                                                              ImmutableArray.Create(t2.CustomModifiers, t1.CustomModifiers.Length, t2.CustomModifiers.Length - t1.CustomModifiers.Length)));
                        return(true);
                    }
                }

                if (t2.Type.IsTypeParameter())
                {
                    var tp2 = (TypeParameterSymbol)t2.Type;

                    if (!untouchables.Contains(tp2))
                    {
                        if (t2.CustomModifiers.IsDefaultOrEmpty)
                        {
                            AddSubstitution(ref substitution, tp2, t1);
                            return(true);
                        }

                        if (t2.CustomModifiers.Length < t1.CustomModifiers.Length &&
                            t2.CustomModifiers.SequenceEqual(t1.CustomModifiers.Take(t2.CustomModifiers.Length)))
                        {
                            AddSubstitution(ref substitution, tp2,
                                            new TypeWithModifiers(t1.Type,
                                                                  ImmutableArray.Create(t1.CustomModifiers, t2.CustomModifiers.Length, t1.CustomModifiers.Length - t2.CustomModifiers.Length)));
                            return(true);
                        }
                    }
                }

                return(false);
            }

            default:
            {
                return(t1 == t2);
            }
            }
        }
Ejemplo n.º 6
0
        public void TestPointerTypeTransforms()
        {
            CommonTestInitialization();

            // public unsafe class UnsafeClass<T> : Base2<int*[], Outer<dynamic>.Inner<Outer<dynamic>.Inner<T[], dynamic>.InnerInner<int*[][]>[], dynamic>.InnerInner<dynamic>[][]> { }
            var unsafeClass = _assembly.Modules[0].GlobalNamespace.GetMember <NamedTypeSymbol>(
                "UnsafeClass"
                );

            Assert.False(unsafeClass.ContainsDynamic());
            Assert.True(unsafeClass.BaseType().ContainsDynamic());

            var unsafeClassTypeParam = unsafeClass.TypeParameters[0];
            // T[]
            var arrayOfDerivedTypeParam = ArrayTypeSymbol.CreateCSharpArray(
                _assembly,
                TypeWithAnnotations.Create(unsafeClassTypeParam),
                1
                );
            // Outer<dynamic>
            var outerClassOfDynamic = _outerClass.Construct(s_dynamicType);
            // Outer<dynamic>.Inner<T[], dynamic>
            var complicatedInner = outerClassOfDynamic
                                   .GetTypeMember("Inner")
                                   .Construct(arrayOfDerivedTypeParam, s_dynamicType);
            // int*[]
            var pointerToInt        = new PointerTypeSymbol(TypeWithAnnotations.Create(_intType));
            var arrayOfPointerToInt = ArrayTypeSymbol.CreateCSharpArray(
                _assembly,
                TypeWithAnnotations.Create(pointerToInt),
                1
                );
            // int*[][]
            var arrayOfArrayOfPointerToInt = ArrayTypeSymbol.CreateCSharpArray(
                _assembly,
                TypeWithAnnotations.Create(arrayOfPointerToInt),
                1
                );
            // Outer<dynamic>.Inner<T[], dynamic>.InnerInner<int*[][]>
            var complicatedInnerInner = complicatedInner
                                        .GetTypeMember("InnerInner")
                                        .Construct(arrayOfArrayOfPointerToInt);
            // Outer<dynamic>.Inner<T[], dynamic>.InnerInner<int*[][]>[]
            var complicatedInnerInnerArray = ArrayTypeSymbol.CreateCSharpArray(
                _assembly,
                TypeWithAnnotations.Create(complicatedInnerInner),
                1
                );

            // Outer<dynamic>.Inner<Outer<dynamic>.Inner<T[], dynamic>.InnerInner<int*[][]>[], dynamic>
            complicatedInner = outerClassOfDynamic
                               .GetTypeMember("Inner")
                               .Construct(complicatedInnerInnerArray, s_dynamicType);
            // Outer<dynamic>.Inner<Outer<dynamic>.Inner<T[], dynamic>.InnerInner<int*[][]>[], dynamic>.InnerInner<dynamic>
            complicatedInnerInner = complicatedInner
                                    .GetTypeMember("InnerInner")
                                    .Construct(s_dynamicType);
            // Outer<dynamic>.Inner<Outer<dynamic>.Inner<T[], dynamic>.InnerInner<int*[][]>[], dynamic>.InnerInner<dynamic>[][]
            complicatedInnerInnerArray = ArrayTypeSymbol.CreateCSharpArray(
                _assembly,
                TypeWithAnnotations.Create(complicatedInnerInner),
                1
                );
            var complicatedInnerInnerArrayOfArray = ArrayTypeSymbol.CreateCSharpArray(
                _assembly,
                TypeWithAnnotations.Create(complicatedInnerInnerArray),
                1
                );
            // Base2<int*[], Outer<dynamic>.Inner<Outer<dynamic>.Inner<T[], dynamic>.InnerInner<int*[][]>[], dynamic>.InnerInner<dynamic>[][]>
            var baseType = _base2Class.Construct(
                arrayOfPointerToInt,
                complicatedInnerInnerArrayOfArray
                );

            Assert.Equal(baseType, unsafeClass.BaseType());
        }
Ejemplo n.º 7
0
        private void BindPCallNativeAndDelegate(InvocationExpressionSyntax node, ArrayBuilder <BoundExpression> args,
                                                DiagnosticBag diagnostics, TypeSyntax type)
        {
            var    XNode  = node.XNode as XP.MethodCallContext;
            string method = XNode?.Expr.GetText();

            if (string.IsNullOrEmpty(method))
            {
                method = "PCALLNATIVE";
            }
            if (!ValidatePCallArguments(node, args, diagnostics, method))
            {
                return;
            }
            // Our parent is the invocation expression of the delegate
            AnalyzedArguments analyzedArguments = AnalyzedArguments.GetInstance();

            try
            {
                var ts = FindPCallDelegateType(type as IdentifierNameSyntax);
                if (ts != null && ts.IsDelegateType())
                {
                    SourceDelegateMethodSymbol delmeth = ts.DelegateInvokeMethod() as SourceDelegateMethodSymbol;
                    // create new parameters based on the parameters from out parent call
                    var invoke    = node.Parent as InvocationExpressionSyntax;
                    var realargs  = invoke.ArgumentList;
                    var delparams = ts.DelegateParameters();
                    BindArgumentsAndNames(realargs, diagnostics, analyzedArguments);
                    var builder = ArrayBuilder <ParameterSymbol> .GetInstance();

                    int i = 0;
                    foreach (var expr in analyzedArguments.Arguments)
                    {
                        var ptype = expr.Type;
                        if (ptype == null)
                        {
                            ptype = new PointerTypeSymbol(Compilation.GetSpecialType(SpecialType.System_Void));
                        }
                        var parameter = new SourceSimpleParameterSymbol(
                            delmeth,
                            ptype,
                            i,
                            delparams[i].RefKind,
                            delparams[i].Name,
                            delparams[i].Locations);
                        builder.Add(parameter);
                        i++;
                    }
                    delmeth.InitializeParameters(builder.ToImmutableAndFree());
                }
                else
                {
                    Error(diagnostics, ErrorCode.ERR_PCallResolveGeneratedDelegate, node, method, type.ToString());
                }

                return;
            }
            finally
            {
                analyzedArguments.Free();
            }
        }
Ejemplo n.º 8
0
 public virtual void VisitPointerType(PointerTypeSymbol symbol)
 {
     DefaultVisit(symbol);
 }
Ejemplo n.º 9
0
 public virtual TResult VisitPointerType(PointerTypeSymbol symbol)
 {
     return(DefaultVisit(symbol));
 }
Ejemplo n.º 10
0
        private void EnsureSignatureIsLoaded()
        {
            if ((object)_lazyType == null)
            {
                var moduleSymbol = _containingType.ContainingPEModule;
                bool isVolatile;
                ImmutableArray<ModifierInfo<TypeSymbol>> customModifiers;
                TypeSymbol type = (new MetadataDecoder(moduleSymbol, _containingType)).DecodeFieldSignature(_handle, out isVolatile, out customModifiers);
                ImmutableArray<CustomModifier> customModifiersArray = CSharpCustomModifier.Convert(customModifiers);
                type = DynamicTypeDecoder.TransformType(type, customModifiersArray.Length, _handle, moduleSymbol);
                _lazyIsVolatile = isVolatile;

                TypeSymbol fixedElementType;
                int fixedSize;
                if (customModifiersArray.IsEmpty && IsFixedBuffer(out fixedSize, out fixedElementType))
                {
                    _lazyFixedSize = fixedSize;
                    _lazyFixedImplementationType = type as NamedTypeSymbol;
                    type = new PointerTypeSymbol(fixedElementType);
                }

                ImmutableInterlocked.InterlockedCompareExchange(ref _lazyCustomModifiers, customModifiersArray, default(ImmutableArray<CustomModifier>));
                Interlocked.CompareExchange(ref _lazyType, type, null);
            }
        }
 private PointerTypeSymbol TransformPointerType(PointerTypeSymbol type)
 {
     Increment();
     return(type.WithPointedAtType(TransformTypeWithAnnotations(type.PointedAtTypeWithAnnotations)));
 }
Ejemplo n.º 12
0
 public override Microsoft.Cci.IReference VisitPointerType(PointerTypeSymbol symbol, bool a)
 {
     return(Translate(symbol));
 }
Ejemplo n.º 13
0
 internal Microsoft.Cci.IPointerTypeReference Translate(PointerTypeSymbol symbol)
 {
     return(symbol);
 }
        public void Test1()
        {
            var oldMsCorLib = TestReferences.NetFx.v4_0_21006.mscorlib;
            var newMsCorLib = MscorlibRef;

            var c1 = CSharpCompilation.Create("C1", references: new[]
            {
                oldMsCorLib,
                TestReferences.SymbolsTests.CustomModifiers.Modifiers.netmodule
            });

            var c1Assembly = c1.Assembly;

            CSharpCompilation c2 = CSharpCompilation.Create("C2", references: new MetadataReference[] { newMsCorLib, new CSharpCompilationReference(c1) });

            var mscorlibAssembly = c2.GetReferencedAssemblySymbol(newMsCorLib);

            Assert.NotSame(mscorlibAssembly, c1.GetReferencedAssemblySymbol(oldMsCorLib));

            var modifiers = c2.GlobalNamespace.GetTypeMembers("Modifiers").Single();

            Assert.IsAssignableFrom <PENamedTypeSymbol>(modifiers);

            FieldSymbol f0 = modifiers.GetMembers("F0").OfType <FieldSymbol>().Single();

            Assert.Equal(1, f0.TypeWithAnnotations.CustomModifiers.Length);

            var f0Mod = f0.TypeWithAnnotations.CustomModifiers[0];

            Assert.True(f0Mod.IsOptional);
            Assert.Equal("System.Runtime.CompilerServices.IsConst", f0Mod.Modifier.ToTestDisplayString());
            Assert.Same(mscorlibAssembly, f0Mod.Modifier.ContainingAssembly.GetSymbol());

            MethodSymbol    m1 = modifiers.GetMembers("F1").OfType <MethodSymbol>().Single();
            ParameterSymbol p1 = m1.Parameters[0];
            ParameterSymbol p2 = modifiers.GetMembers("F2").OfType <MethodSymbol>().Single().Parameters[0];

            MethodSymbol    m5 = modifiers.GetMembers("F5").OfType <MethodSymbol>().Single();
            ParameterSymbol p5 = m5.Parameters[0];

            ParameterSymbol p6 = modifiers.GetMembers("F6").OfType <MethodSymbol>().Single().Parameters[0];

            MethodSymbol m7 = modifiers.GetMembers("F7").OfType <MethodSymbol>().Single();

            Assert.Equal(0, m1.ReturnTypeWithAnnotations.CustomModifiers.Length);

            Assert.Equal(1, p1.TypeWithAnnotations.CustomModifiers.Length);

            var p1Mod = p1.TypeWithAnnotations.CustomModifiers[0];

            Assert.True(p1Mod.IsOptional);
            Assert.Equal("System.Runtime.CompilerServices.IsConst", p1Mod.Modifier.ToTestDisplayString());
            Assert.Same(mscorlibAssembly, p1Mod.Modifier.ContainingAssembly.GetSymbol());

            Assert.Equal(2, p2.TypeWithAnnotations.CustomModifiers.Length);

            foreach (var p2Mod in p2.TypeWithAnnotations.CustomModifiers)
            {
                Assert.True(p2Mod.IsOptional);
                Assert.Equal("System.Runtime.CompilerServices.IsConst", p2Mod.Modifier.ToTestDisplayString());
                Assert.Same(mscorlibAssembly, p2Mod.Modifier.ContainingAssembly.GetSymbol());
            }

            Assert.True(m5.ReturnsVoid);
            Assert.Equal(1, m5.ReturnTypeWithAnnotations.CustomModifiers.Length);

            var m5Mod = m5.ReturnTypeWithAnnotations.CustomModifiers[0];

            Assert.True(m5Mod.IsOptional);
            Assert.Equal("System.Runtime.CompilerServices.IsConst", m5Mod.Modifier.ToTestDisplayString());
            Assert.Same(mscorlibAssembly, m5Mod.Modifier.ContainingAssembly.GetSymbol());

            Assert.Equal(0, p5.TypeWithAnnotations.CustomModifiers.Length);

            ArrayTypeSymbol p5Type = (ArrayTypeSymbol)p5.Type;

            Assert.Equal("System.Int32", p5Type.ElementType.ToTestDisplayString());

            Assert.Equal(1, p5Type.ElementTypeWithAnnotations.CustomModifiers.Length);
            var p5TypeMod = p5Type.ElementTypeWithAnnotations.CustomModifiers[0];

            Assert.True(p5TypeMod.IsOptional);
            Assert.Equal("System.Runtime.CompilerServices.IsConst", p5TypeMod.Modifier.ToTestDisplayString());
            Assert.Same(mscorlibAssembly, p5TypeMod.Modifier.ContainingAssembly.GetSymbol());

            Assert.Equal(0, p6.TypeWithAnnotations.CustomModifiers.Length);

            PointerTypeSymbol p6Type = (PointerTypeSymbol)p6.Type;

            Assert.Equal("System.Int32", p6Type.PointedAtType.ToTestDisplayString());

            Assert.Equal(1, p6Type.PointedAtTypeWithAnnotations.CustomModifiers.Length);
            var p6TypeMod = p6Type.PointedAtTypeWithAnnotations.CustomModifiers[0];

            Assert.True(p6TypeMod.IsOptional);
            Assert.Equal("System.Runtime.CompilerServices.IsConst", p6TypeMod.Modifier.ToTestDisplayString());
            Assert.Same(mscorlibAssembly, p6TypeMod.Modifier.ContainingAssembly.GetSymbol());

            Assert.False(m7.ReturnsVoid);
            Assert.Equal(1, m7.ReturnTypeWithAnnotations.CustomModifiers.Length);

            var m7Mod = m7.ReturnTypeWithAnnotations.CustomModifiers[0];

            Assert.True(m7Mod.IsOptional);
            Assert.Equal("System.Runtime.CompilerServices.IsConst", m7Mod.Modifier.ToTestDisplayString());
            Assert.Same(mscorlibAssembly, m7Mod.Modifier.ContainingAssembly.GetSymbol());
        }
Ejemplo n.º 15
0
 private PointerTypeSymbol DecodePointerType(PointerTypeSymbol type)
 {
     return(type.WithPointedAtType(DecodeTypeInternal(type.PointedAtTypeWithAnnotations)));
 }
Ejemplo n.º 16
0
        /// <summary>
        /// Determine whether there is any substitution of type parameters that will
        /// make two types identical.
        /// </summary>
        /// <param name="t1">LHS</param>
        /// <param name="t2">RHS</param>
        /// <param name="substitution">
        /// Substitutions performed so far (or null for none).
        /// Keys are type parameters, values are types (possibly type parameters).
        /// Will be updated with new substitutions by the callee.
        /// Should be ignored when false is returned.
        /// </param>
        /// <returns>True if there exists a type map such that Map(LHS) == Map(RHS).</returns>
        /// <remarks>
        /// Derived from Dev10's BSYMMGR::UnifyTypes.
        /// Two types will not unify if they have different custom modifiers.
        /// </remarks>
        private static bool CanUnifyHelper(
            TypeWithAnnotations t1,
            TypeWithAnnotations t2,
            ref MutableTypeMap?substitution
            )
        {
            if (!t1.HasType || !t2.HasType)
            {
                return(t1.IsSameAs(t2));
            }

            if (substitution != null)
            {
                t1 = t1.SubstituteType(substitution);
                t2 = t2.SubstituteType(substitution);
            }

            if (
                TypeSymbol.Equals(t1.Type, t2.Type, TypeCompareKind.CLRSignatureCompareOptions) &&
                t1.CustomModifiers.SequenceEqual(t2.CustomModifiers)
                )
            {
                return(true);
            }

            // We can avoid a lot of redundant checks if we ensure that we only have to check
            // for type parameters on the LHS
            if (!t1.Type.IsTypeParameter() && t2.Type.IsTypeParameter())
            {
                TypeWithAnnotations tmp = t1;
                t1 = t2;
                t2 = tmp;
            }

            // If t1 is not a type parameter, then neither is t2
            Debug.Assert(t1.Type.IsTypeParameter() || !t2.Type.IsTypeParameter());

            switch (t1.Type.Kind)
            {
            case SymbolKind.ArrayType:
            {
                if (
                    t2.TypeKind != t1.TypeKind ||
                    !t2.CustomModifiers.SequenceEqual(t1.CustomModifiers)
                    )
                {
                    return(false);
                }

                ArrayTypeSymbol at1 = (ArrayTypeSymbol)t1.Type;
                ArrayTypeSymbol at2 = (ArrayTypeSymbol)t2.Type;

                if (!at1.HasSameShapeAs(at2))
                {
                    return(false);
                }

                return(CanUnifyHelper(
                           at1.ElementTypeWithAnnotations,
                           at2.ElementTypeWithAnnotations,
                           ref substitution
                           ));
            }

            case SymbolKind.PointerType:
            {
                if (
                    t2.TypeKind != t1.TypeKind ||
                    !t2.CustomModifiers.SequenceEqual(t1.CustomModifiers)
                    )
                {
                    return(false);
                }

                PointerTypeSymbol pt1 = (PointerTypeSymbol)t1.Type;
                PointerTypeSymbol pt2 = (PointerTypeSymbol)t2.Type;

                return(CanUnifyHelper(
                           pt1.PointedAtTypeWithAnnotations,
                           pt2.PointedAtTypeWithAnnotations,
                           ref substitution
                           ));
            }

            case SymbolKind.NamedType:
            case SymbolKind.ErrorType:
            {
                if (
                    t2.TypeKind != t1.TypeKind ||
                    !t2.CustomModifiers.SequenceEqual(t1.CustomModifiers)
                    )
                {
                    return(false);
                }

                NamedTypeSymbol nt1 = (NamedTypeSymbol)t1.Type;
                NamedTypeSymbol nt2 = (NamedTypeSymbol)t2.Type;
                if (!nt1.IsGenericType || !nt2.IsGenericType)
                {
                    // Initial TypeSymbol.Equals(...) && CustomModifiers.SequenceEqual(...) failed above,
                    // and custom modifiers compared equal in this case block, so the types must be distinct.
                    Debug.Assert(!nt1.Equals(nt2, TypeCompareKind.CLRSignatureCompareOptions));
                    return(false);
                }

                int arity = nt1.Arity;

                if (
                    nt2.Arity != arity ||
                    !TypeSymbol.Equals(
                        nt2.OriginalDefinition,
                        nt1.OriginalDefinition,
                        TypeCompareKind.ConsiderEverything
                        )
                    )
                {
                    return(false);
                }

                var nt1Arguments = nt1.TypeArgumentsWithAnnotationsNoUseSiteDiagnostics;
                var nt2Arguments = nt2.TypeArgumentsWithAnnotationsNoUseSiteDiagnostics;

                for (int i = 0; i < arity; i++)
                {
                    if (!CanUnifyHelper(nt1Arguments[i], nt2Arguments[i], ref substitution))
                    {
                        return(false);
                    }
                }

                // Note: Dev10 folds this into the loop since GetTypeArgsAll includes type args for containing types
                // TODO: Calling CanUnifyHelper for the containing type is an overkill, we simply need to go through type arguments for all containers.
                return((object)nt1.ContainingType == null ||
                       CanUnifyHelper(nt1.ContainingType, nt2.ContainingType, ref substitution));
            }

            case SymbolKind.TypeParameter:
            {
                // These substitutions are not allowed in C#
                if (t2.Type.IsPointerOrFunctionPointer() || t2.IsVoidType())
                {
                    return(false);
                }

                TypeParameterSymbol tp1 = (TypeParameterSymbol)t1.Type;

                // Perform the "occurs check" - i.e. ensure that t2 doesn't contain t1 to avoid recursive types
                // Note: t2 can't be the same type param - we would have caught that with ReferenceEquals above
                if (Contains(t2.Type, tp1))
                {
                    return(false);
                }

                if (t1.CustomModifiers.IsDefaultOrEmpty)
                {
                    AddSubstitution(ref substitution, tp1, t2);
                    return(true);
                }

                if (t1.CustomModifiers.SequenceEqual(t2.CustomModifiers))
                {
                    AddSubstitution(ref substitution, tp1, TypeWithAnnotations.Create(t2.Type));
                    return(true);
                }

                if (
                    t1.CustomModifiers.Length < t2.CustomModifiers.Length &&
                    t1.CustomModifiers.SequenceEqual(
                        t2.CustomModifiers.Take(t1.CustomModifiers.Length)
                        )
                    )
                {
                    AddSubstitution(
                        ref substitution,
                        tp1,
                        TypeWithAnnotations.Create(
                            t2.Type,
                            customModifiers: ImmutableArray.Create(
                                t2.CustomModifiers,
                                t1.CustomModifiers.Length,
                                t2.CustomModifiers.Length - t1.CustomModifiers.Length
                                )
                            )
                        );
                    return(true);
                }

                if (t2.Type.IsTypeParameter())
                {
                    var tp2 = (TypeParameterSymbol)t2.Type;

                    if (t2.CustomModifiers.IsDefaultOrEmpty)
                    {
                        AddSubstitution(ref substitution, tp2, t1);
                        return(true);
                    }

                    if (
                        t2.CustomModifiers.Length < t1.CustomModifiers.Length &&
                        t2.CustomModifiers.SequenceEqual(
                            t1.CustomModifiers.Take(t2.CustomModifiers.Length)
                            )
                        )
                    {
                        AddSubstitution(
                            ref substitution,
                            tp2,
                            TypeWithAnnotations.Create(
                                t1.Type,
                                customModifiers: ImmutableArray.Create(
                                    t1.CustomModifiers,
                                    t2.CustomModifiers.Length,
                                    t1.CustomModifiers.Length - t2.CustomModifiers.Length
                                    )
                                )
                            );
                        return(true);
                    }
                }

                return(false);
            }

            default:
            {
                return(false);
            }
            }
        }
 internal Microsoft.Cci.IPointerTypeReference Translate(PointerTypeSymbol symbol)
 {
     return symbol;
 }
Ejemplo n.º 18
0
 public virtual TResult VisitPointerType(PointerTypeSymbol symbol, TArgument argument)
 {
     return(DefaultVisit(symbol, argument));
 }
 public override Microsoft.Cci.IReference VisitPointerType(PointerTypeSymbol symbol, bool a)
 {
     return Translate(symbol);
 }
Ejemplo n.º 20
0
        public void Test1()
        {
            var assemblies = MetadataTestHelpers.GetSymbolsForReferences(new[]
            {
                TestReferences.SymbolsTests.CustomModifiers.Modifiers.dll,
                TestReferences.NetFx.v4_0_21006.mscorlib
            });

            var modifiersModule = assemblies[0].Modules[0];


            var modifiers = modifiersModule.GlobalNamespace.GetTypeMembers("Modifiers").Single();

            FieldSymbol f0 = modifiers.GetMembers("F0").OfType <FieldSymbol>().Single();

            Assert.Equal(1, f0.TypeWithAnnotations.CustomModifiers.Length);

            var f0Mod = f0.TypeWithAnnotations.CustomModifiers[0];

            Assert.True(f0Mod.IsOptional);
            Assert.Equal("System.Runtime.CompilerServices.IsConst", f0Mod.Modifier.ToTestDisplayString());

            MethodSymbol    m1 = modifiers.GetMembers("F1").OfType <MethodSymbol>().Single();
            ParameterSymbol p1 = m1.Parameters[0];
            ParameterSymbol p2 = modifiers.GetMembers("F2").OfType <MethodSymbol>().Single().Parameters[0];

            ParameterSymbol p4 = modifiers.GetMembers("F4").OfType <MethodSymbol>().Single().Parameters[0];

            MethodSymbol    m5 = modifiers.GetMembers("F5").OfType <MethodSymbol>().Single();
            ParameterSymbol p5 = m5.Parameters[0];

            ParameterSymbol p6 = modifiers.GetMembers("F6").OfType <MethodSymbol>().Single().Parameters[0];

            MethodSymbol m7 = modifiers.GetMembers("F7").OfType <MethodSymbol>().Single();

            Assert.Equal(0, m1.ReturnTypeWithAnnotations.CustomModifiers.Length);

            Assert.Equal(1, p1.TypeWithAnnotations.CustomModifiers.Length);

            var p1Mod = p1.TypeWithAnnotations.CustomModifiers[0];

            Assert.True(p1Mod.IsOptional);
            Assert.Equal("System.Runtime.CompilerServices.IsConst", p1Mod.Modifier.ToTestDisplayString());

            Assert.Equal(2, p2.TypeWithAnnotations.CustomModifiers.Length);

            foreach (var p2Mod in p2.TypeWithAnnotations.CustomModifiers)
            {
                Assert.True(p2Mod.IsOptional);
                Assert.Equal("System.Runtime.CompilerServices.IsConst", p2Mod.Modifier.ToTestDisplayString());
            }

            Assert.Equal(SymbolKind.ErrorType, p4.Type.Kind);

            Assert.True(m5.ReturnsVoid);
            Assert.Equal(1, m5.ReturnTypeWithAnnotations.CustomModifiers.Length);

            var m5Mod = m5.ReturnTypeWithAnnotations.CustomModifiers[0];

            Assert.True(m5Mod.IsOptional);
            Assert.Equal("System.Runtime.CompilerServices.IsConst", m5Mod.Modifier.ToTestDisplayString());

            Assert.Equal(0, p5.TypeWithAnnotations.CustomModifiers.Length);

            ArrayTypeSymbol p5Type = (ArrayTypeSymbol)p5.Type;

            Assert.Equal("System.Int32", p5Type.ElementType.ToTestDisplayString());

            Assert.Equal(1, p5Type.ElementTypeWithAnnotations.CustomModifiers.Length);
            var p5TypeMod = p5Type.ElementTypeWithAnnotations.CustomModifiers[0];

            Assert.True(p5TypeMod.IsOptional);
            Assert.Equal("System.Runtime.CompilerServices.IsConst", p5TypeMod.Modifier.ToTestDisplayString());

            Assert.Equal(0, p6.TypeWithAnnotations.CustomModifiers.Length);

            PointerTypeSymbol p6Type = (PointerTypeSymbol)p6.Type;

            Assert.Equal("System.Int32", p6Type.PointedAtType.ToTestDisplayString());

            Assert.Equal(1, p6Type.PointedAtTypeWithAnnotations.CustomModifiers.Length);
            var p6TypeMod = p6Type.PointedAtTypeWithAnnotations.CustomModifiers[0];

            Assert.True(p6TypeMod.IsOptional);
            Assert.Equal("System.Runtime.CompilerServices.IsConst", p6TypeMod.Modifier.ToTestDisplayString());

            Assert.False(m7.ReturnsVoid);
            Assert.Equal(1, m7.ReturnTypeWithAnnotations.CustomModifiers.Length);

            var m7Mod = m7.ReturnTypeWithAnnotations.CustomModifiers[0];

            Assert.True(m7Mod.IsOptional);
            Assert.Equal("System.Runtime.CompilerServices.IsConst", m7Mod.Modifier.ToTestDisplayString());
        }
Ejemplo n.º 21
0
 public PointerBackpatcher(PointerTypeSymbol symbol, Type type)
     : base(type)
 {
     this.symbol = symbol;
 }