mirror of https://github.com/microsoft/clang.git
[Modules] Improve diagnostics for incomplete umbrella
One of the -Wincomplete-umbrella warnings diagnoses when a header is present in the directory but it's not present in the umbrella header. Currently, this warning only happens on top level modules; any submodule using an umbrella header does not get this warning. Fix that by also considering the submodules. Differential Revision: https://reviews.llvm.org/D32576 rdar://problem/22623686 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@301597 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
c5a1b98af4
commit
4ef94de349
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
#define BAR_PUBLIC 1
|
|
@ -0,0 +1 @@
|
|||
// FooPublic.h
|
|
@ -0,0 +1,5 @@
|
|||
framework module Foo {
|
||||
umbrella header "FooPublic.h"
|
||||
requires objc
|
||||
export *
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
explicit module Foo.Private {
|
||||
umbrella header "Foo.h"
|
||||
requires objc
|
||||
export *
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
#define BAZ_PRIVATE 1
|
|
@ -0,0 +1 @@
|
|||
// Foo.h
|
|
@ -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;
|
||||
}
|
Loading…
Reference in New Issue