Skip to content

Macros Handling

Eran Ifrah edited this page Dec 3, 2018 · 3 revisions

General

First let me begin by saying that CodeLite does not parse macros, nor it does not attempt to resolve them.

So... what DOES CodeLite do?

CodeLite manages an internal 'Token' replacement table which helps it during the parsing stage to perform simple string replacements.

The 'Token' replacement table is accessible from the main menu: Settings -> Tags Settings -> Advanced tab

Note that CodeLite's default installation comes with a populated 'Token' table which manages most of the commonly used macros in the STL, wxWidgets and QT.

Also, each time you add / remove entries to this table you need to re-tag your workspace (full) from the main menu: Workspace -> Retag workspace (full)

##Various types of token entries##

Type 1: X=Y entry

Lets say that you have the following code snippet:

 CLASS myClass {
 public:
     void foo(){};
 };

The example above uses CLASS as a preprocessor macro which expands to something different for each platform. For instance CLASS may be defined as class __declspec(dllexport) on Win32 platforms and simply class on UNIX. Normally, the absence of the C++ keyword class would cause the source file to be incorrectly parsed.

This can be easily fixed by adding the following entry to the 'Token' table:

CLASS=class

Type 2: Ignore entry

Many APIs are using functions / class decorators which can also confuse the parser, take for example the following code:

class WXDLLIMPEXP_FWD_RICHTEXT wxRichTextCtrl;

By parsing the above line, codelite will mistakenly count wxRichTextCtrl as a variable of type WXDLLIMPEXP_FWD_RICHTEXT rather than forward declaration of the class. To fix this, one need to add the following entry to the 'Token' table:

WXDLLIMPEXP_FWD_RICHTEXT

By adding this entry to the 'Tokens' table codelite knows that whenever it "sees" this token, he can safely ignore it so it will actually sees the above code snippt like this

class wxRichTextCtrl;

Which can be parsed easily by the parser.

Type 3: Complex replacement macros (since codelite revision 4080)###

Some macros are too complex and can not be resolved by using the simple X=Y or the 'ignore' entries. These kind of macros require the third type of macros: complex macros

An example: Most of the Python C API methods looks like this:

PyAPI_FUNC(void*) PySomeFunctionName(PyObject*);

By reading it we know that the API is:

void* PySomeFunctionName(PyObject*);

The problem is that codelite does not know that... We could use the naive solution of adding an X=Y entry like this:

PyAPI_FUNC(void*)=void*

But there are many variations in the code for the PyAPI_FUNC with different types, like:

PyAPI_FUNC(PyObject*), PyAPI_FUNC(int) etc.

What we need is a search pattern that will match ALL the variations of PyAPI_FUNC:

PyAPI_FUNC(%0)=%0

In the above example PyAPI_FUNC(void*):

  • %0 is void*
  • Whenever CodeLite matches a string to the pattern, it will replace PyAPI_FUNC(%0) with %0 so CodeLite will successfully display the function prototype

A more complex example: wxWidgets uses the following macro:

#define wxConstCast(t, x) const_cast<t>(x)

Simply add the following entry:

wxConstCast(%0, %1)=const_cast<%0>(%1)

to fix this