internal static void VerifyAttributeUsage(this AttributeKind kind, FunctionAttributeIndex index)
        {
            FunctionIndexKinds allowedIndexes = kind.GetAllowedIndexes( );

            switch (index)
            {
            case FunctionAttributeIndex.Function:
                if (!allowedIndexes.HasFlag(FunctionIndexKinds.Function))
                {
                    throw new ArgumentException( );
                }

                break;

            case FunctionAttributeIndex.ReturnType:
                if (!allowedIndexes.HasFlag(FunctionIndexKinds.Return))
                {
                    throw new ArgumentException( );
                }

                break;

            // case FunctionAttributeIndex.Parameter0:
            default:
                if (!allowedIndexes.HasFlag(FunctionIndexKinds.Parameter))
                {
                    throw new ArgumentException( );
                }

                break;
            }
        }
Пример #2
0
        /// <summary>Removes an <see cref="AttributeKind"/> from an <see cref="IAttributeContainer"/></summary>
        /// <typeparam name="T">Container type</typeparam>
        /// <param name="self">Container to remove the attribute from</param>
        /// <param name="index"><see cref="FunctionAttributeIndex"/> to remove the attribute from </param>
        /// <param name="kind">Attribute to remove from the container</param>
        /// <returns><paramref name="self"/> for fluent use</returns>
        public static T RemoveAttribute <T>(this T self, FunctionAttributeIndex index, AttributeKind kind)
            where T : class, IAttributeContainer
        {
            self.ValidateNotNull(nameof(self));

            if (kind == AttributeKind.None)
            {
                return(self);
            }

            if (self is IAttributeAccessor container)
            {
                container.RemoveAttributeAtIndex(index, kind);
            }
            else
            {
                ICollection <AttributeValue> attributes = self.Attributes[index];
                AttributeValue attrib = attributes.FirstOrDefault(a => a.Kind == kind);
                if (attrib != default)
                {
                    attributes.Remove(attrib);
                }
            }

            return(self);
        }
Пример #3
0
        public static T AddAttributes <T>(this T self, FunctionAttributeIndex index, IEnumerable <AttributeValue> attributes)
            where T : class, IAttributeContainer
        {
            if (self == null)
            {
                throw new ArgumentNullException(nameof(self));
            }

            if (attributes != null)
            {
                foreach (var attrib in attributes)
                {
                    if (self is IAttributeAccessor container)
                    {
                        container.AddAttributeAtIndex(index, attrib);
                    }
                    else
                    {
                        self.Attributes[index].Add(attrib);
                    }
                }
            }

            return(self);
        }
Пример #4
0
        internal static void VerifyAttributeUsage(this AttributeKind kind, FunctionAttributeIndex index)
        {
            Debug.Assert(kind >= AttributeKind.None && kind < AttributeKind.EndAttrKinds);
            FunctionIndexKinds allowedindices = kind.GetAllowedIndexes( );

            switch (index)
            {
            case FunctionAttributeIndex.Function:
                if (!allowedindices.HasFlag(FunctionIndexKinds.Function))
                {
                    throw new ArgumentException("Attribute not allowed on functions", nameof(index));
                }

                break;

            case FunctionAttributeIndex.ReturnType:
                if (!allowedindices.HasFlag(FunctionIndexKinds.Return))
                {
                    throw new ArgumentException("Attribute not allowed on function Return", nameof(index));
                }

                break;

            // case FunctionAttributeIndex.Parameter0:
            default:
                if (!allowedindices.HasFlag(FunctionIndexKinds.Parameter))
                {
                    throw new ArgumentException("Attribute not allowed on function parameter", nameof(index));
                }

                break;
            }
        }
        internal static void VerifyAttributeUsage(this AttributeKind kind, FunctionAttributeIndex index, Value value)
        {
            VerifyAttributeUsage(kind, index);

            if (index >= FunctionAttributeIndex.Parameter0)
            {
                IrFunction function;
                switch (value)
                {
                case IrFunction f:
                    function = f;
                    break;

                case CallInstruction call:
                    function = call.TargetFunction;
                    break;

                case Argument arg:
                    function = arg.ContainingFunction;
                    break;

                default:
                    function = default;
                    break;
                }

                int paramIndex = index - FunctionAttributeIndex.Parameter0;
                if (paramIndex > ((function?.Parameters.Count ?? 0) - 1))
                {
                    throw new ArgumentException( );
                }
            }
        }
