diff options
Diffstat (limited to 'clang')
8 files changed, 46 insertions, 4 deletions
diff --git a/clang/lib/Lex/PPLexerChange.cpp b/clang/lib/Lex/PPLexerChange.cpp index 9f68f3bb89d..fcc49b38703 100644 --- a/clang/lib/Lex/PPLexerChange.cpp +++ b/clang/lib/Lex/PPLexerChange.cpp @@ -287,6 +287,14 @@ const char *Preprocessor::getCurLexerEndPos() {    return EndPos;  } +static void collectAllSubModulesWithUmbrellaHeader( +    const Module &Mod, SmallVectorImpl<const Module *> &SubMods) { +  if (Mod.getUmbrellaHeader()) +    SubMods.push_back(&Mod); +  for (auto *M : Mod.submodules()) +    collectAllSubModulesWithUmbrellaHeader(*M, SubMods); +} +  void Preprocessor::diagnoseMissingHeaderInUmbrellaDir(const Module &Mod) {    assert(Mod.getUmbrellaHeader() && "Module must use umbrella header");    SourceLocation StartLoc = @@ -507,10 +515,15 @@ bool Preprocessor::HandleEndOfFile(Token &Result, bool isEndOfMacro) {    }    // If we are building a module that has an umbrella header, make sure that -  // each of the headers within the directory covered by the umbrella header -  // was actually included by the umbrella header. -  if (Module *Mod = getCurrentModule()) -    diagnoseMissingHeaderInUmbrellaDir(*Mod); +  // each of the headers within the directory, including all submodules, is +  // covered by the umbrella header was actually included by the umbrella +  // header. +  if (Module *Mod = getCurrentModule()) { +    llvm::SmallVector<const Module *, 4> AllMods; +    collectAllSubModulesWithUmbrellaHeader(*Mod, AllMods); +    for (auto *M : AllMods) +      diagnoseMissingHeaderInUmbrellaDir(*M); +  }    return true;  } diff --git a/clang/test/Modules/Inputs/incomplete-umbrella/Foo.framework/Headers/Bar.h b/clang/test/Modules/Inputs/incomplete-umbrella/Foo.framework/Headers/Bar.h new file mode 100644 index 00000000000..fb5da09bac6 --- /dev/null +++ b/clang/test/Modules/Inputs/incomplete-umbrella/Foo.framework/Headers/Bar.h @@ -0,0 +1 @@ +#define BAR_PUBLIC 1 diff --git a/clang/test/Modules/Inputs/incomplete-umbrella/Foo.framework/Headers/FooPublic.h b/clang/test/Modules/Inputs/incomplete-umbrella/Foo.framework/Headers/FooPublic.h new file mode 100644 index 00000000000..cbbb44f42c7 --- /dev/null +++ b/clang/test/Modules/Inputs/incomplete-umbrella/Foo.framework/Headers/FooPublic.h @@ -0,0 +1 @@ +// FooPublic.h diff --git a/clang/test/Modules/Inputs/incomplete-umbrella/Foo.framework/Modules/module.modulemap b/clang/test/Modules/Inputs/incomplete-umbrella/Foo.framework/Modules/module.modulemap new file mode 100644 index 00000000000..af67e657405 --- /dev/null +++ b/clang/test/Modules/Inputs/incomplete-umbrella/Foo.framework/Modules/module.modulemap @@ -0,0 +1,5 @@ +framework module Foo { +    umbrella header "FooPublic.h" +    requires objc +    export * +} diff --git a/clang/test/Modules/Inputs/incomplete-umbrella/Foo.framework/Modules/module.private.modulemap b/clang/test/Modules/Inputs/incomplete-umbrella/Foo.framework/Modules/module.private.modulemap new file mode 100644 index 00000000000..f6d9dfdcab3 --- /dev/null +++ b/clang/test/Modules/Inputs/incomplete-umbrella/Foo.framework/Modules/module.private.modulemap @@ -0,0 +1,5 @@ +explicit module Foo.Private { +    umbrella header "Foo.h" +    requires objc +    export * +} diff --git a/clang/test/Modules/Inputs/incomplete-umbrella/Foo.framework/PrivateHeaders/Baz.h b/clang/test/Modules/Inputs/incomplete-umbrella/Foo.framework/PrivateHeaders/Baz.h new file mode 100644 index 00000000000..98064e08146 --- /dev/null +++ b/clang/test/Modules/Inputs/incomplete-umbrella/Foo.framework/PrivateHeaders/Baz.h @@ -0,0 +1 @@ +#define BAZ_PRIVATE 1 diff --git a/clang/test/Modules/Inputs/incomplete-umbrella/Foo.framework/PrivateHeaders/Foo.h b/clang/test/Modules/Inputs/incomplete-umbrella/Foo.framework/PrivateHeaders/Foo.h new file mode 100644 index 00000000000..9381133344b --- /dev/null +++ b/clang/test/Modules/Inputs/incomplete-umbrella/Foo.framework/PrivateHeaders/Foo.h @@ -0,0 +1 @@ +// Foo.h diff --git a/clang/test/Modules/incomplete-umbrella.m b/clang/test/Modules/incomplete-umbrella.m new file mode 100644 index 00000000000..8760b815718 --- /dev/null +++ b/clang/test/Modules/incomplete-umbrella.m @@ -0,0 +1,15 @@ +// RUN: rm -rf %t +// RUN: not %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -F%S/Inputs/incomplete-umbrella -fsyntax-only %s 2>&1 | FileCheck %s + +#import <Foo/Foo.h> +#import <Foo/Bar.h> +#import <Foo/Baz.h> +@import Foo.Private; + +// CHECK: warning: umbrella header for module 'Foo' does not include header 'Bar.h' +// CHECK: warning: umbrella header for module 'Foo.Private' does not include header 'Baz.h' +int foo() { +  int a = BAR_PUBLIC; +  int b = BAZ_PRIVATE; +  return 0; +}  | 

