From e325aa38d91c9d11b9645004e786924c49e2b325 Mon Sep 17 00:00:00 2001 From: Roberto Raggi <qtc-committer@nokia.com> Date: Mon, 22 Dec 2008 13:55:42 +0100 Subject: [PATCH] Nicer implementation of CPlusPlus::Macro. --- src/libs/cplusplus/LookupContext.cpp | 1 - src/libs/cplusplus/pp-engine.cpp | 81 +++++++-------- src/libs/cplusplus/pp-environment.cpp | 26 ++--- src/libs/cplusplus/pp-macro-expander.cpp | 24 ++--- src/libs/cplusplus/pp-macro-expander.h | 4 + src/libs/cplusplus/pp-macro.h | 109 +++++++++++++++------ src/plugins/cppeditor/cppeditor.cpp | 4 +- src/plugins/cppeditor/cpphoverhandler.cpp | 5 +- src/plugins/cpptools/cppcodecompletion.cpp | 4 +- 9 files changed, 152 insertions(+), 106 deletions(-) diff --git a/src/libs/cplusplus/LookupContext.cpp b/src/libs/cplusplus/LookupContext.cpp index 28f8b0dd58f..ed70e5b2168 100644 --- a/src/libs/cplusplus/LookupContext.cpp +++ b/src/libs/cplusplus/LookupContext.cpp @@ -40,7 +40,6 @@ #include <Control.h> #include <cplusplus/Overview.h> -#include <QFile> #include <QtDebug> using namespace CPlusPlus; diff --git a/src/libs/cplusplus/pp-engine.cpp b/src/libs/cplusplus/pp-engine.cpp index a6186c6b7c6..6c5930de182 100644 --- a/src/libs/cplusplus/pp-engine.cpp +++ b/src/libs/cplusplus/pp-engine.cpp @@ -600,19 +600,15 @@ void Preprocessor::operator()(const QByteArray &source, QByteArray *result) if (! m) { result->append(spell); } else { - if (! m->function_like) { + if (! m->isFunctionLike()) { if (_dot->isNot(T_LPAREN)) { if (client) client->startExpandingMacro(identifierToken->offset, *m, spell); - m->hidden = true; - - expand(m->definition.constBegin(), - m->definition.constEnd(), - result); - - m->hidden = false; + m->setHidden(true); + expand(m->definition(), result); + m->setHidden(false); if (client) client->stopExpandingMacro(_dot->offset, *m); @@ -624,13 +620,9 @@ void Preprocessor::operator()(const QByteArray &source, QByteArray *result) if (client) client->startExpandingMacro(identifierToken->offset, *m, spell); - m->hidden = true; - - expand(m->definition.constBegin(), - m->definition.constEnd(), - &tmp); - - m->hidden = false; + m->setHidden(true); + expand(m->definition(), &tmp); + m->setHidden(false); if (client) client->stopExpandingMacro(_dot->offset, *m); @@ -641,7 +633,7 @@ void Preprocessor::operator()(const QByteArray &source, QByteArray *result) if (_dot->is(T_IDENTIFIER)) { const QByteArray id = tokenSpell(*_dot); Macro *macro = env.resolve(id); - if (macro && macro->function_like) + if (macro && macro->isFunctionLike()) m = macro; } popState(); @@ -656,7 +648,7 @@ void Preprocessor::operator()(const QByteArray &source, QByteArray *result) // collect the actual arguments if (_dot->isNot(T_LPAREN)) { // ### warnng expected T_LPAREN - result->append(m->name); + result->append(m->name()); continue; } @@ -852,30 +844,30 @@ void Preprocessor::processDefine(TokenIterator firstToken, TokenIterator lastTok } Macro macro; - macro.fileName = env.currentFile; - macro.line = env.currentLine; - macro.name = tokenText(*tk); + macro.setFileName(env.currentFile); + macro.setLine(env.currentLine); + macro.setName(tokenText(*tk)); ++tk; // skip T_IDENTIFIER if (tk->is(T_LPAREN) && ! tk->whitespace) { // a function-like macro definition - macro.function_like = true; + macro.setFunctionLike(true); ++tk; // skip T_LPAREN if (tk->is(T_IDENTIFIER)) { - macro.formals.append(tokenText(*tk)); + macro.addFormal(tokenText(*tk)); ++tk; // skip T_IDENTIFIER while (tk->is(T_COMMA)) { ++tk;// skip T_COMMA if (tk->isNot(T_IDENTIFIER)) break; - macro.formals.append(tokenText(*tk)); + macro.addFormal(tokenText(*tk)); ++tk; // skip T_IDENTIFIER } } if (tk->is(T_DOT_DOT_DOT)) { - macro.variadics = true; + macro.setVariadic(true); ++tk; // skip T_DOT_DOT_DOT } @@ -887,32 +879,31 @@ void Preprocessor::processDefine(TokenIterator firstToken, TokenIterator lastTok ++tk; // skip T_RPAREN } - QByteArray macroId = macro.name; - const bool isQtWord = isQtReservedWord(macroId); - - if (macro.function_like) { - macroId += '('; - for (int i = 0; i < macro.formals.size(); ++i) { - if (i != 0) - macroId += ", "; - - const QByteArray formal = macro.formals.at(i); - macroId += formal; + if (isQtReservedWord(macro.name())) { + QByteArray macroId = macro.name(); + + if (macro.isFunctionLike()) { + macroId += '('; + bool fst = true; + foreach (const QByteArray formal, macro.formals()) { + if (! fst) + macroId += ", "; + fst = false; + macroId += formal; + } + macroId += ')'; } - macroId += ')'; - } - if (isQtWord) - macro.definition = macroId; - else { + macro.setDefinition(macroId); + } else { // ### make me fast! const char *startOfDefinition = startOfToken(*tk); const char *endOfDefinition = startOfToken(*lastToken); - macro.definition.append(startOfDefinition, - endOfDefinition - startOfDefinition); - macro.definition.replace("\\\n", " "); - macro.definition.replace('\n', ' '); - macro.definition = macro.definition.trimmed(); + QByteArray definition(startOfDefinition, + endOfDefinition - startOfDefinition); + definition.replace("\\\n", " "); + definition.replace('\n', ' '); + macro.setDefinition(definition.trimmed()); } env.bind(macro); diff --git a/src/libs/cplusplus/pp-environment.cpp b/src/libs/cplusplus/pp-environment.cpp index 60827d4b9b2..7b93c275d3d 100644 --- a/src/libs/cplusplus/pp-environment.cpp +++ b/src/libs/cplusplus/pp-environment.cpp @@ -91,10 +91,10 @@ Macro *Environment::macroAt(unsigned index) const Macro *Environment::bind(const Macro &__macro) { - Q_ASSERT(! __macro.name.isEmpty()); + Q_ASSERT(! __macro.name().isEmpty()); Macro *m = new Macro (__macro); - m->hashcode = hash_code(m->name); + m->_hashcode = hash_code(m->name()); if (++_macro_count == _allocated_macros) { if (! _allocated_macros) @@ -110,8 +110,8 @@ Macro *Environment::bind(const Macro &__macro) if (! _hash || _macro_count > (_hash_count >> 1)) { rehash(); } else { - const unsigned h = m->hashcode % _hash_count; - m->next = _hash[h]; + const unsigned h = m->_hashcode % _hash_count; + m->_next = _hash[h]; _hash[h] = m; } @@ -121,10 +121,10 @@ Macro *Environment::bind(const Macro &__macro) Macro *Environment::remove(const QByteArray &name) { Macro macro; - macro.name = name; - macro.hidden = true; - macro.fileName = currentFile; - macro.line = currentLine; + macro.setName(name); + macro.setHidden(true); + macro.setFileName(currentFile); + macro.setLine(currentLine); return bind(macro); } @@ -198,10 +198,10 @@ Macro *Environment::resolve (const QByteArray &name) const return 0; Macro *it = _hash[hash_code (name) % _hash_count]; - for (; it; it = it->next) { - if (it->name != name) + for (; it; it = it->_next) { + if (it->name() != name) continue; - else if (it->hidden) + else if (it->isHidden()) return 0; else break; } @@ -229,8 +229,8 @@ void Environment::rehash() for (Macro **it = firstMacro(); it != lastMacro(); ++it) { Macro *m= *it; - const unsigned h = m->hashcode % _hash_count; - m->next = _hash[h]; + const unsigned h = m->_hashcode % _hash_count; + m->_next = _hash[h]; _hash[h] = m; } } diff --git a/src/libs/cplusplus/pp-macro-expander.cpp b/src/libs/cplusplus/pp-macro-expander.cpp index 6a7d7e75df8..5b0f20b66c5 100644 --- a/src/libs/cplusplus/pp-macro-expander.cpp +++ b/src/libs/cplusplus/pp-macro-expander.cpp @@ -62,7 +62,7 @@ const QByteArray *MacroExpander::resolve_formal(const QByteArray &__name) if (! (frame && frame->expanding_macro)) return 0; - const QVector<QByteArray> &formals = frame->expanding_macro->formals; + const QVector<QByteArray> formals = frame->expanding_macro->formals(); for (int index = 0; index < formals.size(); ++index) { const QByteArray formal = formals.at(index); @@ -213,7 +213,7 @@ const char *MacroExpander::operator () (const char *__first, const char *__last, } Macro *macro = env.resolve (fast_name); - if (! macro || macro->hidden || env.hide_next) + if (! macro || macro->isHidden() || env.hide_next) { if (fast_name.size () == 7 && fast_name [0] == 'd' && fast_name == "defined") env.hide_next = true; @@ -260,19 +260,19 @@ const char *MacroExpander::operator () (const char *__first, const char *__last, continue; } - if (! macro->function_like) + if (! macro->isFunctionLike()) { Macro *m = 0; - if (! macro->definition.isEmpty()) + if (! macro->definition().isEmpty()) { - macro->hidden = true; + macro->setHidden(true); QByteArray __tmp; __tmp.reserve (256); MacroExpander expand_macro (env); - expand_macro (macro->definition.constBegin (), macro->definition.constEnd (), &__tmp); + expand_macro (macro->definition(), &__tmp); generated_lines += expand_macro.lines; if (! __tmp.isEmpty ()) @@ -292,7 +292,7 @@ const char *MacroExpander::operator () (const char *__first, const char *__last, *__result += __tmp; } - macro->hidden = false; + macro->setHidden(false); } if (! m) @@ -348,9 +348,9 @@ const char *MacroExpander::operator () (const char *__first, const char *__last, pp_frame frame (macro, actuals); MacroExpander expand_macro (env, &frame); - macro->hidden = true; - expand_macro (macro->definition.constBegin (), macro->definition.constEnd (), __result); - macro->hidden = false; + macro->setHidden(true); + expand_macro (macro->definition(), __result); + macro->setHidden(false); generated_lines += expand_macro.lines; } else @@ -366,8 +366,8 @@ const char *MacroExpander::skip_argument_variadics (QVector<QByteArray> const &_ { const char *arg_end = skip_argument (__first, __last); - while (__macro->variadics && __first != arg_end && arg_end != __last && *arg_end == ',' - && (__actuals.size () + 1) == __macro->formals.size ()) + while (__macro->isVariadic() && __first != arg_end && arg_end != __last && *arg_end == ',' + && (__actuals.size () + 1) == __macro->formals().size ()) { arg_end = skip_argument (++arg_end, __last); } diff --git a/src/libs/cplusplus/pp-macro-expander.h b/src/libs/cplusplus/pp-macro-expander.h index 2959977bb15..3e6217476fa 100644 --- a/src/libs/cplusplus/pp-macro-expander.h +++ b/src/libs/cplusplus/pp-macro-expander.h @@ -88,6 +88,10 @@ namespace CPlusPlus { 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 *skip_argument_variadics (const QVector<QByteArray> &actuals, Macro *macro, const char *first, const char *last); diff --git a/src/libs/cplusplus/pp-macro.h b/src/libs/cplusplus/pp-macro.h index 9f5e32752c5..36fe7995ad2 100644 --- a/src/libs/cplusplus/pp-macro.h +++ b/src/libs/cplusplus/pp-macro.h @@ -64,59 +64,110 @@ namespace CPlusPlus { class CPLUSPLUS_EXPORT Macro { public: - QByteArray name; - QByteArray definition; - QVector<QByteArray> formals; - QByteArray fileName; - int line; - Macro *next; - unsigned hashcode; + Macro() + : _next(0), + _hashcode(0), + _line(0), + _state(0) + { } - union - { - unsigned state; + QByteArray name() const + { return _name; } - struct - { - unsigned hidden: 1; - unsigned function_like: 1; - unsigned variadics: 1; - }; - }; + void setName(const QByteArray &name) + { _name = name; } - inline Macro(): - line(0), - next(0), - hashcode(0), - state(0) - { } + QByteArray definition() const + { return _definition; } + + void setDefinition(const QByteArray &definition) + { _definition = definition; } + + QVector<QByteArray> formals() const + { return _formals; } + + void addFormal(const QByteArray &formal) + { _formals.append(formal); } + + QByteArray fileName() const + { return _fileName; } + + void setFileName(const QByteArray &fileName) + { _fileName = fileName; } + + unsigned line() const + { return _line; } + + void setLine(unsigned line) + { _line = line; } + + bool isHidden() const + { return _hidden; } + + void setHidden(bool isHidden) + { _hidden = isHidden; } + + bool isFunctionLike() const + { return _functionLike; } + + void setFunctionLike(bool isFunctionLike) + { _functionLike = isFunctionLike; } + + bool isVariadic() const + { return _variadic; } + + void setVariadic(bool isVariadic) + { _variadic = isVariadic; } QString toString() const { QString text; - if (hidden) + if (_hidden) text += QLatin1String("#undef "); else text += QLatin1String("#define "); - text += QString::fromUtf8(name.constData(), name.size()); - if (function_like) { + text += QString::fromUtf8(_name.constData(), _name.size()); + if (_functionLike) { text += QLatin1Char('('); bool first = true; - foreach (const QByteArray formal, formals) { + foreach (const QByteArray formal, _formals) { if (! first) text += QLatin1String(", "); else first = false; text += QString::fromUtf8(formal.constData(), formal.size()); } - if (variadics) + if (_variadic) text += QLatin1String("..."); text += QLatin1Char(')'); } text += QLatin1Char(' '); - text += QString::fromUtf8(definition.constData(), definition.size()); + text += QString::fromUtf8(_definition.constData(), _definition.size()); return text; } + +// ### private + Macro *_next; + unsigned _hashcode; + +private: + QByteArray _name; + QByteArray _definition; + QVector<QByteArray> _formals; + QByteArray _fileName; + unsigned _line; + + union + { + unsigned _state; + + struct + { + unsigned _hidden: 1; + unsigned _functionLike: 1; + unsigned _variadic: 1; + }; + }; }; } // namespace CPlusPlus diff --git a/src/plugins/cppeditor/cppeditor.cpp b/src/plugins/cppeditor/cppeditor.cpp index bfc9f3fd5c1..1eb298aa378 100644 --- a/src/plugins/cppeditor/cppeditor.cpp +++ b/src/plugins/cppeditor/cppeditor.cpp @@ -543,8 +543,8 @@ void CPPEditor::jumpToDefinition() foreach (const Document::MacroUse use, doc->macroUses()) { if (use.contains(endOfName - 1)) { const Macro ¯o = use.macro(); - const QString fileName = QString::fromUtf8(macro.fileName); - if (openCppEditorAt(fileName, macro.line, 0)) + const QString fileName = QString::fromUtf8(macro.fileName()); + if (openCppEditorAt(fileName, macro.line(), 0)) return; // done } } diff --git a/src/plugins/cppeditor/cpphoverhandler.cpp b/src/plugins/cppeditor/cpphoverhandler.cpp index f4060d0b60f..ba97e5a212a 100644 --- a/src/plugins/cppeditor/cpphoverhandler.cpp +++ b/src/plugins/cppeditor/cpphoverhandler.cpp @@ -271,8 +271,9 @@ void CppHoverHandler::updateHelpIdAndTooltip(TextEditor::ITextEditor *editor, in if (m_toolTip.isEmpty()) { foreach (const Document::MacroUse &use, doc->macroUses()) { if (use.contains(pos)) { - m_toolTip = use.macro().toString(); - m_helpId = use.macro().name; + const Macro m = use.macro(); + m_toolTip = m.toString(); + m_helpId = m.name(); break; } } diff --git a/src/plugins/cpptools/cppcodecompletion.cpp b/src/plugins/cpptools/cppcodecompletion.cpp index 1e54a2ae092..f8c5fe9b48a 100644 --- a/src/plugins/cpptools/cppcodecompletion.cpp +++ b/src/plugins/cpptools/cppcodecompletion.cpp @@ -741,7 +741,7 @@ void CppCodeCompletion::addMacros(const LookupContext &context) processed.insert(fn); if (Document::Ptr doc = context.document(fn)) { foreach (const Macro ¯o, doc->definedMacros()) { - macroNames.insert(macro.name); + macroNames.insert(macro.name()); } todo += doc->includedFiles(); } @@ -749,7 +749,7 @@ void CppCodeCompletion::addMacros(const LookupContext &context) foreach (const QByteArray ¯oName, macroNames) { TextEditor::CompletionItem item(this); - item.m_text = QString::fromLatin1(macroName.constData(), macroName.length()); + item.m_text = QString::fromUtf8(macroName.constData(), macroName.length()); item.m_icon = m_icons.macroIcon(); m_completions.append(item); } -- GitLab