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); }
/// <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); } } }
/// <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); } } }
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()); }
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(); } }
public virtual void VisitPointerType(PointerTypeSymbol symbol) { DefaultVisit(symbol); }
public virtual TResult VisitPointerType(PointerTypeSymbol symbol) { return(DefaultVisit(symbol)); }
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))); }
public override Microsoft.Cci.IReference VisitPointerType(PointerTypeSymbol symbol, bool a) { return(Translate(symbol)); }
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()); }
private PointerTypeSymbol DecodePointerType(PointerTypeSymbol type) { return(type.WithPointedAtType(DecodeTypeInternal(type.PointedAtTypeWithAnnotations))); }
/// <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; }
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); }
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()); }
public PointerBackpatcher(PointerTypeSymbol symbol, Type type) : base(type) { this.symbol = symbol; }