Author Topic: C++ parsing problem - symbol not found  (Read 435 times)

rjpontefract

  • Community Member
  • Posts: 96
  • Hero Points: 4
C++ parsing problem - symbol not found
« on: January 13, 2021, 09:12:32 pm »
I was building some WxWidgets code on macOS with SE 25.0.1.0 and noticed that wxEVT_MENU was highlighted as "symbol not found".  I narrowed it down to the following short example:

Code: [Select]
class wxCommandEvent {};

template <typename T> class wxEventTypeTag {};

#define WXEXPORT
#define WXDLLIMPEXP_CORE WXEXPORT
#define wxDECLARE_EXPORTED_EVENT( expdecl, name, type ) \
        extern const expdecl wxEventTypeTag< type > name
wxDECLARE_EXPORTED_EVENT(WXDLLIMPEXP_CORE, wxEVT_MENU, wxCommandEvent);
wxEventTypeTag<wxCommandEvent> x = wxEVT_MENU;

When preprocessed with clang++, the output is:

Code: [Select]
class wxCommandEvent {};
template <typename T> class wxEventTypeTag {};
extern const wxEventTypeTag< wxCommandEvent > wxEVT_MENU;
wxEventTypeTag<wxCommandEvent> x = wxEVT_MENU;

It would be nice if SE could tag wxEVT_MENU successfully as it affects other functions such as Bind() which are also highlighted as symbol not found.
 

Dennis

  • SlickEdit Team Member
  • Senior Community Member
  • *
  • Posts: 3245
  • Hero Points: 461
Re: C++ parsing problem - symbol not found
« Reply #1 on: January 14, 2021, 01:09:39 am »
Go to Document > C/C++ Options... > C/C++ Preprocessing

Then add WXEXPORT, WXDLLIMPEXP_CORE, and wxDECLARE_EXPORTED_EVENT as preprocessor symbols, defining them in the way the macros are defined in that header file.

rjpontefract

  • Community Member
  • Posts: 96
  • Hero Points: 4
Re: C++ parsing problem - symbol not found
« Reply #2 on: January 14, 2021, 01:53:58 am »
Thanks, that worked for the example program but unfortunately not for the wxWidgets actual source, in which case wxEVT_MENU is still undefined.

Which preprocessor macros are processed by SE when building tag files and which aren't?  My simple test program for wxWidgets has 5869 macro definitions.  How do I determine which ones I need to add to the C/C++ Preprocessing options to make it work?


mjdl

  • Senior Community Member
  • Posts: 148
  • Hero Points: 17
  • SE 25.0.1.0 x64, Windows 10 x64 20H2
Re: C++ parsing problem - symbol not found
« Reply #3 on: January 14, 2021, 03:08:03 pm »
I seem to recall that GNU g++ dumps all of the #defines included in processing a C++ source file with the command line
Quote
g++ -dM -E -x c++ - < source.cpp

Maybe Clang also has something similar.

Dennis

  • SlickEdit Team Member
  • Senior Community Member
  • *
  • Posts: 3245
  • Hero Points: 461
Re: C++ parsing problem - symbol not found
« Reply #4 on: January 14, 2021, 03:49:34 pm »
It's a dark art, I usually look around for header files that have the core defines, things like "platform.h", "cpp.h", "setup.h", and scrape them for defines that would be relevant to tagging.

I'll go through the WxWidgets source and put together a preprocessing config for you that should get most of the key elements.

rjpontefract

  • Community Member
  • Posts: 96
  • Hero Points: 4
Re: C++ parsing problem - symbol not found
« Reply #5 on: January 14, 2021, 06:21:18 pm »
Hi Dennis

Thanks for confirming that it's a dark art and thanks for offering to put together a configuration, it's appreciated.

@mjdl, clang does offer the same functionality, it's what I used to determine how many macros were defined when I compiled my test program.  Actually I used -dD and grep'd for #define.  Using -dM results in 5795 macros which is an improvement :-)

