Add the option c11 to -std and add the C11 keywords.
authorChristoph Mallon <christoph.mallon@gmx.de>
Mon, 9 Jul 2012 09:55:23 +0000 (11:55 +0200)
committerChristoph Mallon <christoph.mallon@gmx.de>
Mon, 9 Jul 2012 15:20:48 +0000 (17:20 +0200)
- Use _Thread_local instead of __thread internally.
- Use _Alignof instead of __alignof__ internally.

ast.c
cparser.1
entity_t.h
lang_features.h
main.c
parser.c
tokens.inc

diff --git a/ast.c b/ast.c
index cb40c3f..4b2fd15 100644 (file)
--- a/ast.c
+++ b/ast.c
@@ -448,8 +448,8 @@ static void print_array_expression(const array_access_expression_t *expression)
 static void print_typeprop_expression(const typeprop_expression_t *expression)
 {
        switch (expression->base.kind) {
-       case EXPR_SIZEOF:  print_string("sizeof");      break;
-       case EXPR_ALIGNOF: print_string("__alignof__"); break;
+       case EXPR_SIZEOF:  print_string("sizeof");                                   break;
+       case EXPR_ALIGNOF: print_string(c_mode & _C11 ? "_Alignof" : "__alignof__"); break;
        default:           panic("invalid typeprop kind");
        }
        if (expression->tp_expression != NULL) {
@@ -1363,7 +1363,7 @@ void print_declaration(const entity_t *entity)
 
                case ENTITY_VARIABLE:
                        if (entity->variable.thread_local)
-                               print_string("__thread ");
+                               print_string(c_mode & _C11 ? "_Thread_local " : "__thread ");
                        print_type_ext(declaration->type, declaration->base.symbol, NULL);
                        if (entity->variable.initializer != NULL) {
                                print_string(" = ");
index fa997af..0eb7a6e 100644 (file)
--- a/cparser.1
+++ b/cparser.1
@@ -1,5 +1,5 @@
 .\" Please adjust this date whenever revising the manpage.
-.Dd July 3, 2012
+.Dd July 9, 2012
 .Dt CPARSER 1
 .Sh NAME
 .Nm cparser
@@ -74,6 +74,11 @@ ISO C90 with GCC extensions
 ISO C99
 .It Cm gnu99
 ISO C99 with GCC extensions
+.It Cm c11
+.It Cm iso9899:2011
+ISO C11
+.It Cm gnu11
+ISO C11 with GCC extensions
 .It Cm c++98
 ISO C++ 1998.
 Not supported yet.
index b836d0b..2c429c1 100644 (file)
@@ -221,7 +221,7 @@ struct compound_member_t {
 
 struct variable_t {
        declaration_t     base;
-       bool              thread_local   : 1;  /**< GCC __thread */
+       bool              thread_local   : 1;
        bool              restricta      : 1;
        bool              deprecated     : 1;
        bool              noalias        : 1;
index 65ed32e..7bff32e 100644 (file)
 typedef enum lang_features_t {
        _C89  = 1U << 0,
        _C99  = 1U << 1,
-       _CXX  = 1U << 2,
-       _GNUC = 1U << 3,
-       _MS   = 1U << 4,
+       _C11  = 1U << 2,
+       _CXX  = 1U << 3,
+       _GNUC = 1U << 4,
+       _MS   = 1U << 5,
        _ALL  = 0xFF
 } lang_features_t;
 
diff --git a/main.c b/main.c
index 3f3caff..289d825 100644 (file)
--- a/main.c
+++ b/main.c
@@ -131,8 +131,10 @@ typedef enum lang_standard_t {
        STANDARD_C89,     /* ISO C90 (sic) */
        STANDARD_C89AMD1, /* ISO C90 as modified in amendment 1 */
        STANDARD_C99,     /* ISO C99 */
+       STANDARD_C11,     /* ISO C11 */
        STANDARD_GNU89,   /* ISO C90 plus GNU extensions (including some C99) */
        STANDARD_GNU99,   /* ISO C99 plus GNU extensions */
+       STANDARD_GNU11,   /* ISO C11 plus GNU extensions */
        STANDARD_CXX98,   /* ISO C++ 1998 plus amendments */
        STANDARD_GNUXX98  /* ISO C++ 1998 plus amendments and GNU extensions */
 } lang_standard_t;
@@ -298,8 +300,10 @@ static char const* str_lang_standard(lang_standard_t const standard)
        case STANDARD_C89:     return "c89";
        case STANDARD_C89AMD1: return "iso9899:199409";
        case STANDARD_C99:     return "c99";
+       case STANDARD_C11:     return "c11";
        case STANDARD_GNU89:   return "gnu89";
        case STANDARD_GNU99:   return "gnu99";
+       case STANDARD_GNU11:   return "gnu11";
        case STANDARD_CXX98:   return "c++98";
        case STANDARD_GNUXX98: return "gnu++98";
        case STANDARD_ANSI:    break;
@@ -676,11 +680,13 @@ static void print_help_parser(void)
        put_choice("c99",                    "ISO C99 standard");
        put_choice("c89",                    "ISO C89 standard");
        put_choice("c90",                    "Same as -std=c89");
+       put_choice("c11",                    "ISO C11 standard");
        put_choice("c9x",                    "Deprecated");
        put_choice("c++",                    "ISO C++ 98");
        put_choice("c++98",                  "ISO C++ 98");
        put_choice("gnu99",                  "ISO C99 + GNU extensions (default)");
        put_choice("gnu89",                  "ISO C89 + GNU extensions");
+       put_choice("gnu11",                  "ISO C11 + GNU extensions");
        put_choice("gnu9x",                  "Deprecated");
        put_choice("iso9899:1990",           "ISO C89");
        put_choice("iso9899:199409",         "ISO C90");
@@ -1064,11 +1070,13 @@ static void setup_cmode(const compilation_unit_t *unit)
        lang_standard_t         standard = unit->standard;
        if (type == COMPILATION_UNIT_PREPROCESSED_C || type == COMPILATION_UNIT_C) {
                switch (standard) {
-               case STANDARD_C89:     c_mode = _C89;                break;
+               case STANDARD_C89:     c_mode = _C89;                       break;
                                                           /* TODO determine difference between these two */
-               case STANDARD_C89AMD1: c_mode = _C89;                break;
-               case STANDARD_C99:     c_mode = _C89 | _C99;         break;
-               case STANDARD_GNU89:   c_mode = _C89 |        _GNUC; break;
+               case STANDARD_C89AMD1: c_mode = _C89;                       break;
+               case STANDARD_C99:     c_mode = _C89 | _C99;                break;
+               case STANDARD_C11:     c_mode = _C89 | _C99 | _C11;         break;
+               case STANDARD_GNU89:   c_mode = _C89 |               _GNUC; break;
+               case STANDARD_GNU11:   c_mode = _C89 | _C99 | _C11 | _GNUC; break;
 
                case STANDARD_ANSI:
                case STANDARD_CXX98:
@@ -1087,8 +1095,10 @@ static void setup_cmode(const compilation_unit_t *unit)
                case STANDARD_C89:
                case STANDARD_C89AMD1:
                case STANDARD_C99:
+               case STANDARD_C11:
                case STANDARD_GNU89:
                case STANDARD_GNU99:
+               case STANDARD_GNU11:
                case STANDARD_DEFAULT:
                        fprintf(stderr, "warning: command line option \"-std=%s\" is not valid for C++\n", str_lang_standard(standard));
                        /* FALLTHROUGH */
@@ -1846,11 +1856,15 @@ int main(int argc, char **argv)
                                standard =
                                        streq(o, "c++")            ? STANDARD_CXX98   :
                                        streq(o, "c++98")          ? STANDARD_CXX98   :
+                                       streq(o, "c11")            ? STANDARD_C11     :
+                                       streq(o, "c1x")            ? STANDARD_C11     : // deprecated
                                        streq(o, "c89")            ? STANDARD_C89     :
                                        streq(o, "c90")            ? STANDARD_C89     :
                                        streq(o, "c99")            ? STANDARD_C99     :
                                        streq(o, "c9x")            ? STANDARD_C99     : // deprecated
                                        streq(o, "gnu++98")        ? STANDARD_GNUXX98 :
+                                       streq(o, "gnu11")          ? STANDARD_GNU11   :
+                                       streq(o, "gnu1x")          ? STANDARD_GNU11   : // deprecated
                                        streq(o, "gnu89")          ? STANDARD_GNU89   :
                                        streq(o, "gnu99")          ? STANDARD_GNU99   :
                                        streq(o, "gnu9x")          ? STANDARD_GNU99   : // deprecated
@@ -1858,6 +1872,7 @@ int main(int argc, char **argv)
                                        streq(o, "iso9899:199409") ? STANDARD_C89AMD1 :
                                        streq(o, "iso9899:1999")   ? STANDARD_C99     :
                                        streq(o, "iso9899:199x")   ? STANDARD_C99     : // deprecated
+                                       streq(o, "iso9899:2011")   ? STANDARD_C11     :
                                        (fprintf(stderr, "warning: ignoring gcc option '%s'\n", arg), standard);
                        } else if (streq(option, "version")) {
                                print_cparser_version();
index 6439a47..933d059 100644 (file)
--- a/parser.c
+++ b/parser.c
@@ -60,7 +60,7 @@ struct declaration_specifiers_t {
        storage_class_t    storage_class;
        unsigned char      alignment;         /**< Alignment, 0 if not set. */
        bool               is_inline    : 1;
-       bool               thread_local : 1;  /**< GCC __thread */
+       bool               thread_local : 1;
        attribute_t       *attributes;        /**< list of attributes */
        type_t            *type;
 };
@@ -183,7 +183,7 @@ static void semantic_comparison(binary_expression_t *expression);
        case T_static:          \
        case T_auto:            \
        case T_register:        \
-       case T___thread:
+       case T__Thread_local:
 
 #define TYPE_QUALIFIERS     \
        case T_const:           \
@@ -249,10 +249,10 @@ static void semantic_comparison(binary_expression_t *expression);
        case T_MINUSMINUS:                \
        case T_PLUSPLUS:                  \
        case T_STRING_LITERAL:            \
+       case T__Alignof:                  \
        case T___FUNCDNAME__:             \
        case T___FUNCSIG__:               \
        case T___PRETTY_FUNCTION__:       \
-       case T___alignof__:               \
        case T___builtin_classify_type:   \
        case T___builtin_constant_p:      \
        case T___builtin_isgreater:       \
@@ -2650,9 +2650,9 @@ static void parse_declaration_specifiers(declaration_specifiers_t *specifiers)
                                = parse_microsoft_extended_decl_modifier(specifiers->attributes);
                        break;
 
-               case T___thread:
+               case T__Thread_local:
                        if (specifiers->thread_local) {
-                               errorf(HERE, "duplicate '__thread'");
+                               errorf(HERE, "duplicate %K", &token);
                        } else {
                                specifiers->thread_local = true;
 check_thread_storage_class:
@@ -2667,7 +2667,7 @@ check_thread_storage_class:
                                        case STORAGE_CLASS_REGISTER: wrong = "register"; goto wrong_thread_storage_class;
                                        case STORAGE_CLASS_TYPEDEF:  wrong = "typedef";  goto wrong_thread_storage_class;
 wrong_thread_storage_class:
-                                               errorf(HERE, "'__thread' used with '%s'", wrong);
+                                               errorf(HERE, "%K used with '%s'", &token, wrong);
                                                break;
                                }
                        }
@@ -6834,7 +6834,7 @@ static expression_t *parse_typeprop(expression_kind_t const kind)
        expression_t  *tp_expression = allocate_expression_zero(kind);
        tp_expression->base.type     = type_size_t;
 
-       eat(kind == EXPR_SIZEOF ? T_sizeof : T___alignof__);
+       eat(kind == EXPR_SIZEOF ? T_sizeof : T__Alignof);
 
        type_t       *orig_type;
        expression_t *expression;
@@ -8644,7 +8644,7 @@ static void init_expression_parsers(void)
        register_expression_parser(parse_EXPR_UNARY_PREFIX_INCREMENT, T_PLUSPLUS);
        register_expression_parser(parse_EXPR_UNARY_PREFIX_DECREMENT, T_MINUSMINUS);
        register_expression_parser(parse_sizeof,                      T_sizeof);
-       register_expression_parser(parse_alignof,                     T___alignof__);
+       register_expression_parser(parse_alignof,                     T__Alignof);
        register_expression_parser(parse_extension,                   T___extension__);
        register_expression_parser(parse_builtin_classify_type,       T___builtin_classify_type);
        register_expression_parser(parse_delete,                      T_delete);
@@ -9811,11 +9811,12 @@ static statement_t *parse_compound_statement(bool inside_expression_statement)
        add_anchor_token(T_NUMBER);
        add_anchor_token(T_PLUSPLUS);
        add_anchor_token(T_STRING_LITERAL);
+       add_anchor_token(T__Alignof);
        add_anchor_token(T__Bool);
        add_anchor_token(T__Complex);
        add_anchor_token(T__Imaginary);
+       add_anchor_token(T__Thread_local);
        add_anchor_token(T___PRETTY_FUNCTION__);
-       add_anchor_token(T___alignof__);
        add_anchor_token(T___attribute__);
        add_anchor_token(T___builtin_va_start);
        add_anchor_token(T___extension__);
@@ -9823,7 +9824,6 @@ static statement_t *parse_compound_statement(bool inside_expression_statement)
        add_anchor_token(T___imag__);
        add_anchor_token(T___label__);
        add_anchor_token(T___real__);
-       add_anchor_token(T___thread);
        add_anchor_token(T_asm);
        add_anchor_token(T_auto);
        add_anchor_token(T_bool);
@@ -9971,7 +9971,6 @@ static statement_t *parse_compound_statement(bool inside_expression_statement)
        rem_anchor_token(T_bool);
        rem_anchor_token(T_auto);
        rem_anchor_token(T_asm);
-       rem_anchor_token(T___thread);
        rem_anchor_token(T___real__);
        rem_anchor_token(T___label__);
        rem_anchor_token(T___imag__);
@@ -9979,11 +9978,12 @@ static statement_t *parse_compound_statement(bool inside_expression_statement)
        rem_anchor_token(T___extension__);
        rem_anchor_token(T___builtin_va_start);
        rem_anchor_token(T___attribute__);
-       rem_anchor_token(T___alignof__);
        rem_anchor_token(T___PRETTY_FUNCTION__);
+       rem_anchor_token(T__Thread_local);
        rem_anchor_token(T__Imaginary);
        rem_anchor_token(T__Complex);
        rem_anchor_token(T__Bool);
+       rem_anchor_token(T__Alignof);
        rem_anchor_token(T_STRING_LITERAL);
        rem_anchor_token(T_PLUSPLUS);
        rem_anchor_token(T_NUMBER);
index 5064820..6c6c856 100644 (file)
@@ -78,7 +78,13 @@ S(_CXX, virtual)
 S(_CXX, wchar_t)
 
 S(_C99|_GNUC, _Bool)
-S(_ALL, __thread)
+
+S(_C11, _Alignas)
+S(_C11, _Atomic)
+S(_C11, _Generic)
+S(_C11, _Noreturn)
+S(_C11, _Static_assert)
+
 S(_ALL, __extension__)
 S(_ALL, __builtin_classify_type)
 S(_ALL, __builtin_va_list)
@@ -102,6 +108,8 @@ S(_MS, __FUNCDNAME__)
 #define S(mode, x, val) T(mode, T_##x, #x, val)
 S(_C99,            __func__,)
 S(_ALL,            __FUNCTION__,           = T___func__)
+S(_C11,             _Thread_local,         )
+S(_ALL,            __thread,               = T__Thread_local)
 S(_ALL,              signed,               )
 S(_ALL,            __signed,               = T_signed)
 S(_ALL,            __signed__,             = T_signed)
@@ -113,9 +121,10 @@ S(_ALL,            __real__,               )
 S(_ALL,            __real,                 = T___real__)
 S(_ALL,            __imag__,               )
 S(_ALL,            __imag,                 = T___imag__)
-S(_ALL,            __alignof__,            )
-S(_ALL,            __alignof,              = T___alignof__)
-S(_MS,              _alignof,              = T___alignof__)
+S(_C11,             _Alignof,              )
+S(_ALL,            __alignof__,            = T__Alignof)
+S(_ALL,            __alignof,              = T__Alignof)
+S(_MS,              _alignof,              = T__Alignof)
 S(_ALL,              const,                )
 S(_ALL,            __const,                = T_const)
 S(_ALL,            __const__,              = T_const)