you can download the cc-brach version and compile it by yourself.
or you can apply this patch.
note: it work for me , but i am not sure whether it will work for you ,just make a copy when you try to apply this patch.good luck.
Index: parserthread.cpp
===================================================================
--- parserthread.cpp (revision 5730)
+++ parserthread.cpp (working copy)
@@ -465,8 +465,10 @@
DoParse(); // time for recursion ;)
}
else
- SkipToOneOfChars(ParserConsts::semicolon); // skip externs
-// m_Tokenizer.UngetToken(); // nope, return the token back...
+ {
+ // do nothing, just skip keyword "extern", otherwise uncomment:
+ // SkipToOneOfChars(ParserConsts::semicolon); // skip externs
+ }
m_Str.Clear();
}
else if (token.StartsWith(ParserConsts::kw__asm))
@@ -519,7 +521,7 @@
{
m_Str.Clear();
if (m_Options.handleClasses)
- HandleClass();
+ HandleClass(ctClass);
else
SkipToOneOfChars(ParserConsts::semicolonclbrace, true);
}
@@ -527,7 +529,7 @@
{
m_Str.Clear();
if (m_Options.handleClasses)
- HandleClass(false);
+ HandleClass(ctStructure);
else
SkipToOneOfChars(ParserConsts::semicolonclbrace, true);
}
@@ -541,6 +543,7 @@
}
else if (token==ParserConsts::kw_union)
{
+#if 0
SkipToOneOfChars(ParserConsts::opbracesemicolon);
// if (m_Tokenizer.GetToken() == "{")
{
@@ -549,6 +552,13 @@
m_Str.Clear();
m_pLastParent = oldparent;
}
+#endif
+
+ m_Str.Clear();
+ if (m_Options.handleClasses)
+ HandleClass(ctUnion);
+ else
+ SkipToOneOfChars(ParserConsts::semicolonclbrace, true);
}
#if 1
else if (token==ParserConsts::kw_operator)
@@ -834,7 +844,9 @@
if (!newToken && !m_Options.isTemp)
newToken = TokenExists(name, m_pLastParent, kind);
- if (newToken && newToken->m_TokenKind == kind && newToken->m_Args == args)
+
+ wxString newTokenArgs = (newToken) ? (newToken->m_Args) : _T("");
+ if (newToken && newToken->m_TokenKind == kind && newTokenArgs == args)
{
m_pTokens->m_modified = true;
}
@@ -978,14 +990,30 @@
// BLAH_BLAH
if (!token.IsEmpty())
{
- // skip the rest of the #define
- wxString defVal = token + m_Tokenizer.ReadToEOL();
-
+ // skip the rest of the #define
+ wxString defVal = token + m_Tokenizer.ReadToEOL();
+ wxString para(_T(""));
+ size_t start = defVal.find('(');
+ size_t end = defVal.find(')');
+ //Manager::Get()->GetLogManager()->DebugLog(F(_T("Saving nesting level: %d,%d"), start, end));
// make sure preprocessor definitions are not going under namespaces or classes!
+ if (start != wxString::npos && end != wxString::npos)
+ {
+ para = defVal.Mid(start, end-start+1);
+ m_Str = defVal.Mid(end + 1);
+ m_Str.Trim(false);
+ }
+ else
+ {
+ m_Str = defVal.substr(token.length());
+ m_Str.Trim(false);
+ //defVal = _T("");
+ }
Token* oldParent = m_pLastParent;
m_pLastParent = 0L;
- DoAddToken(tkPreprocessor, token, lineNr, lineNr, m_Tokenizer.GetLineNumber(), defVal, false, true);
+ DoAddToken(tkPreprocessor, token, lineNr, lineNr, m_Tokenizer.GetLineNumber(), para, false, true);
m_pLastParent = oldParent;
+ m_Str.Clear();
}
}
@@ -1105,8 +1133,30 @@
}
}
-void ParserThread::HandleClass(bool isClass)
+void ParserThread::ReadVarNames()
{
+ while (1)
+ {
+ wxString current = m_Tokenizer.GetToken();
+
+ if (current.IsEmpty())
+ break;
+ if (current==ParserConsts::comma)
+ continue;
+ else if (current==ParserConsts::semicolon)
+ break;
+ else if (wxIsalpha(current.GetChar(0)))
+ {
+// Manager::Get()->GetLogManager()->DebugLog(F(_T("Adding variable '%s' as '%s' to '%s'"), current.c_str(), m_Str.c_str(), (m_pLastParent?m_pLastParent->m_Name.c_str():_T("<no-parent>"))));
+ DoAddToken(tkVariable, current, m_Tokenizer.GetLineNumber());
+ }
+ else // unexpected
+ break;
+ }
+}
+
+void ParserThread::HandleClass(EClassType ct)
+{
// need to force the tokenizer _not_ skip anything
// as we 're manually parsing class decls
// don't forget to reset that if you add any early exit condition!
@@ -1190,30 +1240,50 @@
// Manager::Get()->GetLogManager()->DebugLog(F(_T("Ancestors: ") + ancestors));
}
- if (current==ParserConsts::opbrace) // unnamed class/struct
+ if (current==ParserConsts::opbrace) // unnamed class/struct/union
{
static size_t num = 0;
wxString unnamedTmp;
- unnamedTmp.Printf(_T("Unnamed-%s-%d"), isClass ? _T("Class") : _T("Struct"), num++);
+ unnamedTmp.Printf(_T("Unnamed%s%d"),
+ ct == ctClass ? _T("Class") :
+ ct == ctUnion ? _T("Union") :
+ _T("Struct"), num++);
Token* newToken = DoAddToken(tkClass, unnamedTmp, lineNr);
Token* lastParent = m_pLastParent;
TokenScope lastScope = m_LastScope;
+ bool parsingTypedef = m_ParsingTypedef;
m_pLastParent = newToken;
- // default scope is: private for classes, public for structs
- m_LastScope = isClass ? tsPrivate : tsPublic;
+ // default scope is: private for classes, public for structs, public for unions
+ m_LastScope = ct == ctClass ? tsPrivate : tsPublic;
+ m_ParsingTypedef = false;
DoParse();
+ m_ParsingTypedef = parsingTypedef;
m_pLastParent = lastParent;
m_LastScope = lastScope;
m_LastUnnamedTokenName = unnamedTmp; // used for typedef'ing anonymous class/struct/union
- // we should now be right after the closing brace: read the var name
- break;
+ // we should now be right after the closing brace
+ // no vars are defined on a typedef, only types
+ // In the former example, aa is not part of the typedef.
+ if (m_ParsingTypedef)
+ {
+ m_Str.Clear();
+ ReadClsNames(newToken->m_Name);
+ break;
+ }
+ else
+ {
+ m_Str = newToken->m_Name;
+ ReadVarNames();
+ m_Str.Clear();
+ break;
+ }
}
else if (next==ParserConsts::opbrace)
{
@@ -1230,17 +1300,35 @@
Token* lastParent = m_pLastParent;
TokenScope lastScope = m_LastScope;
+ bool parsingTypedef = m_ParsingTypedef;
m_pLastParent = newToken;
- // default scope is: private for classes, public for structs
- m_LastScope = isClass ? tsPrivate : tsPublic;
+ // default scope is: private for classes, public for structs, public for unions
+ m_LastScope = ct == ctClass ? tsPrivate : tsPublic;
+ m_ParsingTypedef = false;
DoParse();
+ m_ParsingTypedef = parsingTypedef;
m_pLastParent = lastParent;
m_LastScope = lastScope;
- m_LastUnnamedTokenName = current;
- break;
+
+ // we should now be right after the closing brace
+ // no vars are defined on a typedef, only types
+ // In the former example, aa is not part of the typedef.
+ if (m_ParsingTypedef)
+ {
+ m_Str.Clear();
+ ReadClsNames(newToken->m_Name);
+ break;
+ }
+ else
+ {
+ m_Str = newToken->m_Name;
+ ReadVarNames();
+ m_Str.Clear();
+ break;
+ }
}
else if (next==ParserConsts::semicolon) // forward decl; we don't care
break;
@@ -1249,6 +1337,44 @@
HandleFunction(current);
break;
}
+ else if (next.GetChar(0) != '*')
+ {
+ // might be instantiation, see the following
+ /*
+ struct HiddenStruct {
+ int val;
+ };
+
+ struct HiddenStruct yy;
+ */
+ if (TokenExists(current, m_pLastParent, tkClass))
+ {
+ if (!TokenExists(next, m_pLastParent, tkVariable) )
+ {
+ wxString farnext;
+
+ m_Tokenizer.GetToken(); // go ahead of identifier
+ farnext = m_Tokenizer.PeekToken();
+
+ if (farnext==ParserConsts::semicolon)
+ {
+ if (m_Options.handleVars)
+ {
+ m_Str = current;
+ DoAddToken(tkVariable, next, m_Tokenizer.GetLineNumber());
+ m_Str.Clear();
+ }
+
+ m_Tokenizer.GetToken(); // eat semi-colon
+ break;
+ }
+ else
+ m_Tokenizer.UngetToken(); // restore the identifier
+ }
+ }
+ }
+ else
+ m_Tokenizer.GetToken();
}
else
break;
@@ -1364,7 +1490,7 @@
if (m_ParsingTypedef)
{
static size_t num = 0;
- token.Printf(_T("Unnamed-Enum-%d"), num++);
+ token.Printf(_T("UnnamedEnum%d"), num++);
m_LastUnnamedTokenName = token;
}
else
@@ -1378,7 +1504,31 @@
if (wxIsalpha(token.GetChar(0)) || token.GetChar(0) == '_')
{
if (m_Tokenizer.PeekToken().GetChar(0) != '{')
+ {
+ if (TokenExists(token, m_pLastParent, tkEnum))
+ {
+ if (!TokenExists(m_Tokenizer.PeekToken(), m_pLastParent, tkVariable) )
+ {
+ wxString ident = m_Tokenizer.GetToken(); // go ahead of identifier
+
+ if (m_Tokenizer.PeekToken()==ParserConsts::semicolon)
+ {
+ if (m_Options.handleEnums)
+ {
+ m_Str = token;
+ DoAddToken(tkVariable, ident, m_Tokenizer.GetLineNumber());
+ m_Str.Clear();
+ }
+
+ m_Tokenizer.GetToken(); // eat semi-colon
+ }
+ else
+ m_Tokenizer.UngetToken(); // restore the identifier
+ }
+ }
+
return;
+ }
if (isUnnamed && !m_ParsingTypedef)
{
@@ -1472,21 +1622,26 @@
if (token.IsEmpty() || token == ParserConsts::semicolon)
break;
+#if 0
if (token == ParserConsts::kw_union)
{
// "typedef union" is not supported
SkipToOneOfChars(ParserConsts::semicolon, true);
break;
}
-
- else if (token == ParserConsts::kw_class ||
- token == ParserConsts::kw_struct)
+ else
+#endif
+ if ( token == ParserConsts::kw_class
+ || token == ParserConsts::kw_struct
+ || token == ParserConsts::kw_union)
{
- // "typedef struct|class"
+ // "typedef struct|class|union"
#if PARSER_DEBUG_OUTPUT
Manager::Get()->GetLogManager()->DebugLog(F(_("Before HandleClass m_LastUnnamedTokenName='%s'"), m_LastUnnamedTokenName.c_str()));
#endif
- HandleClass(token == ParserConsts::kw_class);
+ HandleClass(token == ParserConsts::kw_class ? ctClass :
+ token == ParserConsts::kw_union ? ctUnion :
+ ctStructure);
token = m_LastUnnamedTokenName;
#if PARSER_DEBUG_OUTPUT
Manager::Get()->GetLogManager()->DebugLog(F(_("After HandleClass m_LastUnnamedTokenName='%s'"), m_LastUnnamedTokenName.c_str()));
@@ -1582,15 +1737,60 @@
#if PARSER_DEBUG_OUTPUT
Manager::Get()->GetLogManager()->DebugLog(F(_("Adding typedef: name='%s', ancestor='%s'"), components.front().c_str(), ancestor.c_str()));
#endif
- Token* tdef = DoAddToken(tkTypedef, components.front(), lineNr, 0, 0, args);
+// wxString str = components.front();
+ // Token* tdef = DoAddToken(tkClass, components.front(), lineNr, 0, 0, args);
+Token* tdef = DoAddToken(tkTypedef, components.front(), lineNr, 0, 0, args);
+//if ( m_Filename == _T("F:\\fortest\\main.cpp"))
+// Manager::Get()->GetLogManager()->DebugLog(ancestor);
if (tdef)
{
if (!is_function_pointer)
{
tdef->m_AncestorsString = ancestor;
+
tdef->m_ActualType = ancestor;
+// if ( m_Filename == _T("F:\\fortest\\main.cpp"))
+// {
+// Manager::Get()->GetLogManager()->DebugLog(tdef->m_Name + _T(" ") + tdef->m_AncestorsString + tdef->m_ActualType);
+// }
}
else
+ {
tdef->m_ActualType = ancestor + args;
+// tdef->m_AncestorsString = str;
+ }
}
}
+void ParserThread::ReadClsNames(wxString& ancestor)
+{
+ while (1)
+ {
+ wxString current = m_Tokenizer.GetToken();
+
+ if (current.IsEmpty())
+ break;
+ if (current==ParserConsts::comma)
+ continue;
+ else if (current==ParserConsts::semicolon)
+ {
+ m_Tokenizer.UngetToken();
+ break;
+ }
+
+ else if (wxIsalpha(current.GetChar(0)))
+ {
+// Manager::Get()->GetLogManager()->DebugLog(F(_T("Adding variable '%s' as '%s' to '%s'"), current.c_str(), m_Str.c_str(), (m_pLastParent?m_pLastParent->m_Name.c_str():_T("<no-parent>"))));
+ Token* newToken = DoAddToken(tkClass, current, m_Tokenizer.GetLineNumber());
+ if (!newToken)
+ break;
+ else
+ {
+ wxString tempAncestor = ancestor;
+ newToken->m_AncestorsString = tempAncestor;
+ }
+
+ }
+ else // unexpected
+ break;
+ }
+}
Index: parserthread.h
===================================================================
--- parserthread.h (revision 5730)
+++ parserthread.h (working copy)
@@ -79,6 +79,7 @@
virtual void SetTokens(TokensTree* tokens);
const wxString& GetFilename() const { return m_Filename; }
protected:
+ enum EClassType { ctStructure = 0, ctClass = 1, ctUnion = 3 };
wxChar SkipToOneOfChars(const wxString& chars, bool supportNesting = false);
void DoParse();
void SkipBlock();
@@ -87,7 +88,9 @@
void HandleDefines();
void HandlePreprocessorBlocks(const wxString& preproc);
void HandleNamespace();
- void HandleClass(bool isClass = true);
+ void ReadVarNames();
+ void ReadClsNames(wxString& ancestor);
+ void HandleClass(EClassType ct);
void HandleFunction(const wxString& name, bool isOperator = false);
void HandleEnum();
void HandleTypedef();