-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[clang][modules] Separate parsing of modulemaps #119740
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,162 @@ | ||
//===- ModuleMapFile.h - Parsing and representation -------------*- C++ -*-===// | ||
// | ||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
// See https://llvm.org/LICENSE.txt for license information. | ||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
// | ||
//===----------------------------------------------------------------------===// | ||
|
||
#ifndef LLVM_CLANG_LEX_MODULEMAPFILE_H | ||
#define LLVM_CLANG_LEX_MODULEMAPFILE_H | ||
|
||
#include "clang/Basic/LLVM.h" | ||
// TODO: Consider moving ModuleId to another header, parsing a modulemap file is | ||
// intended to not depend on anything about the clang::Module class. | ||
#include "clang/Basic/Module.h" | ||
#include "clang/Basic/SourceLocation.h" | ||
#include "llvm/ADT/StringRef.h" | ||
|
||
#include <optional> | ||
#include <variant> | ||
|
||
namespace clang { | ||
|
||
class DiagnosticsEngine; | ||
class SourceManager; | ||
|
||
namespace modulemap { | ||
|
||
struct ExportDecl; | ||
|
||
/// All declarations that can appear in a `module` declaration. | ||
using Decl = | ||
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>; | ||
Comment on lines
+33
to
+36
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sizes of these types have large variance ( There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. (Also fine as a follow-up.) |
||
|
||
struct RequiresFeature { | ||
StringRef Feature; | ||
SourceLocation Location; | ||
bool RequiredState = true; /// False if preceded by '!'. | ||
}; | ||
|
||
struct RequiresDecl { | ||
SourceLocation Location; | ||
std::vector<RequiresFeature> Features; | ||
}; | ||
|
||
struct HeaderDecl { | ||
StringRef Path; | ||
SourceLocation Location; | ||
SourceLocation PathLoc; | ||
std::optional<int64_t> Size; | ||
std::optional<int64_t> MTime; | ||
LLVM_PREFERRED_TYPE(bool) | ||
unsigned Private : 1; | ||
LLVM_PREFERRED_TYPE(bool) | ||
unsigned Textual : 1; | ||
LLVM_PREFERRED_TYPE(bool) | ||
unsigned Umbrella : 1; | ||
LLVM_PREFERRED_TYPE(bool) | ||
unsigned Excluded : 1; | ||
}; | ||
|
||
struct UmbrellaDirDecl { | ||
StringRef Path; | ||
SourceLocation Location; | ||
}; | ||
|
||
struct ModuleDecl { | ||
ModuleId Id; | ||
SourceLocation Location; /// Points to the first keyword in the decl. | ||
ModuleAttributes Attrs; | ||
std::vector<Decl> Decls; | ||
|
||
LLVM_PREFERRED_TYPE(bool) | ||
unsigned Explicit : 1; | ||
LLVM_PREFERRED_TYPE(bool) | ||
unsigned Framework : 1; | ||
}; | ||
|
||
struct ExcludeDecl { | ||
SourceLocation Location; | ||
StringRef Module; | ||
}; | ||
|
||
struct ExportDecl { | ||
ModuleId Id; | ||
SourceLocation Location; | ||
bool Wildcard; /// True if the last element of the ModuleId is '*'. | ||
}; | ||
|
||
struct ExportAsDecl { | ||
SourceLocation Location; | ||
ModuleId Id; | ||
}; | ||
|
||
struct ExternModuleDecl { | ||
SourceLocation Location; | ||
ModuleId Id; | ||
StringRef Path; | ||
}; | ||
|
||
struct UseDecl { | ||
SourceLocation Location; | ||
ModuleId Id; | ||
}; | ||
|
||
struct LinkDecl { | ||
StringRef Library; | ||
SourceLocation Location; | ||
LLVM_PREFERRED_TYPE(bool) | ||
unsigned Framework : 1; | ||
}; | ||
|
||
struct ConfigMacrosDecl { | ||
std::vector<StringRef> Macros; | ||
SourceLocation Location; | ||
LLVM_PREFERRED_TYPE(bool) | ||
unsigned Exhaustive : 1; | ||
}; | ||
|
||
struct ConflictDecl { | ||
SourceLocation Location; | ||
ModuleId Id; | ||
StringRef Message; | ||
}; | ||
|
||
using TopLevelDecl = std::variant<ModuleDecl, ExternModuleDecl>; | ||
|
||
/// Represents the parsed form of a module map file. | ||
/// | ||
/// This holds many reference types (StringRef, SourceLocation, etc.) whose | ||
/// lifetimes are bound by the SourceManager and FileManager used. | ||
struct ModuleMapFile { | ||
/// Beginning of the file, used for moduleMapFileRead callback. | ||
SourceLocation Start; | ||
std::vector<TopLevelDecl> Decls; | ||
|
||
void dump(llvm::raw_ostream &out) const; | ||
}; | ||
|
||
/// Parse a module map file into an in memory representation. | ||
/// | ||
/// \param ID a valid local FileID. | ||
/// \param Dir the directory in which this module map was found. | ||
/// \param SM the SourceManager for \a ID. | ||
/// \param Diags where to send the diagnostics. | ||
/// \param IsSystem was this module map found in a system search path. | ||
/// \param Offset optional offset into the buffer associated with \a ID. This is | ||
/// used for handling `#pragma clang module build`. Set to the end | ||
/// of the module map on return. | ||
/// | ||
/// \returns The parsed ModuleMapFile if successful, std::nullopt otherwise. | ||
std::optional<ModuleMapFile> | ||
parseModuleMap(FileID ID, clang::DirectoryEntryRef Dir, SourceManager &SM, | ||
DiagnosticsEngine &Diags, bool IsSystem, unsigned *Offset); | ||
|
||
} // namespace modulemap | ||
} // namespace clang | ||
|
||
#endif |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The name is very close to
clang::Decl
though don't know if it causes any problems in practice. I'm mostly concerned if an engineer starts looking into this code and they seeDecl
it can confuse them. Don't know if the nameAnyDecl
is better. Don't. have a strong opinion on this as I don't have any evidence.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The idea was that having it in a namespace would clarify as it would only be used unqualified in the modulemap code.