Author Topic: Several improvements to Code Completion plugin  (Read 111249 times)

Offline Huki

  • Multiple posting newcomer
  • *
  • Posts: 95
Re: Several improvements to Code Completion plugin
« Reply #105 on: June 26, 2014, 08:22:19 pm »
Thanks for the commit. 2 patches for parsing bugs:

1) Don't skip successive opening or closing brackets. For example, see any occurrence of "GetConfigManager(_T("code_completion"))->XXX" in CodeCompletion.cpp,
Code: [Select]
void CodeCompletion::UpdateToolBar()
{
    bool showScope = Manager::Get()->GetConfigManager(_T("code_completion"))->ReadBool(_T("/scope_filter"), true);
                                                                              ^^^^^^^^________________________________ // cannot use CC on ReadBool
    [...]

Fix:
Code: [Select]
From dcc4ea033b398329915a900faada2d1254261313 Mon Sep 17 00:00:00 2001
From: huki <gk7huki@gmail.com>
Date: Tue, 24 Jun 2014 08:11:28 +0530
Subject: [PATCH 04/30] CC: fix parser successive brackets

---
 src/plugins/codecompletion/nativeparser_base.cpp | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/src/plugins/codecompletion/nativeparser_base.cpp b/src/plugins/codecompletion/nativeparser_base.cpp
index 89e252c..3c5cf75 100644
--- a/src/plugins/codecompletion/nativeparser_base.cpp
+++ b/src/plugins/codecompletion/nativeparser_base.cpp
@@ -561,6 +561,9 @@ unsigned int NativeParserBase::FindCCTokenStart(const wxString& line)
 
                     if (IsClosingBracket(startAt, line))
                         ++nest;
+                    //NOTE: do not skip successive opening brackets.
+                    if (IsOpeningBracket(startAt, line))
+                        --nest;
                 }
 
                 startAt = BeforeToken(startAt, line);
@@ -650,6 +653,15 @@ wxString NativeParserBase::GetNextCCToken(const wxString& line,
 
             if (IsOpeningBracket(startAt, line))
                 ++nest;
+            //NOTE: do not skip successive closing brackets. Eg,
+            // "GetConfigManager(_T("code_completion"))->ReadBool"
+            //                                        ^
+            if (IsClosingBracket(startAt, line))
+            {
+                --nest;
+                if (nest == 0)
+                    ++startAt;
+            }
         }
     }
     if (IsOperatorBegin(startAt, line))
--
1.9.4.msysgit.0


2) In DoParse(), when parsing "else" we try to eat the arguments. It breaks support for "else-if" (we will end up eating the "if"), and anyway there is no need to skip anything after "else".
Code: [Select]
From 900b6df9304e30455438c362f2757c88bd690494 Mon Sep 17 00:00:00 2001
From: huki <gk7huki@gmail.com>
Date: Tue, 24 Jun 2014 09:20:07 +0530
Subject: [PATCH 26/30] CC: parser: fixed 'else-if'

---
 src/plugins/codecompletion/parser/parserthread.cpp | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/src/plugins/codecompletion/parser/parserthread.cpp b/src/plugins/codecompletion/parser/parserthread.cpp
index f87b1b7..938a134 100644
--- a/src/plugins/codecompletion/parser/parserthread.cpp
+++ b/src/plugins/codecompletion/parser/parserthread.cpp
@@ -714,8 +714,9 @@ void ParserThread::DoParse()
             {
                 if (!m_Options.useBuffer || m_Options.bufferSkipBlocks)
                     SkipToOneOfChars(ParserConsts::semicolonclbrace, true, true);
-                else
-                    m_Tokenizer.GetToken(); // skip arguments
+                //NOTE: this breaks support for 'else if' !
+                // else
+                //     m_Tokenizer.GetToken(); // skip arguments
                 m_Str.Clear();
             }
             else if (token == ParserConsts::kw_enum)
--
1.9.4.msysgit.0


Offline ollydbg

  • Developer
  • Lives here!
  • *****
  • Posts: 5220
  • OpenCV and Robotics
    • Chinese OpenCV forum moderator
Re: Several improvements to Code Completion plugin
« Reply #106 on: July 16, 2014, 08:51:14 am »
Thanks for the commit. 2 patches for parsing bugs:
...snip...
Hi, sorry for the late reply, I'm busy those days.
I tested and committed the two patches(rev9846 and rev9847), thanks for your contribution. ;)
If some piece of memory should be reused, turn them to variables (or const variables).
If some piece of operations should be reused, turn them to functions.
If they happened together, then turn them to classes.

