[Tooling] Add -x flags when inferring compile commands for files with no/invalid extension.

Summary: We treat them as headers, as the motivating case is C++ standard library.

Reviewers: kadircet

Subscribers: cfe-commits

Tags: #clang

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

llvm-svn: 360153
This commit is contained in:
Sam McCall 2019-05-07 14:34:06 +00:00
parent d6865b7d71
commit 87ad30be5f
2 changed files with 12 additions and 6 deletions

View File

@ -205,10 +205,13 @@ struct TransferableCommand {
bool TypeCertain; bool TypeCertain;
auto TargetType = guessType(Filename, &TypeCertain); auto TargetType = guessType(Filename, &TypeCertain);
// If the filename doesn't determine the language (.h), transfer with -x. // If the filename doesn't determine the language (.h), transfer with -x.
if (TargetType != types::TY_INVALID && !TypeCertain && Type) { if ((!TargetType || !TypeCertain) && Type) {
TargetType = types::onlyPrecompileType(TargetType) // header? // Use *Type, or its header variant if the file is a header.
? types::lookupHeaderTypeForSourceType(*Type) // Treat no/invalid extension as header (e.g. C++ standard library).
: *Type; TargetType =
(!TargetType || types::onlyPrecompileType(TargetType)) // header?
? types::lookupHeaderTypeForSourceType(*Type)
: *Type;
if (ClangCLMode) { if (ClangCLMode) {
const StringRef Flag = toCLFlag(TargetType); const StringRef Flag = toCLFlag(TargetType);
if (!Flag.empty()) if (!Flag.empty())

View File

@ -723,14 +723,17 @@ TEST_F(InterpolateTest, Language) {
// .h is ambiguous, so we add explicit language flags // .h is ambiguous, so we add explicit language flags
EXPECT_EQ(getCommand("foo.h"), EXPECT_EQ(getCommand("foo.h"),
"clang -D dir/foo.cpp -x c++-header -std=c++17"); "clang -D dir/foo.cpp -x c++-header -std=c++17");
// Same thing if we have no extension. (again, we treat as header).
EXPECT_EQ(getCommand("foo"), "clang -D dir/foo.cpp -x c++-header -std=c++17");
// and invalid extensions.
EXPECT_EQ(getCommand("foo.cce"),
"clang -D dir/foo.cpp -x c++-header -std=c++17");
// and don't add -x if the inferred language is correct. // and don't add -x if the inferred language is correct.
EXPECT_EQ(getCommand("foo.hpp"), "clang -D dir/foo.cpp -std=c++17"); EXPECT_EQ(getCommand("foo.hpp"), "clang -D dir/foo.cpp -std=c++17");
// respect -x if it's already there. // respect -x if it's already there.
EXPECT_EQ(getCommand("baz.h"), "clang -D dir/baz.cee -x c-header"); EXPECT_EQ(getCommand("baz.h"), "clang -D dir/baz.cee -x c-header");
// prefer a worse match with the right extension. // prefer a worse match with the right extension.
EXPECT_EQ(getCommand("foo.c"), "clang -D dir/bar.c"); EXPECT_EQ(getCommand("foo.c"), "clang -D dir/bar.c");
// make sure we don't crash on queries with invalid extensions.
EXPECT_EQ(getCommand("foo.cce"), "clang -D dir/foo.cpp");
Entries.erase(path(StringRef("dir/bar.c"))); Entries.erase(path(StringRef("dir/bar.c")));
// Now we transfer across languages, so drop -std too. // Now we transfer across languages, so drop -std too.
EXPECT_EQ(getCommand("foo.c"), "clang -D dir/foo.cpp"); EXPECT_EQ(getCommand("foo.c"), "clang -D dir/foo.cpp");