aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2023-11-03 14:56:31 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2023-11-03 14:56:31 +0200
commit6bd285316c4bceb38d5a7e5e9967cc84302056b4 (patch)
tree534fd589b16a560131b52355bd603205536a9cfb
parent7c0629063ef64b6c7732e7ac94a6ecefcda4d828 (diff)
Generalize and export cc::lexer
-rw-r--r--libbuild2/cc/lexer.cxx11
-rw-r--r--libbuild2/cc/lexer.hxx30
-rw-r--r--libbuild2/cc/lexer.test.cxx2
-rw-r--r--libbuild2/cc/parser.cxx2
4 files changed, 29 insertions, 16 deletions
diff --git a/libbuild2/cc/lexer.cxx b/libbuild2/cc/lexer.cxx
index 467c0b1..96bd887 100644
--- a/libbuild2/cc/lexer.cxx
+++ b/libbuild2/cc/lexer.cxx
@@ -214,7 +214,7 @@ namespace build2
// #line <integer> [<string literal>] ...
// # <integer> [<string literal>] ...
//
- // Also diagnose #include while at it.
+ // Also diagnose #include while at it if preprocessed.
//
if (!(c >= '0' && c <= '9'))
{
@@ -222,10 +222,13 @@ namespace build2
if (t.type == type::identifier)
{
- if (t.value == "include")
- fail (l) << "unexpected #include directive";
- else if (t.value != "line")
+ if (t.value != "line")
+ {
+ if (preprocessed_ && t.value == "include")
+ fail (l) << "unexpected #include directive";
+
continue;
+ }
}
else
continue;
diff --git a/libbuild2/cc/lexer.hxx b/libbuild2/cc/lexer.hxx
index 81e0d97..17d706b 100644
--- a/libbuild2/cc/lexer.hxx
+++ b/libbuild2/cc/lexer.hxx
@@ -12,6 +12,8 @@
#include <libbuild2/diagnostics.hxx>
+#include <libbuild2/cc/export.hxx>
+
namespace build2
{
namespace cc
@@ -20,13 +22,15 @@ namespace build2
// sequence of tokens returned is similar to what a real C/C++ compiler
// would see from its preprocessor.
//
- // The input is a (partially-)preprocessed translation unit that may still
- // contain comments, line continuations, and preprocessor directives such
- // as #line, #pragma, but not #include (which is diagnosed). 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. Note that the
- // modules-related pseudo-directives are not recognized or handled.
+ // The input is a potentially (partially-)preprocessed translation unit
+ // that may still contain comments, line continuations, and preprocessor
+ // directives such as #line and #pragma. If the input is said to be
+ // (partially-)preprocessed then #include directives are diagnosed.
+ // 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. Note
+ // that the modules-related pseudo-directives are not recognized or
+ // handled.
//
// While at it we also calculate the checksum of the input ignoring
// comments, whitespaces, etc. This is used to detect changes that do not
@@ -80,15 +84,19 @@ namespace build2
// Output the token value in a format suitable for diagnostics.
//
- ostream&
+ LIBBUILD2_CC_SYMEXPORT ostream&
operator<< (ostream&, const token&);
- class lexer: protected butl::char_scanner<>
+ class LIBBUILD2_CC_SYMEXPORT lexer: protected butl::char_scanner<>
{
public:
- lexer (ifdstream& is, const path_name& name)
+ // If preprocessed is true, then assume the input is at least partially
+ // preprocessed and therefore should not contain #include directives.
+ //
+ lexer (ifdstream& is, const path_name& name, bool preprocessed)
: char_scanner (is, false /* crlf */),
name_ (name),
+ preprocessed_ (preprocessed),
fail ("error", &name_),
log_file_ (name)
{
@@ -173,6 +181,8 @@ namespace build2
private:
const path_name& name_;
+ bool preprocessed_;
+
const fail_mark fail;
// Logical file and line as set by the #line directives. Note that the
diff --git a/libbuild2/cc/lexer.test.cxx b/libbuild2/cc/lexer.test.cxx
index 39e4279..82163fe 100644
--- a/libbuild2/cc/lexer.test.cxx
+++ b/libbuild2/cc/lexer.test.cxx
@@ -65,7 +65,7 @@ namespace build2
is.open (fddup (stdin_fd ()));
}
- lexer l (is, in);
+ lexer l (is, in, true /* preprocessed */);
// No use printing eos since we will either get it or loop forever.
//
diff --git a/libbuild2/cc/parser.cxx b/libbuild2/cc/parser.cxx
index dc5093f..3e84edb 100644
--- a/libbuild2/cc/parser.cxx
+++ b/libbuild2/cc/parser.cxx
@@ -17,7 +17,7 @@ namespace build2
void parser::
parse (ifdstream& is, const path_name& in, unit& u)
{
- lexer l (is, in);
+ lexer l (is, in, true /* preprocessed */);
l_ = &l;
u_ = &u;