From c3cc7cf4d8060af224ebf8ffe0f06a6f5e0d4eeb Mon Sep 17 00:00:00 2001
From: Christian Kamm <christian.d.kamm@nokia.com>
Date: Mon, 21 Dec 2009 14:47:22 +0100
Subject: [PATCH] Enhance data stored for macros and macro uses.

In preparation for finding macro uses.

* Macro: add offset and length
* MacroUse: add line
* Document: add convenience functions for finding a macro definition, use
  or undefined use at a given location.

Reviewed-by: Erik Verbruggen
---
 src/libs/cplusplus/CppDocument.cpp       | 30 +++++++++++++++++++++++-
 src/libs/cplusplus/CppDocument.h         | 19 +++++++++++----
 src/libs/cplusplus/Macro.cpp             |  2 ++
 src/libs/cplusplus/Macro.h               | 14 +++++++++++
 src/libs/cplusplus/pp-engine.cpp         |  2 ++
 src/plugins/cppeditor/cppeditor.cpp      | 17 +++++++-------
 src/plugins/cpptools/cppmodelmanager.cpp |  5 ++--
 7 files changed, 72 insertions(+), 17 deletions(-)

diff --git a/src/libs/cplusplus/CppDocument.cpp b/src/libs/cplusplus/CppDocument.cpp
index 60898924071..de81ec3dc05 100644
--- a/src/libs/cplusplus/CppDocument.cpp
+++ b/src/libs/cplusplus/CppDocument.cpp
@@ -194,9 +194,10 @@ void Document::appendMacro(const Macro &macro)
 }
 
 void Document::addMacroUse(const Macro &macro, unsigned offset, unsigned length,
+                           unsigned beginLine,
                            const QVector<MacroArgumentReference> &actuals, bool inCondition)
 {
-    MacroUse use(macro, offset, offset + length);
+    MacroUse use(macro, offset, offset + length, beginLine);
     use.setInCondition(inCondition);
 
     foreach (const MacroArgumentReference &actual, actuals) {
@@ -330,6 +331,33 @@ Symbol *Document::findSymbolAt(unsigned line, unsigned column, Scope *scope) con
     return previousSymbol;
 }
 
+const Macro *Document::findMacroDefinitionAt(unsigned line) const
+{
+    foreach (const Macro &macro, _definedMacros) {
+        if (macro.line() == line)
+            return &macro;
+    }
+    return 0;
+}
+
+const Document::MacroUse *Document::findMacroUseAt(unsigned offset) const
+{
+    foreach (const Document::MacroUse &use, _macroUses) {
+        if (use.contains(offset))
+            return &use;
+    }
+    return 0;
+}
+
+const Document::UndefinedMacroUse *Document::findUndefinedMacroUseAt(unsigned offset) const
+{
+    foreach (const Document::UndefinedMacroUse &use, _undefinedMacroUses) {
+        if (use.contains(offset))
+            return &use;
+    }
+    return 0;
+}
+
 Document::Ptr Document::create(const QString &fileName)
 {
     Document::Ptr doc(new Document(fileName));
diff --git a/src/libs/cplusplus/CppDocument.h b/src/libs/cplusplus/CppDocument.h
index e3bbda2ab10..e42ac52bb65 100644
--- a/src/libs/cplusplus/CppDocument.h
+++ b/src/libs/cplusplus/CppDocument.h
@@ -73,7 +73,8 @@ public:
 
     void appendMacro(const Macro &macro);
     void addMacroUse(const Macro &macro, unsigned offset, unsigned length,
-                     const QVector<MacroArgumentReference> &range, bool inCondition);
+                     unsigned beginLine, const QVector<MacroArgumentReference> &range,
+                     bool inCondition);
     void addUndefinedMacroUse(const QByteArray &name, unsigned offset);
 
     Control *control() const;
@@ -234,14 +235,15 @@ public:
         Macro _macro;
         QVector<Block> _arguments;
         bool _inCondition;
+        unsigned _beginLine;
 
     public:
         inline MacroUse(const Macro &macro,
-                        unsigned begin = 0,
-                        unsigned end = 0)
+                        unsigned begin, unsigned end, unsigned beginLine)
             : Block(begin, end),
               _macro(macro),
-              _inCondition(false)
+              _inCondition(false),
+              _beginLine(beginLine)
         { }
 
         const Macro &macro() const
@@ -256,6 +258,9 @@ public:
         bool isInCondition() const
         { return _inCondition; }
 
+        unsigned beginLine() const
+        { return _beginLine; }
+
     private:
         void setArguments(const QVector<Block> &arguments)
         { _arguments = arguments; }
@@ -275,7 +280,7 @@ public:
     public:
         inline UndefinedMacroUse(
                 const QByteArray &name,
-                unsigned begin = 0)
+                unsigned begin)
             : Block(begin, begin + name.length()),
               _name(name)
         { }
@@ -298,6 +303,10 @@ public:
     QList<UndefinedMacroUse> undefinedMacroUses() const
     { return _undefinedMacroUses; }
 
