Commit 454438e4 authored by Roberto Raggi's avatar Roberto Raggi
Browse files

More cleanup.

parent ae046793
......@@ -138,7 +138,7 @@ QString TypeOfExpression::preprocessedExpression(const QString &expression,
processEnvironment(documents, thisDocument,
&env, &processed);
const QByteArray code = expression.toUtf8();
Preprocessor preproc(0, env);
Preprocessor preproc(0, &env);
const QByteArray preprocessedCode = preproc("<expression>", code);
return QString::fromUtf8(preprocessedCode.constData(), preprocessedCode.size());
}
......@@ -55,8 +55,84 @@
#include <QtDebug>
#include <algorithm>
namespace CPlusPlus {
struct Value
{
enum Kind {
Kind_Long,
Kind_ULong,
};
Kind kind;
union {
long l;
unsigned long ul;
};
Value()
: kind(Kind_Long), l(0)
{ }
inline bool is_ulong () const
{ return kind == Kind_ULong; }
inline void set_ulong (unsigned long v)
{
ul = v;
kind = Kind_ULong;
}
inline void set_long (long v)
{
l = v;
kind = Kind_Long;
}
inline bool is_zero () const
{ return l == 0; }
#define PP_DEFINE_BIN_OP(name, op) \
inline Value operator op(const Value &other) const \
{ \
Value v = *this; \
if (v.is_ulong () || other.is_ulong ()) \
v.set_ulong (v.ul op other.ul); \
else \
v.set_long (v.l op other.l); \
return v; \
}
PP_DEFINE_BIN_OP(op_add, +)
PP_DEFINE_BIN_OP(op_sub, -)
PP_DEFINE_BIN_OP(op_mult, *)
PP_DEFINE_BIN_OP(op_div, /)
PP_DEFINE_BIN_OP(op_mod, %)
PP_DEFINE_BIN_OP(op_lhs, <<)
PP_DEFINE_BIN_OP(op_rhs, >>)
PP_DEFINE_BIN_OP(op_lt, <)
PP_DEFINE_BIN_OP(op_gt, >)
PP_DEFINE_BIN_OP(op_le, <=)
PP_DEFINE_BIN_OP(op_ge, >=)
PP_DEFINE_BIN_OP(op_eq, ==)
PP_DEFINE_BIN_OP(op_ne, !=)
PP_DEFINE_BIN_OP(op_bit_and, &)
PP_DEFINE_BIN_OP(op_bit_or, |)
PP_DEFINE_BIN_OP(op_bit_xor, ^)
PP_DEFINE_BIN_OP(op_and, &&)
PP_DEFINE_BIN_OP(op_or, ||)
#undef PP_DEFINE_BIN_OP
};
} // end of namespace CPlusPlus
using namespace CPlusPlus;
namespace {
class RangeLexer
......@@ -449,7 +525,7 @@ private:
} // end of anonymous namespace
Preprocessor::Preprocessor(Client *client, Environment &env)
Preprocessor::Preprocessor(Client *client, Environment *env)
: client(client),
env(env),
_expand(env),
......@@ -528,23 +604,23 @@ Preprocessor::State Preprocessor::createStateFromSource(const QByteArray &source
void Preprocessor::processNewline()
{
if (env.currentLine == _dot->lineno)
if (env->currentLine == _dot->lineno)
return;
if (env.currentLine > _dot->lineno) {
if (env->currentLine > _dot->lineno) {
_result->append("\n# ");
_result->append(QByteArray::number(_dot->lineno));
_result->append(' ');
_result->append('"');
_result->append(env.currentFile);
_result->append(env->currentFile);
_result->append('"');
_result->append('\n');
} else {
for (unsigned i = env.currentLine; i < _dot->lineno; ++i)
for (unsigned i = env->currentLine; i < _dot->lineno; ++i)
_result->append('\n');
}
env.currentLine = _dot->lineno;
env->currentLine = _dot->lineno;
}
void Preprocessor::processSkippingBlocks(bool skippingBlocks,
......@@ -579,11 +655,11 @@ void Preprocessor::preprocess(const QByteArray &fileName, const QByteArray &sour
pushState(createStateFromSource(source));
const QByteArray previousFileName = env.currentFile;
env.currentFile = fileName;
const QByteArray previousFileName = env->currentFile;
env->currentFile = fileName;
const unsigned previousCurrentLine = env.currentLine;
env.currentLine = 0;
const unsigned previousCurrentLine = env->currentLine;
env->currentLine = 0;
while (true) {
processNewline();
......@@ -628,7 +704,8 @@ void Preprocessor::preprocess(const QByteArray &fileName, const QByteArray &sour
++_dot; // skip T_IDENTIFIER
const QByteArray spell = tokenSpell(*identifierToken);
if (env.isBuiltinMacro(spell)) {
if (env->isBuiltinMacro(spell)) {
const Macro trivial;
if (client)
......@@ -643,7 +720,7 @@ void Preprocessor::preprocess(const QByteArray &fileName, const QByteArray &sour
continue;
}
Macro *m = env.resolve(spell);
Macro *m = env->resolve(spell);
if (! m)
_result->append(spell);
......@@ -675,7 +752,7 @@ void Preprocessor::preprocess(const QByteArray &fileName, const QByteArray &sour
if (_dot->is(T_IDENTIFIER)) {
const QByteArray id = tokenSpell(*_dot);
if (Macro *macro = env.resolve(id)) {
if (Macro *macro = env->resolve(id)) {
if (macro->isFunctionLike())
m = macro;
}
......@@ -690,6 +767,8 @@ void Preprocessor::preprocess(const QByteArray &fileName, const QByteArray &sour
}
}
// `m' is function-like macro.
// collect the actual arguments
if (_dot->isNot(T_LPAREN)) {
// ### warnng expected T_LPAREN
......@@ -709,6 +788,7 @@ void Preprocessor::preprocess(const QByteArray &fileName, const QByteArray &sour
++_dot;
}
if (_dot->isNot(T_RPAREN)) {
// ### warning expected T_RPAREN
......@@ -738,8 +818,8 @@ void Preprocessor::preprocess(const QByteArray &fileName, const QByteArray &sour
popState();
env.currentFile = previousFileName;
env.currentLine = previousCurrentLine;
env->currentFile = previousFileName;
env->currentLine = previousCurrentLine;
_result = previousResult;
}
......@@ -899,8 +979,8 @@ void Preprocessor::processDefine(TokenIterator firstToken, TokenIterator lastTok
}
Macro macro;
macro.setFileName(env.currentFile);
macro.setLine(env.currentLine);
macro.setFileName(env->currentFile);
macro.setLine(env->currentLine);
macro.setName(tokenText(*tk));
++tk; // skip T_IDENTIFIER
......@@ -961,7 +1041,7 @@ void Preprocessor::processDefine(TokenIterator firstToken, TokenIterator lastTok
macro.setDefinition(definition.trimmed());
}
env.bind(macro);
env->bind(macro);
if (client)
client->macroAdded(macro);
......@@ -1063,7 +1143,7 @@ void Preprocessor::processIfdef(bool checkUndefined,
if (testIfLevel()) {
if (tk->is(T_IDENTIFIER)) {
const QByteArray macroName = tokenSpell(*tk);
bool value = env.resolve(macroName) != 0 || env.isBuiltinMacro(macroName);
bool value = env->resolve(macroName) != 0 || env->isBuiltinMacro(macroName);
if (checkUndefined)
value = ! value;
......@@ -1083,7 +1163,7 @@ void Preprocessor::processUndef(TokenIterator firstToken, TokenIterator lastToke
if (tk->is(T_IDENTIFIER)) {
const QByteArray macroName = tokenText(*tk);
const Macro *macro = env.remove(macroName);
const Macro *macro = env->remove(macroName);
if (client && macro)
client->macroAdded(*macro);
......@@ -1162,7 +1242,7 @@ int Preprocessor::skipping() const
Value Preprocessor::evalExpression(TokenIterator firstToken, TokenIterator lastToken,
const QByteArray &source) const
{
ExpressionEvaluator eval(&env);
ExpressionEvaluator eval(env);
const Value result = eval(firstToken, lastToken, source);
return result;
}
......
......@@ -60,80 +60,12 @@ namespace CPlusPlus {
namespace CPlusPlus {
struct Value
{
enum Kind {
Kind_Long,
Kind_ULong,
};
Kind kind;
union {
long l;
unsigned long ul;
};
Value()
: kind(Kind_Long), l(0)
{ }
inline bool is_ulong () const
{ return kind == Kind_ULong; }
inline void set_ulong (unsigned long v)
{
ul = v;
kind = Kind_ULong;
}
inline void set_long (long v)
{
l = v;
kind = Kind_Long;
}
inline bool is_zero () const
{ return l == 0; }
#define PP_DEFINE_BIN_OP(name, op) \
inline Value operator op(const Value &other) const \
{ \
Value v = *this; \
if (v.is_ulong () || other.is_ulong ()) \
v.set_ulong (v.ul op other.ul); \
else \
v.set_long (v.l op other.l); \
return v; \
}
PP_DEFINE_BIN_OP(op_add, +)
PP_DEFINE_BIN_OP(op_sub, -)
PP_DEFINE_BIN_OP(op_mult, *)
PP_DEFINE_BIN_OP(op_div, /)
PP_DEFINE_BIN_OP(op_mod, %)
PP_DEFINE_BIN_OP(op_lhs, <<)
PP_DEFINE_BIN_OP(op_rhs, >>)
PP_DEFINE_BIN_OP(op_lt, <)
PP_DEFINE_BIN_OP(op_gt, >)
PP_DEFINE_BIN_OP(op_le, <=)
PP_DEFINE_BIN_OP(op_ge, >=)
PP_DEFINE_BIN_OP(op_eq, ==)
PP_DEFINE_BIN_OP(op_ne, !=)
PP_DEFINE_BIN_OP(op_bit_and, &)
PP_DEFINE_BIN_OP(op_bit_or, |)
PP_DEFINE_BIN_OP(op_bit_xor, ^)
PP_DEFINE_BIN_OP(op_and, &&)
PP_DEFINE_BIN_OP(op_or, ||)
#undef PP_DEFINE_BIN_OP
};
struct Value;
class CPLUSPLUS_EXPORT Preprocessor
{
public:
Preprocessor(Client *client, Environment &env);
Preprocessor(Client *client, Environment *env);
QByteArray operator()(const QByteArray &filename,
const QByteArray &source);
......@@ -218,7 +150,7 @@ private:
private:
Client *client;
Environment &env;
Environment *env;
MacroExpander _expand;
bool _skipping[MAX_LEVEL]; // ### move in state
......
......@@ -32,6 +32,24 @@
#include "pp-macro-expander.h"
#include <QDateTime>
namespace CPlusPlus {
struct pp_frame
{
Macro *expanding_macro;
const QVector<QByteArray> actuals;
pp_frame(Macro *expanding_macro, const QVector<QByteArray> &actuals)
: expanding_macro (expanding_macro),
actuals (actuals)
{ }
};
} // end of namespace CPlusPlus
using namespace CPlusPlus;
inline static bool comment_p (const char *__first, const char *__last)
......@@ -48,7 +66,7 @@ inline static bool comment_p (const char *__first, const char *__last)
return (*__first == '/' || *__first == '*');
}
MacroExpander::MacroExpander (Environment &env, pp_frame *frame)
MacroExpander::MacroExpander(Environment *env, pp_frame *frame)
: env(env), frame(frame),
lines(0), generated_lines(0)
{ }
......@@ -87,10 +105,10 @@ const char *MacroExpander::expand(const char *__first, const char *__last,
if (*__first == '\n')
{
__result->append("\n# ");
__result->append(QByteArray::number(env.currentLine));
__result->append(QByteArray::number(env->currentLine));
__result->append(' ');
__result->append('"');
__result->append(env.currentFile);
__result->append(env->currentFile);
__result->append('"');
__result->append('\n');
++lines;
......@@ -214,20 +232,20 @@ const char *MacroExpander::expand(const char *__first, const char *__last,
continue;
}
Macro *macro = env.resolve (fast_name);
if (! macro || macro->isHidden() || env.hideNext)
Macro *macro = env->resolve (fast_name);
if (! macro || macro->isHidden() || env->hideNext)
{
if (fast_name.size () == 7 && fast_name [0] == 'd' && fast_name == "defined")
env.hideNext = true;
env->hideNext = true;
else
env.hideNext = false;
env->hideNext = false;
if (fast_name.size () == 8 && fast_name [0] == '_' && fast_name [1] == '_')
{
if (fast_name == "__LINE__")
{
char buf [16];
const size_t count = qsnprintf (buf, 16, "%d", env.currentLine + lines);
const size_t count = qsnprintf (buf, 16, "%d", env->currentLine + lines);
__result->append(buf, count);
continue;
}
......@@ -235,7 +253,7 @@ const char *MacroExpander::expand(const char *__first, const char *__last,
else if (fast_name == "__FILE__")
{
__result->append('"');
__result->append(env.currentFile);
__result->append(env->currentFile);
__result->append('"');
continue;
}
......@@ -287,7 +305,7 @@ const char *MacroExpander::expand(const char *__first, const char *__last,
if (__end_id == __tmp_end)
{
const QByteArray __id (__begin_id, __end_id - __begin_id);
m = env.resolve (__id);
m = env->resolve (__id);
}
if (! m)
......
......@@ -49,56 +49,53 @@
#ifndef PP_MACRO_EXPANDER_H
#define PP_MACRO_EXPANDER_H
#include "pp-scanner.h"
#include <QVector>
#include <QByteArray>
namespace CPlusPlus {
struct pp_frame
{
Macro *expanding_macro;
const QVector<QByteArray> actuals;
pp_frame (Macro *expanding_macro, const QVector<QByteArray> &actuals)
: expanding_macro (expanding_macro),
actuals (actuals)
{ }
};
class MacroExpander
{
Environment &env;
pp_frame *frame;
pp_skip_number skip_number;
pp_skip_identifier skip_identifier;
pp_skip_string_literal skip_string_literal;
pp_skip_char_literal skip_char_literal;
pp_skip_argument skip_argument;
pp_skip_comment_or_divop skip_comment_or_divop;
pp_skip_blanks skip_blanks;
pp_skip_whitespaces skip_whitespaces;
const QByteArray *resolve_formal (const QByteArray &name);
public:
MacroExpander (Environment &env, pp_frame *frame = 0);
const char *operator () (const char *first, const char *last,
QByteArray *result);
const char *operator () (const QByteArray &source,
QByteArray *result)
{ return operator()(source.constBegin(), source.constEnd(), result); }
const char *expand(const char *first, const char *last,
QByteArray *result);
const char *skip_argument_variadics (const QVector<QByteArray> &actuals,
Macro *macro,
const char *first, const char *last);
public: // attributes
int lines;
int generated_lines;
};
class Environment;
struct pp_frame;
class MacroExpander
{
Environment *env;
pp_frame *frame;
pp_skip_number skip_number;
pp_skip_identifier skip_identifier;
pp_skip_string_literal skip_string_literal;
pp_skip_char_literal skip_char_literal;
pp_skip_argument skip_argument;
pp_skip_comment_or_divop skip_comment_or_divop;
pp_skip_blanks skip_blanks;
pp_skip_whitespaces skip_whitespaces;
const QByteArray *resolve_formal(const QByteArray &name);
public:
MacroExpander(Environment *env, pp_frame *frame = 0);
const char *operator()(const char *first, const char *last,
QByteArray *result);
const char *operator()(const QByteArray &source,
QByteArray *result)
{ return operator()(source.constBegin(), source.constEnd(), result); }
const char *expand(const char *first, const char *last,
QByteArray *result);
const char *skip_argument_variadics(const QVector<QByteArray> &actuals,
Macro *macro,
const char *first, const char *last);
public: // attributes
int lines;
int generated_lines;
};
} // namespace CPlusPlus
......
......@@ -220,7 +220,7 @@ private:
CppPreprocessor::CppPreprocessor(QPointer<CppModelManager> modelManager)
: snapshot(modelManager->snapshot()),
m_modelManager(modelManager),
preprocess(this, env)
preprocess(this, &env)
{ }
void CppPreprocessor::setWorkingCopy(const QMap<QString, QByteArray> &workingCopy)
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment