diff options
Diffstat (limited to 'src/lj_cparse.c')
-rw-r--r-- | src/lj_cparse.c | 48 |
1 files changed, 32 insertions, 16 deletions
diff --git a/src/lj_cparse.c b/src/lj_cparse.c index 333e7a07..925894a3 100644 --- a/src/lj_cparse.c +++ b/src/lj_cparse.c | |||
@@ -342,6 +342,7 @@ typedef struct CPDecl { | |||
342 | uint32_t mode; /* Declarator mode. */ | 342 | uint32_t mode; /* Declarator mode. */ |
343 | CPState *cp; /* C parser state. */ | 343 | CPState *cp; /* C parser state. */ |
344 | GCstr *name; /* Name of declared identifier (if direct). */ | 344 | GCstr *name; /* Name of declared identifier (if direct). */ |
345 | GCstr *redir; /* Redirected symbol name. */ | ||
345 | CTypeID nameid; /* Existing typedef for declared identifier. */ | 346 | CTypeID nameid; /* Existing typedef for declared identifier. */ |
346 | CTInfo attr; /* Attributes. */ | 347 | CTInfo attr; /* Attributes. */ |
347 | CTInfo fattr; /* Function attributes. */ | 348 | CTInfo fattr; /* Function attributes. */ |
@@ -923,6 +924,7 @@ static void cp_decl_reset(CPDecl *decl) | |||
923 | decl->attr = decl->specattr; | 924 | decl->attr = decl->specattr; |
924 | decl->fattr = decl->specfattr; | 925 | decl->fattr = decl->specfattr; |
925 | decl->name = NULL; | 926 | decl->name = NULL; |
927 | decl->redir = NULL; | ||
926 | } | 928 | } |
927 | 929 | ||
928 | /* Parse constant initializer. */ | 930 | /* Parse constant initializer. */ |
@@ -982,7 +984,15 @@ static void cp_decl_asm(CPState *cp, CPDecl *decl) | |||
982 | UNUSED(decl); | 984 | UNUSED(decl); |
983 | cp_next(cp); | 985 | cp_next(cp); |
984 | cp_check(cp, '('); | 986 | cp_check(cp, '('); |
985 | while (cp->tok == CTOK_STRING) cp_next(cp); /* NYI: currently ignored. */ | 987 | if (cp->tok == CTOK_STRING) { |
988 | GCstr *str = cp->str; | ||
989 | while (cp_next(cp) == CTOK_STRING) { | ||
990 | lj_str_pushf(cp->L, "%s%s", strdata(str), strdata(cp->str)); | ||
991 | cp->L->top--; | ||
992 | str = strV(cp->L->top); | ||
993 | } | ||
994 | decl->redir = str; | ||
995 | } | ||
986 | cp_check(cp, ')'); | 996 | cp_check(cp, ')'); |
987 | } | 997 | } |
988 | 998 | ||
@@ -1428,6 +1438,7 @@ static CPscl cp_decl_spec(CPState *cp, CPDecl *decl, CPscl scl) | |||
1428 | decl->cp = cp; | 1438 | decl->cp = cp; |
1429 | decl->mode = cp->mode; | 1439 | decl->mode = cp->mode; |
1430 | decl->name = NULL; | 1440 | decl->name = NULL; |
1441 | decl->redir = NULL; | ||
1431 | decl->attr = 0; | 1442 | decl->attr = 0; |
1432 | decl->fattr = 0; | 1443 | decl->fattr = 0; |
1433 | decl->pos = decl->top = 0; | 1444 | decl->pos = decl->top = 0; |
@@ -1729,31 +1740,36 @@ static void cp_decl_multi(CPState *cp) | |||
1729 | cp_declarator(cp, &decl); | 1740 | cp_declarator(cp, &decl); |
1730 | typeid = cp_decl_intern(cp, &decl); | 1741 | typeid = cp_decl_intern(cp, &decl); |
1731 | if (decl.name && !decl.nameid) { /* NYI: redeclarations are ignored. */ | 1742 | if (decl.name && !decl.nameid) { /* NYI: redeclarations are ignored. */ |
1743 | CType *ct; | ||
1744 | CTypeID id; | ||
1732 | if ((scl & CDF_TYPEDEF)) { /* Create new typedef. */ | 1745 | if ((scl & CDF_TYPEDEF)) { /* Create new typedef. */ |
1733 | CType *ct; | 1746 | id = lj_ctype_new(cp->cts, &ct); |
1734 | CTypeID tdefid = lj_ctype_new(cp->cts, &ct); | ||
1735 | ct->info = CTINFO(CT_TYPEDEF, typeid); | 1747 | ct->info = CTINFO(CT_TYPEDEF, typeid); |
1736 | ctype_setname(ct, decl.name); | 1748 | goto noredir; |
1737 | lj_ctype_addname(cp->cts, ct, tdefid); | ||
1738 | } else if (ctype_isfunc(ctype_get(cp->cts, typeid)->info)) { | 1749 | } else if (ctype_isfunc(ctype_get(cp->cts, typeid)->info)) { |
1739 | /* Treat both static and extern function declarations as extern. */ | 1750 | /* Treat both static and extern function declarations as extern. */ |
1740 | CType *ct = ctype_get(cp->cts, typeid); | 1751 | ct = ctype_get(cp->cts, typeid); |
1741 | /* We always get new anonymous functions (typedefs are copied). */ | 1752 | /* We always get new anonymous functions (typedefs are copied). */ |
1742 | lua_assert(gcref(ct->name) == NULL); | 1753 | lua_assert(gcref(ct->name) == NULL); |
1743 | ctype_setname(ct, decl.name); /* Just name it. */ | 1754 | id = typeid; /* Just name it. */ |
1744 | lj_ctype_addname(cp->cts, ct, typeid); | ||
1745 | } else if ((scl & CDF_STATIC)) { /* Accept static constants. */ | 1755 | } else if ((scl & CDF_STATIC)) { /* Accept static constants. */ |
1746 | CType *ct; | 1756 | id = cp_decl_constinit(cp, &ct, typeid); |
1747 | CTypeID constid = cp_decl_constinit(cp, &ct, typeid); | 1757 | goto noredir; |
1748 | ctype_setname(ct, decl.name); | ||
1749 | lj_ctype_addname(cp->cts, ct, constid); | ||
1750 | } else { /* External references have extern or no storage class. */ | 1758 | } else { /* External references have extern or no storage class. */ |
1751 | CType *ct; | 1759 | id = lj_ctype_new(cp->cts, &ct); |
1752 | CTypeID extid = lj_ctype_new(cp->cts, &ct); | ||
1753 | ct->info = CTINFO(CT_EXTERN, typeid); | 1760 | ct->info = CTINFO(CT_EXTERN, typeid); |
1754 | ctype_setname(ct, decl.name); | ||
1755 | lj_ctype_addname(cp->cts, ct, extid); | ||
1756 | } | 1761 | } |
1762 | if (decl.redir) { /* Add attribute for redirected symbol name. */ | ||
1763 | CType *cta; | ||
1764 | CTypeID aid = lj_ctype_new(cp->cts, &cta); | ||
1765 | cta->info = CTINFO(CT_ATTRIB, CTATTRIB(CTA_REDIR)); | ||
1766 | cta->sib = ct->sib; | ||
1767 | ct->sib = aid; | ||
1768 | ctype_setname(cta, decl.redir); | ||
1769 | } | ||
1770 | noredir: | ||
1771 | ctype_setname(ct, decl.name); | ||
1772 | lj_ctype_addname(cp->cts, ct, id); | ||
1757 | } | 1773 | } |
1758 | if (!cp_opt(cp, ',')) break; | 1774 | if (!cp_opt(cp, ',')) break; |
1759 | cp_decl_reset(&decl); | 1775 | cp_decl_reset(&decl); |