Caphyon / clang-power-tools

Bringing clang-tidy magic to Visual Studio C++ developers.
http://www.clangpowertools.com
Apache License 2.0
472 stars 57 forks source link

error: definition of macro differs between the precompiled header ('\\') and the command line(')" #1341

Open lursyy opened 4 months ago

lursyy commented 4 months ago

Similar to #410, and maybe related to bdd86b85fdb164ff8af054622ce4908200e4e0eb and 5a465256f9d43db7f5ab0d686af24cb46f7470ce.

Problem

Some of the <PreprocessorDefinitions> generated by our custom build tool contain escaped backslashes, e.g.

[...];VCXPROJ_DIR=L"D:\\src\\path\\to\\some\\project";[...]

The corresponding clang++ parameter generated by clang-build.ps1 looks like this (from verbose output):

INVOKE: C:\Program Files\LLVM\bin\clang++.exe [...] "-DVCXPROJ_DIR=L\"D:\\src\\path\\to\\some\\project\"" [...].

Clang then produces the following error:

error: definition of macro 'VCXPROJ_DIR' differs between the precompiled header ('L"D:\\src\\path\\to\\some\\project"')
and the command line ('L"D:\src\path\to\some\project"') [clang-diagnostic-error]

What I tried

First, am I correct to assume that the escaped backslashes in our generated .vcxproj are not the problem? I tried adding a -replace "\\", "\\" in Get-ProjectPreprocessorDefines, which didn't help:

error: definition of macro 'VCXPROJ_DIR' differs between the precompiled header ('L"D:\\\\src\\\\path\\\\to\\\\some\\\\project"')
and the command line ('L"D:\\\src\\\path\\\to\\\some\\\project"') [clang-diagnostic-error]

Then I tried removing the double backslashes, i.e. -replace "\\\\", "\". That seemed to work, but somehow I doubt that this is the real solution: Wouldn't we want to preserve the ecape sequences as is? Does the Clang(++) handle these escapes differently than CL? Can the PCH be fixed so that both contain the escaped backslashes?

lursyy commented 3 months ago

I think I just noticed an additional bug in the jsondb-export job: See JsonDB-Push:

# use only slashes
$command = $command.Replace('\', '/')
$file = $file.Replace('\', '/')
$directory = $directory.Replace('\', '/')

# escape double quotes
$command = $command.Replace('"', '\"')

where in my case $command contains backslash-escaped quotes. This results in

 \"-DVCXPROJ_DIR=L/\"D://src//path//to//some//project/\"\"

When I the run a tool that uses this compilation database (e.g. clang-rename), clang complains:

In file included from <built-in>:444:
<command line>:14:23: warning: missing terminating '"' character [-Winvalid-pp-token]
   14 | #define VCXPROJ_DIR L/"
      |                       ^

Should I create a separate issue, or are they related enough?