Skip to content

Commit d3e928f

Browse files
committed
[clang][Driver] Don't ignore -gmodules .gch files
A previous commit (82f75ed) made clang ignore .gch files that were not Clang AST files. This broke `-gmodules`, which embeds the Clang AST into an object file containing debug info. This changes the probing to detect any valid object file as a potential Clang PCH.
1 parent 286a366 commit d3e928f

File tree

6 files changed

+28
-7
lines changed

6 files changed

+28
-7
lines changed

clang/lib/Driver/ToolChains/Clang.cpp

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,9 @@
4343
#include "clang/Driver/XRayArgs.h"
4444
#include "llvm/ADT/SmallSet.h"
4545
#include "llvm/ADT/StringExtras.h"
46+
#include "llvm/BinaryFormat/Magic.h"
4647
#include "llvm/Config/llvm-config.h"
48+
#include "llvm/Object/ObjectFile.h"
4749
#include "llvm/Option/ArgList.h"
4850
#include "llvm/Support/CodeGen.h"
4951
#include "llvm/Support/Compiler.h"
@@ -948,11 +950,21 @@ static void handleAMDGPUCodeObjectVersionOptions(const Driver &D,
948950
}
949951
}
950952

951-
static bool hasClangPchSignature(const Driver &D, StringRef Path) {
952-
if (llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> MemBuf =
953-
D.getVFS().getBufferForFile(Path))
954-
return (*MemBuf)->getBuffer().starts_with("CPCH");
955-
return false;
953+
static bool maybeHasClangPchSignature(const Driver &D, StringRef Path) {
954+
llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> MemBuf =
955+
D.getVFS().getBufferForFile(Path);
956+
if (!MemBuf)
957+
return false;
958+
llvm::file_magic Magic = llvm::identify_magic((*MemBuf)->getBuffer());
959+
if (Magic == llvm::file_magic::unknown)
960+
return false;
961+
// Return true for both raw Clang AST files and object files which may
962+
// contain a __clangast section.
963+
if (Magic == llvm::file_magic::clang_ast)
964+
return true;
965+
Expected<std::unique_ptr<llvm::object::ObjectFile>> Obj =
966+
llvm::object::ObjectFile::createObjectFile(**MemBuf, Magic);
967+
return !Obj.takeError();
956968
}
957969

958970
static bool gchProbe(const Driver &D, StringRef Path) {
@@ -964,14 +976,14 @@ static bool gchProbe(const Driver &D, StringRef Path) {
964976
std::error_code EC;
965977
for (llvm::vfs::directory_iterator DI = D.getVFS().dir_begin(Path, EC), DE;
966978
!EC && DI != DE; DI = DI.increment(EC)) {
967-
if (hasClangPchSignature(D, DI->path()))
979+
if (maybeHasClangPchSignature(D, DI->path()))
968980
return true;
969981
}
970982
D.Diag(diag::warn_drv_pch_ignoring_gch_dir) << Path;
971983
return false;
972984
}
973985

974-
if (hasClangPchSignature(D, Path))
986+
if (maybeHasClangPchSignature(D, Path))
975987
return true;
976988
D.Diag(diag::warn_drv_pch_ignoring_gch_file) << Path;
977989
return false;

clang/test/PCH/gch-probe.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22
// RUN: %clang -x c-header -c %s -o %t.h.gch
33
// RUN: %clang -fsyntax-only -include %t.h %s
44

5+
// -gmodules embeds the Clang AST file in an object file.
6+
// RUN: %clang -x c-header -c %s -gmodules -o %t.h.gch
7+
// RUN: %clang -fsyntax-only -include %t.h %s
8+
59
// gch probing should ignore files which are not clang pch files.
610
// RUN: %clang -fsyntax-only -include %S/Inputs/gch-probe.h %s 2>&1 | FileCheck %s
711
// CHECK: warning: precompiled header '{{.*}}gch-probe.h.gch' was ignored because it is not a clang PCH file

llvm/include/llvm/BinaryFormat/Magic.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ struct file_magic {
2121
enum Impl {
2222
unknown = 0, ///< Unrecognized file
2323
bitcode, ///< Bitcode file
24+
clang_ast, ///< Clang PCH or PCM
2425
archive, ///< ar style archive file
2526
elf, ///< ELF Unknown type
2627
elf_relocatable, ///< ELF Relocatable object file

llvm/lib/BinaryFormat/Magic.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,8 @@ file_magic llvm::identify_magic(StringRef Magic) {
9898
case 'C':
9999
if (startswith(Magic, "CCOB"))
100100
return file_magic::offload_bundle_compressed;
101+
if (startswith(Magic, "CPCH"))
102+
return file_magic::clang_ast;
101103
break;
102104
case '!':
103105
if (startswith(Magic, "!<arch>\n") || startswith(Magic, "!<thin>\n"))

llvm/lib/Object/Binary.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ Expected<std::unique_ptr<Binary>> object::createBinary(MemoryBufferRef Buffer,
8484
// PDB does not support the Binary interface.
8585
return errorCodeToError(object_error::invalid_file_type);
8686
case file_magic::unknown:
87+
case file_magic::clang_ast:
8788
case file_magic::cuda_fatbinary:
8889
case file_magic::coff_cl_gl_object:
8990
case file_magic::dxcontainer_object:

llvm/lib/Object/ObjectFile.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,7 @@ ObjectFile::createObjectFile(MemoryBufferRef Object, file_magic Type,
155155
switch (Type) {
156156
case file_magic::unknown:
157157
case file_magic::bitcode:
158+
case file_magic::clang_ast:
158159
case file_magic::coff_cl_gl_object:
159160
case file_magic::archive:
160161
case file_magic::macho_universal_binary:

0 commit comments

Comments
 (0)