Menu

#256 CC's Toolbar does not show function correctly inside the namespace scope

Undefined
open
nobody
Undefined
2015-11-19
2015-11-18
ollydbg
No

Test code:

void g_func1(){
}

void ClassA::func1(){
}

void ClassA::func2(){
}

void ClassB::func1(){
}

void ClassB::func2(){
}

namespace NamespaceA{
    void func2(){
    }

    void ClassC::func1(){
    }

    void ClassC::func2(){
    }
}

And when you look at the Toolbar, under the scope "NamespaceA::ClassC", you see only one member.

Debug the data, I see inside the function void CodeCompletion::ParseFunctionsAndFillToolbar()
If I try to see the value of m_FunctionsScope. I get such results from GDB.

std::vector of length 8, capacity 8 = {
{StartLine = 0, EndLine = 1, ShortName = L"g_func1", Name = L"g_func1() : void", Scope = L"<global>"},
{StartLine = 3, EndLine = 4, ShortName = L"func1", Name = L"func1() : void", Scope = L"ClassA::"},
{StartLine = 6, EndLine = 7, ShortName = L"func2", Name = L"func2() : void", Scope = L"ClassA::"},
{StartLine = 9, EndLine = 10, ShortName = L"func1", Name = L"func1() : void", Scope = L"ClassB::"},
{StartLine = 12, EndLine = 13, ShortName = L"func2", Name = L"func2() : void", Scope = L"ClassB::"},
{StartLine = 14, EndLine = 23, ShortName = L"", Name = L"", Scope = L"NamespaceA::"},
{StartLine = 22, EndLine = 23, ShortName = L"func2", Name = L"func2() : void", Scope = L"NamespaceA::"},
{StartLine = 19, EndLine = 20, ShortName = L"func1", Name = L"func1() : void", Scope = L"NamespaceA::ClassC::"}
}

You see, there are one token which has the name L"". And you also see one token under the scope "NamespaceA::ClassC"

Discussion

  • ollydbg

    ollydbg - 2015-11-18

    I just create a simple test file named ccc_ticket_256.cpp

    namespace NamespaceA{
        void func2(){
        }
    
        void ClassC::func1(){
        }
    
        void ClassC::func2(){
        }
    }
    //NamespaceA::func  //func2
    //NamespaceA::ClassC::func  //func1,func2
    

    And run under cctest, I get:

    ********************************************************
      Testing in file: F:\cb_sf_git\trunk\src\plugins\codecompletion\testing\ccc_ticket_256.cpp
    ********************************************************
    -PASS: NamespaceA::ClassC::func  func1
    *FAIL: NamespaceA::ClassC::func  func2
    -PASS: NamespaceA::func  func2
    --------------------------------------------------------
    Total 3 tests, 2 PASS, 1 FAIL
    --------------------------------------------------------
    

    Note that if I change the test file to the below: (change the first "func2" to "func3")

    namespace NamespaceA{
        void func3(){
        }
    
        void ClassC::func1(){
        }
    
        void ClassC::func2(){
        }
    }
    //NamespaceA::func  //func3
    //NamespaceA::ClassC::func  //func1,func2
    

    And I get the good result

    ********************************************************
      Testing in file: F:\cb_sf_git\trunk\src\plugins\codecompletion\testing\ccc_ticket_256.cpp
    ********************************************************
    -PASS: NamespaceA::ClassC::func  func1
    -PASS: NamespaceA::ClassC::func  func2
    -PASS: NamespaceA::func  func3
    --------------------------------------------------------
    Total 3 tests, 3 PASS, 0 FAIL
    --------------------------------------------------------
    

    Not sure the reason of such bug.

     
  • ollydbg

    ollydbg - 2015-11-18

    Inside the function: DoAddToken()

        // check for implementation member function
        if (!newToken && !m_EncounteredNamespaces.empty())
        {
            localParent = FindTokenFromQueue(m_EncounteredNamespaces, 0, true, m_LastParent);
            if (localParent)
                newToken = TokenExists(newname, baseArgs, localParent, kind);
            if (newToken)
            {
                TRACE(_T("DoAddToken() : Found token (member function)."));
                // Special handling function implementation here, a function declaration and its
                // function implementation share one Token. But the function implementation's arguments
                // should take precedence, as they will be used for code-completion.
                if (isImpl && (kind & tkAnyFunction))
                    newToken->m_Args = args;
            }
        }
    
        // none of the above; check for token under parent
        if (!newToken)
        {
            newToken = TokenExists(newname, baseArgs, m_LastParent, kind);
            if (newToken)
            {
                TRACE(_T("DoAddToken() : Found token (parent)."));
                // Special handling function implementation, see comments above
                if (isImpl && (kind & tkAnyFunction))
                    newToken->m_Args = args;
            }
        }
    

    When adding the third function ClassC::func2, the first piece of the above code failed, and at this time, we should create a Token under the localParent parent. Note at this time, the localParent is the "NamespaceA::ClassC". and the m_LastParent is the "NamespaceA".

     
  • ollydbg

    ollydbg - 2015-11-18

    When searching for the third function, which is NamespaceA::ClassC::func2, the first token is wrongly located by the following code, which is actually NamespaceA::func2. I think the below code is just used to workaround some issues.

        // none of the above; check for token under parent
        if (!newToken)
        {
            newToken = TokenExists(newname, baseArgs, m_LastParent, kind);
            if (newToken)
            {
                TRACE(_T("DoAddToken() : Found token (parent)."));
                // Special handling function implementation, see comments above
                if (isImpl && (kind & tkAnyFunction))
                    newToken->m_Args = args;
            }
        }
    
     

    Last edit: ollydbg 2015-11-18
  • ollydbg

    ollydbg - 2015-11-18
    SHA-1: 1327f06d256263b1bba7f180045c343a2396f4ae
    
    * * Improvements in code-completion parsing.
    * Typedefs parsing in code-completion is back again.
    
    git-svn-id: http://svn.code.sf.net/p/codeblocks/code/trunk@2967 2a5c6006-c6dd-42ca-98ab-0921f2732cef
    

    This is the first code snippet to add the code(in year 2006)

        // none of the above; check for token under parent
        if (!newToken)
            newToken = TokenExists(name, m_pLastParent, kind);
    

    Which means if we try to find ClassC::func2 inside the NamespaceA, but at this time, func2 token is not created, we will try to search the "func2" under NamespaceA, it is totally wrong, as it will overwrite the already added token NamespaceA::func2.

    An idea is just to remove such piece of code, but it could cause other bugs...

     
  • ollydbg

    ollydbg - 2015-11-18

    An idea is just to remove such piece of code, but it could cause other bugs...

    I just run the cctest on all the test cases, and I don't see any regressions if I comment out:

        #if 0
        // none of the above; check for token under parent
        if (!newToken)
        {
            newToken = TokenExists(newname, baseArgs, m_LastParent, kind);
            if (newToken)
            {
                TRACE(_T("DoAddToken() : Found token (parent)."));
                // Special handling function implementation, see comments above
                if (isImpl && (kind & tkAnyFunction))
                    newToken->m_Args = args;
            }
        }
        #endif // 0
    
     
  • ollydbg

    ollydbg - 2015-11-19
    namespace NamespaceA{
        void func2(){
        }
    
        class ClassC {
            void func1(){
            }
    
            void func2(){
            }
        }
        void ClassC::func1(){
        }
    
        void ClassC::func2(){
        }
    
    }
    //NamespaceA::func  //func2
    //NamespaceA::ClassC::func  //func1,func2
    

    This test works OK, normally, I think a class definition(the above class ClassC definition) should put before the function implementation.

     

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.