Offline Huki

  • Multiple posting newcomer
  • *
  • Posts: 95
Re: Several improvements to Code Completion plugin
« Reply #107 on: August 24, 2014, 01:01:01 pm »
Thanks for the commit. 2 patches for parsing bugs:
...snip...
Hi, sorry for the late reply, I'm busy those days.
I tested and committed the two patches(rev9846 and rev9847), thanks for your contribution. ;)
Hi, thanks for the commit.

A small update to the undo token behavior fix.
There was some code I added to CalcConditionExpression() by mistake (assuming it is called directly inside SkipUnwanted()). See my comments below:
[...] A preprocessor condition is hit in SkipUnwanted() and we run CalcConditionExpression(). [...] We need to reset Undo and Saved positions to the proper place after CalcConditionExpression() (because it's not only expanding the macro but also parsing it fully, so we need to reset right after the preprocessor line has ended).

In fact the function which is called in SkipUnwanted() is HandleConditionPreprocessor(), that's where we should reset the undo and savetoken values. If we reset them in CalcConditionExpression() we will always reset to the start of the first conditional block even if it is false.
Code: [Select]
#if 0| <---- adding the code in CalcConditionExpression() will reset undo vars to here which is wrong
// inactive code
#else| <---- adding the code in HandleConditionPreprocessor() will reset undo vars to here
// active code
#endif

I've also added a small note to avoid recursive call to PeekToken() (which shouldn't really happen).


Here's the patch:
Code: [Select]
From fd5af3421e85d9eff782c63ab07736cadf04d45c Mon Sep 17 00:00:00 2001
From: huki <gk7huki@gmail.com>
Date: Fri, 4 Jul 2014 02:32:16 +0530
Subject: CC: update to undo token fix

---
 src/plugins/codecompletion/parser/tokenizer.cpp | 13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/src/plugins/codecompletion/parser/tokenizer.cpp b/src/plugins/codecompletion/parser/tokenizer.cpp
