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 &macro = 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 &macro, 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 &macroName, 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