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

Reply via email to