Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Macro redefinition error inside header stops whole compilation #140

Closed
Yanpas opened this issue Nov 29, 2018 · 15 comments
Closed

Macro redefinition error inside header stops whole compilation #140

Yanpas opened this issue Nov 29, 2018 · 15 comments

Comments

@Yanpas
Copy link

Yanpas commented Nov 29, 2018

UPD:
My project uses warnings intensively:
-Wall -Wextra -Werror=multichar -Wno-deprecated -Wno-unused-parameter -Woverloaded-virtual -Wnon-virtual-dtor -Werror -std=gnu++11 -Wno-unknown-pragmas.

I see macro redefinition error in many c++ files despite project compiles successfully. This error stops compilation on the point of error and autocompletion becomes too limited. The error is in some deep nested boost header, there is macro redefinition (compile command contains -D for that macro). After this error takes place whole compilation stops.

ORIGINAL COMMENT:
I switched from c3b4b7f to 1111, since I get a lot of warnings in my project:

  • size_t not found
  • set, string, vector not found in std
  • tons of others
@Yanpas
Copy link
Author

Yanpas commented Nov 29, 2018

A lot of files are skipped while parsing because of this weird error, which I don't face with cquery:
image

It appears in a lot of files on the line 11 even if there is a comment on that line

@Yanpas
Copy link
Author

Yanpas commented Nov 29, 2018

Logs with -v=100 do not produce any meaningful errors. (ps I don't know what's the maximum level -v argument accepts)

@Yanpas
Copy link
Author

Yanpas commented Nov 29, 2018

clang++ <rest of the command of .cpp with error> compiles successfully witho ut wanings and errors.

@MaskRay
Copy link
Owner

MaskRay commented Nov 29, 2018

-v=1 (LOG_V(1) only has one call site in project.cc) so it won't give too much output.

You may also read #138 (comment) for some useful commands.

Can you give some more information? e.g. if the file is a header or a normal C++ source, as .h .hpp .hh ... header files are handled differently. They are not indexed on their own

https://github.com/MaskRay/ccls/wiki/FAQ#diagnostics-in-headers

@Yanpas
Copy link
Author

Yanpas commented Nov 29, 2018

The error is in some deep nested boost header, there is macro redefinition (compile command contains -D for that macro). After this error takes place whole compilation stops.

It looks like tthis:
command: g++ file.cpp -Dfoo

Some file included in file.cpp contains
#define foo

There seem to be no regressions, all ccls face this issue. Cqery handles it fine.

BTW project build takes place inside docker

@MaskRay
Copy link
Owner

MaskRay commented Nov 29, 2018

Does clang.extraArgs: ["-Wno-macro-redefined"] or -w suppress the issue?

@Yanpas
Copy link
Author

Yanpas commented Nov 30, 2018

Yes, it does. It makes ccls usable since clang doesn't stop on that error and compiles source that goes after. Is there a way to configure libclang to skip such errors and compile each file as much as it can?

@Yanpas Yanpas changed the title Regression in master since 1111: template vector not found in std Macro redefinition error inside header stops whole compilation Nov 30, 2018
@MaskRay
Copy link
Owner

MaskRay commented Nov 30, 2018

If your project uses -Wall -Werror etc, please paste them here. -Werror is known to cause trouble in preamble (longest prefix of the file which consists entirely of preprocessor tokens)

You may try adding "no-macro-redefined" to CI.getDiagnosticOpts().Warnings and tell me what happens.
https://github.com/maskray/ccls/blob/master/src/clang_complete.cc#L321