index 2bfb113..4a8f0cb 100644
--- a/src/plugins/codecompletion/parser/tokenizer.cpp
+++ b/src/plugins/codecompletion/parser/tokenizer.cpp
@@ -1043,7 +1043,6 @@ wxString Tokenizer::PeekToken()
 {
     if (!m_PeekAvailable)
     {
-        m_PeekAvailable = true;
         //NOTE: The m_Saved... vars will be reset to the correct position
         // as necessary when a ReplaceBufferText() is done.
         m_SavedTokenIndex   = m_TokenIndex;
@@ -1055,6 +1054,7 @@ wxString Tokenizer::PeekToken()
         else
             m_PeekToken.Clear();
 
+        m_PeekAvailable     = true; //NOTE: Moved after DoGetToken() to avoid recursive PeekToken() calls.
         m_PeekTokenIndex    = m_TokenIndex;
         m_PeekLineNumber    = m_LineNumber;
         m_PeekNestLevel     = m_NestLevel;
@@ -1407,11 +1407,6 @@ bool Tokenizer::CalcConditionExpression(bool checkResult)
     // reset tokenizer's functionality
     m_State = oldState;
 
-    // reset undo token
-    m_SavedTokenIndex   = m_UndoTokenIndex = m_TokenIndex;
-    m_SavedLineNumber   = m_UndoLineNumber = m_LineNumber;
-    m_SavedNestingLevel = m_UndoNestLevel  = m_NestLevel;
-
     exp.ConvertInfixToPostfix();
     if (exp.CalcPostfix())
     {
@@ -1697,6 +1692,11 @@ void Tokenizer::HandleConditionPreprocessor(const PreprocessorType type)
         default:
             break;
     }
+
+    // reset undo token
+    m_SavedTokenIndex   = m_UndoTokenIndex = m_TokenIndex;
+    m_SavedLineNumber   = m_UndoLineNumber = m_LineNumber;
+    m_SavedNestingLevel = m_UndoNestLevel  = m_NestLevel;
 }
 
 void Tokenizer::SplitArguments(wxArrayString& results)
@@ -1826,6 +1826,7 @@ bool Tokenizer::ReplaceBufferText(const wxString& target, bool updatePeekToken)
     {
         m_PeekAvailable = false;
         PeekToken(); // NOTE (ollydbg#1#): chance of recursive call of this function
+                     // NOTE (huki): updated PeekToken() to prevent unnecessary recursive call
     }
 
     return true;
--
1.9.4.msysgit.0

« Last Edit: August 24, 2014, 01:18:18 pm by Huki »

Offline ollydbg

  • Developer
  • Lives here!
  • *****
  • Posts: 5220
  • OpenCV and Robotics
    • Chinese OpenCV forum moderator
Re: Several improvements to Code Completion plugin
« Reply #108 on: August 27, 2014, 05:54:59 am »
Hi, Huki, thanks for the contribution, today, I looked at you patch, and I think that

Code: [Select]
    // Update the peek token
    if (m_PeekAvailable && updatePeekToken)
    {
        m_PeekAvailable = false;
        PeekToken(); // NOTE (ollydbg#1#): chance of recursive call of this function
                     // NOTE (huki): updated PeekToken() to prevent unnecessary recursive call
    }
I think here, with your patch, the m_PeekAvailable should always be false in the if condition, right?
If some piece of memory should be reused, turn them to variables (or const variables).
If some piece of operations should be reused, turn them to functions.
If they happened together, then turn them to classes.

Offline ollydbg

  • Developer
  • Lives here!
  • *****
  • Posts: 5220
  • OpenCV and Robotics
    • Chinese OpenCV forum moderator
Re: Several improvements to Code Completion plugin
« Reply #109 on: August 27, 2014, 10:01:55 am »
Hi, Huki, thanks for the contribution, today, I looked at you patch, and I think that

Code: [Select]
   // Update the peek token
    if (m_PeekAvailable && updatePeekToken)
    {
        m_PeekAvailable = false;
        PeekToken(); // NOTE (ollydbg#1#): chance of recursive call of this function
                     // NOTE (huki): updated PeekToken() to prevent unnecessary recursive call
    }
I think here, with your patch, the m_PeekAvailable should always be false in the if condition, right?
Oh, I was wrong, I just debug the code and found that the function bool Tokenizer::ReplaceBufferText(const wxString& target, bool updatePeekToken) will be called from void ParserThread::HandleMacroExpansion(int id, const wxString &peek), which is called from DoParse() function.

I understand you idea, that is the function Tokenizer::ReplaceBufferText() can also be called inside the PeekToken() function.
The old way (without your patch) of PeekToken() could be:
Code: [Select]
first set the flag: m_PeekAvailable = true;
some function will call ReplaceBufferText();
Thus, the condition "if (m_PeekAvailable && updatePeekToken)" is true, and we comes with a recursive call to PeekToken().

Now, in your patch, you set the flag a bit later, which are something like:
Code: [Select]
some function will call ReplaceBufferText();
set the flag: m_PeekAvailable = true;
Here, the if condition is always false, so we can avoid the recursive call to PeekToken().

Question: what happens about old way (without your patch), do we enter a infinite recursive call to PeekToken()?

« Last Edit: August 27, 2014, 10:04:26 am by ollydbg »
If some piece of memory should be reused, turn them to variables (or const variables).
If some piece of operations should be reused, turn them to functions.
If they happened together, then turn them to classes.

Offline Huki

  • Multiple posting newcomer
  • *
  • Posts: 95
Re: Several improvements to Code Completion plugin
« Reply #110 on: August 27, 2014, 11:45:51 am »
Yes, the m_PeekAvailable may be true in some cases, eg:
Code: [Select]
In DoParse():
    PeekToken(); // sets m_PeekAvailable to true
    [...]
    ReplaceBufferText(); // m_PeekAvailable is true, so call PeekToken() and update m_PeekToken

My patch makes sure that m_PeekAvailable is not true if we are already inside PeekToken(), so a useless recursive call is avoided. i.e.,
Code: [Select]
PeekToken():
  -> DoGetToken():
    -> ReplaceMacro():
      -> ReplaceBufferText(); // no need for recursive call to PeekToken() as we are already going to
                              // update m_PeekToken after returning from DoGetToken()
      -> DoGetToken(); // recurse DoGetToken()

  -> m_PeekAvailable = true; // got m_PeekToken, now set this to true

Question: what happens about old way (without your patch), do we enter a infinite recursive call to PeekToken()?
I don't think there is an infinite recursive call, but generally PeekToken and GetToken are not supposed to recurse, because they update class variables (GetToken() updates Undo__ vars and PeekToken() updates Save__ vars), so a recursive call would overwrite these values, which is bad. So we should first get the peek token (i.e., m_PeekToken = DoGetToken(); ), then set m_PeekAvailable = true;
« Last Edit: August 27, 2014, 11:55:56 am by Huki »

Offline SteelRat

  • Multiple posting newcomer
  • *
  • Posts: 45
  • Stainless
Re: Several improvements to Code Completion plugin
« Reply #111 on: August 27, 2014, 07:28:51 pm »
Code completion ignores code like this:
Code: [Select]
#if defined(TOUCHSCREEN)
void InputManager::ConvertTouch(sf::Event& event)
{
...
}
#endif

Parser does not understand "final" correctly?
An checkboxes in "Editor->Code complition->C++ parser" "Parse preproceccor..." "Parse macros..." are not saving their state. They are checked always.
« Last Edit: August 27, 2014, 09:12:40 pm by SteelRat »

Offline ollydbg

  • Developer
  • Lives here!
  • *****
  • Posts: 5220
  • OpenCV and Robotics
    • Chinese OpenCV forum moderator
Re: Several improvements to Code Completion plugin
« Reply #112 on: August 28, 2014, 03:09:50 am »
Yes, the m_PeekAvailable may be true in some cases, eg:
Code: [Select]
In DoParse():
    PeekToken(); // sets m_PeekAvailable to true
    [...]
    ReplaceBufferText(); // m_PeekAvailable is true, so call PeekToken() and update m_PeekToken

My patch makes sure that m_PeekAvailable is not true if we are already inside PeekToken(), so a useless recursive call is avoided. i.e.,
Code: [Select]
PeekToken():
  -> DoGetToken():
    -> ReplaceMacro():
      -> ReplaceBufferText(); // no need for recursive call to PeekToken() as we are already going to
                              // update m_PeekToken after returning from DoGetToken()
      -> DoGetToken(); // recurse DoGetToken()

  -> m_PeekAvailable = true; // got m_PeekToken, now set this to true

Question: what happens about old way (without your patch), do we enter a infinite recursive call to PeekToken()?
I don't think there is an infinite recursive call, but generally PeekToken and GetToken are not supposed to recurse, because they update class variables (GetToken() updates Undo__ vars and PeekToken() updates Save__ vars), so a recursive call would overwrite these values, which is bad. So we should first get the peek token (i.e., m_PeekToken = DoGetToken(); ), then set m_PeekAvailable = true;

Hi, Huki, very clear explanation. I have committed your patch to trunk now with some comments added. Thank you very much for the contribution. :)
If some piece of memory should be reused, turn them to variables (or const variables).
If some piece of operations should be reused, turn them to functions.
If they happened together, then turn them to classes.

