Implement parsing, AST, (de-)serialization, and placeholder global
metadata for linking against the libraries/frameworks for imported
modules.
The module map language is extended with a new "link" directive that
specifies what library or framework to link against when a module is
imported, e.g.,
link "clangAST"
or
link framework "MyFramework"
Importing the corresponding module (or any of its submodules) will
eventually link against the named library/framework.
For now, I've added some placeholder global metadata that encodes the
imported libraries/frameworks, so that we can test that this
information gets through to the IR. The format of the data is still
under discussion.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@172437 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Lex/ModuleMap.cpp b/lib/Lex/ModuleMap.cpp
index d954bc9..6b0eb79 100644
--- a/lib/Lex/ModuleMap.cpp
+++ b/lib/Lex/ModuleMap.cpp
@@ -645,6 +645,7 @@
ExplicitKeyword,
ExportKeyword,
FrameworkKeyword,
+ LinkKeyword,
ModuleKeyword,
Period,
UmbrellaKeyword,
@@ -732,6 +733,7 @@
void parseHeaderDecl(SourceLocation UmbrellaLoc, SourceLocation ExcludeLoc);
void parseUmbrellaDirDecl(SourceLocation UmbrellaLoc);
void parseExportDecl();
+ void parseLinkDecl();
void parseInferredModuleDecl(bool Framework, bool Explicit);
bool parseOptionalAttributes(Attributes &Attrs);
@@ -774,6 +776,7 @@
.Case("explicit", MMToken::ExplicitKeyword)
.Case("export", MMToken::ExportKeyword)
.Case("framework", MMToken::FrameworkKeyword)
+ .Case("link", MMToken::LinkKeyword)
.Case("module", MMToken::ModuleKeyword)
.Case("requires", MMToken::RequiresKeyword)
.Case("umbrella", MMToken::UmbrellaKeyword)
@@ -944,6 +947,7 @@
/// header-declaration
/// submodule-declaration
/// export-declaration
+/// link-declaration
///
/// submodule-declaration:
/// module-declaration
@@ -1123,7 +1127,11 @@
case MMToken::HeaderKeyword:
parseHeaderDecl(SourceLocation(), SourceLocation());
break;
-
+
+ case MMToken::LinkKeyword:
+ parseLinkDecl();
+ break;
+
default:
Diags.Report(Tok.getLocation(), diag::err_mmap_expected_member);
consumeToken();
@@ -1440,7 +1448,36 @@
ActiveModule->UnresolvedExports.push_back(Unresolved);
}
-/// \brief Parse an inferried module declaration (wildcard modules).
+/// \brief Parse a link declaration.
+///
+/// module-declaration:
+/// 'link' 'framework'[opt] string-literal
+void ModuleMapParser::parseLinkDecl() {
+ assert(Tok.is(MMToken::LinkKeyword));
+ SourceLocation LinkLoc = consumeToken();
+
+ // Parse the optional 'framework' keyword.
+ bool IsFramework = false;
+ if (Tok.is(MMToken::FrameworkKeyword)) {
+ consumeToken();
+ IsFramework = true;
+ }
+
+ // Parse the library name
+ if (!Tok.is(MMToken::StringLiteral)) {
+ Diags.Report(Tok.getLocation(), diag::err_mmap_expected_library_name)
+ << IsFramework << SourceRange(LinkLoc);
+ HadError = true;
+ return;
+ }
+
+ std::string LibraryName = Tok.getString();
+ consumeToken();
+ ActiveModule->LinkLibraries.push_back(Module::LinkLibrary(LibraryName,
+ IsFramework));
+}
+
+/// \brief Parse an inferred module declaration (wildcard modules).
///
/// module-declaration:
/// 'explicit'[opt] 'framework'[opt] 'module' * attributes[opt]
@@ -1679,13 +1716,14 @@
case MMToken::FrameworkKeyword:
parseModuleDecl();
break;
-
+
case MMToken::Comma:
case MMToken::ExcludeKeyword:
case MMToken::ExportKeyword:
case MMToken::HeaderKeyword:
case MMToken::Identifier:
case MMToken::LBrace:
+ case MMToken::LinkKeyword:
case MMToken::LSquare:
case MMToken::Period:
case MMToken::RBrace: