News:

The new Release 25.03 is out! You can download binaries for Windows and many major Linux distros here .

Main Menu

CC fail after A class's static method called.

Started by nanyu, December 13, 2009, 01:51:37 AM

Previous topic - Next topic

MortenMacFly

Quote from: jens on December 14, 2009, 08:02:18 PM
I took nanyu's example from the first post.
Alright... :?
I did not scroll to the end of the text box and always just copied the upper part (excluding the actual main function). My fault. Now that I can reproduce I realised the following while debugging:

With the static method call look what the buffer looks like:
ParseLocalBlock() Block:
oo;

int main()
{
    A::Test(); //remove this line, then cc work well.

    globalSoo.a = 9; //cc  allways do work well here

    Soo localeSoo;

    localeSoo.

Without the static method call it looks like this:
ParseLocalBlock() Block:

    globalSoo.a = 9; //cc  allways do work well here

    Soo localeSoo;

    localeSoo.

...digging into it...
Compiler logging: Settings->Compiler & Debugger->tab "Other"->Compiler logging="Full command line"
C::B Manual: [url="https://www.codeblocks.org/docs/main_codeblocks_en.html"]https://www.codeblocks.org/docs/main_codeblocks_en.html[/url]
C::B FAQ: [url="https://wiki.codeblocks.org/index.php?title=FAQ"]https://wiki.codeblocks.org/index.php?title=FAQ[/url]

MortenMacFly

Quote from: MortenMacFly on December 15, 2009, 07:09:06 AM
...digging into it...
Here is the problem:
GetQueueAsNamespaceString()
returns "A::" which is wrong.
Who implemented this method??? :lol:

I am committing some more debug stuff later today... so you can try yourself once setting PARSERTHREAD_DEBUG_OUTPUT to 1 while compiling.
Compiler logging: Settings->Compiler & Debugger->tab "Other"->Compiler logging="Full command line"
C::B Manual: [url="https://www.codeblocks.org/docs/main_codeblocks_en.html"]https://www.codeblocks.org/docs/main_codeblocks_en.html[/url]
C::B FAQ: [url="https://wiki.codeblocks.org/index.php?title=FAQ"]https://wiki.codeblocks.org/index.php?title=FAQ[/url]

ollydbg

In the function AI().

The "global search scope" should added for every code completion session.

    // always add scope -1 (i.e. global namespace)
    search_scope->insert(-1);

    // find all other matches
    std::queue<ParserComponent> components;
    BreakUpComponents(parser, actual, components);

    m_LastAISearchWasGlobal = components.size() <= 1;
    if (!components.empty())
        m_LastAIGlobalSearch = components.front().component;

    // actually find all matches in selected namespaces
    for (TokenIdxSet::iterator it = search_scope->begin(); it != search_scope->end(); ++it)
    {
        if (s_DebugSmartSense)
        {
            Token* scopeToken = tree->at(*it);
            Manager::Get()->GetLogManager()->DebugLog(F(_T("AI() Parent scope: '%s' (%d)"),
                                                        scopeToken ? scopeToken->m_Name.wx_str() : _T("Global namespace"),
                                                        *it));
        }
        FindAIMatches(parser, components, result, *it, noPartialMatch, caseSensitive, true, 0xffff, search_scope);
    }

//    if(result.size()<1)//find nothing in the search_scope, add global namespace
//    {
//        if (s_DebugSmartSense)
//        {
//            Manager::Get()->GetLogManager()->DebugLog(F(_T("AI() result is zero, so, add the Global namespace")));
//
//        }
//        search_scope->insert(-1);
//        FindAIMatches(parser, components, result, -1, noPartialMatch, caseSensitive, true, 0xffff, search_scope);
//    }


For example



int aaaa;

main(){

int aaaa;

// do code completion here.
}

both the global aaaa and auto variable aaaa should be matched.

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.

ollydbg

Here is the test code:


class A
{
public:
   static void Test()
   {
   }
};

struct Soo
{
   int aaaa;
};

Soo globalSoo;

int main()
{
   A::Test(); //remove this line, then cc work well.

   globalSoo.aaaa = 9; //cc  allways do work well here

   Soo localeSoo;

   localeSoo.; // <-- cc do nothing

   return 0;
}


and the log output of auto code completion after entering the "dot" after "localeSoo"


MarkItemsByAI()
ParseUsingNamespace() Parse file scope for "using namespace"
ParseFunctionArguments() Parse function arguments
FindCurrentFunctionStart() Cached namespace='', cached proc='main'
GenerateResultSet() search 'main', parent='Global namespace (id:0, type:(null)), isPrefix=0'
ParseFunctionArguments() + Function match: main
ParseLocalBlock() Parse local block
FindCurrentFunctionStart() Cached namespace='', cached proc='main'
Parse() : parsing
DoParse() : Loop:m_Str='', token='A'
DoParse() : Loop:m_Str='', token='Test'
DoParse() : Loop:m_Str='', token='()'
DoParse() : Loop:m_Str='', token=';'
DoParse() : Loop:m_Str='', token='globalSoo'
DoParse() : Loop:m_Str='globalSoo ', token='.'
DoParse() : Loop:m_Str='', token='Soo'
DoParse() : Loop:m_Str='Soo ', token='localeSoo'
DoAddToken() : Created token='localeSoo', file_idx=0, line=6
GetActualTokenType() : Searching within m_Str='Soo'
GetActualTokenType() : Compensated m_Str='Soo'
GetActualTokenType() : Found 'Soo'
DoAddToken() : Prepending 'A::'
DoAddToken() : Added/updated token 'localeSoo' (6), type 'Soo', actual 'A::Soo'. Parent is  (-1)
DoParse() : Loop:m_Str='Soo', token=';'
DoParse() : Loop:m_Str='', token='localeSoo'
DoParse() : Loop:m_Str='localeSoo ', token='.'
ParseLocalBlock() Block:

   A::Test(); //remove this line, then cc work well.

   globalSoo.aaaa = 9; //cc  allways do work well here

   Soo localeSoo;

   localeSoo.
ParseLocalBlock() Local tokens:
ParseLocalBlock() + Soo localeSoo parent =
AI() AI enter, actual: "    localeSoo."
AI() =========================================================
AI() Doing AI for '    localeSoo.':
FindCurrentFunctionStart() Cached namespace='', cached proc='main'
GenerateResultSet() search 'main', parent='Global namespace (id:0, type:(null)), isPrefix=0'
AI() Adding search namespace: Global namespace
BreakUpComponents() Breaking up '    localeSoo.'
BreakUpComponents() Found component: 'localeSoo' (Class)
BreakUpComponents() Found component: '' (SearchText)
AI() Parent scope: 'Global namespace' (-1)
FindAIMatches() ----- FindAIMatches - enter -----
FindAIMatches() Search for localeSoo, isLast = 0
FindAIMatches() Looping 1 results
FindAIMatches() Match: 'localeSoo' (ID='6') : type='A::Soo'
BreakUpComponents() Breaking up 'A::Soo'
BreakUpComponents() Found component: 'A' (Namespace)
BreakUpComponents() Found component: 'Soo' (SearchText)
FindAIMatches() Looking for type: 'A::Soo' (2 components)
FindAIMatches() Now looking under 'Global namespace'
FindAIMatches() ----- FindAIMatches - enter -----
FindAIMatches() Search for A, isLast = 0
FindAIMatches() Looping 1 results
FindAIMatches() Match: 'A' (ID='5') : type=''
FindAIMatches() ----- FindAIMatches - enter -----
FindAIMatches() Search for Soo, isLast = 1
FindAIMatches() Looping 0 results
FindAIMatches() ----- FindAIMatches - leave -----
FindAIMatches() ----- FindAIMatches - leave -----
FindAIMatches() No types matched 'A::Soo'.
FindAIMatches() ----- FindAIMatches - enter -----
FindAIMatches() Search for , isLast = 1
FindAIMatches() Looping 0 results
FindAIMatches() ----- FindAIMatches - leave -----
FindAIMatches() ----- FindAIMatches - leave -----
AI() AI leave, returned 0 results
0 results




Note:
DoAddToken() : Added/updated token 'localeSoo' (6), type 'Soo', actual 'A::Soo'. Parent is  (-1)

This is totally wrong!! I'm trying to find the error......
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.

ollydbg

In the DoParse function.

                else if (peek==ParserConsts::dcolon)
                {
                    if (m_Str.IsEmpty())
                        m_EncounteredTypeNamespaces.push(token); // it's a type's namespace
                    else
                        m_EncounteredNamespaces.push(token);
                    m_Tokenizer.GetToken(); // eat ::
                }


So, for these statement:



    A::Test(); //remove this line, then cc work well.

    globalSoo.aaaa = 9; //cc  allways do work well here

    Soo localeSoo;

    localeSoo.; // <-- cc do nothing



A is pushed as a "typed namespace", this is wrong.

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.

ollydbg

#20
This patch can simply fix the bug.

Index: parserthread.cpp
===================================================================
--- parserthread.cpp (revision 5977)
+++ parserthread.cpp (working copy)
@@ -456,6 +456,9 @@
        if (token==ParserConsts::semicolon)
        {
            m_Str.Clear();
+            // clear typed namespace here
+            while (!m_EncounteredTypeNamespaces.empty())
+                m_EncounteredTypeNamespaces.pop();
        }
        else if (token==ParserConsts::kw_delete ||
                (token==ParserConsts::dot) ||



For example:
   A::Test(); //remove this line, then cc work well.

   globalSoo.aaaa = 9; //cc  allways do work well here

   Soo localeSoo;

   localeSoo.; // <-- cc do nothing


When we meet the first semicolon, we need to clear the typed namespace, because this is always the end of a statement.

Edit:

Is is possible to add a private function named ClearTypedNamespace() :D
Because these codes exist in many places.
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.

blueshake

Keep low and hear the sadness of little dog.
I fall in love with a girl,but I don't dare to tell her.What should I do?

MortenMacFly

Compiler logging: Settings->Compiler & Debugger->tab "Other"->Compiler logging="Full command line"
C::B Manual: [url="https://www.codeblocks.org/docs/main_codeblocks_en.html"]https://www.codeblocks.org/docs/main_codeblocks_en.html[/url]
C::B FAQ: [url="https://wiki.codeblocks.org/index.php?title=FAQ"]https://wiki.codeblocks.org/index.php?title=FAQ[/url]