Offline ollydbg

  • Developer
  • Lives here!
  • *****
  • Posts: 5220
  • OpenCV and Robotics
    • Chinese OpenCV forum moderator
Re: Several improvements to Code Completion plugin
« Reply #113 on: August 28, 2014, 03:32:36 am »
Code completion ignores code like this:
Code: [Select]
#if defined(TOUCHSCREEN)
void InputManager::ConvertTouch(sf::Event& event)
{
...
}
#endif

I just test a minimal sample code
Code: [Select]
#define TOUCHSCREEN 1
#if defined(TOUCHSCREEN)
void InputManager::ConvertTouch(sf::Event& event)
{

}
#endif
It works fine here, I can see the member function symbols in code completion plugin's symbol browser tree.



Code: [Select]
Parser does not understand "final" correctly?Yeah, you can write a feature request in Sourceforge as I can see.

Quote
An checkboxes in "Editor->Code complition->C++ parser" "Parse preproceccor..." "Parse macros..." are not saving their state. They are checked always.
Works fine here. (WinXP, latest nightly build C::B)
If some piece of memory should be reused, turn them to variables (or const variables).
If some piece of operations should be reused, turn them to functions.
If they happened together, then turn them to classes.

Offline SteelRat

  • Multiple posting newcomer
  • *
  • Posts: 45
  • Stainless
Re: Several improvements to Code Completion plugin
« Reply #114 on: August 28, 2014, 07:09:51 am »
Thanks, I'll try other ways or with new .conf file.

Offline Huki

  • Multiple posting newcomer
  • *
  • Posts: 95
Re: Several improvements to Code Completion plugin
« Reply #115 on: August 28, 2014, 08:33:33 pm »
Here is a patch that adds support for:
1) Nested unnamed (struct or union) within unnamed: all the members should be invokable from the parent class or struct.
2) Show tooltips for members of unnamed / enum within class invoked directly (also for nested cases).

Patch:
Code: [Select]
From ef154d4ef188d77b10bc7ff55d5bcb54b18d66a2 Mon Sep 17 00:00:00 2001
From: huki <gk7huki@gmail.com>
Date: Tue, 24 Jun 2014 08:15:00 +0530
Subject: CC: Support unnamed or enum within class, recursive

