22#include "llvm/ADT/STLExtras.h"
26using namespace modulemap;
62 unsigned StringLength;
65 const char *StringData;
78 bool is(TokenKind K)
const {
return Kind == K; }
88 StringRef getString()
const {
90 : StringRef(StringData, StringLength);
94struct ModuleMapFileParser {
102 bool HadError =
false;
107 bool parseTopLevelDecls();
108 std::optional<ModuleDecl> parseModuleDecl(
bool TopLevel);
109 std::optional<ExternModuleDecl> parseExternModuleDecl();
110 std::optional<ConfigMacrosDecl> parseConfigMacrosDecl();
111 std::optional<ConflictDecl> parseConflictDecl();
112 std::optional<ExportDecl> parseExportDecl();
113 std::optional<ExportAsDecl> parseExportAsDecl();
114 std::optional<UseDecl> parseUseDecl();
115 std::optional<RequiresDecl> parseRequiresDecl();
116 std::optional<HeaderDecl> parseHeaderDecl(MMToken::TokenKind LeadingToken,
119 std::optional<UmbrellaDirDecl>
121 std::optional<LinkDecl>
122 parseLinkDecl(llvm::StringMap<SourceLocation> &SeenLinkDecl,
bool Allowed);
125 void skipUntil(MMToken::TokenKind K);
132std::string formatModuleId(
const ModuleId &
Id) {
135 llvm::raw_string_ostream OS(result);
137 for (
unsigned I = 0, N =
Id.size(); I != N; ++I) {
148std::optional<ModuleMapFile>
151 bool IsSystem,
unsigned *Offset) {
152 std::optional<llvm::MemoryBufferRef> Buffer =
SM.getBufferOrNone(ID);
154 LOpts.
LangStd = clang::LangStandard::lang_c99;
155 Lexer L(
SM.getLocForStartOfFile(ID), LOpts, Buffer->getBufferStart(),
156 Buffer->getBufferStart() + (Offset ? *Offset : 0),
157 Buffer->getBufferEnd());
160 ModuleMapFileParser
Parser{L, Diags};
161 bool Failed =
Parser.parseTopLevelDecls();
164 auto Loc =
SM.getDecomposedLoc(
Parser.getLocation());
165 assert(
Loc.first == ID &&
"stopped in a different file?");
166 *Offset =
Loc.second;
174 Parser.MMF.IsSystem = IsSystem;
175 return std::move(
Parser.MMF);
178bool ModuleMapFileParser::parseTopLevelDecls() {
183 case MMToken::EndOfFile:
185 case MMToken::ExternKeyword: {
186 std::optional<ExternModuleDecl> EMD = parseExternModuleDecl();
188 MMF.Decls.push_back(std::move(*EMD));
191 case MMToken::ExplicitKeyword:
192 case MMToken::ModuleKeyword:
193 case MMToken::FrameworkKeyword: {
194 std::optional<ModuleDecl> MD = parseModuleDecl(
true);
196 MMF.Decls.push_back(std::move(*MD));
200 case MMToken::ConfigMacros:
201 case MMToken::Conflict:
202 case MMToken::Exclaim:
203 case MMToken::ExcludeKeyword:
204 case MMToken::ExportKeyword:
205 case MMToken::ExportAsKeyword:
206 case MMToken::HeaderKeyword:
207 case MMToken::Identifier:
208 case MMToken::LBrace:
209 case MMToken::LinkKeyword:
210 case MMToken::LSquare:
211 case MMToken::Period:
212 case MMToken::PrivateKeyword:
213 case MMToken::RBrace:
214 case MMToken::RSquare:
215 case MMToken::RequiresKeyword:
217 case MMToken::StringLiteral:
218 case MMToken::IntegerLiteral:
219 case MMToken::TextualKeyword:
220 case MMToken::UmbrellaKeyword:
221 case MMToken::UseKeyword:
222 Diags.
Report(Tok.getLocation(), diag::err_mmap_expected_module);
248std::optional<ModuleDecl> ModuleMapFileParser::parseModuleDecl(
bool TopLevel) {
249 assert(Tok.is(MMToken::ExplicitKeyword) || Tok.is(MMToken::ModuleKeyword) ||
250 Tok.is(MMToken::FrameworkKeyword));
259 if (Tok.is(MMToken::ExplicitKeyword)) {
260 MDecl.
Location = ExplicitLoc = consumeToken();
265 if (Tok.is(MMToken::FrameworkKeyword)) {
273 if (!Tok.is(MMToken::ModuleKeyword)) {
274 Diags.
Report(Tok.getLocation(), diag::err_mmap_expected_module);
285 if (Tok.is(MMToken::Star)) {
287 MDecl.
Id.push_back({
"*", StarLoc});
289 Diags.
Report(StarLoc, diag::err_mmap_top_level_inferred_submodule);
295 if (parseModuleId(MDecl.
Id)) {
300 if (MDecl.
Id.size() > 1) {
301 Diags.
Report(MDecl.
Id.front().second,
302 diag::err_mmap_nested_submodule_id)
307 }
else if (MDecl.
Id.size() == 1 && MDecl.
Explicit) {
309 Diags.
Report(ExplicitLoc, diag::err_mmap_explicit_top_level);
316 if (parseOptionalAttributes(MDecl.
Attrs))
320 if (!Tok.is(MMToken::LBrace)) {
321 Diags.
Report(Tok.getLocation(), diag::err_mmap_expected_lbrace)
322 << MDecl.
Id.back().first;
329 llvm::StringMap<SourceLocation> SeenLinkDecl;
331 std::optional<Decl> SubDecl;
333 case MMToken::EndOfFile:
334 case MMToken::RBrace:
338 case MMToken::ConfigMacros:
341 Diags.
Report(Tok.getLocation(), diag::err_mmap_config_macro_submodule);
342 SubDecl = parseConfigMacrosDecl();
345 case MMToken::Conflict:
346 SubDecl = parseConflictDecl();
349 case MMToken::ExternKeyword:
350 SubDecl = parseExternModuleDecl();
353 case MMToken::ExplicitKeyword:
354 case MMToken::FrameworkKeyword:
355 case MMToken::ModuleKeyword:
356 SubDecl = parseModuleDecl(
false);
359 case MMToken::ExportKeyword:
360 SubDecl = parseExportDecl();
363 case MMToken::ExportAsKeyword:
365 Diags.
Report(Tok.getLocation(), diag::err_mmap_submodule_export_as);
368 SubDecl = parseExportAsDecl();
371 case MMToken::UseKeyword:
372 SubDecl = parseUseDecl();
375 case MMToken::RequiresKeyword:
376 SubDecl = parseRequiresDecl();
379 case MMToken::TextualKeyword:
380 SubDecl = parseHeaderDecl(MMToken::TextualKeyword, consumeToken());
383 case MMToken::UmbrellaKeyword: {
385 if (Tok.is(MMToken::HeaderKeyword))
386 SubDecl = parseHeaderDecl(MMToken::UmbrellaKeyword, UmbrellaLoc);
388 SubDecl = parseUmbrellaDirDecl(UmbrellaLoc);
392 case MMToken::ExcludeKeyword: {
394 if (Tok.is(MMToken::HeaderKeyword))
395 SubDecl = parseHeaderDecl(MMToken::ExcludeKeyword, ExcludeLoc);
397 SubDecl = parseExcludeDecl(ExcludeLoc);
401 case MMToken::PrivateKeyword:
402 SubDecl = parseHeaderDecl(MMToken::PrivateKeyword, consumeToken());
405 case MMToken::HeaderKeyword:
406 SubDecl = parseHeaderDecl(MMToken::HeaderKeyword, consumeToken());
409 case MMToken::LinkKeyword:
412 SubDecl = parseLinkDecl(SeenLinkDecl, TopLevel || MDecl.
Explicit);
416 Diags.
Report(Tok.getLocation(), diag::err_mmap_expected_member);
421 MDecl.
Decls.push_back(std::move(*SubDecl));
424 if (Tok.is(MMToken::RBrace))
427 Diags.
Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
428 Diags.
Report(LBraceLoc, diag::note_mmap_lbrace_match);
431 return std::move(MDecl);
434std::optional<ExternModuleDecl> ModuleMapFileParser::parseExternModuleDecl() {
435 assert(Tok.is(MMToken::ExternKeyword));
440 if (!Tok.is(MMToken::ModuleKeyword)) {
441 Diags.
Report(Tok.getLocation(), diag::err_mmap_expected_module);
449 if (parseModuleId(EMD.
Id)) {
455 if (!Tok.is(MMToken::StringLiteral)) {
456 Diags.
Report(Tok.getLocation(), diag::err_mmap_expected_mmap_file);
460 EMD.
Path = Tok.getString();
463 return std::move(EMD);
473std::optional<ConfigMacrosDecl> ModuleMapFileParser::parseConfigMacrosDecl() {
474 assert(Tok.is(MMToken::ConfigMacros));
480 if (parseOptionalAttributes(Attrs))
487 if (!Tok.is(MMToken::Identifier))
491 CMDecl.
Macros.push_back(Tok.getString());
496 if (!Tok.is(MMToken::Comma))
502 if (!Tok.is(MMToken::Identifier)) {
503 Diags.
Report(Tok.getLocation(), diag::err_mmap_expected_config_macro);
508 CMDecl.
Macros.push_back(Tok.getString());
511 return std::move(CMDecl);
518std::optional<ConflictDecl> ModuleMapFileParser::parseConflictDecl() {
519 assert(Tok.is(MMToken::Conflict));
524 if (parseModuleId(CD.
Id))
528 if (!Tok.is(MMToken::Comma)) {
529 Diags.
Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_comma)
536 if (!Tok.is(MMToken::StringLiteral)) {
537 Diags.
Report(Tok.getLocation(), diag::err_mmap_expected_conflicts_message)
538 << formatModuleId(CD.
Id);
543 return std::move(CD);
555std::optional<ExportDecl> ModuleMapFileParser::parseExportDecl() {
556 assert(Tok.is(MMToken::ExportKeyword));
558 ED.Location = consumeToken();
564 if (Tok.is(MMToken::Identifier)) {
566 std::make_pair(std::string(Tok.getString()), Tok.getLocation()));
569 if (Tok.is(MMToken::Period)) {
577 if (Tok.is(MMToken::Star)) {
583 Diags.
Report(Tok.getLocation(), diag::err_mmap_module_id);
588 return std::move(ED);
595std::optional<ExportAsDecl> ModuleMapFileParser::parseExportAsDecl() {
596 assert(Tok.is(MMToken::ExportAsKeyword));
600 if (!Tok.is(MMToken::Identifier)) {
601 Diags.
Report(Tok.getLocation(), diag::err_mmap_module_id);
606 if (parseModuleId(EAD.
Id))
608 if (EAD.
Id.size() > 1)
609 Diags.
Report(EAD.
Id[1].second, diag::err_mmap_qualified_export_as);
610 return std::move(EAD);
617std::optional<UseDecl> ModuleMapFileParser::parseUseDecl() {
618 assert(Tok.is(MMToken::UseKeyword));
621 if (parseModuleId(UD.
Id))
623 return std::move(UD);
637std::optional<RequiresDecl> ModuleMapFileParser::parseRequiresDecl() {
638 assert(Tok.is(MMToken::RequiresKeyword));
644 bool RequiredState =
true;
645 if (Tok.is(MMToken::Exclaim)) {
646 RequiredState =
false;
650 if (!Tok.is(MMToken::Identifier)) {
651 Diags.
Report(Tok.getLocation(), diag::err_mmap_expected_feature);
662 RD.
Features.push_back(std::move(RF));
664 if (!Tok.is(MMToken::Comma))
670 return std::move(RD);
680std::optional<HeaderDecl>
681ModuleMapFileParser::parseHeaderDecl(MMToken::TokenKind LeadingToken,
690 if (LeadingToken == MMToken::PrivateKeyword) {
693 if (Tok.is(MMToken::TextualKeyword)) {
695 LeadingToken = Tok.Kind;
698 }
else if (LeadingToken == MMToken::ExcludeKeyword)
700 else if (LeadingToken == MMToken::TextualKeyword)
703 if (LeadingToken != MMToken::HeaderKeyword) {
704 if (!Tok.is(MMToken::HeaderKeyword)) {
705 Diags.
Report(Tok.getLocation(), diag::err_mmap_expected_header)
706 << (LeadingToken == MMToken::PrivateKeyword ?
"private"
707 : LeadingToken == MMToken::ExcludeKeyword ?
"exclude"
708 : LeadingToken == MMToken::TextualKeyword ?
"textual"
716 if (!Tok.is(MMToken::StringLiteral)) {
717 Diags.
Report(Tok.getLocation(), diag::err_mmap_expected_header) <<
"header";
721 HD.
Path = Tok.getString();
723 HD.
Umbrella = LeadingToken == MMToken::UmbrellaKeyword;
727 if (Tok.is(MMToken::LBrace)) {
730 while (!Tok.is(MMToken::RBrace) && !Tok.is(MMToken::EndOfFile)) {
732 StringRef Str = Tok.getString();
734 switch (llvm::StringSwitch<Attribute>(Str)
736 .Case(
"mtime", ModTime)
740 Diags.
Report(
Loc, diag::err_mmap_duplicate_header_attribute) << Str;
741 if (!Tok.is(MMToken::IntegerLiteral)) {
742 Diags.
Report(Tok.getLocation(),
743 diag::err_mmap_invalid_header_attribute_value)
745 skipUntil(MMToken::RBrace);
748 HD.
Size = Tok.getInteger();
754 Diags.
Report(
Loc, diag::err_mmap_duplicate_header_attribute) << Str;
755 if (!Tok.is(MMToken::IntegerLiteral)) {
756 Diags.
Report(Tok.getLocation(),
757 diag::err_mmap_invalid_header_attribute_value)
759 skipUntil(MMToken::RBrace);
762 HD.
MTime = Tok.getInteger();
767 Diags.
Report(
Loc, diag::err_mmap_expected_header_attribute);
768 skipUntil(MMToken::RBrace);
773 if (Tok.is(MMToken::RBrace))
776 Diags.
Report(Tok.getLocation(), diag::err_mmap_expected_rbrace);
777 Diags.
Report(LBraceLoc, diag::note_mmap_lbrace_match);
781 return std::move(HD);
788std::optional<ExcludeDecl>
791 if (!Tok.is(MMToken::Identifier)) {
792 Diags.
Report(Tok.getLocation(), diag::err_mmap_missing_exclude_name);
799 ED.
Module = Tok.getString();
801 return std::move(ED);
808std::optional<UmbrellaDirDecl>
813 if (!Tok.is(MMToken::StringLiteral)) {
814 Diags.
Report(Tok.getLocation(), diag::err_mmap_expected_header)
820 UDD.
Path = Tok.getString();
822 return std::move(UDD);
829std::optional<LinkDecl> ModuleMapFileParser::parseLinkDecl(
830 llvm::StringMap<SourceLocation> &SeenLinkDecl,
bool Allowed) {
831 assert(Tok.is(MMToken::LinkKeyword));
837 if (Tok.is(MMToken::FrameworkKeyword)) {
843 if (!Tok.is(MMToken::StringLiteral)) {
844 Diags.
Report(Tok.getLocation(), diag::err_mmap_expected_library_name)
851 StringRef
Library = Tok.getString();
864 auto [It, Inserted] =
865 SeenLinkDecl.insert(std::make_pair(Library, LD.
Location));
868 Diags.
Report(It->second, diag::note_mmap_prev_link_declaration);
873 return std::move(LD);
885 case tok::raw_identifier: {
887 Tok.StringData = RI.data();
888 Tok.StringLength = RI.size();
889 Tok.Kind = llvm::StringSwitch<MMToken::TokenKind>(RI)
890 .Case(
"config_macros", MMToken::ConfigMacros)
891 .Case(
"conflict", MMToken::Conflict)
892 .Case(
"exclude", MMToken::ExcludeKeyword)
893 .Case(
"explicit", MMToken::ExplicitKeyword)
894 .Case(
"export", MMToken::ExportKeyword)
895 .Case(
"export_as", MMToken::ExportAsKeyword)
896 .Case(
"extern", MMToken::ExternKeyword)
897 .Case(
"framework", MMToken::FrameworkKeyword)
898 .Case(
"header", MMToken::HeaderKeyword)
899 .Case(
"link", MMToken::LinkKeyword)
900 .Case(
"module", MMToken::ModuleKeyword)
901 .Case(
"private", MMToken::PrivateKeyword)
902 .Case(
"requires", MMToken::RequiresKeyword)
903 .Case(
"textual", MMToken::TextualKeyword)
904 .Case(
"umbrella", MMToken::UmbrellaKeyword)
905 .Case(
"use", MMToken::UseKeyword)
906 .Default(MMToken::Identifier);
911 Tok.Kind = MMToken::Comma;
915 Tok.Kind = MMToken::EndOfFile;
919 Tok.Kind = MMToken::LBrace;
923 Tok.Kind = MMToken::LSquare;
927 Tok.Kind = MMToken::Period;
931 Tok.Kind = MMToken::RBrace;
935 Tok.Kind = MMToken::RSquare;
939 Tok.Kind = MMToken::Star;
943 Tok.Kind = MMToken::Exclaim;
946 case tok::string_literal: {
954 Tok.Kind = MMToken::StringLiteral;
956 Tok.StringLength = LToken.
getLength() - 2;
960 case tok::numeric_constant: {
964 .getAsInteger(0,
Value)) {
965 Diags.
Report(Tok.getLocation(), diag::err_mmap_unknown_token);
970 Tok.Kind = MMToken::IntegerLiteral;
971 Tok.IntegerValue =
Value;
984 auto NextIsIdent = [&](StringRef Str) ->
bool {
989 if (NextIsIdent(
"pragma") && NextIsIdent(
"clang") &&
990 NextIsIdent(
"module") && NextIsIdent(
"contents")) {
991 Tok.Kind = MMToken::EndOfFile;
998 Diags.
Report(Tok.getLocation(), diag::err_mmap_unknown_token);
1006void ModuleMapFileParser::skipUntil(MMToken::TokenKind K) {
1007 unsigned braceDepth = 0;
1008 unsigned squareDepth = 0;
1011 case MMToken::EndOfFile:
1014 case MMToken::LBrace:
1015 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
1021 case MMToken::LSquare:
1022 if (Tok.is(K) && braceDepth == 0 && squareDepth == 0)
1028 case MMToken::RBrace:
1035 case MMToken::RSquare:
1036 if (squareDepth > 0)
1043 if (braceDepth == 0 && squareDepth == 0 && Tok.is(K))
1059bool ModuleMapFileParser::parseModuleId(
ModuleId &
Id) {
1062 if (Tok.is(MMToken::Identifier) || Tok.is(MMToken::StringLiteral)) {
1064 std::make_pair(std::string(Tok.getString()), Tok.getLocation()));
1067 Diags.
Report(Tok.getLocation(), diag::err_mmap_expected_module_name);
1071 if (!Tok.is(MMToken::Period))
1092bool ModuleMapFileParser::parseOptionalAttributes(
ModuleAttributes &Attrs) {
1095 while (Tok.is(MMToken::LSquare)) {
1100 if (!Tok.is(MMToken::Identifier)) {
1101 Diags.
Report(Tok.getLocation(), diag::err_mmap_expected_attribute);
1102 skipUntil(MMToken::RSquare);
1103 if (Tok.is(MMToken::RSquare))
1109 enum AttributeKind {
1123 AT_no_undeclared_includes
1127 AttributeKind Attribute =
1128 llvm::StringSwitch<AttributeKind>(Tok.getString())
1129 .Case(
"exhaustive", AT_exhaustive)
1130 .Case(
"extern_c", AT_extern_c)
1131 .Case(
"no_undeclared_includes", AT_no_undeclared_includes)
1132 .Case(
"system", AT_system)
1133 .Default(AT_unknown);
1134 switch (Attribute) {
1136 Diags.
Report(Tok.getLocation(), diag::warn_mmap_unknown_attribute)
1152 case AT_no_undeclared_includes:
1159 if (!Tok.is(MMToken::RSquare)) {
1160 Diags.
Report(Tok.getLocation(), diag::err_mmap_expected_rsquare);
1161 Diags.
Report(LSquareLoc, diag::note_mmap_lsquare_match);
1162 skipUntil(MMToken::RSquare);
1166 if (Tok.is(MMToken::RSquare))
1179 llvm::raw_ostream &
out,
int depth) {
1180 out.indent(depth * 2);
1181 out <<
"extern module " << formatModuleId(EMD.
Id) <<
" \"" << EMD.
Path
1186 for (
const auto &
Decl : Decls) {
1187 std::visit(llvm::makeVisitor(
1189 out.indent(depth * 2);
1190 out <<
"requires\n";
1193 out.indent(depth * 2);
1202 out <<
"header \"" << HD.
Path <<
"\"\n";
1205 out.indent(depth * 2);
1206 out <<
"umbrella\n";
1210 out.indent(depth * 2);
1214 out.indent(depth * 2);
1216 << (ED.Wildcard ?
"*" : formatModuleId(ED.Id)) <<
"\n";
1219 out.indent(depth * 2);
1220 out <<
"export as\n";
1226 out.indent(depth * 2);
1230 out.indent(depth * 2);
1234 out.indent(depth * 2);
1235 out <<
"config_macros ";
1237 out <<
"[exhaustive] ";
1238 for (
auto Macro : CMD.Macros) {
1244 out.indent(depth * 2);
1245 out <<
"conflicts\n";
1253 out.indent(depth * 2);
1254 out <<
"module " << formatModuleId(MD.
Id) <<
"\n";
Defines the Diagnostic-related interfaces.
Defines the clang::LangOptions interface.
static void dumpModule(const ModuleDecl &MD, llvm::raw_ostream &out, int depth)
static void dumpDecls(ArrayRef< Decl > Decls, llvm::raw_ostream &out, int depth)
static void dumpExternModule(const ExternModuleDecl &EMD, llvm::raw_ostream &out, int depth)
Defines the clang::Module class, which describes a module in the source code.
Defines the SourceManager interface.
Decl - This represents one declaration (or definition), e.g.
SourceLocation getLocation() const
Concrete class used by the front-end to report problems and issues.
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
A reference to a DirectoryEntry that includes the name of the directory as it was accessed by the Fil...
Represents a standard C++ module export declaration.
An opaque identifier used by SourceManager which refers to a source file (MemoryBuffer) along with it...
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
LangStandard::Kind LangStd
The used language standard.
Lexer - This provides a simple interface that turns a text buffer into a stream of tokens.
bool LexFromRawLexer(Token &Result)
LexFromRawLexer - Lex a token from a designated raw lexer (one with no associated preprocessor object...
SourceLocation getSourceLocation(const char *Loc, unsigned TokLen=1) const
getSourceLocation - Return a source location identifier for the specified offset in the current file.
Parser - This implements a parser for the C family of languages.
Encodes a location in the source.
static SourceLocation getFromRawEncoding(UIntTy Encoding)
Turn a raw encoding of a SourceLocation object into a real SourceLocation.
bool isValid() const
Return true if this is a valid SourceLocation object.
UIntTy getRawEncoding() const
When a SourceLocation itself cannot be used, this returns an (opaque) 32-bit integer encoding for it.
This class handles loading and caching of source files into memory.
A trivial tuple used to represent a source range.
StringLiteral - This represents a string literal expression, e.g.
Token - This structure provides full information about a lexed token.
SourceLocation getLocation() const
Return a source location identifier for the specified offset in the current file.
unsigned getLength() const
bool is(tok::TokenKind K) const
is/isNot - Predicates to check if this token is a specific kind, as in "if (Tok.is(tok::l_brace)) {....
tok::TokenKind getKind() const
bool isAtStartOfLine() const
isAtStartOfLine - Return true if this token is at the start of a line.
bool hasUDSuffix() const
Return true if this token is a string or character literal which has a ud-suffix.
StringRef getRawIdentifier() const
getRawIdentifier - For a raw identifier token (i.e., an identifier lexed in raw mode),...
const char * getLiteralData() const
getLiteralData - For a literal token (numeric constant, string, etc), this returns a pointer to the s...
std::optional< ModuleMapFile > parseModuleMap(FileID ID, clang::DirectoryEntryRef Dir, SourceManager &SM, DiagnosticsEngine &Diags, bool IsSystem, unsigned *Offset)
Parse a module map file into an in memory representation.
std::variant< struct RequiresDecl, struct HeaderDecl, struct UmbrellaDirDecl, struct ModuleDecl, struct ExcludeDecl, struct ExportDecl, struct ExportAsDecl, struct ExternModuleDecl, struct UseDecl, struct LinkDecl, struct ConfigMacrosDecl, struct ConflictDecl > Decl
All declarations that can appear in a module declaration.
The JSON file list parser is used to communicate input to InstallAPI.
if(T->getSizeExpr()) TRY_TO(TraverseStmt(const_cast< Expr * >(T -> getSizeExpr())))
The set of attributes that can be attached to a module.
unsigned IsExternC
Whether this is an extern "C" module.
unsigned IsSystem
Whether this is a system module.
unsigned IsExhaustive
Whether this is an exhaustive set of configuration macros.
unsigned NoUndeclaredIncludes
Whether files in this module can only include non-modular headers and headers from used modules.
std::vector< StringRef > Macros
ModuleAttributes Attrs
Points to the first keyword in the decl.
std::vector< Decl > Decls
Represents the parsed form of a module map file.
std::vector< TopLevelDecl > Decls
void dump(llvm::raw_ostream &out) const
std::vector< RequiresFeature > Features