Index: clang-tools-extra/trunk/clangd/GlobalCompilationDatabase.h =================================================================== --- clang-tools-extra/trunk/clangd/GlobalCompilationDatabase.h +++ clang-tools-extra/trunk/clangd/GlobalCompilationDatabase.h @@ -52,6 +52,7 @@ public: DirectoryBasedGlobalCompilationDatabase( llvm::Optional CompileCommandsDir); + ~DirectoryBasedGlobalCompilationDatabase() override; /// Scans File's parents looking for compilation databases. /// Any extra flags will be added. Index: clang-tools-extra/trunk/clangd/GlobalCompilationDatabase.cpp =================================================================== --- clang-tools-extra/trunk/clangd/GlobalCompilationDatabase.cpp +++ clang-tools-extra/trunk/clangd/GlobalCompilationDatabase.cpp @@ -18,9 +18,15 @@ tooling::CompileCommand GlobalCompilationDatabase::getFallbackCommand(PathRef File) const { + std::vector Argv = {"clang"}; + // Clang treats .h files as C by default, resulting in unhelpful diagnostics. + // Parsing as Objective C++ is friendly to more cases. + if (llvm::sys::path::extension(File) == ".h") + Argv.push_back("-xobjective-c++-header"); + Argv.push_back(File); return tooling::CompileCommand(llvm::sys::path::parent_path(File), llvm::sys::path::filename(File), - {"clang", File.str()}, + std::move(Argv), /*Output=*/""); } @@ -29,6 +35,9 @@ llvm::Optional CompileCommandsDir) : CompileCommandsDir(std::move(CompileCommandsDir)) {} +DirectoryBasedGlobalCompilationDatabase:: + ~DirectoryBasedGlobalCompilationDatabase() = default; + llvm::Optional DirectoryBasedGlobalCompilationDatabase::getCompileCommand(PathRef File) const { if (auto CDB = getCDBForFile(File)) { Index: clang-tools-extra/trunk/unittests/clangd/CMakeLists.txt =================================================================== --- clang-tools-extra/trunk/unittests/clangd/CMakeLists.txt +++ clang-tools-extra/trunk/unittests/clangd/CMakeLists.txt @@ -18,6 +18,7 @@ DraftStoreTests.cpp FileIndexTests.cpp FuzzyMatchTests.cpp + GlobalCompilationDatabaseTests.cpp HeadersTests.cpp IndexTests.cpp JSONExprTests.cpp Index: clang-tools-extra/trunk/unittests/clangd/GlobalCompilationDatabaseTests.cpp =================================================================== --- clang-tools-extra/trunk/unittests/clangd/GlobalCompilationDatabaseTests.cpp +++ clang-tools-extra/trunk/unittests/clangd/GlobalCompilationDatabaseTests.cpp @@ -0,0 +1,37 @@ +//===-- GlobalCompilationDatabaseTests.cpp ----------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "GlobalCompilationDatabase.h" + +#include "TestFS.h" +#include "llvm/ADT/StringExtras.h" +#include "gmock/gmock.h" +#include "gtest/gtest.h" + +namespace clang { +namespace clangd { +namespace { +using ::testing::ElementsAre; + +TEST(GlobalCompilationDatabaseTest, FallbackCommand) { + DirectoryBasedGlobalCompilationDatabase DB(llvm::None); + auto Cmd = DB.getFallbackCommand(testPath("foo/bar.cc")); + EXPECT_EQ(Cmd.Directory, testPath("foo")); + EXPECT_THAT(Cmd.CommandLine, ElementsAre("clang", testPath("foo/bar.cc"))); + EXPECT_EQ(Cmd.Output, ""); + + // .h files have unknown language, so they are parsed liberally as obj-c++. + Cmd = DB.getFallbackCommand(testPath("foo/bar.h")); + EXPECT_THAT(Cmd.CommandLine, ElementsAre("clang", "-xobjective-c++-header", + testPath("foo/bar.h"))); +} + +} // namespace +} // namespace clangd +} // namespace clang Index: clang-tools-extra/trunk/unittests/clangd/TestFS.cpp =================================================================== --- clang-tools-extra/trunk/unittests/clangd/TestFS.cpp +++ clang-tools-extra/trunk/unittests/clangd/TestFS.cpp @@ -55,8 +55,10 @@ std::string testPath(PathRef File) { assert(sys::path::is_relative(File) && "FileName should be relative"); + SmallString<32> NativeFile = File; + sys::path::native(NativeFile); SmallString<32> Path; - sys::path::append(Path, testRoot(), File); + sys::path::append(Path, testRoot(), NativeFile); return Path.str(); }