private void SetStructLayoutPseudoCustomAttribute(CustomAttributeBuilder customBuilder)
        {
            object     val = customBuilder.GetConstructorArgument(0);
            LayoutKind layout;

            if (val is short)
            {
                layout = (LayoutKind)(short)val;
            }
            else
            {
                layout = (LayoutKind)val;
            }
            int?pack = (int?)customBuilder.GetFieldValue("Pack");
            int?size = (int?)customBuilder.GetFieldValue("Size");

            if (pack.HasValue || size.HasValue)
            {
                ClassLayoutTable.Record rec = new ClassLayoutTable.Record();
                rec.PackingSize = (short)(pack ?? 0);
                rec.ClassSize   = size ?? 0;
                rec.Parent      = token;
                this.ModuleBuilder.ClassLayout.AddRecord(rec);
            }
            attribs &= ~TypeAttributes.LayoutMask;
            switch (layout)
            {
            case LayoutKind.Auto:
                attribs |= TypeAttributes.AutoLayout;
                break;

            case LayoutKind.Explicit:
                attribs |= TypeAttributes.ExplicitLayout;
                break;

            case LayoutKind.Sequential:
                attribs |= TypeAttributes.SequentialLayout;
                break;
            }
            CharSet?charSet = customBuilder.GetFieldValue <CharSet>("CharSet");

            attribs &= ~TypeAttributes.StringFormatMask;
            switch (charSet ?? CharSet.None)
            {
            case CharSet.None:
            case CharSet.Ansi:
                attribs |= TypeAttributes.AnsiClass;
                break;

            case CharSet.Auto:
                attribs |= TypeAttributes.AutoClass;
                break;

            case CharSet.Unicode:
                attribs |= TypeAttributes.UnicodeClass;
                break;
            }
        }
