Jelajahi Sumber

[CrashReproducer] Setup a module collector callback for HeaderInclude

Collect missing include that cannot be fetched otherwise (e.g. when
using headermaps).

rdar://problem/27913709

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@289361 91177308-0d34-0410-b5e6-96231b3b80d8
Bruno Cardoso Lopes 8 tahun lalu
induk
melakukan
f89729f102

+ 20 - 0
lib/Frontend/ModuleDependencyCollector.cpp

@@ -38,6 +38,24 @@ public:
   }
 };
 
+struct ModuleDependencyPPCallbacks : public PPCallbacks {
+  ModuleDependencyCollector &Collector;
+  SourceManager &SM;
+  ModuleDependencyPPCallbacks(ModuleDependencyCollector &Collector,
+                              SourceManager &SM)
+      : Collector(Collector), SM(SM) {}
+
+  void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok,
+                          StringRef FileName, bool IsAngled,
+                          CharSourceRange FilenameRange, const FileEntry *File,
+                          StringRef SearchPath, StringRef RelativePath,
+                          const Module *Imported) override {
+    if (!File)
+      return;
+    Collector.addFile(File->getName());
+  }
+};
+
 struct ModuleDependencyMMCallbacks : public ModuleMapCallbacks {
   ModuleDependencyCollector &Collector;
   ModuleDependencyMMCallbacks(ModuleDependencyCollector &Collector)
@@ -102,6 +120,8 @@ void ModuleDependencyCollector::attachToASTReader(ASTReader &R) {
 }
 
 void ModuleDependencyCollector::attachToPreprocessor(Preprocessor &PP) {
+  PP.addPPCallbacks(llvm::make_unique<ModuleDependencyPPCallbacks>(
+      *this, PP.getSourceManager()));
   PP.getHeaderSearchInfo().getModuleMap().addModuleMapCallbacks(
       llvm::make_unique<ModuleDependencyMMCallbacks>(*this));
 }

+ 7 - 0
test/Modules/crash-vfs-headermaps.m

@@ -40,6 +40,13 @@
 // CHECKYAML-NEXT: 'overlay-relative': 'true',
 // CHECKYAML-NEXT: 'ignore-non-existent-contents': 'false'
 // CHECKYAML: 'type': 'directory'
+// CHECKYAML: 'name': "/[[PATH:.*]]/Foo.framework/Headers",
+// CHECKYAML-NEXT: 'contents': [
+// CHECKYAML-NEXT:   {
+// CHECKYAML-NEXT:     'type': 'file',
+// CHECKYAML-NEXT:     'name': "Foo.h",
+// CHECKYAML-NEXT:     'external-contents': "/[[PATH]]/Foo.framework/Headers/Foo.h"
+// CHECKYAML: 'type': 'directory'
 // CHECKYAML: 'name': "/[[PATH:.*]]/i",
 // CHECKYAML-NEXT: 'contents': [
 // CHECKYAML-NEXT:   {