{
fprintf(out, "at line %u", pos->lineno);
if (show_column)
- fprintf(out, ":%u", pos->colno);
+ fprintf(out, ":%u", (unsigned)pos->colno);
if (curr_pos == NULL || curr_pos->input_name != pos->input_name)
fprintf(out, " of \"%s\"", pos->input_name);
}
FILE *const out = stderr;
fprintf(out, "%s:%u:", pos->input_name, pos->lineno);
if (show_column)
- fprintf(out, "%u:", pos->colno);
+ fprintf(out, "%u:", (unsigned)pos->colno);
fprintf(out, " %s: ", kind);
curr_pos = pos;
diagnosticvf(fmt, ap);
}
if (pp_token.kind == T_STRING_LITERAL) {
lexer_pos.input_name = pp_token.string.string.begin;
+ lexer_pos.is_system_header = false;
next_pp_token();
+
+ /* attempt to parse numeric flags as outputted by gcc preprocessor */
+ while (pp_token.kind == T_INTEGER) {
+ /* flags:
+ * 1 - indicates start of a new file
+ * 2 - indicates return from a file
+ * 3 - indicates system header
+ * 4 - indicates implicit extern "C" in C++ mode
+ *
+ * currently we're only interested in "3"
+ */
+ if (strcmp(pp_token.number.number.begin, "3") == 0) {
+ lexer_pos.is_system_header = true;
+ }
+ next_pp_token();
+ }
}
eat_until_newline();
void dbg_pos(const source_position_t source_position)
{
fprintf(stdout, "%s:%u:%u\n", source_position.input_name,
- source_position.lineno, source_position.colno);
+ source_position.lineno, (unsigned)source_position.colno);
fflush(stdout);
}
goto finish;
}
if (previous_entity->kind == ENTITY_TYPEDEF) {
- /* TODO: C++ allows this for exactly the same type */
- errorf(pos, "redefinition of '%N' (declared %P)", entity, ppos);
+ type_t *const type = skip_typeref(entity->typedefe.type);
+ type_t *const prev_type
+ = skip_typeref(previous_entity->typedefe.type);
+ /* gcc extension redef in system headers is allowed */
+ if ((!(c_mode & _CXX) && !pos->is_system_header)
+ || !types_compatible(type, prev_type)) {
+ errorf(pos, "redefinition of '%N' (declared %P)",
+ entity, ppos);
+ }
goto finish;
}
merge_in_attributes(decl, prev_decl->attributes);
} else if (!is_definition &&
is_type_valid(prev_type) &&
- strcmp(ppos->input_name, "<builtin>") != 0) {
+ !pos->is_system_header) {
warningf(WARN_REDUNDANT_DECLS, pos, "redundant declaration for '%Y' (declared %P)", symbol, ppos);
}
} else if (current_function == NULL) {
static symbol_t *token_symbols[T_LAST_TOKEN];
static symbol_t *pp_token_symbols[TP_LAST_TOKEN];
-const source_position_t builtin_source_position = { "<built-in>", 0, 0 };
+const source_position_t builtin_source_position = { "<built-in>", 0, 0, true };
static int last_id;
struct source_position_t {
const char *input_name;
unsigned lineno;
- unsigned colno;
+ unsigned colno : 31;
+ unsigned is_system_header : 1;
};
/* position used for "builtin" declarations/types */