Dennis

  • SlickEdit Team Member
  • Senior Community Member
  • *
  • Posts: 3245
  • Hero Points: 461
Re: C++ parsing problem - symbol not found
« Reply #6 on: January 14, 2021, 07:10:17 pm »
Here's the file containing the #defines.  Ignore the name, you'll need to append this to your usercpp.h in your configuration directory.

I am also adding these #defines to the pre-configured set of #defines, that will go into 25.0.2.

rjpontefract

  • Community Member
  • Posts: 96
  • Hero Points: 4
Re: C++ parsing problem - symbol not found
« Reply #7 on: January 14, 2021, 08:03:45 pm »
Hi Dennis

Thanks for the quick reply and for providing the definitions.  I've added them to unxcpp.h in the SE configuration directory as that was the file that existed already with my definitions in it.  I'm on macOS so I don't know if the filename is different.  Adding them to usercpp.h didn't seem to work.  But if I'm doing this wrong, please let me know.

So now I have a whole bunch of definitions in the C/C++ Preprocessing options which is good.  However, in my test program I still have the undefined symbols.  I've attached a screen capture showing the problem.  Are there some more defines that I need to add?

Cheers
Rick

Dennis

  • SlickEdit Team Member
  • Senior Community Member
  • *
  • Posts: 3245
  • Hero Points: 461
Re: C++ parsing problem - symbol not found
« Reply #8 on: January 14, 2021, 08:12:42 pm »
Did you rebuild the tag file(s) which contain the WxWidgets source (and any code that you have which uses WxWidgets preprocessing)?  And when you do rebuild it, make sure you *uncheck* "Retag modified files only" to force it to rebuild from scratch.

rjpontefract

  • Community Member
  • Posts: 96
  • Hero Points: 4
Re: C++ parsing problem - symbol not found
« Reply #9 on: January 14, 2021, 08:48:19 pm »
Hi Dennis

As it was a short test program, I was using a single file project.  I created a new project file and put my single test source file in it, rebuilt the workspace tag file as requested and I still have the same undefined symbols.  My entire test program is:

Code: [Select]
// wxWidgets "Hello world" Program

#include <wx/wx.h>

class MyApp: public wxApp
{
public:
    virtual bool OnInit();
};

class MyFrame: public wxFrame
{
public:
    MyFrame();
private:
    void OnHello(wxCommandEvent& event);
    void OnExit(wxCommandEvent& event);
    void OnAbout(wxCommandEvent& event);
};

enum
{
    ID_Hello = 1
};

wxIMPLEMENT_APP(MyApp);

bool MyApp::OnInit()
{
    MyFrame *frame = new MyFrame();
    frame->Show( true );
    return true;
}

MyFrame::MyFrame()
        : wxFrame(NULL, wxID_ANY, "Hello World")
{
  fprintf(stdout,"In %s\n", __func__);
  fflush(stdout);

    wxMenu *menuFile = new wxMenu;
    menuFile->Append(ID_Hello, "&Hello...\tCtrl-H", "Help string shown in status bar for this menu item");
    menuFile->AppendSeparator();
    menuFile->Append(wxID_EXIT);
    wxMenu *menuHelp = new wxMenu;
    menuHelp->Append(wxID_ABOUT);
    wxMenuBar *menuBar = new wxMenuBar;
    menuBar->Append( menuFile, "&File" );
    menuBar->Append( menuHelp, "&Help" );
    SetMenuBar( menuBar );
    CreateStatusBar();
    SetStatusText( "Welcome to wxWidgets!" );
    Bind(wxEVT_MENU, &MyFrame::OnHello, this, ID_Hello);
    Bind(wxEVT_MENU, &MyFrame::OnAbout, this, wxID_ABOUT);
    Bind(wxEVT_MENU, &MyFrame::OnExit, this, wxID_EXIT);
}

