summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
Diffstat (limited to 'clang')
-rw-r--r--clang/include/clang/Frontend/Utils.h3
-rw-r--r--clang/include/clang/Lex/ModuleMap.h5
-rw-r--r--clang/lib/Frontend/ModuleDependencyCollector.cpp21
-rw-r--r--clang/lib/Lex/ModuleMap.cpp4
-rw-r--r--clang/test/Modules/crash-vfs-path-symlink-topheader.m50
5 files changed, 81 insertions, 2 deletions
diff --git a/clang/include/clang/Frontend/Utils.h b/clang/include/clang/Frontend/Utils.h
index 6ee2a15d815..903d70cc3bb 100644
--- a/clang/include/clang/Frontend/Utils.h
+++ b/clang/include/clang/Frontend/Utils.h
@@ -77,7 +77,7 @@ void DoPrintPreprocessedInput(Preprocessor &PP, raw_ostream* OS,
/// interface.
class DependencyCollector {
public:
- void attachToPreprocessor(Preprocessor &PP);
+ virtual void attachToPreprocessor(Preprocessor &PP);
virtual void attachToASTReader(ASTReader &R);
llvm::ArrayRef<std::string> getDependencies() const { return Dependencies; }
@@ -136,6 +136,7 @@ public:
VFSWriter.addFileMapping(VPath, RPath);
}
+ void attachToPreprocessor(Preprocessor &PP) override;
void attachToASTReader(ASTReader &R) override;
void writeFileMap();
diff --git a/clang/include/clang/Lex/ModuleMap.h b/clang/include/clang/Lex/ModuleMap.h
index 522b3f2f9cf..d8d374b622b 100644
--- a/clang/include/clang/Lex/ModuleMap.h
+++ b/clang/include/clang/Lex/ModuleMap.h
@@ -50,6 +50,11 @@ public:
/// \param IsSystem Whether this is a module map from a system include path.
virtual void moduleMapFileRead(SourceLocation FileStart,
const FileEntry &File, bool IsSystem) {}
+
+ /// \brief Called when a header is added during module map parsing.
+ ///
+ /// \param File The header file itself.
+ virtual void moduleMapAddHeader(const FileEntry &File) {}
};
class ModuleMap {
diff --git a/clang/lib/Frontend/ModuleDependencyCollector.cpp b/clang/lib/Frontend/ModuleDependencyCollector.cpp
index fc3958f601a..e0ec674a16c 100644
--- a/clang/lib/Frontend/ModuleDependencyCollector.cpp
+++ b/clang/lib/Frontend/ModuleDependencyCollector.cpp
@@ -12,6 +12,7 @@
//===----------------------------------------------------------------------===//
#include "clang/Frontend/Utils.h"
+#include "clang/Lex/Preprocessor.h"
#include "clang/Serialization/ASTReader.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/iterator_range.h"
@@ -22,7 +23,7 @@
using namespace clang;
namespace {
-/// Private implementation for ModuleDependencyCollector
+/// Private implementations for ModuleDependencyCollector
class ModuleDependencyListener : public ASTReaderListener {
ModuleDependencyCollector &Collector;
public:
@@ -36,12 +37,30 @@ public:
return true;
}
};
+
+struct ModuleDependencyMMCallbacks : public ModuleMapCallbacks {
+ ModuleDependencyCollector &Collector;
+ ModuleDependencyMMCallbacks(ModuleDependencyCollector &Collector)
+ : Collector(Collector) {}
+
+ void moduleMapAddHeader(const FileEntry &File) override {
+ StringRef HeaderPath = File.getName();
+ if (llvm::sys::path::is_absolute(HeaderPath))
+ Collector.addFile(HeaderPath);
+ }
+};
+
}
void ModuleDependencyCollector::attachToASTReader(ASTReader &R) {
R.addListener(llvm::make_unique<ModuleDependencyListener>(*this));
}
+void ModuleDependencyCollector::attachToPreprocessor(Preprocessor &PP) {
+ PP.getHeaderSearchInfo().getModuleMap().addModuleMapCallbacks(
+ llvm::make_unique<ModuleDependencyMMCallbacks>(*this));
+}
+
void ModuleDependencyCollector::writeFileMap() {
if (Seen.empty())
return;
diff --git a/clang/lib/Lex/ModuleMap.cpp b/clang/lib/Lex/ModuleMap.cpp
index 69cb574e2a0..4b782a3e8ec 100644
--- a/clang/lib/Lex/ModuleMap.cpp
+++ b/clang/lib/Lex/ModuleMap.cpp
@@ -811,6 +811,10 @@ void ModuleMap::addHeader(Module *Mod, Module::Header Header,
HeaderInfo.MarkFileModuleHeader(Header.Entry, Role,
isCompilingModuleHeader);
}
+
+ // Notify callbacks that we just added a new header.
+ for (const auto &Cb : Callbacks)
+ Cb->moduleMapAddHeader(*Header.Entry);
}
void ModuleMap::excludeHeader(Module *Mod, Module::Header Header) {
diff --git a/clang/test/Modules/crash-vfs-path-symlink-topheader.m b/clang/test/Modules/crash-vfs-path-symlink-topheader.m
new file mode 100644
index 00000000000..29f6b9322df
--- /dev/null
+++ b/clang/test/Modules/crash-vfs-path-symlink-topheader.m
@@ -0,0 +1,50 @@
+// REQUIRES: crash-recovery, shell
+
+// FIXME: This XFAIL is cargo-culted from crash-report.c. Do we need it?
+// XFAIL: mingw32
+
+// Test clang can collect symbolic link headers used in modules.
+// crash reproducer if there's a symbolic link header file used in a module.
+
+// RUN: rm -rf %t
+// RUN: mkdir -p %t/i %t/m %t %t/sysroot
+// RUN: cp -a %S/Inputs/crash-recovery/usr %t/i/
+// RUN: rm -f %t/i/usr/include/pthread_impl.h
+// RUN: ln -s pthread/pthread_impl.h %t/i/usr/include/pthread_impl.h
+
+// RUN: not env FORCE_CLANG_DIAGNOSTICS_CRASH= TMPDIR=%t TEMP=%t TMP=%t \
+// RUN: %clang -fsyntax-only %s -I %/t/i -isysroot %/t/sysroot/ \
+// RUN: -fmodules -fmodules-cache-path=%t/m/ 2>&1 | FileCheck %s
+
+// RUN: FileCheck --check-prefix=CHECKSRC %s -input-file %t/crash-vfs-*.m
+// RUN: FileCheck --check-prefix=CHECKSH %s -input-file %t/crash-vfs-*.sh
+// RUN: FileCheck --check-prefix=CHECKYAML %s -input-file \
+// RUN: %t/crash-vfs-*.cache/vfs/vfs.yaml
+// RUN: find %t/crash-vfs-*.cache/vfs | \
+// RUN: grep "usr/include/pthread_impl.h" | count 1
+
+#include "usr/include/stdio.h"
+
+// CHECK: Preprocessed source(s) and associated run script(s) are located at:
+// CHECK-NEXT: note: diagnostic msg: {{.*}}.m
+// CHECK-NEXT: note: diagnostic msg: {{.*}}.cache
+
+// CHECKSRC: @import cstd.stdio;
+
+// CHECKSH: # Crash reproducer
+// CHECKSH-NEXT: # Driver args: "-fsyntax-only"
+// CHECKSH-NEXT: # Original command: {{.*$}}
+// CHECKSH-NEXT: "-cc1"
+// CHECKSH: "-isysroot" "{{[^"]*}}/sysroot/"
+// CHECKSH-NOT: "-fmodules-cache-path="
+// CHECKSH: "crash-vfs-{{[^ ]*}}.m"
+// CHECKSH: "-ivfsoverlay" "crash-vfs-{{[^ ]*}}.cache/vfs/vfs.yaml"
+
+// CHECKYAML: 'type': 'directory',
+// CHECKYAML: 'name': "",
+// CHECKYAML-NEXT: 'contents': [
+// CHECKYAML-NEXT: {
+// CHECKYAML-NEXT: 'type': 'file',
+// CHECKYAML-NEXT: 'name': "pthread_impl.h",
+// CHECKYAML-NEXT: 'external-contents': "/{{.*}}/i/usr/include/pthread_impl.h"
+// CHECKYAML-NEXT: },
OpenPOWER on IntegriCloud