From 0dfafa59cace8b477d3ae3ab89f2e662fea0954c Mon Sep 17 00:00:00 2001 From: Ben Langmuir Date: Wed, 25 Jun 2014 23:53:43 +0000 Subject: Make -Wincomplete-umbrella go through the VFS By using vfs::recursive_directory_iterator, this warning will now fire when some or all of a module's headers are from VFS mappings. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@211746 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Basic/VirtualFileSystem.h | 2 +- lib/Lex/PPLexerChange.cpp | 8 +++++--- test/VFS/Inputs/Incomplete.h | 1 + test/VFS/Inputs/IncompleteVFS.h | 1 + test/VFS/Inputs/incomplete-umbrella.modulemap | 5 +++++ test/VFS/Inputs/vfsoverlay.yaml | 17 +++++++++++++++++ test/VFS/incomplete-umbrella.m | 12 ++++++++++++ 7 files changed, 42 insertions(+), 4 deletions(-) create mode 100644 test/VFS/Inputs/Incomplete.h create mode 100644 test/VFS/Inputs/IncompleteVFS.h create mode 100644 test/VFS/Inputs/incomplete-umbrella.modulemap create mode 100644 test/VFS/incomplete-umbrella.m diff --git a/include/clang/Basic/VirtualFileSystem.h b/include/clang/Basic/VirtualFileSystem.h index 882ebdb12b..36f78fd872 100644 --- a/include/clang/Basic/VirtualFileSystem.h +++ b/include/clang/Basic/VirtualFileSystem.h @@ -200,7 +200,7 @@ public: bool IsVolatile = false); /// \brief Get a directory_iterator for \p Dir. - /// \note The 'end' iterator is directory_iterator() + /// \note The 'end' iterator is directory_iterator(). virtual directory_iterator dir_begin(const Twine &Dir, std::error_code &EC) = 0; }; diff --git a/lib/Lex/PPLexerChange.cpp b/lib/Lex/PPLexerChange.cpp index 81bb077632..7586293151 100644 --- a/lib/Lex/PPLexerChange.cpp +++ b/lib/Lex/PPLexerChange.cpp @@ -455,19 +455,21 @@ bool Preprocessor::HandleEndOfFile(Token &Result, bool isEndOfMacro) { typedef llvm::sys::fs::recursive_directory_iterator recursive_directory_iterator; const DirectoryEntry *Dir = Mod->getUmbrellaDir(); + vfs::FileSystem &FS = *FileMgr.getVirtualFileSystem(); std::error_code EC; - for (recursive_directory_iterator Entry(Dir->getName(), EC), End; + for (vfs::recursive_directory_iterator Entry(FS, Dir->getName(), EC), End; Entry != End && !EC; Entry.increment(EC)) { using llvm::StringSwitch; // Check whether this entry has an extension typically associated with // headers. - if (!StringSwitch(llvm::sys::path::extension(Entry->path())) + if (!StringSwitch(llvm::sys::path::extension(Entry->getName())) .Cases(".h", ".H", ".hh", ".hpp", true) .Default(false)) continue; - if (const FileEntry *Header = getFileManager().getFile(Entry->path())) + if (const FileEntry *Header = + getFileManager().getFile(Entry->getName())) if (!getSourceManager().hasFileInfo(Header)) { if (!ModMap.isHeaderInUnavailableModule(Header)) { // Find the relative path that would access this header. diff --git a/test/VFS/Inputs/Incomplete.h b/test/VFS/Inputs/Incomplete.h new file mode 100644 index 0000000000..29fafc3ccf --- /dev/null +++ b/test/VFS/Inputs/Incomplete.h @@ -0,0 +1 @@ +// does not include IncompleteVFS.h or IncompleteReal.h diff --git a/test/VFS/Inputs/IncompleteVFS.h b/test/VFS/Inputs/IncompleteVFS.h new file mode 100644 index 0000000000..22cfe7d6ad --- /dev/null +++ b/test/VFS/Inputs/IncompleteVFS.h @@ -0,0 +1 @@ +// IncompleteVFS.h diff --git a/test/VFS/Inputs/incomplete-umbrella.modulemap b/test/VFS/Inputs/incomplete-umbrella.modulemap new file mode 100644 index 0000000000..5afac92722 --- /dev/null +++ b/test/VFS/Inputs/incomplete-umbrella.modulemap @@ -0,0 +1,5 @@ +framework module Incomplete { + umbrella header "Incomplete.h" + export * + module * { export * } +} diff --git a/test/VFS/Inputs/vfsoverlay.yaml b/test/VFS/Inputs/vfsoverlay.yaml index 0aa8cd619a..f395d45ee3 100644 --- a/test/VFS/Inputs/vfsoverlay.yaml +++ b/test/VFS/Inputs/vfsoverlay.yaml @@ -29,6 +29,23 @@ }, { 'name': 'Foo.framework/Headers/Foo.h', 'type': 'file', 'external-contents': 'INPUT_DIR/Foo.h' + }, + { 'name': 'Incomplete.framework', 'type': 'directory', + 'contents': [ + { 'name': 'Headers', 'type': 'directory', + 'contents': [ + { 'name': 'Incomplete.h', 'type': 'file', + 'external-contents': 'INPUT_DIR/Incomplete.h' + }, + { 'name': 'IncompleteVFS.h', 'type': 'file', + 'external-contents': 'INPUT_DIR/IncompleteVFS.h' + } + ] + }, + { 'name': 'Modules/module.modulemap', 'type': 'file', + 'external-contents': 'INPUT_DIR/incomplete-umbrella.modulemap' + } + ] } ] } diff --git a/test/VFS/incomplete-umbrella.m b/test/VFS/incomplete-umbrella.m new file mode 100644 index 0000000000..4e138cc0f3 --- /dev/null +++ b/test/VFS/incomplete-umbrella.m @@ -0,0 +1,12 @@ +// RUN: rm -rf %t +// RUN: mkdir -p %t/Incomplete.framework/Headers +// RUN: echo '// IncompleteReal.h' > %t/Incomplete.framework/Headers/IncompleteReal.h +// RUN: sed -e "s:INPUT_DIR:%S/Inputs:g" -e "s:OUT_DIR:%t:g" %S/Inputs/vfsoverlay.yaml > %t.yaml +// RUN: not %clang_cc1 -Werror -fmodules -fmodules-cache-path=%t \ +// RUN: -ivfsoverlay %t.yaml -F %t -fsyntax-only %s 2>&1 | FileCheck %s +// REQUIRES: shell + +@import Incomplete; +// CHECK: umbrella header for module 'Incomplete' {{.*}}IncompleteVFS.h +// CHECK: umbrella header for module 'Incomplete' {{.*}}IncompleteReal.h +// CHECK: could not build module 'Incomplete' -- cgit v1.2.3