diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2017-12-18 20:11:37 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2017-12-18 20:11:37 +0000 |
commit | 461a67fa15370a9ec88f8f8a240bf7c123bb2029 (patch) | |
tree | 6942083d7d56bba40ec790a453ca58ad3baf6832 /lib/Lex/ModuleMap.cpp | |
parent | 75c3240472ba6ac2669ee72ca67eb72d4e2851fc (diff) | |
download | src-461a67fa15370a9ec88f8f8a240bf7c123bb2029.tar.gz src-461a67fa15370a9ec88f8f8a240bf7c123bb2029.zip |
Vendor import of clang trunk r321017:vendor/clang/clang-trunk-r321017
Notes
Notes:
svn path=/vendor/clang/dist/; revision=326941
svn path=/vendor/clang/clang-trunk-r321017/; revision=326942; tag=vendor/clang/clang-trunk-r321017
Diffstat (limited to 'lib/Lex/ModuleMap.cpp')
-rw-r--r-- | lib/Lex/ModuleMap.cpp | 148 |
1 files changed, 116 insertions, 32 deletions
diff --git a/lib/Lex/ModuleMap.cpp b/lib/Lex/ModuleMap.cpp index 40f78ce25ceb..fbbae7a09520 100644 --- a/lib/Lex/ModuleMap.cpp +++ b/lib/Lex/ModuleMap.cpp @@ -1,4 +1,4 @@ -//===--- ModuleMap.cpp - Describe the layout of modules ---------*- C++ -*-===// +//===- ModuleMap.cpp - Describe the layout of modules ---------------------===// // // The LLVM Compiler Infrastructure // @@ -11,29 +11,47 @@ // of a module as it relates to headers. // //===----------------------------------------------------------------------===// + #include "clang/Lex/ModuleMap.h" #include "clang/Basic/CharInfo.h" #include "clang/Basic/Diagnostic.h" -#include "clang/Basic/DiagnosticOptions.h" #include "clang/Basic/FileManager.h" +#include "clang/Basic/LLVM.h" +#include "clang/Basic/LangOptions.h" +#include "clang/Basic/Module.h" +#include "clang/Basic/SourceLocation.h" +#include "clang/Basic/SourceManager.h" #include "clang/Basic/TargetInfo.h" -#include "clang/Basic/TargetOptions.h" +#include "clang/Basic/VirtualFileSystem.h" #include "clang/Lex/HeaderSearch.h" #include "clang/Lex/HeaderSearchOptions.h" #include "clang/Lex/LexDiagnostic.h" #include "clang/Lex/Lexer.h" #include "clang/Lex/LiteralSupport.h" +#include "clang/Lex/Token.h" +#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/None.h" +#include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/SmallPtrSet.h" +#include "llvm/ADT/SmallString.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/StringSwitch.h" #include "llvm/Support/Allocator.h" -#include "llvm/Support/FileSystem.h" -#include "llvm/Support/Host.h" +#include "llvm/Support/Compiler.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/Path.h" #include "llvm/Support/raw_ostream.h" -#include <stdlib.h> -#if defined(LLVM_ON_UNIX) -#include <limits.h> -#endif +#include <algorithm> +#include <cassert> +#include <cstdint> +#include <cstring> +#include <string> +#include <system_error> +#include <utility> + using namespace clang; Module::HeaderKind ModuleMap::headerRoleToKind(ModuleHeaderRole Role) { @@ -80,7 +98,7 @@ ModuleMap::resolveExport(Module *Mod, // Resolve the module-id. Module *Context = resolveModuleId(Unresolved.Id, Mod, Complain); if (!Context) - return Module::ExportDecl(); + return {}; return Module::ExportDecl(Context, Unresolved.Wildcard); } @@ -256,8 +274,7 @@ ModuleMap::ModuleMap(SourceManager &SourceMgr, DiagnosticsEngine &Diags, const LangOptions &LangOpts, const TargetInfo *Target, HeaderSearch &HeaderInfo) : SourceMgr(SourceMgr), Diags(Diags), LangOpts(LangOpts), Target(Target), - HeaderInfo(HeaderInfo), BuiltinIncludeDir(nullptr), - SourceModule(nullptr), NumCreatedModules(0) { + HeaderInfo(HeaderInfo) { MMapLangOpts.LineComment = true; } @@ -345,7 +362,7 @@ ModuleMap::KnownHeader ModuleMap::findHeaderInUmbrellaDirs(const FileEntry *File, SmallVectorImpl<const DirectoryEntry *> &IntermediateDirs) { if (UmbrellaDirs.empty()) - return KnownHeader(); + return {}; const DirectoryEntry *Dir = File->getDir(); assert(Dir && "file in no directory"); @@ -373,7 +390,7 @@ ModuleMap::findHeaderInUmbrellaDirs(const FileEntry *File, // Resolve the parent path to a directory entry. Dir = SourceMgr.getFileManager().getDirectory(DirName); } while (Dir); - return KnownHeader(); + return {}; } static bool violatesPrivateInclude(Module *RequestingModule, @@ -503,7 +520,7 @@ ModuleMap::KnownHeader ModuleMap::findModuleForHeader(const FileEntry *File, bool AllowTextual) { auto MakeResult = [&](ModuleMap::KnownHeader R) -> ModuleMap::KnownHeader { if (!AllowTextual && R.getRole() & ModuleMap::TextualHeader) - return ModuleMap::KnownHeader(); + return {}; return R; }; @@ -593,7 +610,7 @@ ModuleMap::findOrCreateModuleForHeaderInUmbrellaDir(const FileEntry *File) { return Header; } - return KnownHeader(); + return {}; } ArrayRef<ModuleMap::KnownHeader> @@ -746,8 +763,18 @@ std::pair<Module *, bool> ModuleMap::findOrCreateModule(StringRef Name, return std::make_pair(Result, true); } +Module *ModuleMap::createGlobalModuleForInterfaceUnit(SourceLocation Loc) { + assert(!PendingGlobalModule && "created multiple global modules"); + PendingGlobalModule.reset( + new Module("<global>", Loc, nullptr, /*IsFramework*/ false, + /*IsExplicit*/ true, NumCreatedModules++)); + PendingGlobalModule->Kind = Module::GlobalModuleFragment; + return PendingGlobalModule.get(); +} + Module *ModuleMap::createModuleForInterfaceUnit(SourceLocation Loc, - StringRef Name) { + StringRef Name, + Module *GlobalModule) { assert(LangOpts.CurrentModule == Name && "module name mismatch"); assert(!Modules[Name] && "redefining existing module"); @@ -757,6 +784,12 @@ Module *ModuleMap::createModuleForInterfaceUnit(SourceLocation Loc, Result->Kind = Module::ModuleInterfaceUnit; Modules[Name] = SourceModule = Result; + // Reparent the current global module fragment as a submodule of this module. + assert(GlobalModule == PendingGlobalModule.get() && + "unexpected global module"); + GlobalModule->setParent(Result); + PendingGlobalModule.release(); // now owned by parent + // Mark the main source file as being within the newly-created module so that // declarations and macros are properly visibility-restricted to it. auto *MainFile = SourceMgr.getFileEntryForID(SourceMgr.getMainFileID()); @@ -1173,6 +1206,7 @@ bool ModuleMap::resolveConflicts(Module *Mod, bool Complain) { //----------------------------------------------------------------------------// namespace clang { + /// \brief A token in a module map file. struct MMToken { enum TokenKind { @@ -1186,6 +1220,7 @@ namespace clang { ExcludeKeyword, ExplicitKeyword, ExportKeyword, + ExportAsKeyword, ExternKeyword, FrameworkKeyword, LinkKeyword, @@ -1210,6 +1245,7 @@ namespace clang { union { // If Kind != IntegerLiteral. const char *StringData; + // If Kind == IntegerLiteral. uint64_t IntegerValue; }; @@ -1259,7 +1295,7 @@ namespace clang { bool IsSystem; /// \brief Whether an error occurred. - bool HadError; + bool HadError = false; /// \brief Stores string data for the various string literals referenced /// during parsing. @@ -1269,7 +1305,7 @@ namespace clang { MMToken Tok; /// \brief The active module. - Module *ActiveModule; + Module *ActiveModule = nullptr; /// \brief Whether a module uses the 'requires excluded' hack to mark its /// contents as 'textual'. @@ -1288,22 +1324,24 @@ namespace clang { /// (or the end of the file). void skipUntil(MMToken::TokenKind K); - typedef SmallVector<std::pair<std::string, SourceLocation>, 2> ModuleId; + using ModuleId = SmallVector<std::pair<std::string, SourceLocation>, 2>; + bool parseModuleId(ModuleId &Id); void parseModuleDecl(); void parseExternModuleDecl(); void parseRequiresDecl(); - void parseHeaderDecl(clang::MMToken::TokenKind, - SourceLocation LeadingLoc); + void parseHeaderDecl(MMToken::TokenKind, SourceLocation LeadingLoc); void parseUmbrellaDirDecl(SourceLocation UmbrellaLoc); void parseExportDecl(); + void parseExportAsDecl(); void parseUseDecl(); void parseLinkDecl(); void parseConfigMacros(); void parseConflict(); void parseInferredModuleDecl(bool Framework, bool Explicit); - typedef ModuleMap::Attributes Attributes; + using Attributes = ModuleMap::Attributes; + bool parseOptionalAttributes(Attributes &Attrs); public: @@ -1314,10 +1352,9 @@ namespace clang { const FileEntry *ModuleMapFile, const DirectoryEntry *Directory, bool IsSystem) - : L(L), SourceMgr(SourceMgr), Target(Target), Diags(Diags), Map(Map), - ModuleMapFile(ModuleMapFile), Directory(Directory), - IsSystem(IsSystem), HadError(false), ActiveModule(nullptr) - { + : L(L), SourceMgr(SourceMgr), Target(Target), Diags(Diags), Map(Map), + ModuleMapFile(ModuleMapFile), Directory(Directory), + IsSystem(IsSystem) { Tok.clear(); consumeToken(); } @@ -1327,7 +1364,8 @@ namespace clang { bool terminatedByDirective() { return false; } SourceLocation getLocation() { return Tok.getLocation(); } }; -} + +} // namespace clang SourceLocation ModuleMapParser::consumeToken() { SourceLocation Result = Tok.getLocation(); @@ -1348,6 +1386,7 @@ retry: .Case("exclude", MMToken::ExcludeKeyword) .Case("explicit", MMToken::ExplicitKeyword) .Case("export", MMToken::ExportKeyword) + .Case("export_as", MMToken::ExportAsKeyword) .Case("extern", MMToken::ExternKeyword) .Case("framework", MMToken::FrameworkKeyword) .Case("header", MMToken::HeaderKeyword) @@ -1548,20 +1587,26 @@ bool ModuleMapParser::parseModuleId(ModuleId &Id) { } namespace { + /// \brief Enumerates the known attributes. enum AttributeKind { /// \brief An unknown attribute. AT_unknown, + /// \brief The 'system' attribute. AT_system, + /// \brief The 'extern_c' attribute. AT_extern_c, + /// \brief The 'exhaustive' attribute. AT_exhaustive, + /// \brief The 'no_undeclared_includes' attribute. AT_no_undeclared_includes }; -} + +} // namespace /// \brief Parse a module declaration. /// @@ -1575,6 +1620,7 @@ namespace { /// header-declaration /// submodule-declaration /// export-declaration +/// export-as-declaration /// link-declaration /// /// submodule-declaration: @@ -1683,7 +1729,6 @@ void ModuleMapParser::parseModuleDecl() { if (parseOptionalAttributes(Attrs)) return; - // Parse the opening brace. if (!Tok.is(MMToken::LBrace)) { Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace) @@ -1809,6 +1854,10 @@ void ModuleMapParser::parseModuleDecl() { parseExportDecl(); break; + case MMToken::ExportAsKeyword: + parseExportAsDecl(); + break; + case MMToken::UseKeyword: parseUseDecl(); break; @@ -2269,6 +2318,41 @@ void ModuleMapParser::parseExportDecl() { ActiveModule->UnresolvedExports.push_back(Unresolved); } +/// \brief Parse a module export_as declaration. +/// +/// export-as-declaration: +/// 'export_as' identifier +void ModuleMapParser::parseExportAsDecl() { + assert(Tok.is(MMToken::ExportAsKeyword)); + consumeToken(); + + if (!Tok.is(MMToken::Identifier)) { + Diags.Report(Tok.getLocation(), diag::err_mmap_module_id); + HadError = true; + return; + } + + if (ActiveModule->Parent) { + Diags.Report(Tok.getLocation(), diag::err_mmap_submodule_export_as); + consumeToken(); + return; + } + + if (!ActiveModule->ExportAsModule.empty()) { + if (ActiveModule->ExportAsModule == Tok.getString()) { + Diags.Report(Tok.getLocation(), diag::warn_mmap_redundant_export_as) + << ActiveModule->Name << Tok.getString(); + } else { + Diags.Report(Tok.getLocation(), diag::err_mmap_conflicting_export_as) + << ActiveModule->Name << ActiveModule->ExportAsModule + << Tok.getString(); + } + } + + ActiveModule->ExportAsModule = Tok.getString(); + consumeToken(); +} + /// \brief Parse a module use declaration. /// /// use-declaration: @@ -2516,7 +2600,7 @@ void ModuleMapParser::parseInferredModuleDecl(bool Framework, bool Explicit) { Done = true; break; - case MMToken::ExcludeKeyword: { + case MMToken::ExcludeKeyword: if (ActiveModule) { Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member) << (ActiveModule != nullptr); @@ -2535,7 +2619,6 @@ void ModuleMapParser::parseInferredModuleDecl(bool Framework, bool Explicit) { .push_back(Tok.getString()); consumeToken(); break; - } case MMToken::ExportKeyword: if (!ActiveModule) { @@ -2674,6 +2757,7 @@ bool ModuleMapParser::parseModuleMapFile() { case MMToken::Exclaim: case MMToken::ExcludeKeyword: case MMToken::ExportKeyword: + case MMToken::ExportAsKeyword: case MMToken::HeaderKeyword: case MMToken::Identifier: case MMToken::LBrace: |