void MyFrame::OnExit(wxCommandEvent& event)
{
    Close( true );
}

void MyFrame::OnAbout(wxCommandEvent& event)
{
    wxMessageBox( "This is a wxWidgets' Hello world sample",
                  "About Hello World", wxOK | wxICON_INFORMATION );
}

void MyFrame::OnHello(wxCommandEvent& event)
{
    wxLogMessage("Hello world from wxWidgets!");
}


Dennis

  • SlickEdit Team Member
  • Senior Community Member
  • *
  • Posts: 3245
  • Hero Points: 461
Re: C++ parsing problem - symbol not found
« Reply #10 on: January 14, 2021, 09:30:15 pm »
Do you have a language specific tag file for WxWidgets?  Did you rebuild that?

Dennis

  • SlickEdit Team Member
  • Senior Community Member
  • *
  • Posts: 3245
  • Hero Points: 461
Re: C++ parsing problem - symbol not found
« Reply #11 on: January 14, 2021, 09:50:09 pm »
Just for future reference, the way I cobbled together that header file quickly was as follows:

1) Concatenate together all the headers from the "wx" include directory.
Code: [Select]
     cd WxWidgets/include/
     find wx -type f -print0 | xargs -0 cat >allheaders.h

2) Created a temporary workspace.  Project > New...,
    Added the WxWidgets include/wx subdirectory to it.

3) Import all the defines from "allheaders.h" into the C/C++ Preprocessing dialog
        Project > Workspace Properties... > C/C++ Preprocessing > Import...
    I'm not going to lie to you.  This step was not fast, but it worked.

4) Edited the workspace C/C++ preprocessing header file (workspace_cpp.h)
    to remove unwanted #defines and narrow it down to the ones that actually
    matter to tagging.  Specifically make sure that all the header-file guard #defines
    are taken out, and all the #defines used to define constants are removed,
    as well as any #defines that really had nothing to do with the library or were
    highly platform specific or just generated statements.
 
     I'm not going to lie to you, step (4) is tedious, very tedious.

Now you know the dark art of preprocessing configuration for 3rdparty libraries.

rjpontefract

  • Community Member
  • Posts: 96
  • Hero Points: 4
Re: C++ parsing problem - symbol not found
« Reply #12 on: January 14, 2021, 10:10:08 pm »
Thanks for explaining the method you use, it does look rather time consuming.
I rebuilt all of my tag files and I'm happy to say that wxEVT_MENU is now resolved correctly.
I was hoping when that symbol was resolved that SE would be able to work out which Bind() function the code was referring to, but unfortunately it doesn't.  It highlights it as "symbol not found" and offers a whole bunch of possible Bind() functions when queried.  Is there something I can do to to help SE resolve which one it really is?
« Last Edit: January 15, 2021, 02:05:03 am by rjpontefract »

Dennis

  • SlickEdit Team Member
  • Senior Community Member
  • *
  • Posts: 3245
  • Hero Points: 461
Re: C++ parsing problem - symbol not found
« Reply #13 on: January 15, 2021, 03:58:12 pm »
I created a WxWidgets project with your source file, and I do not have the same problems you have with Bind() not being resolved correctly.  This may because I don't have Boost in the mix, but that should not have made any difference.  The main difference may be that I narrowed down the WxWidgets source to the necessary subdirectories (src and include).

rjpontefract

  • Community Member
  • Posts: 96
  • Hero Points: 4
Re: C++ parsing problem - symbol not found
« Reply #14 on: January 15, 2021, 06:08:28 pm »
Hi Dennis

Thanks for the update.  I was only tagging the wxWidgets include files as I only had the includes and libraries installed, not the source.  I cloned the wxWidgets source tree and tagged that instead and it now resolves Bind() and Close() correctly.  However, I did remove my /usr/local/include tag file which included boost, so I cloned the boost source code and tagged that as well and it all looks OK.

Thanks very much for your help with this, it's been a good learning experience.

Rick