public void AddABIAttributesForByValueStructure(Function function, int paramIndex) { // ByVal pointers indicate by value semantics. The actual semantics are along the lines of // "pass the arg as copy on the arguments stack and set parameter implicitly to that copy's address" // (src: https://github.com/ldc-developers/ldc/issues/937 ) [e.g. caller copies byval args] // // LLVM recognizes this pattern and has a pass to map to an efficient register usage whenever plausible. // Though it seems Clang doesn't apply the attribute in all cases, for x86 it doesn't appear to ever use // it, for Cortex-Mx it seems to use it only for larger structs, otherwise it uses an [ n x i32]. (Max // value of n is not known) and performs casts. Thus, on cortex-m the function parameters are handled // quite differently by clang, which seems odd to put such target dependent differences into the front-end. var argType = function.Parameters[paramIndex].NativeType as IPointerType; if (argType == null || !argType.ElementType.IsStruct) { throw new ArgumentException("Signature for specified parameter must be a pointer to a structure"); } var layout = function.ParentModule.Layout; function.AddAttributes(FunctionAttributeIndex.Parameter0 + paramIndex , function.Context.CreateAttribute(AttributeKind.ByVal) , function.Context.CreateAttribute(AttributeKind.Alignment, layout.AbiAlignmentOf(argType.ElementType)) ); }