Пример #6
0
        public static T AddAttributes <T>(this T self, FunctionAttributeIndex index, params AttributeKind[] values)
            where T : class, IAttributeContainer
        {
            if (self == null)
            {
                throw new ArgumentNullException(nameof(self));
            }

            if (values != null)
            {
                foreach (var kind in values)
                {
                    AttributeValue attrib = self.Context.CreateAttribute(kind);
                    if (self is IAttributeAccessor container)
                    {
                        container.AddAttributeAtIndex(index, attrib);
                    }
                    else
                    {
                        self.Attributes[index].Add(attrib);
                    }
                }
            }

            return(self);
        }
Пример #7
0
        public static T RemoveAttribute <T>(this T self, FunctionAttributeIndex index, AttributeKind kind)
            where T : class, IAttributeContainer
        {
            if (self == null)
            {
                throw new ArgumentNullException(nameof(self));
            }

            if (kind == AttributeKind.None)
            {
                return(self);
            }

            if (self is IAttributeAccessor container)
            {
                container.RemoveAttributeAtIndex(index, kind);
            }
            else
            {
                IAttributeCollection attributes = self.Attributes[index];
                AttributeValue       attrib     = attributes.FirstOrDefault(a => a.Kind == kind);
                if (attrib != default(AttributeValue))
                {
                    attributes.Remove(attrib);
                }
            }

            return(self);
        }
Пример #8
0
        internal static void VerifyAttributeUsage(this AttributeKind kind, FunctionAttributeIndex index)
        {
            kind.ValidateDefined(nameof(kind));

            FunctionIndexKinds allowedIndexes = kind.GetAllowedIndexes( );

            switch (index)
            {
            case FunctionAttributeIndex.Function:
                if (!allowedIndexes.HasFlag(FunctionIndexKinds.Function))
                {
                    throw new ArgumentException(Resources.Attribute_not_allowed_on_functions, nameof(index));
                }

                break;

            case FunctionAttributeIndex.ReturnType:
                if (!allowedIndexes.HasFlag(FunctionIndexKinds.Return))
                {
                    throw new ArgumentException(Resources.Attribute_not_allowed_on_function_Return, nameof(index));
                }

                break;

            // case FunctionAttributeIndex.Parameter0:
            default:
                if (!allowedIndexes.HasFlag(FunctionIndexKinds.Parameter))
                {
                    throw new ArgumentException(Resources.Attribute_not_allowed_on_function_parameter, nameof(index));
                }

                break;
            }
        }
Пример #9
0
        /// <inheritdoc/>
        public AttributeValue GetAttributeAtIndex(FunctionAttributeIndex index, string name)
        {
            name.ValidateNotNullOrWhiteSpace(nameof(name));

            var handle = LLVMGetCallSiteStringAttribute(ValueHandle, ( LLVMAttributeIndex )index, name, ( uint )name.Length);

            return(AttributeValue.FromHandle(Context, handle));
        }
