view dmd/hdrgen.c @ 1410:cc2d8a7388c7

Count the sret register as well when keeping track of how many integer registers are available for extern(C) functions on x86-64. Interestingly, llvm-g++ seems to have a very similar bug: http://llvm.org/pr4242 (So this breaks ABI-compatibility with llvm-gcc for this corner case, but gains it with gcc...) To clarify, this is about code like this: {{{ struct S { void*[3] data; } struct T { void*[2] data; } // The T should be passed in memory, and p in the last int register. extern(C) S fail(int, int, int, int, T t, void* p) { S s; s.data[0] = t.data[0]; s.data[1] = t.data[1]; s.data[2] = p; return s; } }}} which should generate code functionally equivalent to this: {{{ extern(C) S* succeed(S* s, int, int, int, int, T t, void* p) { s.data[0] = t.data[0]; s.data[1] = t.data[1]; s.data[2] = p; return s; } }}} (with the same definitions for S and T)
author Frits van Bommel <fvbommel wxs.nl>
date Fri, 22 May 2009 13:17:06 +0200
parents b30fe7e1dbb9
children
line wrap: on
line source


// Compiler implementation of the D programming language
// Copyright (c) 1999-2006 by Digital Mars
// All Rights Reserved
// Initial header generation implementation by Dave Fladebo
// http://www.digitalmars.com
// License for redistribution is by either the Artistic License
// in artistic.txt, or the GNU General Public License in gnu.txt.
// See the included readme.txt for details.

// Routines to emit header files

#ifdef _DH

#define PRETTY_PRINT
#define TEST_EMIT_ALL  0	// For Testing

#define LOG 0

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#if __DMC__
#include <complex.h>
#endif

#include "rmem.h"

#include "id.h"
#include "init.h"

#include "attrib.h"
#include "cond.h"
#include "enum.h"
#include "import.h"
#include "module.h"
#include "mtype.h"
#include "scope.h"
#include "staticassert.h"
#include "template.h"
#include "utf.h"
#include "version.h"

#include "declaration.h"
#include "aggregate.h"
#include "expression.h"
#include "statement.h"
#include "mtype.h"
#include "hdrgen.h"

void argsToCBuffer(OutBuffer *buf, Array *arguments, HdrGenState *hgs);

void Module::genhdrfile()
{
    OutBuffer hdrbufr;

    hdrbufr.printf("// D import file generated from '%s'", srcfile->toChars());
    hdrbufr.writenl();

    HdrGenState hgs;
    memset(&hgs, 0, sizeof(hgs));
    hgs.hdrgen = 1;

    toCBuffer(&hdrbufr, &hgs);

    // Transfer image to file
    hdrfile->setbuffer(hdrbufr.data, hdrbufr.offset);
    hdrbufr.data = NULL;

    char *pt = FileName::path(hdrfile->toChars());
    if (*pt)
	FileName::ensurePathExists(pt);
    mem.free(pt);
    hdrfile->writev();
}


void Module::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
{
    if (md)
    {
        buf->writestring("module ");
	buf->writestring(md->toChars());
        buf->writebyte(';');
        buf->writenl();
    }

    for (int i = 0; i < members->dim; i++)
    {   Dsymbol *s = (Dsymbol *)members->data[i];

        s->toHBuffer(buf, hgs);
    }
}


void Dsymbol::toHBuffer(OutBuffer *buf, HdrGenState *hgs)
{
    toCBuffer(buf, hgs);
}


/*************************************/

#endif // #ifdef _DH