[libcxx] r249738 - Split <ctype.h> out of <cctype>.
Richard Smith via cfe-commits
cfe-commits at lists.llvm.org
Fri Oct 14 15:09:33 PDT 2016
On Fri, Oct 14, 2016 at 11:44 AM, Bruno Cardoso Lopes <
bruno.cardoso at gmail.com> wrote:
> Hi Richard,
>
> I have a patch on top of your suggested patch from a year ago, that
> break the cyclic dependency we're seeing, with this (and a few changes
> to the SDK) we can bootstrap clang with submodule local visibility on
> darwin. I've attached the patch with a reduced, standalone testcase
> that doesn't depend on the SDK. The issues that are not covered by
> your patch, that I cover in mine, are related to built-in and textual
> headers: they can be found in paths where they don't map to any
> modules, triggering other cycles. I fix that by looking further to
> find a matching module for the header in question, instead the first
> found header in header search.
>
It looks like the 0002 patch is working around a bug in the 0001 patch:
with 0001 applied, a module with [no_undeclared_includes] can still include
a textual header from another module on which it doesn't declare a
dependency (in the testcase, the libc module is incorrectly permitted to
include the textual header <stdio.h> from libc++). Rather than preferring
non-modular headers over modular headers as the 0002 patch does, I wonder
if the issue could instead be resolved by fixing that apparent bug.
I gave that a go; the result is attached. I also had to change the way we
handle builtin headers -- instead of implicitly including (for instance)
the builtin <stddef.h> as a modular header in any module that provides its
own <stddef.h>, I now only include it as a textual header (this also lets
us use the same approach for this case whether or not we're using local
submodule visibility). That exposed a couple of testcases that were
(unreasonably, in my opinion) failing to include_next the real builtin
header from their wrapper header.
The attached patch causes your testcase to pass; I'd be interested to know
if it works in practice on Darwin.
Thanks!
> Can you take a look?
>
> Thanks,
>
>
> On Thu, Jul 28, 2016 at 3:55 PM, Adrian Prantl via cfe-commits
> <cfe-commits at lists.llvm.org> wrote:
> > +Bruno
> >
> > On Jul 27, 2016, at 11:58 PM, Nico Weber <thakis at chromium.org> wrote:
> >
> > I played with modules a bit today, and as far as I can tell this is still
> > broken. If this proves difficult to fix, should this change be reverted
> for
> > now? It breaks using modules on Darwin.
> >
> > On Sun, Mar 13, 2016 at 12:53 AM, Adrian Prantl via cfe-commits
> > <cfe-commits at lists.llvm.org> wrote:
> >>
> >> > On Mar 11, 2016, at 4:11 PM, Duncan P. N. Exon Smith
> >> > <dexonsmith at apple.com> wrote:
> >> >
> >> > Did anyone file a PR for this?
> >> >
> >>
> >> I filed PR 26928 - Prune the include path for modules
> >> https://llvm.org/bugs/show_bug.cgi?id=26928
> >> as a starting point.
> >>
> >> -- adrian
> >>
> >> _______________________________________________
> >> cfe-commits mailing list
> >> cfe-commits at lists.llvm.org
> >> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
> >
> >
> >
> >
> > _______________________________________________
> > cfe-commits mailing list
> > cfe-commits at lists.llvm.org
> > http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
> >
>
>
>
> --
> Bruno Cardoso Lopes
> http://www.brunocardoso.cc
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20161014/8dd75e50/attachment-0001.html>
-------------- next part --------------
Index: include/clang/Basic/Module.h
===================================================================
--- include/clang/Basic/Module.h (revision 284181)
+++ include/clang/Basic/Module.h (working copy)
@@ -201,6 +201,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/HeaderSearch.h
===================================================================
--- include/clang/Lex/HeaderSearch.h (revision 284181)
+++ include/clang/Lex/HeaderSearch.h (working copy)
@@ -523,8 +523,10 @@
/// \brief Retrieve the module that corresponds to the given file, if any.
///
/// \param File The header that we wish to map to a module.
- ModuleMap::KnownHeader findModuleForHeader(const FileEntry *File) const;
-
+ /// \param AllowTextual Whether we want to find textual headers too.
+ ModuleMap::KnownHeader findModuleForHeader(const FileEntry *File,
+ bool AllowTextual = false) const;
+
/// \brief Read the contents of the given module map file.
///
/// \param File The module map file.
Index: include/clang/Lex/ModuleMap.h
===================================================================
--- include/clang/Lex/ModuleMap.h (revision 284181)
+++ include/clang/Lex/ModuleMap.h (working copy)
@@ -171,7 +171,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;
@@ -181,6 +182,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.
@@ -315,10 +320,15 @@
///
/// \param File The header file that is likely to be included.
///
+ /// \param AllowTextual If \c true and \p File is a textual header, return
+ /// its owning module. Otherwise, no KnownHeader will be returned if the
+ /// file is only known as a textual header.
+ ///
/// \returns The module KnownHeader, which provides the module that owns the
/// given header file. The KnownHeader is default constructed to indicate
/// that no module owns this header file.
- KnownHeader findModuleForHeader(const FileEntry *File);
+ KnownHeader findModuleForHeader(const FileEntry *File,
+ bool AllowTextual = false);
/// \brief Retrieve all the modules that contain the given header file. This
/// may not include umbrella modules, nor information from external sources,
Index: lib/Basic/Module.cpp
===================================================================
--- lib/Basic/Module.cpp (revision 284181)
+++ lib/Basic/Module.cpp (working copy)
@@ -33,7 +33,7 @@
IsExplicit(IsExplicit), IsSystem(false), IsExternC(false),
IsInferred(false), InferSubmodules(false), InferExplicitSubmodules(false),
InferExportWildcard(false), ConfigMacrosExhaustive(false),
- NameVisibility(Hidden) {
+ NoUndeclaredIncludes(false), NameVisibility(Hidden) {
if (Parent) {
if (!Parent->isAvailable())
IsAvailable = false;
@@ -41,6 +41,8 @@
IsSystem = true;
if (Parent->IsExternC)
IsExternC = true;
+ if (Parent->NoUndeclaredIncludes)
+ NoUndeclaredIncludes = true;
IsMissingRequirement = Parent->IsMissingRequirement;
Parent->SubModuleIndex[Name] = Parent->SubModules.size();
@@ -181,6 +183,11 @@
for (auto *Use : Top->DirectUses)
if (Requested->isSubModuleOf(Use))
return true;
+
+ // Anyone is allowed to use our builtin stddef.h and its accompanying module.
+ if (!Requested->Parent && Requested->Name == "_Builtin_stddef_max_align_t")
+ return true;
+
return false;
}
Index: lib/Lex/HeaderSearch.cpp
===================================================================
--- lib/Lex/HeaderSearch.cpp (revision 284181)
+++ lib/Lex/HeaderSearch.cpp (working copy)
@@ -413,6 +413,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(
@@ -508,7 +514,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;
@@ -1158,22 +1164,45 @@
}
ModuleMap::KnownHeader
-HeaderSearch::findModuleForHeader(const FileEntry *File) const {
+HeaderSearch::findModuleForHeader(const FileEntry *File,
+ bool AllowTextual) const {
if (ExternalSource) {
// Make sure the external source has handled header info about this file,
// which includes whether the file is part of a module.
(void)getExistingFileInfo(File);
}
- return ModMap.findModuleForHeader(File);
+ return ModMap.findModuleForHeader(File, AllowTextual);
}
+static bool suggestModule(HeaderSearch &HS, const FileEntry *File,
+ Module *RequestingModule,
+ ModuleMap::KnownHeader *SuggestedModule) {
+ ModuleMap::KnownHeader Module =
+ HS.findModuleForHeader(File, /*AllowTextual*/true);
+ if (SuggestedModule)
+ *SuggestedModule = (Module.getRole() & ModuleMap::TextualHeader)
+ ? ModuleMap::KnownHeader()
+ : 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;
}
@@ -1182,7 +1211,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
@@ -1199,7 +1228,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 284181)
+++ lib/Lex/ModuleMap.cpp (working copy)
@@ -327,9 +327,10 @@
return false;
}
-ModuleMap::KnownHeader ModuleMap::findModuleForHeader(const FileEntry *File) {
+ModuleMap::KnownHeader ModuleMap::findModuleForHeader(const FileEntry *File,
+ bool AllowTextual) {
auto MakeResult = [&](ModuleMap::KnownHeader R) -> ModuleMap::KnownHeader {
- if (R.getRole() & ModuleMap::TextualHeader)
+ if (!AllowTextual && R.getRole() & ModuleMap::TextualHeader)
return ModuleMap::KnownHeader();
return R;
};
@@ -674,6 +675,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;
}
}
@@ -711,6 +714,7 @@
Result->IsSystem |= Attrs.IsSystem;
Result->IsExternC |= Attrs.IsExternC;
Result->ConfigMacrosExhaustive |= Attrs.IsExhaustive;
+ Result->NoUndeclaredIncludes |= Attrs.NoUndeclaredIncludes;
Result->Directory = FrameworkDir;
// umbrella header "umbrella-header-name"
@@ -1309,7 +1313,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
};
}
@@ -1479,6 +1485,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;
@@ -1845,13 +1854,7 @@
// If Clang supplies this header but the underlying system does not,
// just silently swap in our builtin version. Otherwise, we'll end
// up adding both (later).
- //
- // For local visibility, entirely replace the system file with our
- // one and textually include the system one. We need to pass macros
- // from our header to the system one if we #include_next it.
- //
- // FIXME: Can we do this in all cases?
- if (BuiltinFile && (!File || Map.LangOpts.ModulesLocalVisibility)) {
+ if (BuiltinFile && !File) {
File = BuiltinFile;
RelativePathName = BuiltinPathName;
BuiltinFile = nullptr;
@@ -1877,15 +1880,16 @@
Module::Header H = {RelativePathName.str(), File};
Map.excludeHeader(ActiveModule, H);
} else {
- // If there is a builtin counterpart to this file, add it now, before
- // the "real" header, so we build the built-in one first when building
- // the module.
+ // If there is a builtin counterpart to this file, add it now as a textual
+ // header, so it can be #include_next'd by the wrapper header, and can
+ // receive macros from the wrapper header.
if (BuiltinFile) {
// FIXME: Taking the name from the FileEntry is unstable and can give
// different results depending on how we've previously named that file
// in this build.
Module::Header H = { BuiltinFile->getName(), BuiltinFile };
- Map.addHeader(ActiveModule, H, Role);
+ Map.addHeader(ActiveModule, H, ModuleMap::ModuleHeaderRole(
+ Role | ModuleMap::TextualHeader));
}
// Record this header.
@@ -2375,6 +2379,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) {
@@ -2394,6 +2399,10 @@
case AT_exhaustive:
Attrs.IsExhaustive = true;
break;
+
+ case AT_no_undeclared_includes:
+ Attrs.NoUndeclaredIncludes = true;
+ break;
}
consumeToken();
Index: test/Modules/Inputs/System/usr/include/stdbool.h
===================================================================
--- test/Modules/Inputs/System/usr/include/stdbool.h (revision 284181)
+++ test/Modules/Inputs/System/usr/include/stdbool.h (working copy)
@@ -1 +1 @@
-// Testing hack: does not define bool/true/false.
+#include_next <stdbool.h>
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/Inputs/libc-libcxx/sysroot/usr/include/c++/v1/__config
===================================================================
--- test/Modules/Inputs/libc-libcxx/sysroot/usr/include/c++/v1/__config (revision 0)
+++ test/Modules/Inputs/libc-libcxx/sysroot/usr/include/c++/v1/__config (working copy)
@@ -0,0 +1,6 @@
+#ifndef _LIBCPP_CONFIG
+#define _LIBCPP_CONFIG
+
+#define __LIBCXX_CONFIG
+
+#endif
Index: test/Modules/Inputs/libc-libcxx/sysroot/usr/include/c++/v1/math.h
===================================================================
--- test/Modules/Inputs/libc-libcxx/sysroot/usr/include/c++/v1/math.h (revision 0)
+++ test/Modules/Inputs/libc-libcxx/sysroot/usr/include/c++/v1/math.h (working copy)
@@ -0,0 +1,7 @@
+#ifndef LIBCXX_MATH_H
+#define LIBCXX_MATH_H
+
+#include_next <math.h>
+template<typename T> T abs(T t) { return (t < 0) ? -t : t; }
+
+#endif
Index: test/Modules/Inputs/libc-libcxx/sysroot/usr/include/c++/v1/module.modulemap
===================================================================
--- test/Modules/Inputs/libc-libcxx/sysroot/usr/include/c++/v1/module.modulemap (revision 0)
+++ test/Modules/Inputs/libc-libcxx/sysroot/usr/include/c++/v1/module.modulemap (working copy)
@@ -0,0 +1,7 @@
+module "libc++" {
+ module math { header "math.h" export * }
+ module stdlib { header "stdlib.h" export * }
+ module stddef { header "stddef.h" export * }
+ module stdio { textual header "stdio.h" export * }
+ module __config { header "__config" export * }
+}
Index: test/Modules/Inputs/libc-libcxx/sysroot/usr/include/c++/v1/stddef.h
===================================================================
--- test/Modules/Inputs/libc-libcxx/sysroot/usr/include/c++/v1/stddef.h (revision 0)
+++ test/Modules/Inputs/libc-libcxx/sysroot/usr/include/c++/v1/stddef.h (working copy)
@@ -0,0 +1,6 @@
+#ifndef LIBCXX_STDDEF_H
+#define LIBCXX_STDDEF_H
+
+#include <__config>
+
+#endif
Index: test/Modules/Inputs/libc-libcxx/sysroot/usr/include/c++/v1/stdio.h
===================================================================
--- test/Modules/Inputs/libc-libcxx/sysroot/usr/include/c++/v1/stdio.h (revision 0)
+++ test/Modules/Inputs/libc-libcxx/sysroot/usr/include/c++/v1/stdio.h (working copy)
@@ -0,0 +1,6 @@
+#ifndef LIBCXX_STDIO_H
+#define LIBCXX_STDIO_H
+
+#include <__config>
+
+#endif
Index: test/Modules/Inputs/libc-libcxx/sysroot/usr/include/c++/v1/stdlib.h
===================================================================
--- test/Modules/Inputs/libc-libcxx/sysroot/usr/include/c++/v1/stdlib.h (revision 0)
+++ test/Modules/Inputs/libc-libcxx/sysroot/usr/include/c++/v1/stdlib.h (working copy)
@@ -0,0 +1,6 @@
+#ifndef LIBCXX_STDLIB_H
+#define LIBCXX_STDLIB_H
+
+#include_next "stdlib.h"
+
+#endif
Index: test/Modules/Inputs/libc-libcxx/sysroot/usr/include/math.h
===================================================================
--- test/Modules/Inputs/libc-libcxx/sysroot/usr/include/math.h (revision 0)
+++ test/Modules/Inputs/libc-libcxx/sysroot/usr/include/math.h (working copy)
@@ -0,0 +1 @@
+int abs(int);
Index: test/Modules/Inputs/libc-libcxx/sysroot/usr/include/module.modulemap
===================================================================
--- test/Modules/Inputs/libc-libcxx/sysroot/usr/include/module.modulemap (revision 0)
+++ test/Modules/Inputs/libc-libcxx/sysroot/usr/include/module.modulemap (working copy)
@@ -0,0 +1,9 @@
+module libc [no_undeclared_includes] {
+ module math { header "math.h" export * }
+ module stdlib { header "stdlib.h" export * }
+ module stdatomic { header "stdatomic.h" export * }
+ module stddef { header "stddef.h" export * }
+ module stdint { header "stdint.h" export * }
+ module stdio { header "stdio.h" export * }
+ module util { header "util.h" export * }
+}
Index: test/Modules/Inputs/libc-libcxx/sysroot/usr/include/stddef.h
===================================================================
--- test/Modules/Inputs/libc-libcxx/sysroot/usr/include/stddef.h (revision 0)
+++ test/Modules/Inputs/libc-libcxx/sysroot/usr/include/stddef.h (working copy)
@@ -0,0 +1,2 @@
+// stddef.h
+#include_next "stddef.h"
Index: test/Modules/Inputs/libc-libcxx/sysroot/usr/include/stdint.h
===================================================================
--- test/Modules/Inputs/libc-libcxx/sysroot/usr/include/stdint.h (revision 0)
+++ test/Modules/Inputs/libc-libcxx/sysroot/usr/include/stdint.h (working copy)
@@ -0,0 +1,22 @@
+typedef char int_least8_t;
+typedef short int_least16_t;
+typedef int int_least32_t;
+typedef long long int int_least64_t;
+typedef unsigned char uint_least8_t;
+typedef unsigned short uint_least16_t;
+typedef unsigned int uint_least32_t;
+typedef unsigned long long uint_least64_t;
+
+typedef char int_fast8_t;
+typedef short int_fast16_t;
+typedef int int_fast32_t;
+typedef long long int int_fast64_t;
+typedef unsigned char uint_fast8_t;
+typedef unsigned short uint_fast16_t;
+typedef unsigned int uint_fast32_t;
+typedef unsigned long long uint_fast64_t;
+
+typedef int * intptr_t;
+typedef unsigned int * uintptr_t;
+typedef int intmax_t;
+typedef unsigned int uintmax_t;
Index: test/Modules/Inputs/libc-libcxx/sysroot/usr/include/stdio.h
===================================================================
--- test/Modules/Inputs/libc-libcxx/sysroot/usr/include/stdio.h (revision 0)
+++ test/Modules/Inputs/libc-libcxx/sysroot/usr/include/stdio.h (working copy)
@@ -0,0 +1,4 @@
+#ifndef DARWIN_STDIO_H
+#define DARWIN_STDIO_H
+
+#endif
Index: test/Modules/Inputs/libc-libcxx/sysroot/usr/include/stdlib.h
===================================================================
--- test/Modules/Inputs/libc-libcxx/sysroot/usr/include/stdlib.h (revision 0)
+++ test/Modules/Inputs/libc-libcxx/sysroot/usr/include/stdlib.h (working copy)
@@ -0,0 +1 @@
+#include <math.h>
Index: test/Modules/Inputs/libc-libcxx/sysroot/usr/include/util.h
===================================================================
--- test/Modules/Inputs/libc-libcxx/sysroot/usr/include/util.h (revision 0)
+++ test/Modules/Inputs/libc-libcxx/sysroot/usr/include/util.h (working copy)
@@ -0,0 +1,6 @@
+#ifndef DARWIN_UTIL_H
+#define DARWIN_UTIL_H
+
+#include <stdio.h>
+
+#endif
Index: test/Modules/libc-libcxx.cpp
===================================================================
--- test/Modules/libc-libcxx.cpp (revision 0)
+++ test/Modules/libc-libcxx.cpp (working copy)
@@ -0,0 +1,10 @@
+// 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
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -x c++ -fmodules-cache-path=%t -fmodules -fimplicit-module-maps -fmodules-local-submodule-visibility -nostdinc++ -isystem %S/Inputs/libc-libcxx/sysroot/usr/include/c++/v1 -isystem %S/Inputs/libc-libcxx/sysroot/usr/include -fsyntax-only %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