- Use _Thread_local instead of __thread internally.
- Use _Alignof instead of __alignof__ internally.
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) {
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(" = ");
.\" Please adjust this date whenever revising the manpage.
-.Dd July 3, 2012
+.Dd July 9, 2012
.Dt CPARSER 1
.Sh NAME
.Nm cparser
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.
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;
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;
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;
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;
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");
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:
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 */
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
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();
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;
};
case T_static: \
case T_auto: \
case T_register: \
- case T___thread:
+ case T__Thread_local:
#define TYPE_QUALIFIERS \
case T_const: \
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: \
= 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:
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;
}
}
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;
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);
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__);
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);
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__);
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);
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)
#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)
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)