[libcxx] r249738 - Split <ctype.h> out of <cctype>.
Richard Smith via cfe-commits
cfe-commits at lists.llvm.org
Fri Oct 16 15:27:26 PDT 2015
On Thu, Oct 15, 2015 at 11:14 AM, Adrian Prantl <aprantl at apple.com> wrote:
>
> On Oct 14, 2015, at 5:07 PM, Richard Smith <richard at metafoo.co.uk> wrote:
>
> Ack, there are non-modular headers in the Darwin module. =( I seem to
> recall that they're not version-locked to your compiler, so we've got to
> support them as-is?
>
> If we can't turn on local submodule visibility, then we need a module map
> for libc++ that covers all of its headers. I'll look into pruning the
> include path when building a module from an implicitly-loaded module map.
>
>
> The attached patch implements this in the most hacky way; with it I can
> successfully compile the first few hundred files of LLVM.
>
Slightly less hacky approach attached, does this also unstick you?
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20151016/ef80dba9/attachment.html>
-------------- next part --------------
Index: include/clang/Basic/Module.h
===================================================================
--- include/clang/Basic/Module.h (revision 250139)
+++ include/clang/Basic/Module.h (working copy)
@@ -200,6 +200,10 @@
/// built.
unsigned ConfigMacrosExhaustive : 1;
+ /// \brief Whether files in this module can only include files from used
+ /// modules.
+ unsigned NoUndeclaredIncludes : 1;
+
/// \brief Describes the visibility of the various names within a
/// particular module.
enum NameVisibilityKind {
Index: include/clang/Lex/ModuleMap.h
===================================================================
--- include/clang/Lex/ModuleMap.h (revision 250139)
+++ include/clang/Lex/ModuleMap.h (working copy)
@@ -157,7 +157,8 @@
/// \brief The set of attributes that can be attached to a module.
struct Attributes {
- Attributes() : IsSystem(), IsExternC(), IsExhaustive() {}
+ Attributes()
+ : IsSystem(), IsExternC(), IsExhaustive(), NoUndeclaredIncludes() {}
/// \brief Whether this is a system module.
unsigned IsSystem : 1;
@@ -167,6 +168,10 @@
/// \brief Whether this is an exhaustive set of configuration macros.
unsigned IsExhaustive : 1;
+
+ /// \brief Whether files in this module can only include files from
+ /// explicit dependencies of the module.
+ unsigned NoUndeclaredIncludes : 1;
};
/// \brief A directory for which framework modules can be inferred.
Index: lib/Basic/Module.cpp
===================================================================
--- lib/Basic/Module.cpp (revision 250139)
+++ lib/Basic/Module.cpp (working copy)
@@ -32,7 +32,8 @@
IsFramework(IsFramework), IsExplicit(IsExplicit), IsSystem(false),
IsExternC(false), IsInferred(false), InferSubmodules(false),
InferExplicitSubmodules(false), InferExportWildcard(false),
- ConfigMacrosExhaustive(false), NameVisibility(Hidden) {
+ ConfigMacrosExhaustive(false), NoUndeclaredIncludes(false),
+ NameVisibility(Hidden) {
if (Parent) {
if (!Parent->isAvailable())
IsAvailable = false;
@@ -40,6 +41,8 @@
IsSystem = true;
if (Parent->IsExternC)
IsExternC = true;
+ if (Parent->NoUndeclaredIncludes)
+ NoUndeclaredIncludes = true;
IsMissingRequirement = Parent->IsMissingRequirement;
Parent->SubModuleIndex[Name] = Parent->SubModules.size();
Index: lib/Lex/HeaderSearch.cpp
===================================================================
--- lib/Lex/HeaderSearch.cpp (revision 250554)
+++ lib/Lex/HeaderSearch.cpp (working copy)
@@ -393,6 +393,12 @@
return TopFrameworkDir;
}
+static bool needModuleLookup(Module *RequestingModule,
+ bool HasSuggestedModule) {
+ return HasSuggestedModule ||
+ (RequestingModule && RequestingModule->NoUndeclaredIncludes);
+}
+
/// DoFrameworkLookup - Do a lookup of the specified file in the current
/// DirectoryLookup, which is a framework directory.
const FileEntry *DirectoryLookup::DoFrameworkLookup(
@@ -488,7 +494,7 @@
}
// If we found the header and are allowed to suggest a module, do so now.
- if (FE && SuggestedModule) {
+ if (FE && needModuleLookup(RequestingModule, SuggestedModule)) {
// Find the framework in which this header occurs.
StringRef FrameworkPath = FE->getDir()->getName();
bool FoundFramework = false;
@@ -1144,13 +1150,31 @@
return ModMap.findModuleForHeader(File);
}
+static bool suggestModule(HeaderSearch &HS, const FileEntry *File,
+ Module *RequestingModule,
+ ModuleMap::KnownHeader *SuggestedModule) {
+ ModuleMap::KnownHeader Module = HS.findModuleForHeader(File);
+ if (SuggestedModule)
+ *SuggestedModule = Module;
+
+ // If this module specifies [no_undeclared_includes], we cannot find any
+ // file that's in a non-dependency module.
+ if (RequestingModule && Module && RequestingModule->NoUndeclaredIncludes) {
+ HS.getModuleMap().resolveUses(RequestingModule, /*Complain*/false);
+ if (!RequestingModule->directlyUses(Module.getModule()))
+ return false;
+ }
+
+ return true;
+}
+
bool HeaderSearch::findUsableModuleForHeader(
const FileEntry *File, const DirectoryEntry *Root, Module *RequestingModule,
ModuleMap::KnownHeader *SuggestedModule, bool IsSystemHeaderDir) {
- if (File && SuggestedModule) {
+ if (File && needModuleLookup(RequestingModule, SuggestedModule)) {
// If there is a module that corresponds to this header, suggest it.
hasModuleMap(File->getName(), Root, IsSystemHeaderDir);
- *SuggestedModule = findModuleForHeader(File);
+ return suggestModule(*this, File, RequestingModule, SuggestedModule);
}
return true;
}
@@ -1159,7 +1183,7 @@
const FileEntry *File, StringRef FrameworkName, Module *RequestingModule,
ModuleMap::KnownHeader *SuggestedModule, bool IsSystemFramework) {
// If we're supposed to suggest a module, look for one now.
- if (SuggestedModule) {
+ if (needModuleLookup(RequestingModule, SuggestedModule)) {
// Find the top-level framework based on this framework.
SmallVector<std::string, 4> SubmodulePath;
const DirectoryEntry *TopFrameworkDir
@@ -1176,7 +1200,7 @@
// important so that we're consistent about whether this header
// corresponds to a module. Possibly we should lock down framework modules
// so that this is not possible.
- *SuggestedModule = findModuleForHeader(File);
+ return suggestModule(*this, File, RequestingModule, SuggestedModule);
}
return true;
}
Index: lib/Lex/ModuleMap.cpp
===================================================================
--- lib/Lex/ModuleMap.cpp (revision 250139)
+++ lib/Lex/ModuleMap.cpp (working copy)
@@ -663,6 +663,8 @@
Attrs.IsSystem |= inferred->second.Attrs.IsSystem;
Attrs.IsExternC |= inferred->second.Attrs.IsExternC;
Attrs.IsExhaustive |= inferred->second.Attrs.IsExhaustive;
+ Attrs.NoUndeclaredIncludes |=
+ inferred->second.Attrs.NoUndeclaredIncludes;
ModuleMapFile = inferred->second.ModuleMapFile;
}
}
@@ -699,6 +701,7 @@
Result->IsSystem |= Attrs.IsSystem;
Result->IsExternC |= Attrs.IsExternC;
Result->ConfigMacrosExhaustive |= Attrs.IsExhaustive;
+ Result->NoUndeclaredIncludes |= Attrs.NoUndeclaredIncludes;
Result->Directory = FrameworkDir;
if (!Parent)
@@ -1286,7 +1289,9 @@
/// \brief The 'extern_c' attribute.
AT_extern_c,
/// \brief The 'exhaustive' attribute.
- AT_exhaustive
+ AT_exhaustive,
+ /// \brief The 'no_undeclared_includes' attribute.
+ AT_no_undeclared_includes
};
}
@@ -1454,6 +1459,9 @@
ActiveModule->IsSystem = true;
if (Attrs.IsExternC)
ActiveModule->IsExternC = true;
+ if (Attrs.NoUndeclaredIncludes ||
+ (!ActiveModule->Parent && ModuleName == "Darwin"))
+ ActiveModule->NoUndeclaredIncludes = true;
ActiveModule->Directory = Directory;
bool Done = false;
@@ -2345,6 +2353,7 @@
= llvm::StringSwitch<AttributeKind>(Tok.getString())
.Case("exhaustive", AT_exhaustive)
.Case("extern_c", AT_extern_c)
+ .Case("no_undeclared_includes", AT_no_undeclared_includes)
.Case("system", AT_system)
.Default(AT_unknown);
switch (Attribute) {
@@ -2364,6 +2373,10 @@
case AT_exhaustive:
Attrs.IsExhaustive = true;
break;
+
+ case AT_no_undeclared_includes:
+ Attrs.NoUndeclaredIncludes = true;
+ break;
}
consumeToken();
Index: test/Modules/Inputs/libc-libcxx/include/c++/math.h
===================================================================
--- test/Modules/Inputs/libc-libcxx/include/c++/math.h (revision 0)
+++ test/Modules/Inputs/libc-libcxx/include/c++/math.h (working copy)
@@ -0,0 +1,2 @@
+#include_next <math.h>
+template<typename T> T abs(T t) { return (t < 0) ? -t : t; }
Index: test/Modules/Inputs/libc-libcxx/include/c++/module.modulemap
===================================================================
--- test/Modules/Inputs/libc-libcxx/include/c++/module.modulemap (revision 0)
+++ test/Modules/Inputs/libc-libcxx/include/c++/module.modulemap (working copy)
@@ -0,0 +1,4 @@
+module "libc++" {
+ module math { header "math.h" export * }
+ module stdlib { header "stdlib.h" export * }
+}
Index: test/Modules/Inputs/libc-libcxx/include/c++/stdlib.h
===================================================================
--- test/Modules/Inputs/libc-libcxx/include/c++/stdlib.h (revision 0)
+++ test/Modules/Inputs/libc-libcxx/include/c++/stdlib.h (working copy)
@@ -0,0 +1 @@
+#include_next "stdlib.h"
Index: test/Modules/Inputs/libc-libcxx/include/math.h
===================================================================
--- test/Modules/Inputs/libc-libcxx/include/math.h (revision 0)
+++ test/Modules/Inputs/libc-libcxx/include/math.h (working copy)
@@ -0,0 +1 @@
+int abs(int);
Index: test/Modules/Inputs/libc-libcxx/include/module.modulemap
===================================================================
--- test/Modules/Inputs/libc-libcxx/include/module.modulemap (revision 0)
+++ test/Modules/Inputs/libc-libcxx/include/module.modulemap (working copy)
@@ -0,0 +1,4 @@
+module libc [no_undeclared_includes] {
+ module math { header "math.h" export * }
+ module stdlib { header "stdlib.h" export * }
+}
Index: test/Modules/Inputs/libc-libcxx/include/stdlib.h
===================================================================
--- test/Modules/Inputs/libc-libcxx/include/stdlib.h (revision 0)
+++ test/Modules/Inputs/libc-libcxx/include/stdlib.h (working copy)
@@ -0,0 +1 @@
+#include <math.h>
Index: test/Modules/libc-libcxx.cpp
===================================================================
--- test/Modules/libc-libcxx.cpp (revision 0)
+++ test/Modules/libc-libcxx.cpp (working copy)
@@ -0,0 +1,8 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -x c++ -fmodules-cache-path=%t -fmodules -fimplicit-module-maps -I %S/Inputs/libc-libcxx/include/c++ -I %S/Inputs/libc-libcxx/include %s -verify
+// expected-no-diagnostics
+
+#include "math.h"
+
+int n = abs(0);
+float f = abs<float>(0.f);
More information about the cfe-commits
mailing list