Пример #10
0
        /// <summary>Adds the attributes from and <see cref="IAttributeDictionary"/> to an <see cref="IAttributeContainer"/></summary>
        /// <typeparam name="T">Container type</typeparam>
        /// <param name="self">Container to add the attributes to</param>
        /// <param name="index"><see cref="FunctionAttributeIndex"/> to add the attributes to  </param>
        /// <param name="attributes"><see cref="IAttributeDictionary"/> containing the attributes to add to the container</param>
        /// <returns><paramref name="self"/> for fluent use</returns>
        public static T AddAttributes <T>(this T self, FunctionAttributeIndex index, IAttributeDictionary attributes)
            where T : class, IAttributeContainer
        {
            self.ValidateNotNull(nameof(self));
            attributes.ValidateNotNull(nameof(attributes));

            return(AddAttributes(self, index, attributes[index]));
        }
Пример #11
0
        public static T AddAttributes <T>(this T self, FunctionAttributeIndex index, IAttributeDictionary attributes)
            where T : class, IAttributeContainer
        {
            if (attributes == null)
            {
                return(self);
            }

            return(AddAttributes(self, index, attributes[index]));
        }
Пример #12
0
        public bool TryGetValue(FunctionAttributeIndex key, out ICollection <AttributeValue> value)
        {
            value = null;
            if (ContainsKey(key))
            {
                return(false);
            }

            value = new ValueAttributeCollection(Container, key);
            return(true);
        }
Пример #13
0
        /// <inheritdoc/>
        public AttributeValue GetAttributeAtIndex(FunctionAttributeIndex index, string name)
        {
            if (string.IsNullOrWhiteSpace(name))
            {
                throw new ArgumentException(Resources.Name_cannot_be_null_or_empty, nameof(name));
            }

            var handle = LLVMGetCallSiteStringAttribute(ValueHandle, ( LLVMAttributeIndex )index, name, ( uint )name.Length);

            return(AttributeValue.FromHandle(Context, handle));
        }
Пример #14
0
        public AttributeValue GetAttributeAtIndex(FunctionAttributeIndex index, string name)
        {
            if (string.IsNullOrWhiteSpace(name))
            {
                throw new ArgumentException("name cannot be null or empty", nameof(name));
            }

            var handle = NativeMethods.GetCallSiteStringAttribute(ValueHandle, ( LLVMAttributeIndex )index, name, ( uint )name.Length);

            return(AttributeValue.FromHandle(Context, handle));
        }
Пример #15
0
        public ICollection <AttributeValue> this[FunctionAttributeIndex key]
        {
            get
            {
                if (!this.ContainsKey(key))
                {
                    throw new KeyNotFoundException();
                }

                return(new ValueAttributeCollection(this.container, key));
            }
        }
Пример #16
0
#pragma warning disable CS8767 // IReadOnlyDictionary<TKey,TValue> interface does not have nullability attributes in netstandard2.1, this suppression could be removed after move to .NET 5
        public bool TryGetValue(FunctionAttributeIndex key, [MaybeNullWhen(false)] out ICollection <AttributeValue> value)
#pragma warning restore CS8767
        {
            value = default;
            if (this.ContainsKey(key))
            {
                return(false);
            }

            value = new ValueAttributeCollection(this.container, key);
            return(true);
        }
        /// <summary>Adds a single <see cref="AttributeValue"/> to an <see cref="IAttributeContainer"/>.</summary>
        /// <typeparam name="T">Container type.</typeparam>
        /// <param name="self">Container to add the attribute to.</param>
        /// <param name="index"><see cref="FunctionAttributeIndex"/> to add the attribute to.</param>
        /// <param name="attrib">Attribute to add to the container.</param>
        /// <returns><paramref name="self"/> for fluent use.</returns>
        public static T AddAttribute <T>(this T self, FunctionAttributeIndex index, AttributeValue attrib)
            where T : class, IAttributeContainer
        {
            if (self is IAttributeAccessor container)
            {
                container.AddAttributeAtIndex(index, attrib);
            }
            else
            {
                self.Attributes[index].Add(attrib);
            }

            return(self);
        }
