Author Topic: Code-Completion compiler built-in defines and c++ version  (Read 14073 times)

Offline EnterTheNameHere

  • Multiple posting newcomer
  • *
  • Posts: 19
Code-Completion compiler built-in defines and c++ version
« on: July 31, 2013, 02:23:37 pm »
The code completion doesn't take into account the c++ version when asking for builtin defines from compiler.


(SVN revision at the time of writting: 9239)
In the file "plugins\codecompletion\nativeparser.cpp",
function NativeParser::AddCompilerPredefinedMacrosGCC,
on the line 2170 is the command to get the builtin defines
Code: c++
#ifdef __WXMSW__
        const wxString args(_T(" -E -dM -x c++ nul"));
#else
        const wxString args(_T(" -E -dM -x c++ /dev/null"));
#endif

This command doesn't take into account if user wants to compile project with -std=c++11 (-std=c++0x).
It means the __cplusplus define is always 199711L, instead of 201103L. Code completion then ignores std::shared_ptr, std::enable_if, [map::]emplace and other tokens which are "hidden" under #if __cplusplus >= 201103L.

I tried hacking the code to
Code: c++
#ifdef __WXMSW__
        const wxString args(_T(" -E -dM -std=c++11 -x c++ nul"));
#else
        const wxString args(_T(" -E -dM -std=c++11 -x c++ /dev/null"));
#endif

and then the __cplusplus define is 201103L (checked under Symbols(View: Everything)->#Preprocessor symbols) and code completion can successfuly parse std::shared_ptr, std::enable_if, [map::]emplace and emplace_hint and other tokens.

Unfortunately I don't know Code::Blocks source code well enough to make an adequate patch depending of project compiler options...
« Last Edit: August 24, 2013, 10:02:01 pm by EnterTheNameHere »

Offline EnterTheNameHere

  • Multiple posting newcomer
  • *
  • Posts: 19
Re: Code-Completion compiler built-in defines and c++ version
« Reply #1 on: August 24, 2013, 10:17:22 pm »
So the problem for me was the NativeParser::AddCompilerPredefinedMacrosGCC() function only looks if "-std=c++0x" or "-std=gnu++0x" is set in project/target compiler options, and if it is, it will add __GXX_EXPERIMENTAL_CXX0X__ to defines.

I am using -std=c++11 and GCC 4.8.1-2, which is already using #if __cplusplus > 199711L, not __GXX_EXPERIMENTAL_CXX0X__, so parser couldn't parse c++11 features like std::shared_ptr, even with -std=c++0x.

I have rewritten the function to look for "-std=", so now You can specify any standard You want (eg. -std=c++11, -std=gnu++11, -std=c89, -std=gnu11 or even -std=iso9899:199409), and this standard will be used in the query to compiler. First the global compiler options are searched, if standard is set there. If not, as second the project compiler options are searched. Targets are searched as third in row, getting the first standard that is encountered. If no standard is set, no standard will be sent to compiler, so compiler will return defines for the default standard (__cplusplus 199711L).

Patch can be found here:
http://developer.berlios.de/patch/index.php?func=detailpatch&patch_id=3493&group_id=5358
« Last Edit: August 24, 2013, 10:19:09 pm by EnterTheNameHere »

Offline oBFusCATed

  • Developer
  • Lives here!
  • *****
  • Posts: 13406
    • Travis build status
Re: Code-Completion compiler built-in defines and c++ version
« Reply #2 on: August 25, 2013, 08:51:48 pm »
First the global compiler options are searched, if standard is set there. If not, as second the project compiler options are searched. Targets are searched as third in row, getting the first standard that is encountered. If no standard is set, no standard will be sent to compiler, so compiler will return defines for the default standard (__cplusplus 199711L).
From this description it sounds like you're doing it wrong. You should search first the target, then the project and last global settings. For the target there is an option telling if it should override the project settings, append to them and so on.

@devs: Do you know if there is an API for querying if compiler or linker option is set?
(most of the time I ignore long posts)
[strangers don't send me private messages, I'll ignore them; post a topic in the forum, but first read the rules!]

Offline EnterTheNameHere

  • Multiple posting newcomer
  • *
  • Posts: 19
Re: Code-Completion compiler built-in defines and c++ version
« Reply #3 on: August 26, 2013, 01:51:10 pm »
Good point, thank You, I'll update it.

BTW the compiler takes into account the latest standard passed on command line, so "g++.exe -std=c++1y -g -std=c++11 -wAll -std=c++98" will yield defines for c++98. From my test the global compiler options are appended to the end - so it overrides any other standard set - and that's why I search globals as first. I think it's correct behavior for parser then...

So should the order be:
1. Compiler global options
2. Target options - I check if targets appends to/discards project options
3. Project options
4. Target options - I check if targets prepends to project options

ie.
g++.exe [Target prepend options] [Project options] [Target append options] [Target only options] [Compiler global options]

However neither of this take into account the current behavior of parser. If I understand it correctly, the defines are now loaded _only once_ after Code::Blocks is(are) run, on the loading of first project/workspace or individual file. Even if You close-load new project or workspace, or file, defines are never queried again.

So should the parser take into account current project (ie. the project to which the current file belongs to) and target and requery defines too?
« Last Edit: August 26, 2013, 01:53:07 pm by EnterTheNameHere »