From 6c876cf3280ba63d6077656476c2fc692e4bb1ff Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Sun, 28 Nov 2010 13:56:07 +0200 Subject: Qualify all unqualified name components in pointer types This this necessary since they may not resolve in the typedef that we generate in namespace odb. --- odb/cxx-lexer.cxx | 164 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 164 insertions(+) create mode 100644 odb/cxx-lexer.cxx (limited to 'odb/cxx-lexer.cxx') diff --git a/odb/cxx-lexer.cxx b/odb/cxx-lexer.cxx new file mode 100644 index 0000000..525de82 --- /dev/null +++ b/odb/cxx-lexer.cxx @@ -0,0 +1,164 @@ +// file : odb/cxx-lexer.cxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2009-2010 Code Synthesis Tools CC +// license : GNU GPL v3; see accompanying LICENSE file + +#include + +#include +#include + +#include // std::bad_alloc +#include +#include + +#include + +using namespace std; + +// Token spelling. See cpplib.h for details. +// +#define OP(e, s) s , +#define TK(e, s) #e , +char const* cxx_lexer::token_spelling[N_TTYPES + 1] = { TTYPE_TABLE "KEYWORD"}; +#undef OP +#undef TK + +// Diagnostics callback. +// +extern "C" bool +cpp_error_callback ( + cpp_reader* reader, int level, location_t, unsigned int, + char const* msg, va_list *ap) +{ + char const* kind (0); + switch (level) + { + case CPP_DL_NOTE: + case CPP_DL_WARNING_SYSHDR: + case CPP_DL_WARNING: + case CPP_DL_PEDWARN: + // Ignore these. + break; + case CPP_DL_ERROR: + case CPP_DL_FATAL: + kind = "error"; + break; + case CPP_DL_ICE: + kind = "ice"; + break; + default: + kind = "unknown"; + break; + } + + if (kind != 0) + { + fprintf (stderr, "%s: ", kind); + vfprintf (stderr, msg, *ap); + fprintf (stderr, "\n"); + + // By resetting the error callback we indicate to cxx_lexer + // that there was an error. + // + cpp_get_callbacks (reader)->error = 0; + return true; + } + + return false; +} + +cxx_lexer:: +cxx_lexer () + : reader_ (0) +{ + linemap_init (&line_map_); + linemap_add (&line_map_, LC_ENTER, 0, "", 0); + + reader_ = cpp_create_reader ( + cxx_dialect == cxx0x ? CLK_CXX0X : CLK_CXX98, 0, &line_map_); + + if (reader_ == 0) + throw bad_alloc (); + + callbacks_ = cpp_get_callbacks (reader_); +} + +cxx_lexer:: +~cxx_lexer () +{ + if (reader_ != 0) + cpp_destroy (reader_); + + linemap_free (&line_map_); +} + +void cxx_lexer:: +start (string const& data) +{ + // The previous lexing session should have popped the buffer. + // + assert (cpp_get_buffer (reader_) == 0); + callbacks_->error = &cpp_error_callback; + + data_ = data; + buf_ = data; + buf_ += '\n'; + + cpp_push_buffer ( + reader_, + reinterpret_cast (buf_.c_str ()), + buf_.size (), + true); +} + +cpp_ttype cxx_lexer:: +next (string& token) +{ + token.clear (); + cpp_token const* t (cpp_get_token (reader_)); + + // If there was an error, the error callback will be reset to 0. + // Diagnostics has already been issued. + // + if (callbacks_->error == 0) + throw invalid_input (); + + cpp_ttype tt (t->type); + + // @@ Need to handle literals, at least integer. + // + switch (tt) + { + case CPP_NAME: + { + char const* name ( + reinterpret_cast (NODE_NAME (t->val.node.node))); + + // See if this is a keyword using the C++ parser machinery and + // the current C++ dialect. + // + tree id (get_identifier (name)); + + if (C_IS_RESERVED_WORD (id)) + tt = CPP_KEYWORD; + + token = name; + break; + } + default: + { + if (tt <= CPP_LAST_PUNCTUATOR) + token += token_spelling[tt]; + else + { + cerr << "unexpected token '" << token_spelling[tt] << "' in '" << + data_ << "'" << endl; + throw invalid_input (); + } + break; + } + } + + return tt; +} -- cgit v1.1