From eb7b9eb18b59c28d41d4dcddd55a3ec98c23d437 Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Tue, 31 Jan 2012 21:57:50 +0000 Subject: [PATCH] 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. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@149434 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Frontend/FrontendActions.cpp | 65 +++++++++++++++++++------------- lib/Headers/module.map | 29 ++++++++------ test/Modules/compiler_builtins.m | 12 ++++-- 3 files changed, 64 insertions(+), 42 deletions(-) diff --git a/lib/Frontend/FrontendActions.cpp b/lib/Frontend/FrontendActions.cpp index c0302329c1..edadf37766 100644 --- a/lib/Frontend/FrontendActions.cpp +++ b/lib/Frontend/FrontendActions.cpp @@ -126,6 +126,32 @@ ASTConsumer *GenerateModuleAction::CreateASTConsumer(CompilerInstance &CI, 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 /// module. /// @@ -137,31 +163,21 @@ static void collectModuleHeaderIncludes(const LangOptions &LangOpts, FileManager &FileMgr, ModuleMap &ModMap, clang::Module *Module, + bool IsBuiltinModule, llvm::SmallString<256> &Includes) { // Don't collect any headers for unavailable modules. if (!Module->isAvailable()) return; // Add includes for each of these headers. - for (unsigned I = 0, N = Module->Headers.size(); I != N; ++I) { - if (LangOpts.ObjC1) - Includes += "#import \""; - else - Includes += "#include \""; - Includes += Module->Headers[I]->getName(); - Includes += "\"\n"; - } + for (unsigned I = 0, N = Module->Headers.size(); I != N; ++I) + addHeaderInclude(Module->Headers[I]->getName(), IsBuiltinModule, LangOpts, + Includes); if (const FileEntry *UmbrellaHeader = Module->getUmbrellaHeader()) { - if (Module->Parent) { - // Include the umbrella header for submodules. - if (LangOpts.ObjC1) - Includes += "#import \""; - else - Includes += "#include \""; - Includes += UmbrellaHeader->getName(); - Includes += "\"\n"; - } + if (Module->Parent) + addHeaderInclude(UmbrellaHeader->getName(), IsBuiltinModule, LangOpts, + Includes); } else if (const DirectoryEntry *UmbrellaDir = Module->getUmbrellaDir()) { // Add all of the headers we find in this subdirectory. llvm::error_code EC; @@ -183,13 +199,8 @@ static void collectModuleHeaderIncludes(const LangOptions &LangOpts, if (ModMap.isHeaderInUnavailableModule(Header)) continue; - // Include this header umbrella header for submodules. - if (LangOpts.ObjC1) - Includes += "#import \""; - else - Includes += "#include \""; - Includes += Dir->path(); - Includes += "\"\n"; + // Include this header. + addHeaderInclude(Dir->path(), IsBuiltinModule, LangOpts, Includes); } } @@ -197,7 +208,8 @@ static void collectModuleHeaderIncludes(const LangOptions &LangOpts, for (clang::Module::submodule_iterator Sub = Module->submodule_begin(), SubEnd = Module->submodule_end(); Sub != SubEnd; ++Sub) - collectModuleHeaderIncludes(LangOpts, FileMgr, ModMap, *Sub, Includes); + collectModuleHeaderIncludes(LangOpts, FileMgr, ModMap, *Sub, + IsBuiltinModule, Includes); } bool GenerateModuleAction::BeginSourceFileAction(CompilerInstance &CI, @@ -249,10 +261,11 @@ bool GenerateModuleAction::BeginSourceFileAction(CompilerInstance &CI, const FileEntry *UmbrellaHeader = Module->getUmbrellaHeader(); // Collect the set of #includes we need to build the module. + bool IsBuiltinModule = StringRef(Module->Name).startswith("_Builtin_"); llvm::SmallString<256> HeaderContents; collectModuleHeaderIncludes(CI.getLangOpts(), CI.getFileManager(), CI.getPreprocessor().getHeaderSearchInfo().getModuleMap(), - Module, HeaderContents); + Module, IsBuiltinModule, HeaderContents); if (UmbrellaHeader && HeaderContents.empty()) { // Simple case: we have an umbrella header and there are no additional // includes, we can just parse the umbrella header directly. diff --git a/lib/Headers/module.map b/lib/Headers/module.map index cd18e5efb4..e321ca3ca5 100644 --- a/lib/Headers/module.map +++ b/lib/Headers/module.map @@ -1,9 +1,4 @@ -module __compiler_builtins [system] { - explicit module altivec { - requires altivec - header "altivec.h" - } - +module _Builtin_stdlib [system] { explicit module float_constants { header "float.h" } @@ -36,6 +31,18 @@ module __compiler_builtins [system] { 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 { requires x86 @@ -129,14 +136,12 @@ module __compiler_builtins [system] { requires mm3dnow header "mm3dnow.h" } + + explicit module mm_malloc { + header "mm_malloc.h" + } } - // FIXME: mm_malloc.h // FIXME: tgmath.h // FIXME: unwind.h - - explicit module varargs { - requires unavailable - header "varargs.h" - } } diff --git a/test/Modules/compiler_builtins.m b/test/Modules/compiler_builtins.m index 283ff0eefe..d5b58b06ff 100644 --- a/test/Modules/compiler_builtins.m +++ b/test/Modules/compiler_builtins.m @@ -1,20 +1,24 @@ // RUN: rm -rf %t // 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; } -@import __compiler_builtins.limits; +@import _Builtin_stdlib.limits; char getCharMax() { return CHAR_MAX; } size_t size; // expected-error{{unknown type name 'size_t'}} +@import _Builtin_stdlib.stdint; + +intmax_t value; + #ifdef __SSE__ -@import __compiler_builtins.intel.sse; +@import _Builtin_intrinsics.intel.sse; #endif #ifdef __AVX2__ -@import __compiler_builtins.intel.avx2; +@import _Builtin_intrinsics.intel.avx2; #endif -- 2.40.0