---
 src/plugins/codecompletion/nativeparser_base.cpp | 13 +++++++--
 src/plugins/codecompletion/nativeparser_base.h   | 34 +++++++++++++++++++++++-
 2 files changed, 44 insertions(+), 3 deletions(-)

diff --git a/src/plugins/codecompletion/nativeparser_base.cpp b/src/plugins/codecompletion/nativeparser_base.cpp
index e85b8be..5f04b0c 100644
--- a/src/plugins/codecompletion/nativeparser_base.cpp
+++ b/src/plugins/codecompletion/nativeparser_base.cpp
@@ -1411,7 +1411,14 @@ size_t NativeParserBase::GenerateResultSet(TokenTree*          tree,
                 {
                     const Token* token = tree->at(*it);
                     // check whether its under the parentIdx
-                    if (token && (token->m_ParentIndex == parentIdx))
+                    //NOTE: check for unnamed or enum inside class.
+                    // eg, 'ParserCommon::ParserState::ptCreateParser' should be accessed as 'ParserCommon::ptCreateParser'.
+                    // Here, token is ptCreateParser and parentIdx is ParserCommon, so 'token->m_ParentIndex == parentIdx'
+                    // is false. Now, we iterate over the children of parentIdx and check if any of them is unnamed or enum
+                    // and match with token->m_ParentIndex. Thus if we confirm that 'token' is a child of unnamed or enum
+                    // (i.e., m_ParentIndex), we add the token to result.
+                    if (token && ((token->m_ParentIndex == parentIdx)
+                              || IsChildOfUnnamedOrEnum(tree, token->m_ParentIndex, parentIdx)))
                         result.insert(*it);
 
                     // "result" will become the search scope for the next loop, so
@@ -1437,7 +1444,9 @@ size_t NativeParserBase::GenerateResultSet(TokenTree*          tree,
                                   ancestorIterator != tokenParent->m_Ancestors.end();
                                   ++ancestorIterator )
                             {
-                                if (token->m_ParentIndex == (*ancestorIterator)) //matched
+                                //NOTE: check for unnamed or enum inside class (see note above).
+                                if (token && ((token->m_ParentIndex == (*ancestorIterator)) //matched
+                                          || IsChildOfUnnamedOrEnum(tree, token->m_ParentIndex, (*ancestorIterator))))
                                     result.insert(*it);
                             }
                         }
diff --git a/src/plugins/codecompletion/nativeparser_base.h b/src/plugins/codecompletion/nativeparser_base.h
index 3141e61..da60fea 100644
--- a/src/plugins/codecompletion/nativeparser_base.h
+++ b/src/plugins/codecompletion/nativeparser_base.h
@@ -495,7 +495,12 @@ private:
                 if (    tokenChild
                     && (parent->m_TokenKind == tkClass || tokenChild->m_Scope != tsPrivate) )
                 {
-                    result.insert(*it);
+                    //NOTE: recurse (eg: class A contains struct contains union or enum)
+                    if ( !AddChildrenOfUnnamed(tree, tokenChild, result) )
+                    {
+                        result.insert(*it);
+                        AddChildrenOfEnum(tree, tokenChild, result);
+                    }
                 }
             }
             return true;
@@ -520,6 +525,33 @@ private:
         }
         return false;
     }
+
+    bool IsChildOfUnnamedOrEnum(TokenTree* tree, const int targetIdx, const int parentIdx)
+    {
+        if (targetIdx == parentIdx)
+            return true;
+        if (parentIdx == -1)
+            return false;
+
+        Token* parent = tree->at(parentIdx);
+        if (parent && (parent->m_TokenKind & tkClass))
+        {
+            for (TokenIdxSet::const_iterator it = parent->m_Children.begin();
+                                             it != parent->m_Children.end(); ++it)
+            {
+                Token* token = tree->at(*it);
+                if (token && (((token->m_TokenKind & tkClass)
+                                && (token->m_IsAnonymous == true))
+                             || (token->m_TokenKind & tkEnum)))
+                {
+                    if ((targetIdx == (*it)) || IsChildOfUnnamedOrEnum(tree, targetIdx, (*it)))
+                        return true;
+                }
+            }
+        }
+        return false;
+    }
+
 
     /**  loop on the input Token index set (source), add all its public constructors to output Token index set (dest) */
     void AddConstructors(TokenTree *tree, const TokenIdxSet& source, TokenIdxSet& dest);
