User forums > Using Code::Blocks

Code completion does not solve STDMETHOD macro for COM interfaces

(1/4) > >>

GPBeta:
As the title said I could not get any correct code completion hints for all the COM interfaces and theirs' methods.

I also noticed that there's a 'Replacement Tokens' option in the 'C/C++ parser(adv) panel of C::B->Settings->Editor->Code completions settings,
so I tried to add a 'DECLARE_INTERFACE_ -> +struct INTERFACE' replacement and the code completions is going to recognize the COM interfaces now,
but I could not find suitable patterns for the STDMETHOD macro, so I'm still not able to get code completion solving the methods for COM interfaces.

Many thanks if anyone could give me some advice. ;D

ollydbg:
I would recommend you can create a simple/minimal test cpp file, which contains the code patters of the unrecognized code snippet. So, we can test and try to fix it.
(the test cpp file should not include any other COM related files, because I don't have any COM related header files in my system.)
Thank you for the report.

GPBeta:
Thank you for the recommend.
I copied & pasted a minimum sample from a MinGW header 'unknwn.h' to reproduce this issue.


--- Code: ---#define _COM_interface struct
#define interface _COM_interface
#define DECLARE_INTERFACE(i) _COM_interface i
#define DECLARE_INTERFACE_(i,b) _COM_interface i : public b

#define PURE =0
#define STDMETHODCALLTYPE __stdcall
#define STDMETHOD(m) virtual HRESULT STDMETHODCALLTYPE m
#define STDMETHOD_(t,m) virtual t STDMETHODCALLTYPE m

#define REFIID const IID&
#define THIS_
#define THIS void

typedef struct GUID IID;
typedef unsigned long ULONG;
typedef long HRESULT;
typedef bool BOOL;
typedef void *PVOID;

DECLARE_INTERFACE(IUnknown)
{
STDMETHOD(QueryInterface)(THIS_ REFIID,PVOID*) PURE;
STDMETHOD_(ULONG,AddRef)(THIS) PURE;
STDMETHOD_(ULONG,Release)(THIS) PURE;
};

typedef IUnknown *LPUNKNOWN;

DECLARE_INTERFACE_(IClassFactory,IUnknown)
{
STDMETHOD(QueryInterface)(THIS_ REFIID,PVOID*) PURE;
STDMETHOD_(ULONG,AddRef)(THIS) PURE;
STDMETHOD_(ULONG,Release)(THIS) PURE;
STDMETHOD(CreateInstance)(THIS_ LPUNKNOWN,REFIID,PVOID*) PURE;
STDMETHOD(LockServer)(THIS_ BOOL) PURE;
};


int main()
{
    IUnknown* unknwown;
    IClassFactory* factory;

    return 0;
}


--- End code ---

You can see the code completion does not resolve symbols correctly as my attachment image shown, both hints for IUnknown & IClassFactory interfaces are wrong.
(occurring in Code::Blocks 13.12 stable and recent nightly builds)

ollydbg:
OK, thanks for the sample code. I little complex for me since it use a lot of macros.
What is the expect suggestion list if you press the "unknwown->"?

ollydbg:
I just debugged the code, and I see we get a failure when expanding the macro usage of:
STDMETHOD(QueryInterface)

Here have a code snippet:

--- Code: ---bool Tokenizer::GetMacroExpandedText(const Token* tk, wxString& expandedText)
{
    // e.g. "#define AAA AAA" and usage "AAA(x)"
    if (!tk || tk->m_Name == tk->m_FullType)
        return false;

    // sanity check if we have such macro definition that #define AAA(x,y) x+y+AAA
    // if a macro name exists in its definition, it will cause a infinite expansion loop
    if (tk->m_FullType.Find(tk->m_Name) != wxNOT_FOUND)
        return false;

--- End code ---
Here, the macro definition token tk is:

--- Code: ---[debug]> p *tk
[debug]$3 = {m_FullType = L"virtual HRESULT STDMETHODCALLTYPE m", m_BaseType = L"m", m_Name = L"STDMETHOD", m_Args = L"(m)",
--- End code ---
Now, I see that m_FullType contains the m_Name, so we just stop expansion, and return false to avoid infinite recursive call :(

It looks like this case, we should still expand, also we should improve how macro expansion works in our CC's parser.

EDIT:
The reason of this issue is that currently, expansion of macro usage just do some text replacement, but we never consider the text as a token serials. So, the improvement should be use the Tokenizer::DoGetToken() function with tsReadRawExpression bit set, so that we get a raw token sequence(we can store them in a wxArrayString), and later, we need to compare each element. Thus, we need to remove all the KMP related functions, since they are generally search for the plain text, not the token sequence.

Navigation

[0] Message Index

[#] Next page

Go to full version