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; } }
/// <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); }
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); }
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( ); } } }
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); }
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); }
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; } }
/// <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)); }
/// <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])); }
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])); }
public bool TryGetValue(FunctionAttributeIndex key, out ICollection <AttributeValue> value) { value = null; if (ContainsKey(key)) { return(false); } value = new ValueAttributeCollection(Container, key); return(true); }
/// <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)); }
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)); }
public ICollection <AttributeValue> this[FunctionAttributeIndex key] { get { if (!this.ContainsKey(key)) { throw new KeyNotFoundException(); } return(new ValueAttributeCollection(this.container, key)); } }
#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); }
/// <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)); }
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); } }
/// <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)); }
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); }
/// <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); }
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); }
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)); } } }
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); }
/// <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); }