compressed table) and only storing pointers to it on the AST.
Parser:
-- disallow storage class specifiers in sturct/union members
-- the expect macros abort functions directly. This leads to some functions
- not resetting the current context properly (parse_for); expect in expressions
- suddenly return NULL which triggers asserts
+- disallow storage class specifiers in struct/union members
- label: declaration; is no valid C99 but we parse it anyway
- add constant folding code (optional, ast2firm already does it)
- Refactor code, so code to handle number values (and strings?) is an own
fputs("if (", out);
print_expression(statement->condition);
fputs(") ", out);
- if(statement->true_statement != NULL) {
- print_statement(statement->true_statement);
- }
+ print_statement(statement->true_statement);
if(statement->false_statement != NULL) {
print_indent();
if(declaration->alignment != 0) {
fputs(next, out); next = ", "; fprintf(out, "align(%u)", declaration->alignment);
}
+ if(modifiers & DM_RESTRICT) {
+ fputs(next, out); next = ", "; fputs("restrict", out);
+ }
+ if(modifiers & DM_NOALIAS) {
+ fputs(next, out); next = ", "; fputs("noalias", out);
+ }
if(declaration->get_property_sym != NULL || declaration->put_property_sym != NULL) {
char *comma = "";
fputs(next, out); next = ", "; fprintf(out, "property(");
DM_NOVTABLE = (1 << 8),
DM_NORETURN = (1 << 9),
DM_NOINLINE = (1 << 10),
- DM_DEPRECATED = (1 << 11)
+ DM_DEPRECATED = (1 << 11),
+ DM_RESTRICT = (1 << 12),
+ DM_NOALIAS = (1 << 13)
} decl_modifier_t;
typedef unsigned short decl_modifiers_t;
}
va_end(ap);
}
+
+static void internal_errorvf(const source_position_t pos,
+ const char *const fmt, va_list ap)
+{
+ fprintf(stderr, "%s:%u: internal error: ", pos.input_name, pos.linenr);
+ diagnosticvf(fmt, ap);
+ fputc('\n', stderr);
+}
+
+void internal_errorf(const source_position_t pos, const char *const fmt, ...)
+{
+ va_list ap;
+ va_start(ap, fmt);
+ internal_errorvf(pos, fmt, ap);
+ va_end(ap);
+ abort();
+}
#include <stdbool.h>
#include "token_t.h"
+/* define a NORETURN attribute */
+#ifndef NORETURN
+# if defined(__GNUC__)
+# if __GNUC__ >= 3 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 70)
+# define NORETURN void __attribute__ ((noreturn))
+# endif /* __GNUC__ >= 3 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 70) */
+# endif /* defined(__GNUC__) */
+
+# if defined(_MSC_VER)
+# define NORETURN void __declspec(noreturn)
+# endif /* defined(_MSC_VER) */
+
+/* If not set above, use "void" for DOES_NOT_RETURN. */
+# ifndef NORETURN
+# define NORETURN void
+# endif /* ifndef NORETURN */
+#endif /* ifndef NORETURN */
+
void diagnosticf(const char *fmt, ...);
void errorf(source_position_t pos, const char *fmt, ...);
void warningf(source_position_t pos, const char *fmt, ...);
+NORETURN internal_errorf(source_position_t pos, const char *fmt, ...);
extern unsigned diagnostic_count;
extern unsigned error_count;
errorf(lexer_token.source_position, "%s", msg);
}
+/**
+ * Prints an internal error message at the current token.
+ *
+ * @param msg the error message
+ */
+static NORETURN internal_error(const char *msg)
+{
+ internal_errorf(lexer_token.source_position, "%s", msg);
+}
+
static inline void next_real_char(void)
{
assert(bufpos <= bufend);
if(c == '.' || c == 'p' || c == 'P') {
next_char();
- panic("Hex floating point numbers not implemented yet");
+ internal_error("Hex floating point numbers not implemented yet");
}
if(*string == '\0') {
parse_error("invalid hex number");
case 'f':
case 'F': return 15;
default:
- panic("wrong character given");
+ internal_error("wrong character given");
}
}
static const symbol_t *sym_thread = NULL;
static const symbol_t *sym_uuid = NULL;
static const symbol_t *sym_deprecated = NULL;
+static const symbol_t *sym_restrict = NULL;
+static const symbol_t *sym_noalias = NULL;
/** The token anchor set */
static unsigned char token_anchor_set[T_LAST_TOKEN];
break;
default:
- panic("invalid initializer type");
+ internal_errorf(HERE, "invalid initializer type");
}
expression_t *cnst = allocate_expression_zero(EXPR_CONST);
static void parse_microsoft_extended_decl_modifier(declaration_specifiers_t *specifiers)
{
- symbol_t *symbol;
decl_modifiers_t *modifiers = &specifiers->decl_modifiers;
- while(token.type == T_IDENTIFIER) {
- symbol = token.v.symbol;
+ while(true) {
+ if(token.type == T_restrict) {
+ next_token();
+ DET_MOD(restrict, DM_RESTRICT);
+ goto end_loop;
+ } else if(token.type != T_IDENTIFIER)
+ break;
+ symbol_t *symbol = token.v.symbol;
if(symbol == sym_align) {
next_token();
expect('(');
}
expect(')');
}
+ } else if(symbol == sym_noalias) {
+ next_token();
+ DET_MOD(noalias, DM_NOALIAS);
} else {
warningf(HERE, "Unknown modifier %Y ignored", token.v.symbol);
next_token();
if(token.type == '(')
skip_until(')');
}
+end_loop:
if (token.type == ',')
next_token();
}
for( ; iter != NULL; iter = iter->next) {
switch(iter->kind) {
case CONSTRUCT_INVALID:
- panic("invalid type construction found");
+ internal_errorf(HERE, "invalid type construction found");
case CONSTRUCT_FUNCTION: {
construct_function_type_t *construct_function_type
= (construct_function_type_t*) iter;
case T___builtin_va_end:
return make_function_1_type(type_void, type_valist);
default:
- panic("not implemented builtin symbol found");
+ internal_errorf(HERE, "not implemented builtin symbol found");
}
}
expression = allocate_expression_zero(EXPR_BINARY_ISUNORDERED);
break;
default:
- panic("invalid compare builtin found");
+ internal_errorf(HERE, "invalid compare builtin found");
break;
}
expression->base.source_position = HERE;
case EXPR_BINARY_ISUNORDERED: return false;
}
- panic("unexpected expression");
+ internal_errorf(HERE, "unexpected expression");
}
static void semantic_comma(binary_expression_t *expression)
sym_thread = symbol_table_insert("thread");
sym_uuid = symbol_table_insert("uuid");
sym_deprecated = symbol_table_insert("deprecated");
+ sym_restrict = symbol_table_insert("restrict");
+ sym_noalias = symbol_table_insert("noalias");
}
memset(token_anchor_set, 0, sizeof(token_anchor_set));
struct x {
int __declspec(property(get=get_a, put=put_a)) a;
};
+
+__declspec(restrict) char * malloc_like();
+int __declspec(noalias) test1(void *a, void *b);