diff --git a/clang/docs/JSONCompilationDatabase.rst b/clang/docs/JSONCompilationDatabase.rst --- a/clang/docs/JSONCompilationDatabase.rst +++ b/clang/docs/JSONCompilationDatabase.rst @@ -86,7 +86,8 @@ compilation step. This is used by tools as the key into the compilation database. There can be multiple command objects for the same file, for example if the same source file is compiled with - different configurations. + different configurations. ``dot`` (./) ``dotdot`` (../) in the path is + stripped lexically. - **arguments:** The compile command argv as list of strings. This should run the compilation step for the translation unit ``file``. ``arguments[0]`` should be the executable name, such as ``clang++``. diff --git a/clang/lib/Tooling/JSONCompilationDatabase.cpp b/clang/lib/Tooling/JSONCompilationDatabase.cpp --- a/clang/lib/Tooling/JSONCompilationDatabase.cpp +++ b/clang/lib/Tooling/JSONCompilationDatabase.cpp @@ -426,6 +426,7 @@ llvm::sys::path::native(AbsolutePath, NativeFilePath); } else { llvm::sys::path::native(FileName, NativeFilePath); + llvm::sys::path::remove_dots(NativeFilePath, /*remove_dot_dot=*/ true); } auto Cmd = CompileCommandRef(Directory, File, *Command, Output); IndexByFile[NativeFilePath].push_back(Cmd); diff --git a/clang/unittests/Tooling/CompilationDatabaseTest.cpp b/clang/unittests/Tooling/CompilationDatabaseTest.cpp --- a/clang/unittests/Tooling/CompilationDatabaseTest.cpp +++ b/clang/unittests/Tooling/CompilationDatabaseTest.cpp @@ -92,16 +92,32 @@ expected_files.push_back(std::string(PathStorage.str())); llvm::sys::path::native("//net/file1", PathStorage); expected_files.push_back(std::string(PathStorage.str())); + llvm::sys::path::native("//net/dir/file3", PathStorage); + expected_files.push_back(std::string(PathStorage.str())); EXPECT_EQ(expected_files, - getAllFiles("[{\"directory\":\"//net/dir\"," - "\"command\":\"command\"," - "\"file\":\"file1\"}," - " {\"directory\":\"//net/dir\"," - "\"command\":\"command\"," - "\"file\":\"../file1\"}," - " {\"directory\":\"//net/dir\"," - "\"command\":\"command\"," - "\"file\":\"file2\"}]", + getAllFiles(R"json( + [ + { + "directory": "//net/dir", + "command": "command", + "file": "file1" + }, + { + "directory": "//net/dir", + "command": "command", + "file": "../file1" + }, + { + "directory": "//net/dir", + "command": "command", + "file": "file2" + }, + { + "directory": "//net/dir", + "command": "command", + "file": "//net/dir/foo/../file3" + } + ])json", ErrorMessage, JSONCommandLineSyntax::Gnu)) << ErrorMessage; }