Author Topic: C/C++ Parser issue [Solved/Workaround]  (Read 2976 times)

Offline mburge

  • Single posting newcomer
  • *
  • Posts: 2
C/C++ Parser issue [Solved/Workaround]
« on: September 23, 2021, 05:03:45 am »
Workaround:
Go to Settings->Compiler
Select your project's LLVM compiler
Rename Copy it and make sure it has  "GCC" in the new name!

Why:
Hard coded values in the parser

Where:
https://svn.code.sf.net/p/codeblocks/code/trunk/src/plugins/codecompletion/nativeparser.cpp

bool NativeParser::AddCompilerPredefinedMacros(cbProject* project, ParserBase* parser)
...
    // gcc
    if (compilerId.Contains(_T("gcc")))
    {
        if ( !AddCompilerPredefinedMacrosGCC(compilerId, project, defs, parser) )
            return false;
    }
    // vc
    else if (compilerId.StartsWith(_T("msvc")))
    {
        if ( !AddCompilerPredefinedMacrosVC(compilerId, defs, parser) )
          return false;
    }
...
}

Quote
Hi all!

issue w/ the c/c++ parser when evaluating if defined(__cplusplus) when parsing a .h file in a C++ project?

some info
have a C++ Project
have a header file (.h) with many instances of:
Code
#if defined(__cplusplus)
#define MACRO thing
#else
#define MACRO other_thing
#endif

Now the Editor correctly parses the preprocessor directives and greys out the second directive, i.e., #define MACRO other_thing ..
But!
..internally things aren't so:
1) on use, when one hovers over the macro the tooltip content is "#define MACRO other_thing" !
2) in code, select macro, right click, choose "Find declaration of: 'MACRO'" will land you at the second directive .

Does not affect compiler and/or resulting code but does a number on my mind :'(

Windows 10 64bit
Code::Blocks svn12452
LLVM Clang

I have everything enabled in
General Settings -> C/C++ Editor settings
and
Code Completion -> C/C++ parser

pls help  :(
« Last Edit: September 23, 2021, 11:06:36 am by mburge »

Offline ollydbg

  • Developer
  • Lives here!
  • *****
  • Posts: 5391
  • OpenCV and Robotics
    • Chinese OpenCV forum moderator
Re: C/C++ Parser issue [Solved/Workaround]
« Reply #1 on: September 23, 2021, 04:11:44 pm »
Quote
Now the Editor correctly parses the preprocessor directives and greys out the second directive

Currently, the Editor's syntax highlight is not related to the CodeCompletion plugin.

You mentioned code is inside the CodeCompletion plugin, but the editor highlight is related to Scintilla control.
If some piece of memory should be reused, turn them to variables (or const variables).
If some piece of operations should be reused, turn them to functions.
If they happened together, then turn them to classes.

Offline mburge

  • Single posting newcomer
  • *
  • Posts: 2
Re: C/C++ Parser issue [Solved/Workaround]
« Reply #2 on: September 23, 2021, 07:26:53 pm »
Quote
Now the Editor correctly parses the preprocessor directives and greys out the second directive

Currently, the Editor's syntax highlight is not related to the CodeCompletion plugin.

You mentioned code is inside the CodeCompletion plugin, but the editor highlight is related to Scintilla control.

Yes, I were pointing out that visually things were correct, but functionally not.

The workaround simply makes the parser treat the LLVM compiler as it would the GCC compiler, i.e.,
it triggers the AddCompilerPredefinedMacrosGCC code path which is to retrieve the compiler's predefined macros by
invoking it with  " -E -dM -x c++ %s nul"
(Caveat : this only works with the LLVM compiler as it responds the same to the parameters as GCC would.)

Having the predefined macros solves 1)having the incorrect info in tooltips and 2)Find declaration misleading you to an inactive declaration.


One last thing - on the Editor side (Scintilla) doesn't take into account that when working with LLVM on Windows it has _MSC_EXTENSIONS defined by default
which results in visually having large sections of code grey'd out (#if defined(_MSC_EXTENSIONS) ... #endif) but that's small beans as
CodeCompetion still parses it correctly and has the right information in tooltips and Find declaration points to the right places.


Regards

Offline ollydbg

  • Developer
  • Lives here!
  • *****
  • Posts: 5391
  • OpenCV and Robotics
    • Chinese OpenCV forum moderator
Re: C/C++ Parser issue [Solved/Workaround]
« Reply #3 on: September 27, 2021, 01:11:24 am »
Quote
Now the Editor correctly parses the preprocessor directives and greys out the second directive

Currently, the Editor's syntax highlight is not related to the CodeCompletion plugin.

You mentioned code is inside the CodeCompletion plugin, but the editor highlight is related to Scintilla control.

Yes, I were pointing out that visually things were correct, but functionally not.

The workaround simply makes the parser treat the LLVM compiler as it would the GCC compiler, i.e.,
it triggers the AddCompilerPredefinedMacrosGCC code path which is to retrieve the compiler's predefined macros by
invoking it with  " -E -dM -x c++ %s nul"
(Caveat : this only works with the LLVM compiler as it responds the same to the parameters as GCC would.)

Having the predefined macros solves 1)having the incorrect info in tooltips and 2)Find declaration misleading you to an inactive declaration.



Thanks for the explanation.

I think the correct way to fix such issue is adding some special if condition for "llvm" compiler.

In this code:

Code
bool NativeParser::AddCompilerPredefinedMacros(cbProject* project, ParserBase* parser)
{
    if (!parser)
        return false;

    if (!parser->Options().wantPreprocessor)
        return false;

    TRACE(_T("NativeParser::AddCompilerPredefinedMacros: Enter"));

    // Default compiler is used for for single file parser (non project)
    wxString compilerId = project ? project->GetCompilerID() : CompilerFactory::GetDefaultCompilerID();

    wxString defs;
    // gcc
    if (compilerId.Contains(_T("gcc")))
    {
        if ( !AddCompilerPredefinedMacrosGCC(compilerId, project, defs, parser) )
            return false;
    }
    // vc
    else if (compilerId.StartsWith(_T("msvc")))
    {
        if ( !AddCompilerPredefinedMacrosVC(compilerId, defs, parser) )
          return false;
    }

    TRACE(_T("NativeParser::AddCompilerPredefinedMacros: Add compiler predefined preprocessor macros:\n%s"), defs.wx_str());
    parser->AddPredefinedMacros(defs);

    TRACE(_T("NativeParser::AddCompilerPredefinedMacros: Leave"));
    if ( defs.IsEmpty() )
        return false;

    return true;
}

We can fetch a special command for llvm compiler.



Quote
One last thing - on the Editor side (Scintilla) doesn't take into account that when working with LLVM on Windows it has _MSC_EXTENSIONS defined by default
which results in visually having large sections of code grey'd out (#if defined(_MSC_EXTENSIONS) ... #endif) but that's small beans as
CodeCompetion still parses it correctly and has the right information in tooltips and Find declaration points to the right places.


Regards

Scintilla doesn't have the symbols in global scope, which means it only parse the current h/cpp file.
The best idea is to let the CodeCompletion plugin to supply a symbol list for the Scintilla, I have implemented that feature years ago, that need changes in scintilla source code.
Maybe, search the forum will gives the related discussion. :)
If some piece of memory should be reused, turn them to variables (or const variables).
If some piece of operations should be reused, turn them to functions.
If they happened together, then turn them to classes.