Parse .h files as objective-c++ if we don't have a compile command.

Summary: This makes C++/objC not totally broken, without hurting C files too much.

Reviewers: ilya-biryukov

Subscribers: klimek, jkorous-apple, ioeric, cfe-commits

Differential Revision: https://reviews.llvm.org/D45442

llvm-svn: 330418
This commit is contained in:
Sam McCall 2018-04-20 11:35:17 +00:00
parent 3085cdc99e
commit 690dcf12c2
5 changed files with 52 additions and 2 deletions

View File

@ -18,9 +18,15 @@ namespace clangd {
tooling::CompileCommand
GlobalCompilationDatabase::getFallbackCommand(PathRef File) const {
std::vector<std::string> 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 @@ DirectoryBasedGlobalCompilationDatabase::
llvm::Optional<Path> CompileCommandsDir)
: CompileCommandsDir(std::move(CompileCommandsDir)) {}
DirectoryBasedGlobalCompilationDatabase::
~DirectoryBasedGlobalCompilationDatabase() = default;
llvm::Optional<tooling::CompileCommand>
DirectoryBasedGlobalCompilationDatabase::getCompileCommand(PathRef File) const {
if (auto CDB = getCDBForFile(File)) {

View File

@ -52,6 +52,7 @@ class DirectoryBasedGlobalCompilationDatabase
public:
DirectoryBasedGlobalCompilationDatabase(
llvm::Optional<Path> CompileCommandsDir);
~DirectoryBasedGlobalCompilationDatabase() override;
/// Scans File's parents looking for compilation databases.
/// Any extra flags will be added.

View File

@ -18,6 +18,7 @@ add_extra_unittest(ClangdTests
DraftStoreTests.cpp
FileIndexTests.cpp
FuzzyMatchTests.cpp
GlobalCompilationDatabaseTests.cpp
HeadersTests.cpp
IndexTests.cpp
JSONExprTests.cpp

View File

@ -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

View File

@ -55,8 +55,10 @@ const char *testRoot() {
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();
}