forked from OSchip/llvm-project
Split compiler builtin module into "stdlib" builtins and "intrinsic"
builds, and bring mm_alloc.h into the fold. Start playing some tricks with these builtin modules to mirror the include_next tricks that the headers already perform. llvm-svn: 149434
This commit is contained in:
parent
2c1ef87e39
commit
232e3431e2
|
@ -126,6 +126,32 @@ ASTConsumer *GenerateModuleAction::CreateASTConsumer(CompilerInstance &CI,
|
||||||
Sysroot, OS);
|
Sysroot, OS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// \brief Add an appropriate #include/#import for the given header within
|
||||||
|
/// the current module context.
|
||||||
|
static void addHeaderInclude(StringRef Header,
|
||||||
|
bool IsBuiltinModule,
|
||||||
|
const LangOptions &LangOpts,
|
||||||
|
llvm::SmallString<256> &Includes) {
|
||||||
|
if (IsBuiltinModule) {
|
||||||
|
// Our own builtin headers play some evil tricks that depend both on
|
||||||
|
// knowing that our headers will be found first and on include_next. To
|
||||||
|
// Make sure these include_next tricks work, we include with <> and
|
||||||
|
// just the filename itself rather than using an absolutely path.
|
||||||
|
// FIXME: Is there some sensible way to generalize this?
|
||||||
|
Includes += "#include <";
|
||||||
|
Includes += llvm::sys::path::filename(Header);
|
||||||
|
Includes += ">\n";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (LangOpts.ObjC1)
|
||||||
|
Includes += "#import \"";
|
||||||
|
else
|
||||||
|
Includes += "#include \"";
|
||||||
|
Includes += Header;
|
||||||
|
Includes += "\"\n";
|
||||||
|
}
|
||||||
|
|
||||||
/// \brief Collect the set of header includes needed to construct the given
|
/// \brief Collect the set of header includes needed to construct the given
|
||||||
/// module.
|
/// module.
|
||||||
///
|
///
|
||||||
|
@ -137,31 +163,21 @@ static void collectModuleHeaderIncludes(const LangOptions &LangOpts,
|
||||||
FileManager &FileMgr,
|
FileManager &FileMgr,
|
||||||
ModuleMap &ModMap,
|
ModuleMap &ModMap,
|
||||||
clang::Module *Module,
|
clang::Module *Module,
|
||||||
|
bool IsBuiltinModule,
|
||||||
llvm::SmallString<256> &Includes) {
|
llvm::SmallString<256> &Includes) {
|
||||||
// Don't collect any headers for unavailable modules.
|
// Don't collect any headers for unavailable modules.
|
||||||
if (!Module->isAvailable())
|
if (!Module->isAvailable())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Add includes for each of these headers.
|
// Add includes for each of these headers.
|
||||||
for (unsigned I = 0, N = Module->Headers.size(); I != N; ++I) {
|
for (unsigned I = 0, N = Module->Headers.size(); I != N; ++I)
|
||||||
if (LangOpts.ObjC1)
|
addHeaderInclude(Module->Headers[I]->getName(), IsBuiltinModule, LangOpts,
|
||||||
Includes += "#import \"";
|
Includes);
|
||||||
else
|
|
||||||
Includes += "#include \"";
|
|
||||||
Includes += Module->Headers[I]->getName();
|
|
||||||
Includes += "\"\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (const FileEntry *UmbrellaHeader = Module->getUmbrellaHeader()) {
|
if (const FileEntry *UmbrellaHeader = Module->getUmbrellaHeader()) {
|
||||||
if (Module->Parent) {
|
if (Module->Parent)
|
||||||
// Include the umbrella header for submodules.
|
addHeaderInclude(UmbrellaHeader->getName(), IsBuiltinModule, LangOpts,
|
||||||
if (LangOpts.ObjC1)
|
Includes);
|
||||||
Includes += "#import \"";
|
|
||||||
else
|
|
||||||
Includes += "#include \"";
|
|
||||||
Includes += UmbrellaHeader->getName();
|
|
||||||
Includes += "\"\n";
|
|
||||||
}
|
|
||||||
} else if (const DirectoryEntry *UmbrellaDir = Module->getUmbrellaDir()) {
|
} else if (const DirectoryEntry *UmbrellaDir = Module->getUmbrellaDir()) {
|
||||||
// Add all of the headers we find in this subdirectory.
|
// Add all of the headers we find in this subdirectory.
|
||||||
llvm::error_code EC;
|
llvm::error_code EC;
|
||||||
|
@ -183,13 +199,8 @@ static void collectModuleHeaderIncludes(const LangOptions &LangOpts,
|
||||||
if (ModMap.isHeaderInUnavailableModule(Header))
|
if (ModMap.isHeaderInUnavailableModule(Header))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Include this header umbrella header for submodules.
|
// Include this header.
|
||||||
if (LangOpts.ObjC1)
|
addHeaderInclude(Dir->path(), IsBuiltinModule, LangOpts, Includes);
|
||||||
Includes += "#import \"";
|
|
||||||
else
|
|
||||||
Includes += "#include \"";
|
|
||||||
Includes += Dir->path();
|
|
||||||
Includes += "\"\n";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -197,7 +208,8 @@ static void collectModuleHeaderIncludes(const LangOptions &LangOpts,
|
||||||
for (clang::Module::submodule_iterator Sub = Module->submodule_begin(),
|
for (clang::Module::submodule_iterator Sub = Module->submodule_begin(),
|
||||||
SubEnd = Module->submodule_end();
|
SubEnd = Module->submodule_end();
|
||||||
Sub != SubEnd; ++Sub)
|
Sub != SubEnd; ++Sub)
|
||||||
collectModuleHeaderIncludes(LangOpts, FileMgr, ModMap, *Sub, Includes);
|
collectModuleHeaderIncludes(LangOpts, FileMgr, ModMap, *Sub,
|
||||||
|
IsBuiltinModule, Includes);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GenerateModuleAction::BeginSourceFileAction(CompilerInstance &CI,
|
bool GenerateModuleAction::BeginSourceFileAction(CompilerInstance &CI,
|
||||||
|
@ -249,10 +261,11 @@ bool GenerateModuleAction::BeginSourceFileAction(CompilerInstance &CI,
|
||||||
const FileEntry *UmbrellaHeader = Module->getUmbrellaHeader();
|
const FileEntry *UmbrellaHeader = Module->getUmbrellaHeader();
|
||||||
|
|
||||||
// Collect the set of #includes we need to build the module.
|
// Collect the set of #includes we need to build the module.
|
||||||
|
bool IsBuiltinModule = StringRef(Module->Name).startswith("_Builtin_");
|
||||||
llvm::SmallString<256> HeaderContents;
|
llvm::SmallString<256> HeaderContents;
|
||||||
collectModuleHeaderIncludes(CI.getLangOpts(), CI.getFileManager(),
|
collectModuleHeaderIncludes(CI.getLangOpts(), CI.getFileManager(),
|
||||||
CI.getPreprocessor().getHeaderSearchInfo().getModuleMap(),
|
CI.getPreprocessor().getHeaderSearchInfo().getModuleMap(),
|
||||||
Module, HeaderContents);
|
Module, IsBuiltinModule, HeaderContents);
|
||||||
if (UmbrellaHeader && HeaderContents.empty()) {
|
if (UmbrellaHeader && HeaderContents.empty()) {
|
||||||
// Simple case: we have an umbrella header and there are no additional
|
// Simple case: we have an umbrella header and there are no additional
|
||||||
// includes, we can just parse the umbrella header directly.
|
// includes, we can just parse the umbrella header directly.
|
||||||
|
|
|
@ -1,9 +1,4 @@
|
||||||
module __compiler_builtins [system] {
|
module _Builtin_stdlib [system] {
|
||||||
explicit module altivec {
|
|
||||||
requires altivec
|
|
||||||
header "altivec.h"
|
|
||||||
}
|
|
||||||
|
|
||||||
explicit module float_constants {
|
explicit module float_constants {
|
||||||
header "float.h"
|
header "float.h"
|
||||||
}
|
}
|
||||||
|
@ -36,6 +31,18 @@ module __compiler_builtins [system] {
|
||||||
header "stdint.h"
|
header "stdint.h"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
explicit module varargs {
|
||||||
|
requires unavailable
|
||||||
|
header "varargs.h"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module _Builtin_intrinsics [system] {
|
||||||
|
explicit module altivec {
|
||||||
|
requires altivec
|
||||||
|
header "altivec.h"
|
||||||
|
}
|
||||||
|
|
||||||
explicit module intel {
|
explicit module intel {
|
||||||
requires x86
|
requires x86
|
||||||
|
|
||||||
|
@ -129,14 +136,12 @@ module __compiler_builtins [system] {
|
||||||
requires mm3dnow
|
requires mm3dnow
|
||||||
header "mm3dnow.h"
|
header "mm3dnow.h"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
explicit module mm_malloc {
|
||||||
|
header "mm_malloc.h"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: mm_malloc.h
|
|
||||||
// FIXME: tgmath.h
|
// FIXME: tgmath.h
|
||||||
// FIXME: unwind.h
|
// FIXME: unwind.h
|
||||||
|
|
||||||
explicit module varargs {
|
|
||||||
requires unavailable
|
|
||||||
header "varargs.h"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,20 +1,24 @@
|
||||||
// RUN: rm -rf %t
|
// RUN: rm -rf %t
|
||||||
// RUN: %clang -fsyntax-only -fmodules -fmodule-cache-path %t %s -Xclang -verify
|
// RUN: %clang -fsyntax-only -fmodules -fmodule-cache-path %t %s -Xclang -verify
|
||||||
|
|
||||||
@import __compiler_builtins.float_constants;
|
@import _Builtin_stdlib.float_constants;
|
||||||
|
|
||||||
float getFltMax() { return FLT_MAX; }
|
float getFltMax() { return FLT_MAX; }
|
||||||
|
|
||||||
@import __compiler_builtins.limits;
|
@import _Builtin_stdlib.limits;
|
||||||
|
|
||||||
char getCharMax() { return CHAR_MAX; }
|
char getCharMax() { return CHAR_MAX; }
|
||||||
|
|
||||||
size_t size; // expected-error{{unknown type name 'size_t'}}
|
size_t size; // expected-error{{unknown type name 'size_t'}}
|
||||||
|
|
||||||
|
@import _Builtin_stdlib.stdint;
|
||||||
|
|
||||||
|
intmax_t value;
|
||||||
|
|
||||||
#ifdef __SSE__
|
#ifdef __SSE__
|
||||||
@import __compiler_builtins.intel.sse;
|
@import _Builtin_intrinsics.intel.sse;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __AVX2__
|
#ifdef __AVX2__
|
||||||
@import __compiler_builtins.intel.avx2;
|
@import _Builtin_intrinsics.intel.avx2;
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue