forked from qt-creator/qt-creator
More cleanup.
This commit is contained in:
@@ -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;
|
||||
class Environment;
|
||||
|
||||
pp_frame (Macro *expanding_macro, const QVector<QByteArray> &actuals)
|
||||
: expanding_macro (expanding_macro),
|
||||
actuals (actuals)
|
||||
{ }
|
||||
};
|
||||
struct pp_frame;
|
||||
|
||||
class MacroExpander
|
||||
{
|
||||
Environment &env;
|
||||
pp_frame *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;
|
||||
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);
|
||||
const QByteArray *resolve_formal(const QByteArray &name);
|
||||
|
||||
public:
|
||||
MacroExpander (Environment &env, pp_frame *frame = 0);
|
||||
public:
|
||||
MacroExpander(Environment *env, pp_frame *frame = 0);
|
||||
|
||||
const char *operator () (const char *first, const char *last,
|
||||
QByteArray *result);
|
||||
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 *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 *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);
|
||||
const char *skip_argument_variadics(const QVector<QByteArray> &actuals,
|
||||
Macro *macro,
|
||||
const char *first, const char *last);
|
||||
|
||||
public: // attributes
|
||||
int lines;
|
||||
int generated_lines;
|
||||
};
|
||||
public: // attributes
|
||||
int lines;
|
||||
int generated_lines;
|
||||
};
|
||||
|
||||
} // namespace CPlusPlus
|
||||
|
||||
|
||||
Reference in New Issue
Block a user