Changeset 666 for trunk/src


Ignore:
Timestamp:
Sep 9, 2003, 1:17:27 AM (22 years ago)
Author:
bird
Message:

#572: Fixing calling conventions again... not 100 cleaned up yet.

Location:
trunk/src/gcc/gcc/config/i386
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/gcc/gcc/config/i386/emx.c

    • Property cvs2svn:cvs-rev changed from 1.21 to 1.22
    r665 r666  
    3131#include "flags.h"
    3232#include "i386-protos.h"
     33#include "diagnostic.h"
    3334
    3435/* The size of the target's pointer type.  */
     
    7273}
    7374
    74 static void dump (tree node);
    75 static void dump (tree node)
     75const char *birddump_callingconv(tree node);
     76const char *birddump_callingconv(tree node)
     77{
     78    static const char *apsz[] = {"system", "optlink", "stdcall"};
     79    static const char *psznone = "none";
     80    static const char *pszdefault = "default";
     81    tree        attr;
     82    unsigned    i;
     83
     84    if (!node)
     85        return psznone;
     86
     87    attr = (DECL_P (node) ? DECL_ATTRIBUTES (node) : TYPE_ATTRIBUTES (node));
     88    if (!attr)
     89        return pszdefault;
     90
     91    for (i = 0; i < sizeof(apsz) / sizeof(apsz[0]); i++)
     92        if (node && attr && lookup_attribute (apsz[i], attr))
     93            return apsz[i];
     94
     95    return pszdefault;
     96}
     97
     98void birddump (tree node);
     99void birddump (tree node)
    76100{
    77101    tree type, type2, context, name;
     
    83107    context = DECL_P (node) ? DECL_CONTEXT (node) : NULL_TREE;
    84108    name = DECL_P (node) ? DECL_NAME (node) : NULL_TREE;
    85     fprintf(stderr, "dbg: node=%d %s type=%d %s type_type=%d %s context=%d %s name=%s\n",
    86             TREE_CODE(node), code(node),
    87             type ? (int)TREE_CODE(type) : -1, code(type),
    88             type2 ? (int)TREE_CODE(type2) : -1, code(type2),
    89             context ? (int)TREE_CODE(context) : -1, code(context),
     109
     110    fprintf(stderr, "dbg: node=%d %s %p %s  type=%d %s %p %s  type_type=%d %s %p %s  context=%d %s %p  name=%s\n",
     111            TREE_CODE(node), code(node), (void*)node, birddump_callingconv(node),
     112            type ? (int)TREE_CODE(type) : -1, code(type), (void*)type, birddump_callingconv(type),
     113            type2 ? (int)TREE_CODE(type2) : -1, code(type2), (void*)type2, birddump_callingconv(type2),
     114            context ? (int)TREE_CODE(context) : -1, code(context), (void*)context,
    90115            name ? IDENTIFIER_POINTER (name) : "<none>");
    91116}
    92117
    93118#define dfprintf(a) fprintf a
    94 #define DUMP(node) dump(node)
     119#define DUMP(node) birddump(node)
    95120#else
    96121#define dfprintf(a) do {} while (0)
     
    112137    return 0;
    113138
     139  /* Only functions declarations are subject to mangling. */
     140  if (TREE_CODE (decl) != FUNCTION_DECL)
     141    return 0;
     142
     143  dfprintf((stderr, "emx_c_set_decl_assembler_name\n"));
     144  DUMP(decl);
     145
    114146  recurse++;
    115 
    116147  type = TREE_TYPE (decl);
    117148
     
    205236}
    206237
     238#if 0 /* choose between the smaller non working version, and the
     239         large ugly one which is working. */
     240
    207241tree emx_handle_vacpp_attribute (tree *node, tree name, tree args,
    208242  int flags, bool *no_add_attrs)
    209243{
     244  tree *type;
    210245  (void) args;
    211246  (void) flags;
    212247
     248  dfprintf((stderr, "emx_handle_vacpp_attribute\n"));
    213249  DUMP (*node);
    214250
     
    233269    return NULL_TREE;
    234270
     271  /* Now, a new type with our attribute please!
     272     If the FUNCTION_TYPE/METHOD_TYPE already have the attribute associated,
     273     there is no need to duplicate the type.
     274     @todo: I'm unsure wether or not we should do this from node and down... */
     275  for (type = node;
     276       TREE_CODE (*type) != FUNCTION_TYPE && TREE_CODE (*type) != METHOD_TYPE;
     277       type = &TREE_TYPE (*type))
     278      /* do nothing */;
     279
     280  if (lookup_attribute (IDENTIFIER_POINTER (name), TYPE_ATTRIBUTES (*type)))
     281      return NULL_TREE;
     282
     283  *type = build_type_copy (*type);
     284  *type = build_type_attribute_variant (*type, tree_cons (name, args, TYPE_ATTRIBUTES (*type)) );
     285  /**no_add_attrs = true; ?? */
     286
     287  dfprintf((stderr, "emx_handle_vacpp_attribute: new type (%p)\n", (void*)type));
     288  DUMP (*node);
    235289  return NULL_TREE;
    236290}
     291
     292#else
     293
     294/* This is the working version which we belive duplicate some which could be
     295   done by the generic attribute stuff in GCC... */
     296tree emx_handle_vacpp_attribute (tree *node, tree name, tree args,
     297  int flags, bool *no_add_attrs)
     298{
     299  tree type;
     300
     301  dfprintf((stderr, "emx_handle_vacpp_attribute: node=%p\n", node));
     302  DUMP (*node);
     303
     304  switch (TREE_CODE (*node))
     305    {
     306      /* Declarations!
     307         We need to attach the attribute to the type of the declaration.
     308         (Name mangling is done by emx_c_set_decl_assembler_name().)  */
     309      case FUNCTION_DECL:/* Function declaration. */
     310      case TYPE_DECL:    /* Function or function pointer type. */
     311      case FIELD_DECL:   /* Function pointer (or function?) as a struct, union or class member. */
     312      case PARM_DECL:    /* Function pointer as a parameter. */
     313      case VAR_DECL:     /* Function pointer variable. */
     314        /* If this is a type declaration with our attribute, we allow it
     315           only if it is a pointer-to-a-function type or a function type. */
     316        type = TREE_TYPE (*node);
     317        if (TREE_CODE (type) == POINTER_TYPE)
     318          type = TREE_TYPE(type);
     319        if (   TREE_CODE (type) != FUNCTION_TYPE
     320            && TREE_CODE (type) != METHOD_TYPE)
     321          {
     322            warning ("`%s' attribute only applies to functions and function types, not to '%T'.",
     323                     IDENTIFIER_POINTER (name), type);
     324            *no_add_attrs = true;
     325            break;
     326          }
     327
     328        if (ix86_check_append_attr (type, name, no_add_attrs))
     329          break;
     330
     331        /* If required we'll make a variant of the type for this attribute. */
     332        if (!lookup_attribute (IDENTIFIER_POINTER (name),
     333                               TYPE_ATTRIBUTES (type)))
     334          {
     335            tree *ptype = node;
     336            while (*ptype != type)
     337                ptype = &TREE_TYPE (*ptype);
     338            *ptype = build_type_copy (*ptype);
     339            *ptype = build_type_attribute_variant (
     340                *ptype, tree_cons (name, args, TYPE_ATTRIBUTES (*ptype)) );
     341            dfprintf((stderr, "emx_handle_vacpp_attribute: new type\n"));
     342            DUMP(*node);
     343          }
     344        else
     345          dfprintf((stderr, "emx_handle_vacpp_attribute: use old type\n"));
     346        *no_add_attrs = true;
     347        break;
     348
     349
     350      /* Types!
     351         For types involving functions we need to convince decl_attributes()
     352         (and its callers) to supply a declaration so we safely can change
     353         the type. */
     354      case POINTER_TYPE:
     355        /* We allow:
     356           This being the return type of a function which is coming soon.
     357           This being a function pointer which declaration is coming next.
     358           Everything else is considered inappropriate use of the attribute. */
     359        if (   !(flags & ATTR_FLAG_FUNCTION_NEXT)
     360            && (    !(flags & ATTR_FLAG_DECL_NEXT)
     361                ||  !(type = TREE_TYPE (*node))
     362                || (   TREE_CODE (type) != FUNCTION_TYPE
     363                    && TREE_CODE (type) != METHOD_TYPE)))
     364        {
     365            warning ("`%s' attribute only applies to functions and function types",
     366                     IDENTIFIER_POINTER (name));
     367            *no_add_attrs = true;
     368            break;
     369        }
     370        /* fall thru */
     371      case FUNCTION_TYPE:
     372      case METHOD_TYPE:
     373#if 0 /* bird: This fixes optlink/tst4.c and doesn't seem to break anything.
     374               If set to true we are in some cases imposing _Optlink onto following
     375               declarations. This is weird stuff!
     376            !! This problem is actually what we see with the other implementation!! */
     377        *no_add_attrs = true;
     378#endif
     379        return tree_cons (name, args, NULL_TREE);
     380
     381      default:
     382        warning ("`%s' attribute only applies to functions and function types (code=%d)",
     383                 IDENTIFIER_POINTER (name), TREE_CODE (*node));
     384        *no_add_attrs = true;
     385        break;
     386    }
     387
     388  return NULL_TREE;
     389}
     390#endif
    237391
    238392void
     
    265419  }
    266420}
     421
     422/* Adds calling convention to a function dump. (diagnostic) */
     423void emx_print_callingconvention (tree type, struct output_buffer *scratch_buffer)
     424{
     425  const char *conv = NULL;
     426
     427  if (lookup_attribute ("system", TYPE_ATTRIBUTES (type)))
     428    conv = "_System ";
     429  else if (lookup_attribute ("optlink", TYPE_ATTRIBUTES (type)))
     430    conv = "_Optlink ";
     431  else if (lookup_attribute ("stdcall", TYPE_ATTRIBUTES (type)))
     432    conv = "__stdcall ";
     433  else if (lookup_attribute ("cdecl", TYPE_ATTRIBUTES (type)))
     434    conv = "__cdecl ";
     435
     436  if (conv)
     437    output_add_string(scratch_buffer, conv);
     438
     439}
     440
  • trunk/src/gcc/gcc/config/i386/i386.c

    • Property cvs2svn:cvs-rev changed from 1.12 to 1.13
    r665 r666  
    12731273{
    12741274  /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
     1275#ifdef EMX /** @todo: ugly stuff, cleanup later. */
     1276  /* Stdcall attribute says callee is responsible for popping arguments
     1277     if they are not variable.  */
     1278  { "stdcall",   0, 0, false, false, false, ix86_handle_system_attribute },
     1279  /* Cdecl attribute says the callee is a normal C declaration */
     1280  { "cdecl",     0, 0, false, false, false, ix86_handle_system_attribute },
     1281#else
    12751282  /* Stdcall attribute says callee is responsible for popping arguments
    12761283     if they are not variable.  */
     
    12781285  /* Cdecl attribute says the callee is a normal C declaration */
    12791286  { "cdecl",     0, 0, false, true,  true,  ix86_handle_cdecl_attribute },
     1287#endif
    12801288  /* Regparm attribute specifies how many integer arguments are to be
    12811289     passed in registers.  */
     
    12861294  { "shared",    0, 0, true,  false, false, ix86_handle_shared_attribute },
    12871295#endif
     1296#ifdef EMX /** @todo: ugly stuff, cleanup later. */
     1297#ifdef TARGET_SYSTEM_DECL_ATTRIBUTES
     1298  /* System says the function is extern "C" and is not underscored. */
     1299  { "system",    0, 0, false, false, false, ix86_handle_system_attribute },
     1300#endif
     1301#ifdef TARGET_OPTLINK_DECL_ATTRIBUTES
     1302  /* Optlink is like regparm with a few differences */
     1303  { "optlink",   0, 0, false, false, false, ix86_handle_optlink_attribute },
     1304#endif
     1305#else
    12881306#ifdef TARGET_SYSTEM_DECL_ATTRIBUTES
    12891307  /* System says the function is extern "C" and is not underscored. */
     
    12931311  /* Optlink is like regparm with a few differences */
    12941312  { "optlink",   0, 0, false, true,  true,  ix86_handle_optlink_attribute },
     1313#endif
    12951314#endif
    12961315  { NULL,        0, 0, false, false, false, NULL }
     
    15581577  unsigned i, cc1 = 0, cc2 = 0;
    15591578
    1560   /* The following calling conventions have meaning only for functions */
    1561   if (TREE_CODE (type1) != FUNCTION_TYPE)
     1579  /* The following calling conventions have meaning only for functions,
     1580     methods and pointers to such. */
     1581  if (TREE_CODE (type1) == POINTER_TYPE)
     1582      type1 = TREE_TYPE(type1);
     1583  if (TREE_CODE (type2) == POINTER_TYPE)
     1584      type2 = TREE_TYPE(type2);
     1585  if (   TREE_CODE (type1) != FUNCTION_TYPE
     1586      && TREE_CODE (type1) != METHOD_TYPE
     1587      && TREE_CODE (type2) != FUNCTION_TYPE
     1588      && TREE_CODE (type2) != METHOD_TYPE)
    15621589    return 1;
    15631590
    1564 /*@@@todo: this doesn't work yet because of some bug somewhere inside gcc.
    1565 testcase for both C and C++:
    1566   void f (); static void (* _Optlink x) () = f;           <-- compiles ok
    1567 testcase for C++:
    1568   void _Optlink f (); static void (* _Optlink x) () = f;  <-- bad types
    1569 */
    1570 #if __ANNOYING_BUG_IN_GCC_IS_FINALLY_FIXED
    15711591  /* The function may have only one calling convention.
    15721592   * For simplicity we translate the calling conversion attribute
     
    15761596   * (e.g. issue a warning but allow the operation).
    15771597   */
    1578 
    15791598  for (i = 0; ix86_attribute_table [i].name; i++)
    15801599    if (ix86_attribute_codes [i] & IX86_ATTR_TYPE_CALLCONV)
     
    16011620  /* They are nearly compatible */
    16021621  return 2;
    1603 #else
    1604   return 1;
    1605 #endif
    16061622}
    16071623
Note: See TracChangeset for help on using the changeset viewer.