*/
#include <config.h>
+#include "adt/strutil.h"
#include "input.h"
#include "diagnostic.h"
#include "lexer.h"
#include "adt/util.h"
#include "types.h"
#include "type_t.h"
-#include "target_architecture.h"
#include "parser.h"
#include "warning.h"
#include "lang_features.h"
}
obstack_1grow(&symbol_obstack, '\0');
- size_t size = obstack_object_size(&symbol_obstack);
- char *string = obstack_finish(&symbol_obstack);
+ size_t size = obstack_object_size(&symbol_obstack) - 1;
+ char *string = obstack_finish(&symbol_obstack);
lexer_token.number.suffix = identify_string(string, size);
}
+static void parse_exponent(void)
+{
+ if (c == '-' || c == '+') {
+ obstack_1grow(&symbol_obstack, (char)c);
+ next_char();
+ }
+
+ if (isdigit(c)) {
+ do {
+ obstack_1grow(&symbol_obstack, (char)c);
+ next_char();
+ } while (isdigit(c));
+ } else {
+ errorf(&lexer_token.base.source_position, "exponent has no digits");
+ }
+}
+
/**
* Parses a hex number including hex floats and set the
* lexer_token.
bool is_float = false;
bool has_digits = false;
- assert(obstack_object_size(&symbol_obstack) == 0);
while (isxdigit(c)) {
has_digits = true;
obstack_1grow(&symbol_obstack, (char) c);
is_float = true;
obstack_1grow(&symbol_obstack, (char) c);
next_char();
-
- if (c == '-' || c == '+') {
- obstack_1grow(&symbol_obstack, (char) c);
- next_char();
- }
-
- while (isxdigit(c)) {
- obstack_1grow(&symbol_obstack, (char) c);
- next_char();
- }
+ parse_exponent();
} else if (is_float) {
errorf(&lexer_token.base.source_position,
"hexadecimal floatingpoint constant requires an exponent");
is_float ? T_FLOATINGPOINT_HEXADECIMAL : T_INTEGER_HEXADECIMAL;
if (!has_digits) {
- errorf(&lexer_token.base.source_position,
- "invalid number literal '0x%S'", &lexer_token.number.number);
+ errorf(&lexer_token.base.source_position, "invalid number literal '%S'", &lexer_token.number.number);
lexer_token.number.number.begin = "0";
lexer_token.number.number.size = 1;
}
assert(obstack_object_size(&symbol_obstack) == 0);
if (c == '0') {
+ obstack_1grow(&symbol_obstack, (char)c);
next_char();
if (c == 'x' || c == 'X') {
+ obstack_1grow(&symbol_obstack, (char)c);
next_char();
parse_number_hex();
return;
} else {
has_digits = true;
}
- obstack_1grow(&symbol_obstack, '0');
}
while (isdigit(c)) {
is_float = true;
obstack_1grow(&symbol_obstack, 'e');
next_char();
-
- if (c == '-' || c == '+') {
- obstack_1grow(&symbol_obstack, (char) c);
- next_char();
- }
-
- while (isdigit(c)) {
- obstack_1grow(&symbol_obstack, (char) c);
- next_char();
- }
+ parse_exponent();
}
obstack_1grow(&symbol_obstack, '\0');
break;
}
- case EOF: {
+ case EOF:
errorf(&lexer_token.base.source_position, "string has no end");
- lexer_token.kind = T_ERROR;
- return;
- }
+ goto end_of_string;
case '"':
next_char();
next_char();
goto end_of_wide_char_constant;
- case EOF: {
- errorf(&lexer_token.base.source_position,
- "EOF while parsing character constant");
- lexer_token.kind = T_ERROR;
- return;
- }
+ case EOF:
+ errorf(&lexer_token.base.source_position, "EOF while parsing character constant");
+ goto end_of_wide_char_constant;
default:
obstack_grow_symbol(&symbol_obstack, c);
next_char();
goto end_of_char_constant;
- case EOF: {
- errorf(&lexer_token.base.source_position,
- "EOF while parsing character constant");
- lexer_token.kind = T_ERROR;
- return;
- }
+ case EOF:
+ errorf(&lexer_token.base.source_position, "EOF while parsing character constant");
+ goto end_of_char_constant;
default:
obstack_grow_symbol(&symbol_obstack, c);
}
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 (streq(pp_token.number.number.begin, "3")) {
+ lexer_pos.is_system_header = true;
+ }
+ next_pp_token();
+ }
}
eat_until_newline();
dollar_sign:
errorf(&lexer_pos, "unknown character '%c' found", c);
next_char();
- lexer_token.kind = T_ERROR;
- return;
+ break;
}
}
}
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);
}