Exemple #2
0
        public override void ApplyAttributeBuilder(Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
        {
            if (a.Target == AttributeTargets.Assembly)
            {
                assembly.ApplyAttributeBuilder(a, ctor, cdata, pa);
                return;
            }

            if (a.Type == pa.DefaultCharset)
            {
                switch (a.GetCharSetValue())
                {
                case CharSet.Ansi:
                case CharSet.None:
                    break;

                case CharSet.Auto:
                    DefaultCharSet     = CharSet.Auto;
                    DefaultCharSetType = TypeAttributes.AutoClass;
                    break;

                case CharSet.Unicode:
                    DefaultCharSet     = CharSet.Unicode;
                    DefaultCharSetType = TypeAttributes.UnicodeClass;
                    break;

                default:
                    Report.Error(1724, a.Location, "Value specified for the argument to `{0}' is not valid",
                                 a.GetSignatureForError());
                    break;
                }
            }
            else if (a.Type == pa.CLSCompliant)
            {
                Attribute cls = DeclaringAssembly.CLSCompliantAttribute;
                if (cls == null)
                {
                    Report.Warning(3012, 1, a.Location,
                                   "You must specify the CLSCompliant attribute on the assembly, not the module, to enable CLS compliance checking");
                }
                else if (DeclaringAssembly.IsCLSCompliant != a.GetBoolean())
                {
                    Report.SymbolRelatedToPreviousError(cls.Location, cls.GetSignatureForError());
                    Report.Warning(3017, 1, a.Location,
                                   "You cannot specify the CLSCompliant attribute on a module that differs from the CLSCompliant attribute on the assembly");
                    return;
                }
            }

            builder.SetCustomAttribute((ConstructorInfo)ctor.GetMetaInfo(), cdata);
        }
Exemple #3
0
        private void SetDllImportPseudoCustomAttribute(CustomAttributeBuilder customBuilder)
        {
            CallingConvention?callingConvention = customBuilder.GetFieldValue <CallingConvention>("CallingConvention");
            CharSet?          charSet           = customBuilder.GetFieldValue <CharSet>("CharSet");

            SetDllImportPseudoCustomAttribute((string)customBuilder.GetConstructorArgument(0),
                                              (string)customBuilder.GetFieldValue("EntryPoint"),
                                              callingConvention,
                                              charSet,
                                              (bool?)customBuilder.GetFieldValue("BestFitMapping"),
                                              (bool?)customBuilder.GetFieldValue("ThrowOnUnmappableChar"),
                                              (bool?)customBuilder.GetFieldValue("SetLastError"),
                                              (bool?)customBuilder.GetFieldValue("PreserveSig"),
                                              (bool?)customBuilder.GetFieldValue("ExactSpelling"));
        }
Exemple #4
0
		public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
		{
			if (a.Target == AttributeTargets.Assembly) {
				assembly.ApplyAttributeBuilder (a, ctor, cdata, pa);
				return;
			}

			if (a.Type == pa.DefaultCharset) {
				switch (a.GetCharSetValue ()) {
				case CharSet.Ansi:
				case CharSet.None:
					break;
				case CharSet.Auto:
					DefaultCharSet = CharSet.Auto;
					DefaultCharSetType = TypeAttributes.AutoClass;
					break;
				case CharSet.Unicode:
					DefaultCharSet = CharSet.Unicode;
					DefaultCharSetType = TypeAttributes.UnicodeClass;
					break;
				default:
					Report.Error (1724, a.Location, "Value specified for the argument to `{0}' is not valid",
						a.GetSignatureForError ());
					break;
				}
			} else if (a.Type == pa.CLSCompliant) {
				Attribute cls = DeclaringAssembly.CLSCompliantAttribute;
				if (cls == null) {
					Report.Warning (3012, 1, a.Location,
						"You must specify the CLSCompliant attribute on the assembly, not the module, to enable CLS compliance checking");
				} else if (DeclaringAssembly.IsCLSCompliant != a.GetBoolean ()) {
					Report.SymbolRelatedToPreviousError (cls.Location, cls.GetSignatureForError ());
					Report.Warning (3017, 1, a.Location,
						"You cannot specify the CLSCompliant attribute on a module that differs from the CLSCompliant attribute on the assembly");
					return;
				}
			}

			builder.SetCustomAttribute ((ConstructorInfo) ctor.GetMetaInfo (), cdata);
		}
Exemple #5
0
            public void AnalyzeSymbol(SymbolAnalysisContext context)
            {
                var methodSymbol = (IMethodSymbol)context.Symbol;

                if (methodSymbol == null)
                {
                    return;
                }

                DllImportData dllImportData = methodSymbol.GetDllImportData();

                if (dllImportData == null)
                {
                    return;
                }

                AttributeData dllAttribute    = methodSymbol.GetAttributes().FirstOrDefault(attr => attr.AttributeClass.Equals(_dllImportType));
                Location      defaultLocation = dllAttribute == null?methodSymbol.Locations.FirstOrDefault() : GetAttributeLocation(dllAttribute);

                // CA1401 - PInvoke methods should not be visible
                if (methodSymbol.IsExternallyVisible())
                {
                    context.ReportDiagnostic(context.Symbol.CreateDiagnostic(RuleCA1401, methodSymbol.Name));
                }

                // CA2101 - Specify marshalling for PInvoke string arguments
                if (dllImportData.BestFitMapping != false ||
                    context.Options.GetMSBuildPropertyValue(MSBuildPropertyOptionNames.InvariantGlobalization, context.Compilation) is not "true")
                {
                    bool appliedCA2101ToMethod = false;
                    foreach (IParameterSymbol parameter in methodSymbol.Parameters)
                    {
                        if (parameter.Type.SpecialType == SpecialType.System_String || parameter.Type.Equals(_stringBuilderType))
                        {
                            AttributeData marshalAsAttribute = parameter.GetAttributes().FirstOrDefault(attr => attr.AttributeClass.Equals(_marshalAsType));
                            CharSet?      charSet            = marshalAsAttribute == null
                                ? dllImportData.CharacterSet
                                : MarshalingToCharSet(GetParameterMarshaling(marshalAsAttribute));

                            // only unicode marshaling is considered safe
                            if (charSet != CharSet.Unicode)
                            {
                                if (marshalAsAttribute != null)
                                {
                                    // track the diagnostic on the [MarshalAs] attribute
                                    Location marshalAsLocation = GetAttributeLocation(marshalAsAttribute);
                                    context.ReportDiagnostic(Diagnostic.Create(RuleCA2101, marshalAsLocation));
                                }
                                else if (!appliedCA2101ToMethod)
                                {
                                    // track the diagnostic on the [DllImport] attribute
                                    appliedCA2101ToMethod = true;
                                    context.ReportDiagnostic(Diagnostic.Create(RuleCA2101, defaultLocation));
                                }
                            }
                        }
                    }

                    // only unicode marshaling is considered safe, but only check this if we haven't already flagged the attribute
                    if (!appliedCA2101ToMethod && dllImportData.CharacterSet != CharSet.Unicode &&
                        (methodSymbol.ReturnType.SpecialType == SpecialType.System_String || methodSymbol.ReturnType.Equals(_stringBuilderType)))
                    {
                        context.ReportDiagnostic(Diagnostic.Create(RuleCA2101, defaultLocation));
                    }
                }
            }
Exemple #6
0
        internal void SetDllImportPseudoCustomAttribute(string dllName, string entryName, CallingConvention?nativeCallConv, CharSet?nativeCharSet,
                                                        bool?bestFitMapping, bool?throwOnUnmappableChar, bool?setLastError, bool?preserveSig, bool?exactSpelling)
        {
            const short NoMangle          = 0x0001;
            const short CharSetMask       = 0x0006;
            const short CharSetNotSpec    = 0x0000;
            const short CharSetAnsi       = 0x0002;
            const short CharSetUnicode    = 0x0004;
            const short CharSetAuto       = 0x0006;
            const short SupportsLastError = 0x0040;
            const short CallConvMask      = 0x0700;
            const short CallConvWinapi    = 0x0100;
            const short CallConvCdecl     = 0x0200;
            const short CallConvStdcall   = 0x0300;
            const short CallConvThiscall  = 0x0400;
            const short CallConvFastcall  = 0x0500;
            // non-standard flags
            const short BestFitOn       = 0x0010;
            const short BestFitOff      = 0x0020;
            const short CharMapErrorOn  = 0x1000;
            const short CharMapErrorOff = 0x2000;
            short       flags           = CharSetNotSpec | CallConvWinapi;

            if (bestFitMapping.HasValue)
            {
                flags |= bestFitMapping.Value ? BestFitOn : BestFitOff;
            }
            if (throwOnUnmappableChar.HasValue)
            {
                flags |= throwOnUnmappableChar.Value ? CharMapErrorOn : CharMapErrorOff;
            }
            if (nativeCallConv.HasValue)
            {
                flags &= ~CallConvMask;
                switch (nativeCallConv.Value)
                {
                case System.Runtime.InteropServices.CallingConvention.Cdecl:
                    flags |= CallConvCdecl;
                    break;

                case System.Runtime.InteropServices.CallingConvention.FastCall:
                    flags |= CallConvFastcall;
                    break;

                case System.Runtime.InteropServices.CallingConvention.StdCall:
                    flags |= CallConvStdcall;
                    break;

                case System.Runtime.InteropServices.CallingConvention.ThisCall:
                    flags |= CallConvThiscall;
                    break;

                case System.Runtime.InteropServices.CallingConvention.Winapi:
                    flags |= CallConvWinapi;
                    break;
                }
            }
            if (nativeCharSet.HasValue)
            {
                flags &= ~CharSetMask;
                switch (nativeCharSet.Value)
                {
                case CharSet.Ansi:
                case CharSet.None:
                    flags |= CharSetAnsi;
                    break;

                case CharSet.Auto:
                    flags |= CharSetAuto;
                    break;

                case CharSet.Unicode:
                    flags |= CharSetUnicode;
                    break;
                }
            }
            if (exactSpelling.HasValue && exactSpelling.Value)
            {
                flags |= NoMangle;
            }
            if (!preserveSig.HasValue || preserveSig.Value)
            {
                implFlags |= MethodImplAttributes.PreserveSig;
            }
            if (setLastError.HasValue && setLastError.Value)
            {
                flags |= SupportsLastError;
            }
            ImplMapTable.Record rec = new ImplMapTable.Record();
            rec.MappingFlags    = flags;
            rec.MemberForwarded = pseudoToken;
            rec.ImportName      = this.ModuleBuilder.Strings.Add(entryName ?? name);
            rec.ImportScope     = this.ModuleBuilder.ModuleRef.FindOrAddRecord(dllName == null ? 0 : this.ModuleBuilder.Strings.Add(dllName));
            this.ModuleBuilder.ImplMap.AddRecord(rec);
        }