https://github.com/HighCommander4 updated https://github.com/llvm/llvm-project/pull/184560
>From 616555108bf6a266e58d026d63845b2f9a651a10 Mon Sep 17 00:00:00 2001 From: Dominique Fuchs <[email protected]> Date: Wed, 4 Mar 2026 08:05:46 +0100 Subject: [PATCH] [clang][Tooling] Preserve -std flag across same-family transferance transferTo() stripped the -std flag when inferring a header's compile command from sources of a different but compatible language mode, not only when changing language family. This commit replaces the foldType() equality check with a standard-family comparison using the existing types::isCXX() and types::isDerivedFromC() predicate. Fixes https://github.com/clangd/clangd/issues/2613 Signed-off-by: Dominique Fuchs <[email protected]> --- .../Tooling/InterpolatingCompilationDatabase.cpp | 16 +++++++++++++--- .../Tooling/CompilationDatabaseTest.cpp | 14 ++++++++++++++ 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/clang/lib/Tooling/InterpolatingCompilationDatabase.cpp b/clang/lib/Tooling/InterpolatingCompilationDatabase.cpp index f8306a6ad6e90..3f71165547244 100644 --- a/clang/lib/Tooling/InterpolatingCompilationDatabase.cpp +++ b/clang/lib/Tooling/InterpolatingCompilationDatabase.cpp @@ -123,6 +123,14 @@ static types::ID foldType(types::ID Lang) { } } +// Whether two types use the same -std flag family. +// C and ObjC share C standards; C++, ObjC++, CUDA, HIP share C++ standards. +static bool typesSameStandardFamily(types::ID T1, types::ID T2) { + if (!types::isDerivedFromC(T1) || !types::isDerivedFromC(T2)) + return false; + return types::isCXX(T1) == types::isCXX(T2); +} + // Return the language standard that's activated by the /std:clatest // flag in clang-CL mode. static LangStandard::Kind latestLangStandardC() { @@ -253,9 +261,11 @@ struct TransferableCommand { } } - // --std flag may only be transferred if the language is the same. - // We may consider "translating" these, e.g. c++11 -> c11. - if (Std != LangStandard::lang_unspecified && foldType(TargetType) == Type) { + // --std flag may only be transferred if the language families share + // compatible standards. C/ObjC share C standards; C++/ObjC++/CUDA/HIP + // share C++ standards. + if (Std != LangStandard::lang_unspecified && Type && + typesSameStandardFamily(foldType(TargetType), *Type)) { const char *Spelling = LangStandard::getLangStandardForKind(Std).getName(); diff --git a/clang/unittests/Tooling/CompilationDatabaseTest.cpp b/clang/unittests/Tooling/CompilationDatabaseTest.cpp index 2d68e0994c93e..0640a1e7ba9b1 100644 --- a/clang/unittests/Tooling/CompilationDatabaseTest.cpp +++ b/clang/unittests/Tooling/CompilationDatabaseTest.cpp @@ -847,6 +847,20 @@ TEST_F(InterpolateTest, Language) { "clang -D dir/aux.cpp -x objective-c++-header -std=c++17"); } +TEST_F(InterpolateTest, StdTransferSameFamily) { + // ObjC++ → C++ header: same standard family, -std should survive. + add("dir/foo.mm", "-std=c++20"); + EXPECT_EQ(getCommand("dir/foo.hh"), "clang -D dir/foo.mm -std=c++20"); + + // Explicit -x objective-c++ on .cpp → C++ header: same family. + add("dir/bar.cpp", "-x objective-c++ -std=c++20"); + EXPECT_EQ(getCommand("dir/bar.hh"), "clang -D dir/bar.cpp -std=c++20"); + + // ObjC → C: same standard family, -std should survive. + add("dir/baz.m", "-std=c17"); + EXPECT_EQ(getCommand("dir/baz.c"), "clang -D dir/baz.m -std=c17"); +} + TEST_F(InterpolateTest, Strip) { add("dir/foo.cpp", "-o foo.o -Wall"); // the -o option and the input file are removed, but -Wall is preserved. _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