+    const Macro *findMacroDefinitionAt(unsigned line) const;
+    const MacroUse *findMacroUseAt(unsigned offset) const;
+    const UndefinedMacroUse *findUndefinedMacroUseAt(unsigned offset) const;
+
 private:
     Symbol *findSymbolAt(unsigned line, unsigned column, Scope *scope) const;
 
diff --git a/src/libs/cplusplus/Macro.cpp b/src/libs/cplusplus/Macro.cpp
index 36f4318a640..e7af2db9317 100644
--- a/src/libs/cplusplus/Macro.cpp
+++ b/src/libs/cplusplus/Macro.cpp
@@ -54,6 +54,8 @@ Macro::Macro()
     : _next(0),
       _hashcode(0),
       _line(0),
+      _offset(0),
+      _length(0),
       _state(0)
 { }
 
diff --git a/src/libs/cplusplus/Macro.h b/src/libs/cplusplus/Macro.h
index 683b796f5df..6e41c034b8c 100644
--- a/src/libs/cplusplus/Macro.h
+++ b/src/libs/cplusplus/Macro.h
@@ -92,6 +92,18 @@ public:
     void setLine(unsigned line)
     { _line = line; }
 
+    unsigned offset() const
+    { return _offset; }
+
+    void setOffset(unsigned offset)
+    { _offset = offset; }
+
+    unsigned length() const
+    { return _length; }
+
+    void setLength(unsigned length)
+    { _length = length; }
+
     bool isHidden() const
     { return f._hidden; }
 
@@ -129,6 +141,8 @@ private:
     QVector<QByteArray> _formals;
     QString _fileName;
     unsigned _line;
+    unsigned _offset;
+    unsigned _length;
 
     union
     {
diff --git a/src/libs/cplusplus/pp-engine.cpp b/src/libs/cplusplus/pp-engine.cpp
index 473086f08c0..39b40a397bd 100644
--- a/src/libs/cplusplus/pp-engine.cpp
+++ b/src/libs/cplusplus/pp-engine.cpp
@@ -1205,6 +1205,8 @@ void Preprocessor::processDefine(TokenIterator firstToken, TokenIterator lastTok
     macro.setFileName(env->currentFile);
     macro.setLine(env->currentLine);
     macro.setName(tokenText(*tk));
+    macro.setOffset(firstToken->offset);
+    macro.setLength(endOfToken(lastToken[- 1]) - startOfToken(*firstToken));
     ++tk; // skip T_IDENTIFIER
 
     if (tk->is(T_LPAREN) && ! tk->f.whitespace) {
diff --git a/src/plugins/cppeditor/cppeditor.cpp b/src/plugins/cppeditor/cppeditor.cpp
index 0a5edd352cd..c45f86834c2 100644
--- a/src/plugins/cppeditor/cppeditor.cpp
+++ b/src/plugins/cppeditor/cppeditor.cpp
@@ -1363,15 +1363,14 @@ CPPEditor::Link CPPEditor::findLinkAt(const QTextCursor &cursor,
         }
     } else {
         // Handle macro uses
-        foreach (const Document::MacroUse use, doc->macroUses()) {
-            if (use.contains(endOfName - 1)) {
-                const Macro &macro = use.macro();
-                link.fileName = macro.fileName();
-                link.line = macro.line();
-                link.pos = use.begin();
-                link.length = use.end() - use.begin();
-                return link;
-            }
+        const Document::MacroUse *use = doc->findMacroUseAt(endOfName - 1);
+        if (use) {
+            const Macro &macro = use->macro();
+            link.fileName = macro.fileName();
+            link.line = macro.line();
+            link.pos = use->begin();
+            link.length = use->end() - use->begin();
+            return link;
         }
     }
 
diff --git a/src/plugins/cpptools/cppmodelmanager.cpp b/src/plugins/cpptools/cppmodelmanager.cpp
index 31cab874581..a31ed64df5c 100644
--- a/src/plugins/cpptools/cppmodelmanager.cpp
+++ b/src/plugins/cpptools/cppmodelmanager.cpp
@@ -455,7 +455,7 @@ void CppPreprocessor::passedMacroDefinitionCheck(unsigned offset, const Macro &m
     if (! m_currentDoc)
         return;
 
-    m_currentDoc->addMacroUse(macro, offset, macro.name().length(),
+    m_currentDoc->addMacroUse(macro, offset, macro.name().length(), env.currentLine,
                               QVector<MacroArgumentReference>(), true);
 }
 
@@ -477,7 +477,8 @@ void CppPreprocessor::startExpandingMacro(unsigned offset,
         return;
 
     //qDebug() << "start expanding:" << macro.name() << "text:" << originalText;
-    m_currentDoc->addMacroUse(macro, offset, originalText.length(), actuals, inCondition);
+    m_currentDoc->addMacroUse(macro, offset, originalText.length(), env.currentLine,
+                              actuals, inCondition);
 }
 
 void CppPreprocessor::stopExpandingMacro(unsigned, const Macro &)
-- 
GitLab