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:
Douglas Gregor 2012-01-31 21:57:50 +00:00
parent 2c1ef87e39
commit 232e3431e2
3 changed files with 64 additions and 42 deletions

View File

@ -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.

View File

@ -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"
}
} }

View File

@ -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