From d81557a01fc841ecf798a2f134668c04a3cc7d70 Mon Sep 17 00:00:00 2001 From: Alex Lorenz Date: Thu, 4 May 2023 10:34:12 -0700 Subject: [PATCH] [interop][SwiftToCxx] remove extraneous semicolon when emitting 'pragma clang module import' The semicolon actually causes a compiler error in that case (cherry picked from commit 228078f074760215a799d363dea5e0adf05eacfd) --- lib/PrintAsClang/PrintAsClang.cpp | 6 +++--- .../bridge-cxx-struct-back-to-cxx.swift | 7 +++++-- .../bridge-cxx-struct-back-to-objcxx.swift | 13 +++++++++++++ 3 files changed, 21 insertions(+), 5 deletions(-) create mode 100644 test/Interop/CxxToSwiftToCxx/bridge-cxx-struct-back-to-objcxx.swift diff --git a/lib/PrintAsClang/PrintAsClang.cpp b/lib/PrintAsClang/PrintAsClang.cpp index ed3bacf10448a..278a4af50373d 100644 --- a/lib/PrintAsClang/PrintAsClang.cpp +++ b/lib/PrintAsClang/PrintAsClang.cpp @@ -448,6 +448,7 @@ writeImports(raw_ostream &out, llvm::SmallPtrSetImpl &imports, bool includeUnderlying = false; StringRef importDirective = useCxxImport ? "#pragma clang module import" : "@import"; + StringRef importDirectiveLineEnd = useCxxImport ? "\n" : ";\n"; for (auto import : sortedImports) { if (auto *swiftModule = import.dyn_cast()) { if (useCxxImport) { @@ -464,7 +465,7 @@ writeImports(raw_ostream &out, llvm::SmallPtrSetImpl &imports, continue; } if (seenImports.insert(Name).second) { - out << importDirective << ' ' << Name.str() << ";\n"; + out << importDirective << ' ' << Name.str() << importDirectiveLineEnd; if (frontendOpts.EmitClangHeaderWithNonModularIncludes) { if (const clang::Module *underlyingClangModule = swiftModule->findUnderlyingClangModule()) { @@ -487,8 +488,7 @@ writeImports(raw_ostream &out, llvm::SmallPtrSetImpl &imports, "top-level modules should use a normal swift::ModuleDecl"); out << importDirective << ' '; ModuleDecl::ReverseFullNameIterator(clangModule).printForward(out); - out << ";\n"; - + out << importDirectiveLineEnd; if (frontendOpts.EmitClangHeaderWithNonModularIncludes) { collectClangModuleHeaderIncludes( clangModule, fileManager, requiredTextualIncludes, visitedModules, diff --git a/test/Interop/CxxToSwiftToCxx/bridge-cxx-struct-back-to-cxx.swift b/test/Interop/CxxToSwiftToCxx/bridge-cxx-struct-back-to-cxx.swift index 259bf9fd8099d..550885c073905 100644 --- a/test/Interop/CxxToSwiftToCxx/bridge-cxx-struct-back-to-cxx.swift +++ b/test/Interop/CxxToSwiftToCxx/bridge-cxx-struct-back-to-cxx.swift @@ -15,7 +15,10 @@ // RUN: %check-interop-cxx-header-in-clang(%t/full-cxx-swift-cxx-bridging.h -Wno-reserved-identifier) -// FIXME: test in C++ with modules (but libc++ modularization is preventing this) +// Check that the generated header can be +// built with Clang modules enabled in C++. + +// RUN: %target-interop-build-clangxx -fsyntax-only -x c++-header %t/full-cxx-swift-cxx-bridging.h -std=gnu++20 -c -fmodules -fcxx-modules -I %t //--- header.h @@ -149,7 +152,7 @@ public func takeTrivialInout(_ x: inout Trivial) { // CHECK-NEXT: #if __has_warning("-Watimport-in-framework-header") // CHECK-NEXT: #pragma clang diagnostic ignored "-Watimport-in-framework-header" // CHECK-NEXT:#endif -// CHECK-NEXT: #pragma clang module import CxxTest; +// CHECK-NEXT: #pragma clang module import CxxTest // CHECK-NEXT: #endif diff --git a/test/Interop/CxxToSwiftToCxx/bridge-cxx-struct-back-to-objcxx.swift b/test/Interop/CxxToSwiftToCxx/bridge-cxx-struct-back-to-objcxx.swift new file mode 100644 index 0000000000000..09893eb82badc --- /dev/null +++ b/test/Interop/CxxToSwiftToCxx/bridge-cxx-struct-back-to-objcxx.swift @@ -0,0 +1,13 @@ +// RUN: %empty-directory(%t) +// RUN: split-file %S/bridge-cxx-struct-back-to-cxx.swift %t + +// RUN: %target-swift-frontend -typecheck %t/use-cxx-types.swift -typecheck -module-name UseCxxTy -emit-clang-header-path %t/UseCxxTy.h -I %t -enable-experimental-cxx-interop -clang-header-expose-decls=all-public -disable-availability-checking +// RUN: echo "#include \"header.h\"" > %t/full-cxx-swift-cxx-bridging.h +// RUN: cat %t/UseCxxTy.h >> %t/full-cxx-swift-cxx-bridging.h + +// Check that the generated header can be +// built with Clang modules enabled in ObjC++. + +// REQUIRES: objc_interop + +// RUN: %target-interop-build-clangxx -fsyntax-only -x objective-c++-header %t/full-cxx-swift-cxx-bridging.h -std=gnu++20 -c -fmodules -fcxx-modules -I %t