--
1.9.4.msysgit.0


Code to test:
Code: [Select]
class ClassA
{
public:
    int a;
    struct A
    {
        int c;
    } z;
    struct
    {
        int s;
        union
        {
            int u;
            short v;
        };
        enum EnumS
        {
            STRUCT_A,
            STRUCT_B,
        };
    };

    enum
    {
        UNNAMED_A,
        UNNAMED_B
    };
    enum EnumA
    {
        ENUM_A,
        ENUM_B
    };
};

// Hovering on following member variables should
// show tooltip: a, s, u, v, all the enums like STRUCT_A, etc.
ClassA::a; // replace 'a' with other members listed above

// However ClassA::c is illegal and should not display tooltip.
ClassA::c; // no tip
ClassA::A::c; // should show tip

// Code completion should show all legal members.
ClassA:: // cursor here

« Last Edit: August 29, 2014, 08:51:32 am by Huki »

Offline SteelRat

  • Multiple posting newcomer
  • *
  • Posts: 45
  • Stainless
Re: Several improvements to Code Completion plugin
« Reply #116 on: August 29, 2014, 10:34:53 pm »
I just test a minimal sample code
Code: [Select]
#define TOUCHSCREEN 1
#if defined(TOUCHSCREEN)
void InputManager::ConvertTouch(sf::Event& event)
{

}
#endif
It works fine here, I can see the member function symbols in code completion plugin's symbol browser tree.

Here it is, macros highlighting for inactive code is ON, TEST defined in Compiler's global defines. Parser knows about it and about TEST2, but it can't find declaration for TEST2 and TEST3.

Offline ollydbg

  • Developer
  • Lives here!
  • *****
  • Posts: 5220
  • OpenCV and Robotics
    • Chinese OpenCV forum moderator
Re: Several improvements to Code Completion plugin
« Reply #117 on: August 30, 2014, 08:11:00 am »
Here it is, macros highlighting for inactive code is ON
This option is not related to CC plugin.


Quote
TEST defined in Compiler's global defines. Parser knows about it and about TEST2, but it can't find declaration for TEST2 and TEST3.

Confirm this bug. It looks like CC doesn't collect the macro definitions if it is defined in "Compiler's global defines".

Note that the below code works OK
Code: [Select]
#define TEST

#ifdef TEST
    #define TEST2
#endif // TEST

#ifdef TEST2
    #define TEST3
#endif // TEST2



If some piece of memory should be reused, turn them to variables (or const variables).
If some piece of operations should be reused, turn them to functions.
If they happened together, then turn them to classes.

Offline MortenMacFly

  • Administrator
  • Lives here!
  • *****
  • Posts: 9493
Re: Several improvements to Code Completion plugin
« Reply #118 on: August 30, 2014, 11:47:55 am »
Confirm this bug. It looks like CC doesn't collect the macro definitions if it is defined in "Compiler's global defines".
I've noticed this, too. Its even worse: CC does not honour if you've setup something like "target options only" or alike. Also the order of global compile/project/target settings is not considered which may override #defines. Collecting existing macros could need some improvements.

I have it on my todo list but didn't look into it so far...
Compiler logging: Settings->Compiler & Debugger->tab "Other"->Compiler logging="Full command line"
C::B Manual: http://www.codeblocks.org/docs/main_codeblocks_en.html
C::B FAQ: http://wiki.codeblocks.org/index.php?title=FAQ

Offline ollydbg

  • Developer
  • Lives here!
  • *****
  • Posts: 5220
  • OpenCV and Robotics
    • Chinese OpenCV forum moderator
Re: Several improvements to Code Completion plugin
« Reply #119 on: August 30, 2014, 11:57:05 am »
Confirm this bug. It looks like CC doesn't collect the macro definitions if it is defined in "Compiler's global defines".
I've noticed this, too. Its even worse: CC does not honour if you've setup something like "target options only" or alike.
I think CC just collect all the target options, we have discussed this some times ago in this thread, Huki has a patch to reparse the project if an active target changes, but I have some concerns about this option.

Quote
Also the order of global compile/project/target settings is not considered which may override #defines. Collecting existing macros could need some improvements.
We have already a function bool NativeParser::AddProjectDefinedMacros(cbProject* project, ParserBase* parser), which collects macro definitions for a whole project. Adding the global compiler options should be similar.
If some piece of memory should be reused, turn them to variables (or const variables).
If some piece of operations should be reused, turn them to functions.
If they happened together, then turn them to classes.