void BuildPreamble(CompletionSession &session, CompilerInvocation &CI,
...
  // -Werror makes warnings issued as errors, which stops parsing
  // prematurely because of -ferror-limit=. This also works around the issue
  // of -Werror + -Wunused-parameter in interaction with SkipFunctionBodies.
  auto &Ws = CI.getDiagnosticOpts().Warnings;
  Ws.erase(std::remove(Ws.begin(), Ws.end(), "error"), Ws.end());

@Yanpas
Copy link
Author

Yanpas commented Dec 6, 2018

My project uses warnings intensively:
-Wall -Wextra -Werror=multichar -Wno-deprecated -Wno-unused-parameter -Woverloaded-virtual -Wnon-virtual-dtor -Werror -std=gnu++11 -Wno-unknown-pragmas

@Yanpas
Copy link
Author

Yanpas commented Dec 6, 2018

index fab5daf7..cdd2ff32 100644
--- a/src/clang_complete.cc
+++ b/src/clang_complete.cc
@@ -318,6 +318,7 @@ void BuildPreamble(CompletionSession &session, CompilerInvocation &CI,
   // prematurely because of -ferror-limit=. This also works around the issue
   // of -Werror + -Wunused-parameter in interaction with SkipFunctionBodies.
   auto &Ws = CI.getDiagnosticOpts().Warnings;
+  Ws.push_back("no-macro-redefined");
   Ws.erase(std::remove(Ws.begin(), Ws.end(), "error"), Ws.end());
   CI.getDiagnosticOpts().IgnoreWarnings = false;
   CI.getFrontendOpts().SkipFunctionBodies = true;

that didn't help, still get same error

@MaskRay
Copy link
Owner

MaskRay commented Dec 7, 2018

Can you take a look at https://github.com/llvm-mirror/clang/blob/master/test/Index/preamble.c and use

  • c-index-test -write-pch t.pch <options>
  • CINDEXTEST_EDITING=1 c-index-test -test-load-source-reparse 5 local -include t <options>

to check if libclang has the same issue? pp-trace <options> can be used to verify if you do have macro redefinition issue.

Please put all the pieces of information into one place. You can amend #140 (comment)

@Yanpas
Copy link
Author

Yanpas commented Dec 7, 2018

I've created COMMAND and COMMAND2 files. First one contains compile command without first argument (g++). Second is the same as first but without -Werror.

c-index-test -write-pch t.pch $(< COMMAND) printed 8 lines with the error "error: class 'XXX' was previously declared as a struct [-Wmismatched-tags]". Same with COMMAND2 didn't print anything.

CINDEXTEST_EDITING=1 c-index-test -test-load-source-reparse 5 local -include t $(< COMMAND) printed a loooot of // CHECK and

error: 'BOOST_NO_CXX11_HDR_CODECVT' macro redefined [-Wmacro-redefined]
/home/yan/dev/project/build/contrib/boost_1_57_0/include/boost-1_57/boost/config/stdlib/libstdcpp3.hpp:221:11: note: previous definition is here

by the end.

@MaskRay
Copy link
Owner

MaskRay commented Dec 9, 2018

c-index-test -write-pch t.pch $(< COMMAND) printed 8 lines with the error "error: class 'XXX' was previously declared as a struct [-Wmismatched-tags]". Same with COMMAND2 didn't print anything.

-Wmismatched-tags is enabled by -Wmost (and also -Wall). You do have issues in your header files.

% diagtool show-enabled -Wmost a.cc | grep mismatched-tag 
W  warn_struct_class_previous_tag_mismatch [-Wmismatched-tags]
W  warn_struct_class_tag_mismatch [-Wmismatched-tags]

You probably have -Werror somewhere which turns warnings to errors (note your diagnostic messages). Please delete them.

The default -ferror-limit is 19, after that many of errors clang will stop parsing.

@MaskRay MaskRay closed this as completed Dec 9, 2018
@Yanpas
Copy link
Author

Yanpas commented Dec 9, 2018

Do these errors occur because of the logic of header parsing? (reduced number of header parsing)

@MaskRay
Copy link
Owner

MaskRay commented Dec 9, 2018

Yes.

"error: class 'XXX' was previously declared as a struct [-Wmismatched-tags]"

Delete your -Wall to make it a warning, or figure out why Ws.erase(std::remove(Ws.begin(), Ws.end(), "error"), Ws.end()); does not fix it for you

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants