/**
* Adds a token to the token anchor set (a multi-set).
*/
-static void add_anchor_token(int token_type) {
+static void add_anchor_token(int token_type)
+{
assert(0 <= token_type && token_type < T_LAST_TOKEN);
++token_anchor_set[token_type];
}
-static int save_and_reset_anchor_state(int token_type) {
+static int save_and_reset_anchor_state(int token_type)
+{
assert(0 <= token_type && token_type < T_LAST_TOKEN);
int count = token_anchor_set[token_type];
token_anchor_set[token_type] = 0;
return count;
}
-static void restore_anchor_state(int token_type, int count) {
+static void restore_anchor_state(int token_type, int count)
+{
assert(0 <= token_type && token_type < T_LAST_TOKEN);
token_anchor_set[token_type] = count;
}
/**
* Remove a token from the token anchor set (a multi-set).
*/
-static void rem_anchor_token(int token_type) {
+static void rem_anchor_token(int token_type)
+{
assert(0 <= token_type && token_type < T_LAST_TOKEN);
--token_anchor_set[token_type];
}
-static bool at_anchor(void) {
+static bool at_anchor(void)
+{
if (token.type < 0)
return false;
return token_anchor_set[token.type];
/**
* Eat tokens until a matching token is found.
*/
-static void eat_until_matching_token(int type) {
+static void eat_until_matching_token(int type)
+{
unsigned parenthesis_count = 0;
unsigned brace_count = 0;
unsigned bracket_count = 0;
default: end_token = type; break;
}
- while(token.type != end_token ||
+ while (token.type != end_token ||
(parenthesis_count > 0 || brace_count > 0 || bracket_count > 0)) {
switch(token.type) {
/**
* Eat input tokens until an anchor is found.
*/
-static void eat_until_anchor(void) {
+static void eat_until_anchor(void)
+{
if (token.type == T_EOF)
return;
- while(token_anchor_set[token.type] == 0) {
+ while (token_anchor_set[token.type] == 0) {
if (token.type == '(' || token.type == '{' || token.type == '[')
eat_until_matching_token(token.type);
if (token.type == T_EOF)
}
}
-static void eat_block(void) {
+static void eat_block(void)
+{
eat_until_matching_token('{');
if (token.type == '}')
next_token();
/**
* eat all token until a ';' is reached or a stop token is found.
*/
-static void eat_statement(void) {
+static void eat_statement(void)
+{
eat_until_matching_token(';');
if (token.type == ';')
next_token();
}
-#define eat(token_type) do { assert(token.type == token_type); next_token(); } while(0)
+#define eat(token_type) do { assert(token.type == token_type); next_token(); } while (0)
/**
* Report a parse error because an expected token was not found.
goto end_error; \
} \
next_token(); \
- } while(0)
+ } while (0)
static void set_scope(scope_t *new_scope)
{
return result;
}
-static const char *gnu_attribute_names[GNU_AK_LAST] = {
+static const char *const gnu_attribute_names[GNU_AK_LAST] = {
[GNU_AK_CONST] = "const",
[GNU_AK_VOLATILE] = "volatile",
[GNU_AK_CDECL] = "cdecl",
[GNU_AK_ALWAYS_INLINE] = "always_inline",
[GNU_AK_MALLOC] = "malloc",
[GNU_AK_WEAK] = "weak",
- [GNU_AK_CONSTRUCTOR] = "constructor",
+ [GNU_AK_CONSTRUCTOR] = "constructor",
[GNU_AK_DESTRUCTOR] = "destructor",
[GNU_AK_NOTHROW] = "nothrow",
[GNU_AK_TRANSPARENT_UNION] = "transparent_union",
[GNU_AK_NO_INSTRUMENT_FUNCTION] = "no_instrument_function",
[GNU_AK_WARN_UNUSED_RESULT] = "warn_unused_result",
[GNU_AK_LONGCALL] = "longcall",
- [GNU_AK_SHORTCALL] = "shortcall",
+ [GNU_AK_SHORTCALL] = "shortcall",
[GNU_AK_LONG_CALL] = "long_call",
- [GNU_AK_SHORT_CALL] = "short_call",
+ [GNU_AK_SHORT_CALL] = "short_call",
[GNU_AK_FUNCTION_VECTOR] = "function_vector",
- [GNU_AK_INTERRUPT] = "interrupt",
- [GNU_AK_INTERRUPT_HANDLER] = "interrupt_handler",
- [GNU_AK_NMI_HANDLER] = "nmi_handler",
- [GNU_AK_NESTING] = "nesting",
- [GNU_AK_NEAR] = "near",
+ [GNU_AK_INTERRUPT] = "interrupt",
+ [GNU_AK_INTERRUPT_HANDLER] = "interrupt_handler",
+ [GNU_AK_NMI_HANDLER] = "nmi_handler",
+ [GNU_AK_NESTING] = "nesting",
+ [GNU_AK_NEAR] = "near",
[GNU_AK_FAR] = "far",
[GNU_AK_SIGNAL] = "signal",
[GNU_AK_EIGTHBIT_DATA] = "eightbit_data",
/**
* compare two string, ignoring double underscores on the second.
*/
-static int strcmp_underscore(const char *s1, const char *s2) {
+static int strcmp_underscore(const char *s1, const char *s2)
+{
if (s2[0] == '_' && s2[1] == '_') {
size_t len2 = strlen(s2);
size_t len1 = strlen(s1);
/**
* Allocate a new gnu temporal attribute.
*/
-static gnu_attribute_t *allocate_gnu_attribute(gnu_attribute_kind_t kind) {
+static gnu_attribute_t *allocate_gnu_attribute(gnu_attribute_kind_t kind)
+{
gnu_attribute_t *attribute = obstack_alloc(&temp_obst, sizeof(*attribute));
attribute->kind = kind;
attribute->next = NULL;
/**
* parse one constant expression argument.
*/
-static void parse_gnu_attribute_const_arg(gnu_attribute_t *attribute) {
+static void parse_gnu_attribute_const_arg(gnu_attribute_t *attribute)
+{
expression_t *expression;
add_anchor_token(')');
expression = parse_constant_expression();
/**
* parse a list of constant expressions arguments.
*/
-static void parse_gnu_attribute_const_arg_list(gnu_attribute_t *attribute) {
+static void parse_gnu_attribute_const_arg_list(gnu_attribute_t *attribute)
+{
argument_list_t **list = &attribute->u.arguments;
argument_list_t *entry;
expression_t *expression;
/**
* parse one tls model.
*/
-static void parse_gnu_attribute_tls_model_arg(gnu_attribute_t *attribute) {
- static const char *tls_models[] = {
+static void parse_gnu_attribute_tls_model_arg(gnu_attribute_t *attribute)
+{
+ static const char *const tls_models[] = {
"global-dynamic",
"local-dynamic",
"initial-exec",
/**
* parse one tls model.
*/
-static void parse_gnu_attribute_visibility_arg(gnu_attribute_t *attribute) {
- static const char *visibilities[] = {
+static void parse_gnu_attribute_visibility_arg(gnu_attribute_t *attribute)
+{
+ static const char *const visibilities[] = {
"default",
"protected",
"hidden",
/**
* parse one (code) model.
*/
-static void parse_gnu_attribute_model_arg(gnu_attribute_t *attribute) {
- static const char *visibilities[] = {
+static void parse_gnu_attribute_model_arg(gnu_attribute_t *attribute)
+{
+ static const char *const visibilities[] = {
"small",
"medium",
"large"
/**
* parse one interrupt argument.
*/
-static void parse_gnu_attribute_interrupt_arg(gnu_attribute_t *attribute) {
- static const char *interrupts[] = {
+static void parse_gnu_attribute_interrupt_arg(gnu_attribute_t *attribute)
+{
+ static const char *const interrupts[] = {
"IRQ",
"FIQ",
"SWI",
/**
* parse ( identifier, const expression, const expression )
*/
-static void parse_gnu_attribute_format_args(gnu_attribute_t *attribute) {
- static const char *format_names[] = {
+static void parse_gnu_attribute_format_args(gnu_attribute_t *attribute)
+{
+ static const char *const format_names[] = {
"printf",
"scanf",
"strftime",
if (token.type != ')') {
/* find the end of the list */
if (last != NULL) {
- while(last->next != NULL)
+ while (last->next != NULL)
last = last->next;
}
/* non-empty attribute list */
- while(true) {
+ while (true) {
const char *name;
if (token.type == T_const) {
name = "const";
{
decl_modifiers_t modifiers = 0;
- while(true) {
+ while (true) {
switch(token.type) {
case T___attribute__:
modifiers |= parse_gnu_attribute(attributes);
designator_t *result = NULL;
designator_t *last = NULL;
- while(true) {
+ while (true) {
designator_t *designator;
switch(token.type) {
case '[':
}
bool additional_warning_displayed = false;
- while(braces > 0) {
+ while (braces > 0) {
if (token.type == ',') {
next_token();
}
{
size_t len = ARR_LEN(path->path);
- while(len > top_path_level) {
+ while (len > top_path_level) {
ascend_from_subtype(path);
len = ARR_LEN(path->path);
}
/**
* skip until token is found.
*/
-static void skip_until(int type) {
- while(token.type != type) {
+static void skip_until(int type)
+{
+ while (token.type != type) {
if (token.type == T_EOF)
return;
next_token();
if (token.type == '{')
next_token();
- while(token.type != '}') {
+ while (token.type != '}') {
if (token.type == T_EOF)
return;
if (token.type == '{') {
initializer_t **initializers = NEW_ARR_F(initializer_t*, 0);
- while(true) {
+ while (true) {
designator_t *designator = NULL;
if (token.type == '.' || token.type == '[') {
designator = parse_designation();
}
/* descend into subtypes until expression matches type */
- while(true) {
+ while (true) {
orig_type = path->top_type;
type = skip_typeref(orig_type);
if (token.type != ',')
break;
next_token();
- } while(token.type != '}');
+ } while (token.type != '}');
rem_anchor_token('}');
expect('}');
restart:
switch(token.type) {
case T___extension__:
- /* this can be a prefix to a typename or an expression */
- /* we simply eat it now. */
+ /* This can be a prefix to a typename or an expression. We simply eat
+ * it now. */
do {
next_token();
- } while(token.type == T___extension__);
+ } while (token.type == T___extension__);
goto restart;
case T_IDENTIFIER:
/**
* check for the allowed MS alignment values.
*/
-static bool check_elignment_value(long long intvalue) {
+static bool check_alignment_value(long long intvalue)
+{
if (intvalue < 1 || intvalue > 8192) {
errorf(HERE, "illegal alignment value");
return false;
#define DET_MOD(name, tag) do { \
if (*modifiers & tag) warningf(HERE, #name " used more than once"); \
*modifiers |= tag; \
-} while(0)
+} while (0)
static void parse_microsoft_extended_decl_modifier(declaration_specifiers_t *specifiers)
{
decl_modifiers_t *modifiers = &specifiers->modifiers;
- while(true) {
+ while (true) {
if (token.type == T_restrict) {
next_token();
DET_MOD(restrict, DM_RESTRICT);
expect('(');
if (token.type != T_INTEGER)
goto end_error;
- if (check_elignment_value(token.v.intvalue)) {
+ if (check_alignment_value(token.v.intvalue)) {
if (specifiers->alignment != 0)
warningf(HERE, "align used more than once");
specifiers->alignment = (unsigned char)token.v.intvalue;
specifiers->source_position = token.source_position;
- while(true) {
+ while (true) {
specifiers->modifiers
|= parse_attributes(&specifiers->gnu_attributes);
if (specifiers->modifiers & DM_TRANSPARENT_UNION)
case token: \
qualifiers |= qualifier; \
next_token(); \
- break;
+ break
MATCH_TYPE_QUALIFIER(T_const, TYPE_QUALIFIER_CONST);
MATCH_TYPE_QUALIFIER(T_restrict, TYPE_QUALIFIER_RESTRICT);
} else { \
type_specifiers |= specifier; \
} \
- break;
-
- MATCH_SPECIFIER(T_void, SPECIFIER_VOID, "void")
- MATCH_SPECIFIER(T_char, SPECIFIER_CHAR, "char")
- MATCH_SPECIFIER(T_short, SPECIFIER_SHORT, "short")
- MATCH_SPECIFIER(T_int, SPECIFIER_INT, "int")
- MATCH_SPECIFIER(T_float, SPECIFIER_FLOAT, "float")
- MATCH_SPECIFIER(T_double, SPECIFIER_DOUBLE, "double")
- MATCH_SPECIFIER(T_signed, SPECIFIER_SIGNED, "signed")
- MATCH_SPECIFIER(T_unsigned, SPECIFIER_UNSIGNED, "unsigned")
- MATCH_SPECIFIER(T__Bool, SPECIFIER_BOOL, "_Bool")
- MATCH_SPECIFIER(T__int8, SPECIFIER_INT8, "_int8")
- MATCH_SPECIFIER(T__int16, SPECIFIER_INT16, "_int16")
- MATCH_SPECIFIER(T__int32, SPECIFIER_INT32, "_int32")
- MATCH_SPECIFIER(T__int64, SPECIFIER_INT64, "_int64")
- MATCH_SPECIFIER(T__int128, SPECIFIER_INT128, "_int128")
- MATCH_SPECIFIER(T__Complex, SPECIFIER_COMPLEX, "_Complex")
- MATCH_SPECIFIER(T__Imaginary, SPECIFIER_IMAGINARY, "_Imaginary")
+ break
+
+ MATCH_SPECIFIER(T_void, SPECIFIER_VOID, "void");
+ MATCH_SPECIFIER(T_char, SPECIFIER_CHAR, "char");
+ MATCH_SPECIFIER(T_short, SPECIFIER_SHORT, "short");
+ MATCH_SPECIFIER(T_int, SPECIFIER_INT, "int");
+ MATCH_SPECIFIER(T_float, SPECIFIER_FLOAT, "float");
+ MATCH_SPECIFIER(T_double, SPECIFIER_DOUBLE, "double");
+ MATCH_SPECIFIER(T_signed, SPECIFIER_SIGNED, "signed");
+ MATCH_SPECIFIER(T_unsigned, SPECIFIER_UNSIGNED, "unsigned");
+ MATCH_SPECIFIER(T__Bool, SPECIFIER_BOOL, "_Bool");
+ MATCH_SPECIFIER(T__int8, SPECIFIER_INT8, "_int8");
+ MATCH_SPECIFIER(T__int16, SPECIFIER_INT16, "_int16");
+ MATCH_SPECIFIER(T__int32, SPECIFIER_INT32, "_int32");
+ MATCH_SPECIFIER(T__int64, SPECIFIER_INT64, "_int64");
+ MATCH_SPECIFIER(T__int128, SPECIFIER_INT128, "_int128");
+ MATCH_SPECIFIER(T__Complex, SPECIFIER_COMPLEX, "_Complex");
+ MATCH_SPECIFIER(T__Imaginary, SPECIFIER_IMAGINARY, "_Imaginary");
case T__forceinline:
/* only in microsoft mode */
{
type_qualifiers_t qualifiers = TYPE_QUALIFIER_NONE;
- while(true) {
+ while (true) {
switch(token.type) {
/* type qualifiers */
MATCH_TYPE_QUALIFIER(T_const, TYPE_QUALIFIER_CONST);
break;
}
next_token();
- } while(token.type == T_IDENTIFIER);
+ } while (token.type == T_IDENTIFIER);
return declarations;
}
function_parameter_t *parameter;
function_parameter_t *last_parameter = NULL;
- while(true) {
+ while (true) {
switch(token.type) {
case T_DOTDOTDOT:
next_token();
decl_modifiers_t modifiers = parse_attributes(&attributes);
/* pointers */
- while(token.type == '*') {
+ while (token.type == '*') {
construct_type_t *type = parse_pointer_declarator();
if (last == NULL) {
* When called with first_err set, prints the name of the current function,
* else does noting.
*/
-static void print_in_function(void) {
+static void print_in_function(void)
+{
if (first_err) {
first_err = false;
diagnosticf("%s: In function '%Y':\n",
/**
* Parses a MS assume() expression.
*/
-static expression_t *parse_assume(void) {
+static expression_t *parse_assume(void)
+{
eat(T__assume);
expression_t *expression
/**
* Parse a microsoft __noop expression.
*/
-static expression_t *parse_noop_expression(void) {
+static expression_t *parse_noop_expression(void)
+{
source_position_t source_position = *HERE;
eat(T___noop);
/**
* Check if the expression has the character type and issue a warning then.
*/
-static void check_for_char_index_type(const expression_t *expression) {
+static void check_for_char_index_type(const expression_t *expression)
+{
type_t *const type = expression->base.type;
const type_t *const base_type = skip_typeref(type);
errorf(HERE, "label at end of compound statement");
statement->label.statement = create_invalid_statement();
}
+ } else if (token.type == ';') {
+ /* Eat an empty statement here, to avoid the warning about an empty
+ * statement after a label. label:; is commonly used to have a label
+ * before a closing brace. */
+ statement->label.statement = create_empty_statement();
+ next_token();
} else {
- if (token.type == ';') {
- /* eat an empty statement here, to avoid the warning about an empty
- * after a label. label:; is commonly used to have a label before
- * a }. */
- statement->label.statement = create_empty_statement();
- next_token();
- } else {
- statement->label.statement = parse_statement();
- }
+ statement->label.statement = parse_statement();
}
/* remember the labels in a list for later checking */
/**
* Check if a given declaration represents a local variable.
*/
-static bool is_local_var_declaration(const declaration_t *declaration) {
+static bool is_local_var_declaration(const declaration_t *declaration)
+{
switch ((storage_class_tag_t) declaration->storage_class) {
case STORAGE_CLASS_AUTO:
case STORAGE_CLASS_REGISTER: {
/**
* Check if a given declaration represents a variable.
*/
-static bool is_var_declaration(const declaration_t *declaration) {
+static bool is_var_declaration(const declaration_t *declaration)
+{
if (declaration->storage_class == STORAGE_CLASS_TYPEDEF)
return false;
* Parse a microsoft __try { } __finally { } or
* __try{ } __except() { }
*/
-static statement_t *parse_ms_try_statment(void) {
+static statement_t *parse_ms_try_statment(void)
+{
statement_t *statement = allocate_statement_zero(STATEMENT_MS_TRY);
statement->base.source_position = token.source_position;
return create_invalid_statement();
}
+static statement_t *parse_empty_statement(void)
+{
+ if (warning.empty_statement) {
+ warningf(HERE, "statement is empty");
+ }
+ eat(';');
+ return create_empty_statement();
+}
+
/**
* Parse a statement.
* There's also parse_statement() which additionally checks for
/* declaration or statement */
add_anchor_token(';');
- switch(token.type) {
- case T_asm:
- statement = parse_asm_statement();
- break;
-
- case T_case:
- statement = parse_case_statement();
- break;
-
- case T_default:
- statement = parse_default_statement();
- break;
-
- case '{':
- statement = parse_compound_statement(false);
- break;
-
- case T_if:
- statement = parse_if ();
- break;
-
- case T_switch:
- statement = parse_switch();
- break;
-
- case T_while:
- statement = parse_while();
- break;
-
- case T_do:
- statement = parse_do();
- break;
-
- case T_for:
- statement = parse_for();
- break;
-
- case T_goto:
- statement = parse_goto();
- break;
-
- case T_continue:
- statement = parse_continue();
- break;
-
- case T_break:
- statement = parse_break();
- break;
-
- case T___leave:
- statement = parse_leave();
- break;
-
- case T_return:
- statement = parse_return();
- break;
-
- case ';':
- if (warning.empty_statement) {
- warningf(HERE, "statement is empty");
- }
- statement = create_empty_statement();
- next_token();
- break;
-
+ switch (token.type) {
case T_IDENTIFIER:
if (look_ahead(1)->type == ':') {
statement = parse_label_statement();
- break;
- }
-
- if (is_typedef_symbol(token.v.symbol)) {
+ } else if (is_typedef_symbol(token.v.symbol)) {
statement = parse_declaration_statement();
- break;
+ } else {
+ statement = parse_expression_statement();
}
-
- statement = parse_expression_statement();
break;
case T___extension__:
- /* this can be a prefix to a declaration or an expression statement */
- /* we simply eat it now and parse the rest with tail recursion */
+ /* This can be a prefix to a declaration or an expression statement.
+ * We simply eat it now and parse the rest with tail recursion. */
do {
next_token();
- } while(token.type == T___extension__);
+ } while (token.type == T___extension__);
statement = parse_statement();
break;
statement = parse_declaration_statement();
break;
- case T___try:
- statement = parse_ms_try_statment();
- break;
-
- default:
- statement = parse_expression_statement();
- break;
+ case ';': statement = parse_empty_statement(); break;
+ case '{': statement = parse_compound_statement(false); break;
+ case T___leave: statement = parse_leave(); break;
+ case T___try: statement = parse_ms_try_statment(); break;
+ case T_asm: statement = parse_asm_statement(); break;
+ case T_break: statement = parse_break(); break;
+ case T_case: statement = parse_case_statement(); break;
+ case T_continue: statement = parse_continue(); break;
+ case T_default: statement = parse_default_statement(); break;
+ case T_do: statement = parse_do(); break;
+ case T_for: statement = parse_for(); break;
+ case T_goto: statement = parse_goto(); break;
+ case T_if: statement = parse_if (); break;
+ case T_return: statement = parse_return(); break;
+ case T_switch: statement = parse_switch(); break;
+ case T_while: statement = parse_while(); break;
+ default: statement = parse_expression_statement(); break;
}
rem_anchor_token(';');
statement_t *last_statement = NULL;
- while(token.type != '}' && token.type != T_EOF) {
+ while (token.type != '}' && token.type != T_EOF) {
statement_t *sub_statement = intern_parse_statement();
if (is_invalid_statement(sub_statement)) {
/* an error occurred. if we are at an anchor, return */
statement->compound.statements = sub_statement;
}
- while(sub_statement->base.next != NULL)
+ while (sub_statement->base.next != NULL)
sub_statement = sub_statement->base.next;
last_statement = sub_statement;
*/
static void parse_translation_unit(void)
{
- while(token.type != T_EOF) {
+ while (token.type != T_EOF) {
switch (token.type) {
case ';':
/* TODO error in strict mode */