diff options
author | Boris Kolpackov <boris@codesynthesis.com> | 2017-05-27 15:24:25 +0200 |
---|---|---|
committer | Boris Kolpackov <boris@codesynthesis.com> | 2017-05-27 15:24:25 +0200 |
commit | 2e19434e09b819105055ddc8e58f69db98ec8669 (patch) | |
tree | e806e15f6e940a9135f0e7d8cf9ba08637512bd8 /build2/cc/lexer.hxx | |
parent | de417f02b2b1f3a02c5c9d206f399c574a93bf7f (diff) |
Handle #line directives in C/C++ lexer
This way the parser now reports logical rather than physical location in
diagnostics.
Diffstat (limited to 'build2/cc/lexer.hxx')
-rw-r--r-- | build2/cc/lexer.hxx | 38 |
1 files changed, 22 insertions, 16 deletions
diff --git a/build2/cc/lexer.hxx b/build2/cc/lexer.hxx index 7865a4e..8767606 100644 --- a/build2/cc/lexer.hxx +++ b/build2/cc/lexer.hxx @@ -22,8 +22,10 @@ namespace build2 // // The input is a (partially-)preprocessed translation unit that may still // contain comments, line continuations, and preprocessor directives such - // as #line, #pragma, etc. Currently all preprocessor directives are - // discarded and no values are saved for literals. + // as #line, #pragma, etc., but not #include's. Currently all preprocessor + // directives except #line are ignored and no values are saved from + // literals. The #line directive (and its shorthand notation) is + // recognized to provide the logical token location. // enum class token_type { @@ -51,6 +53,7 @@ namespace build2 token_type type; string value; + path file; uint64_t line; uint64_t column; @@ -74,7 +77,10 @@ namespace build2 { public: lexer (istream& is, const path& name) - : char_scanner (is, false), name_ (name), fail ("error", &name_) {} + : char_scanner (is, false), + name_ (name), + fail ("error", &name_), + log_file_ (name) {} const path& name () const {return name_;} @@ -121,6 +127,9 @@ namespace build2 void literal_suffix (xchar); + void + line_directive (token&, xchar); + xchar skip_spaces (bool newline = true); @@ -134,7 +143,7 @@ namespace build2 get (bool escape = true); void - get (const xchar& peeked) {base::get (peeked);} + get (const xchar& peeked); xchar peek (bool escape = true); @@ -142,23 +151,20 @@ namespace build2 private: const path name_; const fail_mark fail; + + // Logical file and line as set by the #line directives. Note that the + // lexer diagnostics still uses the physical file/lines. + // + path log_file_; + optional<uint64_t> log_line_; }; - // Diagnostics plumbing. We assume that any diag stream for which we can - // use token as location has its aux data pointing to pointer to path. + // Diagnostics plumbing. // inline location - get_location (const token& t, const path& p) - { - return location (&p, t.line, t.column); - } - - inline location - get_location (const token& t, const void* data) + get_location (const token& t, const void*) { - assert (data != nullptr); // E.g., must be &parser::path_. - const path* p (*static_cast<const path* const*> (data)); - return get_location (t, *p); + return location (&t.file, t.line, t.column); } } } |