This is the patch to fix such issue:
src/plugins/codecompletion/parser/parserthread.cpp | 166 ++++++++++++---------
1 file changed, 97 insertions(+), 69 deletions(-)
diff --git a/src/plugins/codecompletion/parser/parserthread.cpp b/src/plugins/codecompletion/parser/parserthread.cpp
index a22cb61..bd9a31f 100644
--- a/src/plugins/codecompletion/parser/parserthread.cpp
+++ b/src/plugins/codecompletion/parser/parserthread.cpp
@@ -1762,95 +1762,123 @@ void ParserThread::HandleNamespace()
}
else
{
- // for namespace aliases to be parsed, we need to tell the tokenizer
- // not to skip the usually unwanted tokens. One of those tokens is the
- // "assignment" (=).
- // we just have to remember to revert this setting below, or else problems will follow
- m_Tokenizer.SetState(tsNormal);
- wxString next = m_Tokenizer.PeekToken(); // named namespace
- if (next==ParserConsts::opbrace)
+ while (true)
{
+ // for namespace aliases to be parsed, we need to tell the tokenizer
+ // not to skip the usually unwanted tokens. One of those tokens is the
+ // "assignment" (=).
+ // we just have to remember to revert this setting below, or else problems will follow
m_Tokenizer.SetState(tsNormal);
- // use the existing copy (if any)
- Token* newToken = TokenExists(ns, m_LastParent, tkNamespace);
- if (!newToken)
- newToken = DoAddToken(tkNamespace, ns, line);
- if (!newToken)
+ wxString next = m_Tokenizer.PeekToken(); // named namespace
+ if (next==ParserConsts::opbrace)
{
- TRACE(_T("HandleNamespace() : Unable to create/add new token: ") + ns);
- return;
- }
+ m_Tokenizer.SetState(tsNormal);
- m_Tokenizer.GetToken(); // eat {
- int lineStart = m_Tokenizer.GetLineNumber();
+ // use the existing copy (if any)
+ Token* newToken = TokenExists(ns, m_LastParent, tkNamespace);
+ if (!newToken)
+ newToken = DoAddToken(tkNamespace, ns, line);
+ if (!newToken)
+ {
+ TRACE(_T("HandleNamespace() : Unable to create/add new token: ") + ns);
+ return;
+ }
- Token* lastParent = m_LastParent; // save status, will restore after DoParse()
- TokenScope lastScope = m_LastScope;
+ m_Tokenizer.GetToken(); // eat {
+ int lineStart = m_Tokenizer.GetLineNumber();
- m_LastParent = newToken;
- // default scope is: public for namespaces (actually no, but emulate it)
- m_LastScope = tsPublic;
+ Token* lastParent = m_LastParent; // save status, will restore after DoParse()
+ TokenScope lastScope = m_LastScope;
- DoParse();
+ m_LastParent = newToken;
+ // default scope is: public for namespaces (actually no, but emulate it)
+ m_LastScope = tsPublic;
- m_LastParent = lastParent;
- m_LastScope = lastScope;
-
- // update implementation file and lines of namespace.
- // this doesn't make much sense because namespaces are all over the place,
- // but do it anyway so that buffer-based parsing returns the correct values.
- newToken->m_ImplFileIdx = m_FileIdx;
- newToken->m_ImplLine = line;
- newToken->m_ImplLineStart = lineStart;
- newToken->m_ImplLineEnd = m_Tokenizer.GetLineNumber();
- }
- else if (next==ParserConsts::equals)
- {
- // namespace alias; example from cxxabi.h:
- //
- // namespace __cxxabiv1
- // {
- // ...
- // }
- // namespace abi = __cxxabiv1; <-- we 're in this case now
-
- m_Tokenizer.GetToken(); // eat '='
- m_Tokenizer.SetState(tsNormal);
+ DoParse();
- Token* lastParent = m_LastParent;
- Token* aliasToken = NULL;
+ m_LastParent = lastParent;
+ m_LastScope = lastScope;
- while (IS_ALIVE)
+ // update implementation file and lines of namespace.
+ // this doesn't make much sense because namespaces are all over the place,
+ // but do it anyway so that buffer-based parsing returns the correct values.
+ newToken->m_ImplFileIdx = m_FileIdx;
+ newToken->m_ImplLine = line;
+ newToken->m_ImplLineStart = lineStart;
+ newToken->m_ImplLineEnd = m_Tokenizer.GetLineNumber();
+
+ // the namespace body is correctly parsed
+ break;
+ }
+ else if (next==ParserConsts::equals)
{
- wxString aliasStr = m_Tokenizer.GetToken();
+ // namespace alias; example from cxxabi.h:
+ //
+ // namespace __cxxabiv1
+ // {
+ // ...
+ // }
+ // namespace abi = __cxxabiv1; <-- we 're in this case now
- // use the existing copy (if any)
- aliasToken = TokenExists(aliasStr, m_LastParent, tkNamespace);
- if (!aliasToken)
- aliasToken = DoAddToken(tkNamespace, aliasStr, line);
- if (!aliasToken)
- return;
+ m_Tokenizer.GetToken(); // eat '='
+ m_Tokenizer.SetState(tsNormal);
- if (m_Tokenizer.PeekToken() == ParserConsts::dcolon)
+ Token* lastParent = m_LastParent;
+ Token* aliasToken = NULL;
+
+ while (IS_ALIVE)
{
- m_Tokenizer.GetToken();
- m_LastParent = aliasToken;
+ wxString aliasStr = m_Tokenizer.GetToken();
+
+ // use the existing copy (if any)
+ aliasToken = TokenExists(aliasStr, m_LastParent, tkNamespace);
+ if (!aliasToken)
+ aliasToken = DoAddToken(tkNamespace, aliasStr, line);
+ if (!aliasToken)
+ return;
+
+ if (m_Tokenizer.PeekToken() == ParserConsts::dcolon)
+ {
+ m_Tokenizer.GetToken();
+ m_LastParent = aliasToken;
+ }
+ else
+ break;
}
+
+ aliasToken->m_Aliases.Add(ns);
+ m_LastParent = lastParent;
+
+ // the namespace alias statement is correctly parsed
+ break;
+ }
+ else
+ {
+ m_Tokenizer.SetState(tsNormal);
+ // probably some kind of error in code ?
+ SkipToOneOfChars(ParserConsts::semicolonopbrace);
+
+ // in case of the code:
+ //
+ // # define _GLIBCXX_VISIBILITY(V) _GLIBCXX_PSEUDO_VISIBILITY(V)
+ // namespace std _GLIBCXX_VISIBILITY(default)
+ // {
+ // class vector
+ // {
+ // size_t size();
+ // }
+ // }
+ // we still want to parse the body of the namespace, but skip the tokens before "{"
+ m_Tokenizer.UngetToken();
+ wxString peek = m_Tokenizer.PeekToken();
+ if(peek == ParserConsts::opbrace)
+ continue;
else
break;
}
-
- aliasToken->m_Aliases.Add(ns);
- m_LastParent = lastParent;
- }
- else
- {
- m_Tokenizer.SetState(tsNormal);
- // probably some kind of error in code ?
- SkipToOneOfChars(ParserConsts::semicolonopbrace);
- }
+ } // while(true)
}
}
Please test and give feedback. The method I use is: I just check which token is skipped by the SkipToOneOfChars(), if it is the "{", then I need to still parse it as the beginning of the namespace body.
The issue I see that, when I hit the dot, I see the suggestion window pop up, and disappeared quickly, so no suggestion after the dot. I'm not sure the reason. But if I continue enter the member function, like "push_", I get the correct result, see the image shot below:

The patch is in GIT style, so you need the patch utility to apply it in your local copy.