Developer forums (C::B DEVELOPMENT STRICTLY!) > CodeCompletion redesign
Is it possible for the parser to support newlib prototypes?
ollydbg:
--- Quote from: Huki on September 21, 2014, 07:44:47 pm ---
--- Quote ---I'm testing your patch now. It looks like macro expansion is enabled on every identifier like tokens.
--- End quote ---
Yes, when the (!switchHandled) case is reached in DoParse(), it now expands all macros, including variable-like ones.
--- End quote ---
When I first look at this function, I see that it only expand function-like macro usage.
--- Code: ---void ParserThread::HandleMacroExpansion(int id, const wxString &peek)
{
Token* tk = m_TokenTree->at(id);
if (tk)
{
TRACE(_T("HandleMacroExpansion() : Adding token '%s' (peek='%s')"), tk->m_Name.wx_str(), peek.wx_str());
DoAddToken(tkMacroUse, tk->m_Name, m_Tokenizer.GetLineNumber(), 0, 0, peek);
if (m_Options.parseComplexMacros)
m_Tokenizer.ReplaceFunctionLikeMacro(tk);
}
}
--- End code ---
But This is not true.
--- Code: ---bool Tokenizer::ReplaceFunctionLikeMacro(const Token* tk)
{
wxString macroExpandedText;
if ( GetMacroExpandedText(tk, macroExpandedText) )
return ReplaceBufferText(macroExpandedText);
return false;
}
--- End code ---
Our recent changes in GetMacroExpandedText() function covers the handling of variable-like macro usage expansion.
So, the function name "ReplaceFunctionLikeMacro" cause confusing and need to be renamed. ;D
ollydbg:
--- Quote from: Huki on September 21, 2014, 07:44:47 pm ---...
On second look I noticed we can do a little optimization. This code:
--- Code: ---wxString arg = peek;
arg.Remove(0,1); // remove '('
if (arg.GetChar(0) == ParserConsts::ptr)
{
arg.Remove(0,1).Trim(false); // remove '*'
[...]
}
--- End code ---
can be changed to:
--- Code: ---if (peek.GetChar(1) == ParserConsts::ptr)
{
wxString arg = peek;
arg.Remove(0,2).Trim(false); // remove "(*"
[...]
}
--- End code ---
So the entire code for this case:
--- Code: ---// see what is inside the (...)
// try to see whether the peek pattern is (* BBB)
if (peek.GetChar(1) == ParserConsts::ptr)
{
wxString arg = peek;
arg.RemoveLast(); // remove ")"
arg.Remove(0,2).Trim(false); // remove "(* "
m_Str << token;
token = m_Tokenizer.GetToken(); //consume the peek
// BBB is now the function ptr's name
HandleFunction(/*function name*/ arg,
/*isOperator*/ false,
/*isPointer*/ true);
}
else if [...]
--- End code ---
That way we don't have to create a temporary variable 'arg' every time when we see a function declaration-like pattern, but only when we know for sure it can be a function pointer.
--- Quote ---I'm testing your patch now. It looks like macro expansion is enabled on every identifier like tokens.
--- End quote ---
Yes, when the (!switchHandled) case is reached in DoParse(), it now expands all macros, including variable-like ones.
--- End quote ---
Hi, Huki' patch is in trunk now, thanks for your contribution!
ollydbg:
--- Quote from: ollydbg on September 22, 2014, 04:04:38 am ---...
So, the function name "ReplaceFunctionLikeMacro" cause confusing and need to be renamed. ;D
--- End quote ---
Done in the trunk r9934.
WinterMute:
Wow! Amazing job. Thank you so much for doing this - I really wasn't expecting it :D
Huki:
Hi,
I reviewed some remaining patches I have and noticed I have not yet submitted this one:
--- Quote from: Huki on September 18, 2014, 01:16:09 pm ---
--- Quote from: Teybeo on September 17, 2014, 02:52:54 pm ---Oops yeah, I confirm, it works like in your screenshot, good job :) !
(Minor UI detail, it would be nice if the function calltip was showing the true name of the function and not PFNGLDRAWARRAYSINSTANCEDPROC)
--- End quote ---
Yes, I think it would be better to show the variable name rather than the typedef name. See here:
I'll submit the patch soon...
--- End quote ---
When we display the calltip for a typedef'd function pointer, we can show the function pointer's name rather than the typedef's name.
Here is the patch:
--- Code: ---From 65004d39e614519c66475a5295a6f6d44e4e3341 Mon Sep 17 00:00:00 2001
From: huki <gk7huki@gmail.com>
Date: Thu, 18 Sep 2014 18:25:20 +0530
Subject: CC: update typedef'd func pointer calltip
---
src/plugins/codecompletion/nativeparser_base.cpp | 47 +++++++++++++-----------
src/plugins/codecompletion/nativeparser_base.h | 8 ++--
2 files changed, 29 insertions(+), 26 deletions(-)
diff --git a/src/plugins/codecompletion/nativeparser_base.cpp b/src/plugins/codecompletion/nativeparser_base.cpp
index 778d55a..5abfadb 100644
--- a/src/plugins/codecompletion/nativeparser_base.cpp
+++ b/src/plugins/codecompletion/nativeparser_base.cpp
@@ -1685,7 +1685,7 @@ void NativeParserBase::ComputeCallTip(TokenTree* tree,
// either a function or a variable, but it is OK if a macro with not empty m_Args.
if (tk && ((tk->m_TokenKind ^ tkMacroDef) || !tk->m_Args.empty()))
- token = tk; // tkVariable could be a typedef'd function ptr (checked later down below)
+ token = tk; // tkVariable could be a typedef'd function ptr (checked in PrettyPrintToken())
else
{
// a variable like macro, this token don't have m_Args(call tip information), but
@@ -1711,33 +1711,36 @@ void NativeParserBase::ComputeCallTip(TokenTree* tree,
}
}
- // a variable basically don't have call tips, but if it's type is a typedef'd function
- // pointer, we can still have call tips (which is the typedef function's arguments)
- if (token->m_TokenKind == tkVariable)
- {
- const Token* tk = tree->at(tree->TokenExists(token->m_BaseType, token->m_ParentIndex, tkTypedef));
- if (!tk && token->m_ParentIndex != -1)
- tk = tree->at(tree->TokenExists(token->m_BaseType, -1, tkTypedef));
- if (tk && !tk->m_Args.empty())
- token = tk; // typedef'd function pointer
- }
+ wxString tkTip;
+ if ( !PrettyPrintToken(tree, token, tkTip) )
+ tkTip = wxT("Error while pretty printing token!");
+ items.Add(tkTip);
- {
- wxString tkTip;
- if ( !PrettyPrintToken(tree, token, tkTip) )
- tkTip = wxT("Error while pretty printing token!");
- items.Add(tkTip);
- }
}// for
CC_LOCKER_TRACK_TT_MTX_UNLOCK(s_TokenTreeMutex)
}
-bool NativeParserBase::PrettyPrintToken(const TokenTree* tree,
- const Token* token,
- wxString& result,
- bool isRoot)
+bool NativeParserBase::PrettyPrintToken(TokenTree* tree,
+ const Token* token,
+ wxString& result,
+ bool isRoot)
{
+ wxString name = token->m_Name;
+ // a variable basically don't have call tips, but if it's type is a typedef'd function
+ // pointer, we can still have call tips (which is the typedef function's arguments)
+ if (token->m_TokenKind == tkVariable)
+ {
+ const Token* tk = tree->at(tree->TokenExists(token->m_BaseType, token->m_ParentIndex, tkTypedef));
+ if (!tk && token->m_ParentIndex != -1)
+ tk = tree->at(tree->TokenExists(token->m_BaseType, -1, tkTypedef));
+ if (tk && !tk->m_Args.empty()) // typedef'd function pointer
+ {
+ name = token->m_Name;
+ token = tk;
+ }
+ }
+
// if the token has parents and the token is a container or a function,
// then pretty print the parent of the token->
if ( (token->m_ParentIndex != -1)
@@ -1776,7 +1779,7 @@ bool NativeParserBase::PrettyPrintToken(const TokenTree* tree,
return true;
case tkTypedef:
- result = token->m_BaseType + wxT(" ") + result + token->m_Name + token->GetFormattedArgs();
+ result = token->m_BaseType + wxT(" ") + result + name + token->GetFormattedArgs();
return true;
case tkEnum:
diff --git a/src/plugins/codecompletion/nativeparser_base.h b/src/plugins/codecompletion/nativeparser_base.h
index 586c5ae..ab90894 100644
--- a/src/plugins/codecompletion/nativeparser_base.h
+++ b/src/plugins/codecompletion/nativeparser_base.h
@@ -321,10 +321,10 @@ protected:
/** For ComputeCallTip()
* No critical section needed in this recursive function!
* All functions that call this recursive function, should already entered a critical section. */
- bool PrettyPrintToken(const TokenTree* tree,
- const Token* token,
- wxString& result,
- bool isRoot = true);
+ bool PrettyPrintToken(TokenTree* tree,
+ const Token* token,
+ wxString& result,
+ bool isRoot = true);
// convenient static funcs for fast access and improved readability
--
1.9.4.msysgit.0
--- End code ---
PS: I got your notification about checking macro usage for every token, but I was too busy to check it earlier. Anyway, it's too complex so I think it's better to keep it aside for now...
Navigation
[0] Message Index
[#] Next page
[*] Previous page
Go to full version