Пример #18
0
        /// <inheritdoc/>
        public IEnumerable <AttributeValue> GetAttributesAtIndex(FunctionAttributeIndex index)
        {
            uint count = GetAttributeCountAtIndex(index);

            if (count == 0)
            {
                return(Enumerable.Empty <AttributeValue>( ));
            }

            var buffer = new LLVMAttributeRef[count];

            LLVMGetCallSiteAttributes(ValueHandle, ( LLVMAttributeIndex )index, buffer);
            return(from attribRef in buffer
                   select AttributeValue.FromHandle(Context, attribRef));
        }
Пример #19
0
        internal static bool CheckAttributeUsage(this AttributeKind kind, FunctionAttributeIndex index, Value value)
        {
            FunctionIndexKinds allowedindices = kind.GetAllowedIndexes();

            switch (index)
            {
            case FunctionAttributeIndex.Function:
                if (!allowedindices.HasFlag(FunctionIndexKinds.Function))
                {
                    return(false);
                }

                break;

            case FunctionAttributeIndex.ReturnType:
                if (!allowedindices.HasFlag(FunctionIndexKinds.Return))
                {
                    return(false);
                }

                break;

            // case FunctionAttributeIndex.Parameter0:
            default:
            {
                if (value == default)
                {
                    throw new ArgumentNullException(nameof(value));
                }

                if (!allowedindices.HasFlag(FunctionIndexKinds.Parameter))
                {
                    return(false);
                }

                IrFunction?function = value switch
                {
                    IrFunction f => f,
                    CallInstruction call => call.TargetFunction,
                    Argument arg => arg.ContainingFunction,
                          _ => default,
                };
                int paramIndex = index - FunctionAttributeIndex.Parameter0;
                if (paramIndex >= (function?.Parameters.Count ?? 0))
                {
                    return(false);
                }
            }
Пример #20
0
        /// <summary>Tests if the attribute is valid for a <see cref="Value"/> on a given <see cref="FunctionAttributeIndex"/></summary>
        /// <param name="index">Attribute index to test if the attribute is valid on</param>
        /// <param name="value"><see cref="Value"/> </param>
        /// <returns><see lang="true"/> if the attribute is valid on the specified <paramref name="index"/> of the given <paramref name="value"/></returns>
        public bool IsValidOn(FunctionAttributeIndex index, Value value)
        {
            if (value == null)
            {
                throw new ArgumentNullException(nameof(value));
            }

            // for now all string attributes are valid everywhere as they are target dependent
            // (e.g. no way to verify the validity of an arbitrary without knowing the target)
            if (IsString)
            {
                return(value.IsCallSite || value.IsFunction); // TODO: Attributes on globals??
            }

            return(Kind.CheckAttributeUsage(index, value));
        }
Пример #21
0
        public bool TryGetValue(FunctionAttributeIndex key, /*[MaybeNullWhen( false )]*/ out ICollection <AttributeValue> value)
        {
            // sadly the runtime provided interface doesn't correctly apply the MaybeNullWhen attribute,
            // and the compiler generates warning:
            // CS8767: Nullability of reference types in type of parameter 'value' of 'bool ValueAttributeDictionary.TryGetValue(FunctionAttributeIndex key, out ICollection<AttributeValue> value)' doesn't match implicitly implemented member 'bool IReadOnlyDictionary<FunctionAttributeIndex, ICollection<AttributeValue>>.TryGetValue(FunctionAttributeIndex key, out ICollection<AttributeValue> value)' because of nullability attributes.
            // Yeah, clear as mud, right?
            // So, use the ! to silence the compiler and don't use the attribute, sigh... what a mess...
            value = null !;
            if (ContainsKey(key))
            {
                return(false);
            }

            value = new ValueAttributeCollection(Container, key);
            return(true);
        }
Пример #22
0
        /// <summary>Adds a single <see cref="AttributeKind"/> to an <see cref="IAttributeContainer"/></summary>
        /// <typeparam name="T">Container type</typeparam>
        /// <param name="self">Container to add the attribute to</param>
        /// <param name="index"><see cref="FunctionAttributeIndex"/> to add the attribute to</param>
        /// <param name="kind">Attribute to add to the container</param>
        /// <returns><paramref name="self"/> for fluent use</returns>
        public static T AddAttribute <T>(this T self, FunctionAttributeIndex index, AttributeKind kind)
            where T : class, IAttributeContainer
        {
            self.ValidateNotNull(nameof(self));

            AttributeValue attrib = self.Context.CreateAttribute(kind);

            if (self is IAttributeAccessor container)
            {
                container.AddAttributeAtIndex(index, attrib);
            }
            else
            {
                self.Attributes[index].Add(self.Context.CreateAttribute(kind));
            }

            return(self);
        }
        /// <summary>Removes a named attribute from an <see cref="IAttributeContainer"/>.</summary>
        /// <typeparam name="T">Container type.</typeparam>
        /// <param name="self">Container to remove the attribute from.</param>
        /// <param name="index"><see cref="FunctionAttributeIndex"/> to remove the attribute from. </param>
        /// <param name="name">Attribute name to remove from the container.</param>
        /// <returns><paramref name="self"/> for fluent use.</returns>
        public static T RemoveAttribute <T>(this T self, FunctionAttributeIndex index, string name)
            where T : class, IAttributeContainer
        {
            if (self is IAttributeAccessor container)
            {
                container.RemoveAttributeAtIndex(index, name);
            }
            else
            {
                ICollection <AttributeValue> attributes = self.Attributes[index];
                AttributeValue attrib = attributes.FirstOrDefault(a => a.Name == name);
                if (attrib != default)
                {
                    attributes.Remove(attrib);
                }
            }

            return(self);
        }
Пример #24
0
        public static T AddAttribute <T>(this T self, FunctionAttributeIndex index, AttributeValue attrib)
            where T : class, IAttributeContainer
        {
            if (self == null)
            {
                throw new ArgumentNullException(nameof(self));
            }

            if (self is IAttributeAccessor container)
            {
                container.AddAttributeAtIndex(index, attrib);
            }
            else
            {
                self.Attributes[index].Add(attrib);
            }

            return(self);
        }
Пример #25
0
        internal static void VerifyAttributeUsage(this AttributeKind kind, FunctionAttributeIndex index, Value value)
        {
            Debug.Assert(kind >= AttributeKind.None && kind < AttributeKind.EndAttrKinds);
            VerifyAttributeUsage(kind, index);

            if (index >= FunctionAttributeIndex.Parameter0)
            {
                Function function;
                switch (value)
                {
                case Function f:
                    function = f;
                    break;

                case Instructions.Invoke inv:
                    function = inv.TargetFunction;
                    break;

                case Instructions.CallInstruction call:
                    function = call.TargetFunction;
                    break;

                case Argument arg:
                    function = arg.ContainingFunction;
                    if (index != FunctionAttributeIndex.Parameter0 + ( int )arg.Index)
                    {
                        throw new ArgumentException("Index for paramters must be the actual position of the argument");
                    }

                    break;

                default:
                    function = null;
                    break;
                }

                int paramIndex = index - FunctionAttributeIndex.Parameter0;
                if (paramIndex > (function.Parameters.Count - 1))
                {
                    throw new ArgumentException("Specified parameter index exceeds the number of parameters in the function", nameof(index));
                }
            }
        }
Пример #26
0
        internal static void VerifyAttributeUsage(this AttributeKind kind, FunctionAttributeIndex index, Value value)
        {
            VerifyAttributeUsage(kind, index);

            if (index >= FunctionAttributeIndex.Parameter0)
            {
                IrFunction function;
                switch (value)
                {
                case IrFunction f:
                    function = f;
                    break;

                case Invoke inv:
                    function = inv.TargetFunction;
                    break;

                case CallInstruction call:
                    function = call.TargetFunction;
                    break;

                case Argument arg:
                    function = arg.ContainingFunction;
                    if (index != FunctionAttributeIndex.Parameter0 + ( int )arg.Index)
                    {
                        throw new ArgumentException(Resources.Index_for_parameters_must_be_the_actual_position_of_the_argument);
                    }

                    break;

                default:
                    function = null;
                    break;
                }

                int paramIndex = index - FunctionAttributeIndex.Parameter0;
                if (paramIndex > ((function?.Parameters.Count ?? 0) - 1))
                {
                    throw new ArgumentException(Resources.Specified_parameter_index_exceeds_the_number_of_parameters_in_the_function, nameof(index));
                }
            }
        }
        /// <summary>Adds <see cref="AttributeValue"/>s to an <see cref="IAttributeContainer"/>.</summary>
        /// <typeparam name="T">Container type.</typeparam>
        /// <param name="self">Container to add the attribute to.</param>
        /// <param name="index"><see cref="FunctionAttributeIndex"/> to add the attributes to.</param>
        /// <param name="attributes">Attribute to add to the container.</param>
        /// <returns><paramref name="self"/> for fluent use.</returns>
        public static T AddAttributes <T>(this T self, FunctionAttributeIndex index, IEnumerable <AttributeValue> attributes)
            where T : class, IAttributeContainer
        {
            if (attributes != default)
            {
                foreach (var attrib in attributes)
                {
                    if (self is IAttributeAccessor container)
                    {
                        container.AddAttributeAtIndex(index, attrib);
                    }
                    else
                    {
                        self.Attributes[index].Add(attrib);
                    }
                }
            }

            return(self);
        }
        /// <summary>Adds attributes to an <see cref="IAttributeContainer"/>.</summary>
        /// <typeparam name="T">Container type.</typeparam>
        /// <param name="self">Container to add the attributes to.</param>
        /// <param name="index"><see cref="FunctionAttributeIndex"/> to add the attributes to.</param>
        /// <param name="values">Attributes to add to the container.</param>
        /// <returns><paramref name="self"/> for fluent use.</returns>
        public static T AddAttributes <T>(this T self, FunctionAttributeIndex index, params AttributeKind[] values)
            where T : class, IAttributeContainer
        {
            if (values != default)
            {
                foreach (var kind in values)
                {
                    AttributeValue attrib = self.Context.CreateAttribute(kind);
                    if (self is IAttributeAccessor container)
                    {
                        container.AddAttributeAtIndex(index, attrib);
                    }
                    else
                    {
                        self.Attributes[index].Add(attrib);
                    }
                }
            }

            return(self);
        }
Пример #29
0
        /// <summary>Verifies the attribute is valid for a <see cref="Value"/> on a given <see cref="FunctionAttributeIndex"/></summary>
        /// <param name="index">Index to verify</param>
        /// <param name="value">Value to check this attribute on</param>
        /// <exception cref="ArgumentException">The attribute is not valid on <paramref name="value"/> for the <paramref name="index"/></exception>
        public void VerifyValidOn(FunctionAttributeIndex index, Value value)
        {
            if (value == null)
            {
                throw new ArgumentNullException(nameof(value));
            }

            // TODO: Attributes on globals??
            if (!(value.IsCallSite || value.IsFunction))
            {
                throw new ArgumentException("Attributes only allowed on functions and call sites");
            }

            // for now all string attributes are valid everywhere as they are target dependent
            // (e.g. no way to verify the validity of an arbitrary attribute without knowing the target)
            if (IsString)
            {
                return;
            }

            Kind.VerifyAttributeUsage(index, value);
        }
 // To prevent native asserts or crashes - validates parameters before passing down to native code
 internal static void VerifyAttributeUsage(this AttributeKind kind, FunctionAttributeIndex index, ulong value)
 {
     kind.VerifyAttributeUsage(index);
     kind.RangeCheckValue(value);
 }