예제 #1
0
        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))
                                   );
        }