#include <iostream>
using namespace std;
class A
{
public:
static void Test()
{
}
};
struct Soo
{
int a;
};
Soo globalSoo;
int main()
{
A::Test(); //remove this line, then cc work well.
globalSoo.a = 9; //cc allways do work well here
Soo localeSoo;
localeSoo. // <-- cc do nothing
return 0;
}
CC didn't work after I input "localSoo.".
After remove the line "A::Test()", cc work well when I input "localeSoo."
//////////////
Windows XP
Code::Blocks svn5911
yes,you are right.you also can move the statement Soo localeSoo; to the top of A::Test(); since the A:: will affect the scope of localeSoo
Quote from: blueshake on December 13, 2009, 03:08:31 AM
yes,you are right.you also can move the statement Soo localeSoo; to the top of A::Test(); since the A:: will affect the scope of localeSoo
Is it a bug of CC?
Seem
Quote from: nanyu on December 13, 2009, 03:24:49 AM
Quote from: blueshake on December 13, 2009, 03:08:31 AM
yes,you are right.you also can move the statement Soo localeSoo; to the top of A::Test(); since the A:: will affect the scope of localeSoo
Is it a bug of CC?
Seem so.no time to check into it.
I do the same thing in CodeLite, everything ok. :(
Cannot reproduce with trunk. Please try the testing workspace, namely the project "function_decls". There is such a class inside with a static member function, as well as a global struct. I see all: The static (class) method, the methods after that as well as the struct and it's member variable.
So...?!
...even with the test case provided here: Works just fine... (see attached image)?!
[attachment deleted by admin]
You're missing the
A::Test(); //remove this line, then cc work well.
line
Doesn't work for me either (trunk), it also does not work if I have std::cout before the declaration of localeSoo, std::endl doesn't matter.
Quote from: oBFusCATed on December 14, 2009, 04:28:31 PM
You're missing the
A::Test(); //remove this line, then cc work well.
line
Quote from: jens on December 14, 2009, 04:57:42 PM
Doesn't work for me either (trunk), it also does not work if I have std::cout before the declaration of localeSoo, std::endl doesn't matter.
I did that, it still works (see image attached). Could you please try to reproduce with CC from trunk, and the testing project from trunk?
[attachment deleted by admin]
I'm not telling you that I've reproduced it :)
I've just spotted this accidentally.
Quote from: MortenMacFly on December 14, 2009, 05:51:47 PM
Quote from: oBFusCATed on December 14, 2009, 04:28:31 PM
You're missing the
A::Test(); //remove this line, then cc work well.
line
Quote from: jens on December 14, 2009, 04:57:42 PM
Doesn't work for me either (trunk), it also does not work if I have std::cout before the declaration of localeSoo, std::endl doesn't matter.
I did that, it still works (see image attached). Could you please try to reproduce with CC from trunk, and the testing project from trunk?
Quote from: jens on December 14, 2009, 04:57:42 PM
Doesn't work for me either (trunk), it also does not work if I have std::cout before the declaration of localeSoo, std::endl doesn't matter.
Quote from: jens on December 14, 2009, 06:12:56 PM
Quote from: jens on December 14, 2009, 04:57:42 PM
Doesn't work for me either (trunk), it also does not work if I have std::cout before the declaration of localeSoo, std::endl doesn't matter.
I realised that but thought it's a mistake because putting
std::cout before the definition of the global variable (struct) results in invalid code. I mean: It's outside any function / method then...?!
Could yu just post what exactly I have to put into my
main file to reproduce? Surely it should be valid code somehow.... otherwise I see no value in adding support to CC for parsing invalid code. :shock:
Quote from: MortenMacFly on December 14, 2009, 07:53:14 PM
Quote from: jens on December 14, 2009, 06:12:56 PM
Quote from: jens on December 14, 2009, 04:57:42 PM
Doesn't work for me either (trunk), it also does not work if I have std::cout before the declaration of localeSoo, std::endl doesn't matter.
I realised that but thought it's a mistake because putting std::cout before the definition of the global variable (struct) results in invalid code. I mean: It's outside any function / method then...?!
Could yu just post what exactly I have to put into my main file to reproduce? Surely it should be valid code somehow.... otherwise I see no value in adding support to CC for parsing invalid code. :shock:
I took nanyu's example from the first post (http://forums.next.codeblocks.org/index.php/topic,11677.msg79385.html#msg79385).
localeSoo is a locale variable, that means it's perfectly legal to have
std::cout before it.
There's no problem with global variables, but with variables, that are declared locally after the use of
std::cout or the use of the static class method
A::Test().
hi,guys
it is a bug as I knew.
you can see the debug log if turn the
debugSmartSense on.
and you will find that the variable scope of
localeSoo are different with/without statement
A::Test(); with:QuoteFindAIMatches() Looping 1 results
FindAIMatches() Match: 'localeSoo' (30032) : '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 -----
withoutQuoteFindAIMatches() Looping 1 results
FindAIMatches() Match: 'localeSoo' (30032) : 'Soo'
BreakUpComponents() Breaking up 'Soo'
BreakUpComponents() Found component: 'Soo' (SearchText)
FindAIMatches() Looking for type: 'Soo' (1 components)
FindAIMatches() Now looking under 'Global namespace'
FindAIMatches() ----- FindAIMatches - enter -----
as I said above, the
A:: will affect the scope of
localeSoo
Quote from: jens on December 14, 2009, 08:02:18 PM
I took nanyu's example from the first post (http://forums.next.codeblocks.org/index.php/topic,11677.msg79385.html#msg79385).
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...
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.
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.
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......
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.
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.
confirm it.Thanks. O(∩_∩)O~
Quote from: ollydbg on December 15, 2009, 10:45:41 AM
This patch can simply fix the bug.
Confirmed && applied. Thanks! :-)