21#include "llvm/ADT/StringExtras.h"
28 bool FromInclude =
false) {
31 if (
auto *LSD = dyn_cast<LinkageSpecDecl>(DC)) {
32 switch (LSD->getLanguage()) {
33 case LinkageSpecLanguageIDs::C:
35 ExternCLoc = LSD->getBeginLoc();
37 case LinkageSpecLanguageIDs::CXX:
43 while (isa<LinkageSpecDecl>(DC) || isa<ExportDecl>(DC))
46 if (!isa<TranslationUnitDecl>(DC)) {
48 ? diag::ext_module_import_not_at_top_level_noop
49 : diag::err_module_import_not_at_top_level_fatal)
51 S.
Diag(cast<Decl>(DC)->getBeginLoc(),
52 diag::note_module_import_not_at_top_level)
55 S.
Diag(ImportLoc, diag::ext_module_import_in_extern_c)
57 S.
Diag(ExternCLoc, diag::note_extern_c_begins_here);
70 for (
auto &Piece :
Path) {
73 Name += Piece.getIdentifierInfo()->getName();
88 Module *&FoundPrimaryModuleInterface) {
99 if (FoundPrimaryModuleInterface)
100 return Imported == FoundPrimaryModuleInterface;
115 assert(!FoundPrimaryModuleInterface ||
116 FoundPrimaryModuleInterface == Imported);
117 FoundPrimaryModuleInterface = Imported;
134 bool IsImportingPrimaryModuleInterface =
false) {
136 "'makeTransitiveImportsVisible()' is intended for standard C++ named "
141 Worklist.push_back(Imported);
143 Module *FoundPrimaryModuleInterface =
144 IsImportingPrimaryModuleInterface ? Imported :
nullptr;
146 while (!Worklist.empty()) {
147 Module *Importing = Worklist.pop_back_val();
155 VisibleModules.
setVisible(Importing, ImportLoc);
158 FoundPrimaryModuleInterface)) {
160 Worklist.push_back(TransImported);
162 for (
auto [Exports, _] : Importing->
Exports)
163 Worklist.push_back(Exports);
172 PushGlobalModuleFragment(ModuleLoc);
184 TU->setLocalOwningModule(GlobalModule);
190void Sema::HandleStartOfHeaderUnit() {
192 "Header units are only valid for C++20 modules");
197 if (HUName.empty()) {
212 assert(F &&
"failed to find the header unit source?");
215 Module *Mod = Map.createHeaderUnit(StartOfTU, HUName, H);
216 assert(Mod &&
"module creation should not fail");
217 ModuleScopes.push_back({});
218 ModuleScopes.back().BeginLoc = StartOfTU;
219 ModuleScopes.back().Module = Mod;
226 TU->setLocalOwningModule(Mod);
240 if (II->
isStr(
"module") || II->
isStr(
"import"))
256 return S.
Diag(
Loc, diag::err_invalid_module_name) << II;
258 S.
Diag(
Loc, diag::warn_reserved_module_name) << II;
261 llvm_unreachable(
"fell off a fully covered switch");
268 bool SeenNoTrivialPPDirective) {
270 "should only have module decl in standard C++ modules");
278 bool IsPartition = !Partition.empty();
288 llvm_unreachable(
"how did we get a partition type set?");
307 Diag(ModuleLoc, diag::err_module_interface_implementation_mismatch)
313 Diag(ModuleLoc, diag::err_module_decl_in_module_map_module);
317 Diag(ModuleLoc, diag::err_module_decl_in_header_unit);
321 assert(ModuleScopes.size() <= 1 &&
"expected to be at global module scope");
327 if (isCurrentModulePurview()) {
328 Diag(ModuleLoc, diag::err_module_redeclaration);
330 diag::note_prev_module_declaration);
335 SeenGMF == (
bool)this->TheGlobalModuleFragment) &&
336 "mismatched global module state");
341 (!IsFirstDecl || SeenNoTrivialPPDirective) && !SeenGMF) {
342 Diag(ModuleLoc, diag::err_module_decl_not_at_start);
344 Diag(BeginLoc, diag::note_global_module_introducer_missing)
357 StringRef FirstComponentName =
Path[0].getIdentifierInfo()->getName();
359 (FirstComponentName ==
"std" ||
360 (FirstComponentName.starts_with(
"std") &&
361 llvm::all_of(FirstComponentName.drop_front(3), &llvm::isDigit))))
362 Diag(
Path[0].getLoc(), diag::warn_reserved_module_name)
363 <<
Path[0].getIdentifierInfo();
367 for (
auto Part :
Path) {
384 Diag(
Path.front().getLoc(), diag::err_current_module_name_mismatch)
386 ? Partition.back().getLoc()
387 :
Path.back().getLoc())
401 if (
auto *M = Map.findOrLoadModule(ModuleName)) {
402 Diag(
Path[0].getLoc(), diag::err_module_redefinition) << ModuleName;
403 if (M->DefinitionLoc.isValid())
404 Diag(M->DefinitionLoc, diag::note_prev_module_definition);
406 Diag(M->DefinitionLoc, diag::note_prev_module_definition_from_ast_file)
413 Mod = Map.createModuleForInterfaceUnit(ModuleLoc, ModuleName);
416 assert(Mod &&
"module creation should not fail");
439 Diag(ModuleLoc, diag::err_module_not_defined) << ModuleName;
441 Mod = Map.createModuleForInterfaceUnit(ModuleLoc, ModuleName);
443 Mod = Map.createModuleForImplementationUnit(ModuleLoc, ModuleName);
450 Mod = Map.createModuleForInterfaceUnit(ModuleLoc, ModuleName);
455 if (!this->TheGlobalModuleFragment) {
456 ModuleScopes.push_back({});
458 ModuleScopes.back().OuterVisibleModules = std::move(VisibleModules);
465 ModuleScopes.back().BeginLoc = StartLoc;
466 ModuleScopes.back().Module = Mod;
476 TU->setLocalOwningModule(Mod);
485 Listener->EnteringModulePurview();
491 HadImportedNamedModules =
true;
523 : ModuleScopes.back().Module->Kind) {
530 Diag(PrivateLoc, diag::err_private_module_fragment_not_module);
534 Diag(PrivateLoc, diag::err_private_module_fragment_redefined);
535 Diag(ModuleScopes.back().BeginLoc, diag::note_previous_definition);
539 Diag(PrivateLoc, diag::err_private_module_fragment_not_module_interface);
540 Diag(ModuleScopes.back().BeginLoc,
541 diag::note_not_module_interface_add_export)
557 Module *PrivateModuleFragment =
558 Map.createPrivateModuleFragmentForInterfaceUnit(
559 ModuleScopes.back().Module, PrivateLoc);
560 assert(PrivateModuleFragment &&
"module creation should not fail");
563 ModuleScopes.push_back({});
564 ModuleScopes.back().BeginLoc = ModuleLoc;
565 ModuleScopes.back().Module = PrivateModuleFragment;
566 VisibleModules.
setVisible(PrivateModuleFragment, ModuleLoc);
573 TU->setLocalOwningModule(PrivateModuleFragment);
583 assert((!IsPartition ||
getLangOpts().CPlusPlusModules) &&
584 "partition seen in non-C++20 code?");
590 std::string ModuleName;
593 assert(!ModuleScopes.empty() &&
"in a module purview, but no module?");
594 Module *NamedMod = ModuleScopes.back().Module;
617 if (
getLangOpts().CPlusPlusModules && isCurrentModulePurview() &&
619 Diag(ImportLoc, diag::err_module_self_import_cxx20)
631 Diag(ImportLoc, diag::err_module_import_non_interface_nor_parition)
642 if (
auto *ED = dyn_cast<ExportDecl>(DC))
652 Diag(ImportLoc, diag::warn_experimental_header_unit);
661 "We can only import a partition unit in a named module.");
665 diag::warn_import_implementation_partition_unit_in_interface_unit)
676 ? diag::err_module_self_import
677 : diag::err_module_import_in_implementation)
687 for (
Module *ModCheck = Mod; ModCheck; ModCheck = ModCheck->
Parent)
691 IdentifierLocs.push_back(
Path[0].getLoc());
694 for (
unsigned I = 0, N =
Path.size(); I != N; ++I) {
699 ModCheck = ModCheck->
Parent;
701 IdentifierLocs.push_back(
Path[I].getLoc());
706 Mod, IdentifierLocs);
711 if (!ModuleScopes.empty())
717 Diag(ExportLoc, diag::err_export_partition_impl)
719 }
else if (ExportLoc.
isValid() &&
724 Diag(ExportLoc, diag::err_export_not_in_module_interface);
725 }
else if (!ModuleScopes.empty()) {
735 HadImportedNamedModules =
true;
751 bool IsInModuleIncludes =
757 if (
getLangOpts().Modules && !IsInModuleIncludes) {
762 if (!ModuleScopes.empty())
773 getLangOpts().CurrentModule, DirectiveLoc,
false,
false);
775 assert(ThisModule &&
"was expecting a module if building one");
782 ModuleScopes.push_back({});
783 ModuleScopes.back().Module = Mod;
785 ModuleScopes.back().OuterVisibleModules = std::move(VisibleModules);
794 cast<Decl>(DC)->setModuleOwnershipKind(
798 cast<Decl>(DC)->setLocalOwningModule(Mod);
805 VisibleModules = std::move(ModuleScopes.back().OuterVisibleModules);
811 assert(!ModuleScopes.empty() && ModuleScopes.back().Module == Mod &&
812 "left the wrong module scope");
813 ModuleScopes.pop_back();
822 "end of submodule in main source file");
826 DirectiveLoc = EomLoc;
837 cast<Decl>(DC)->setModuleOwnershipKind(
867 D->setRBraceLoc(LBraceLoc);
877 if (!isCurrentModulePurview()) {
878 Diag(ExportLoc, diag::err_export_not_in_module_interface) << 0;
882 Diag(ExportLoc, diag::err_export_not_in_module_interface) << 1;
883 Diag(ModuleScopes.back().BeginLoc,
884 diag::note_not_module_interface_add_export)
888 }
else if (ModuleScopes.back().Module->Kind ==
890 Diag(ExportLoc, diag::err_export_in_private_module_fragment);
891 Diag(ModuleScopes.back().BeginLoc, diag::note_private_module_fragment);
898 if (
const auto *ND = dyn_cast<NamespaceDecl>(DC)) {
901 if (ND->isAnonymousNamespace()) {
902 Diag(ExportLoc, diag::err_export_within_anonymous_namespace);
903 Diag(ND->getLocation(), diag::note_anonymous_namespace);
914 if (!
getLangOpts().
HLSL && !DeferredExportedNamespaces.insert(ND).second)
922 Diag(ExportLoc, diag::err_export_within_export);
924 Diag(ED->getLocation(), diag::note_export);
940 bool AllUnnamed =
true;
941 for (
auto *
D : DC->
decls())
952 if (!isa<FunctionDecl, ExportDecl>(
D)) {
961 bool HasName =
false;
962 if (
auto *ND = dyn_cast<NamedDecl>(
D)) {
965 HasName = (
bool)ND->getDeclName();
967 S.
Diag(ND->getLocation(), diag::err_export_internal) << ND;
969 S.
Diag(BlockStart, diag::note_export);
977 if (
auto *USD = dyn_cast<UsingShadowDecl>(
D)) {
981 S.
Diag(USD->getLocation(), diag::err_export_using_internal)
983 S.
Diag(
Target->getLocation(), diag::note_using_decl_target);
985 S.
Diag(BlockStart, diag::note_export);
992 if (
auto *DC = dyn_cast<DeclContext>(
D)) {
993 if (!isa<NamespaceDecl>(
D))
996 if (
auto *ND = dyn_cast<NamedDecl>(
D)) {
997 if (!ND->getDeclName()) {
998 S.
Diag(ND->getLocation(), diag::err_export_anon_ns_internal);
1000 S.
Diag(BlockStart, diag::note_export);
1002 }
else if (!DC->decls().empty() &&
1003 DC->getRedeclContext()->isFileContext()) {
1012 auto *ED = cast<ExportDecl>(
D);
1014 ED->setRBraceLoc(RBraceLoc);
1021 for (
auto *Child : ED->decls()) {
1023 if (
auto *FD = dyn_cast<FunctionDecl>(Child)) {
1031 if (FD->isInlineSpecified() && !FD->isDefined())
1032 PendingInlineFuncDecls.insert(FD);
1038 for (
auto *Exported : ED->decls())
1047 if (!TheGlobalModuleFragment) {
1053 assert(TheGlobalModuleFragment &&
"module creation should not fail");
1056 ModuleScopes.push_back({BeginLoc, TheGlobalModuleFragment,
1058 VisibleModules.
setVisible(TheGlobalModuleFragment, BeginLoc);
1060 return TheGlobalModuleFragment;
1063void Sema::PopGlobalModuleFragment() {
1064 assert(!ModuleScopes.empty() &&
1066 "left the wrong module scope, which is not global module fragment");
1067 ModuleScopes.pop_back();
1071 if (!TheImplicitGlobalModuleFragment) {
1073 TheImplicitGlobalModuleFragment =
1077 assert(TheImplicitGlobalModuleFragment &&
"module creation should not fail");
1080 ModuleScopes.push_back({BeginLoc, TheImplicitGlobalModuleFragment,
1082 VisibleModules.
setVisible(TheImplicitGlobalModuleFragment, BeginLoc);
1083 return TheImplicitGlobalModuleFragment;
1086void Sema::PopImplicitGlobalModuleFragment() {
1087 assert(!ModuleScopes.empty() &&
1089 "left the wrong module scope, which is not global module fragment");
1090 ModuleScopes.pop_back();
1093bool Sema::isCurrentModulePurview()
const {
1117class ExposureChecker {
1119 ExposureChecker(
Sema &S) : SemaRef(S) {}
1123 bool checkExposure(
const Stmt *S,
bool Diag);
1126 void checkExposureInContext(
const DeclContext *DC);
1127 bool isExposureCandidate(
const NamedDecl *
D);
1131 bool isTULocal(
const Expr *
E);
1136 llvm::DenseSet<const NamedDecl *> ExposureSet;
1137 llvm::DenseSet<const NamedDecl *> KnownNonExposureSet;
1140bool ExposureChecker::isTULocal(
QualType Ty) {
1155bool ExposureChecker::isTULocal(
const NamedDecl *
D) {
1175 ND && isTULocal(ND))
1183 if (
auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(
D)) {
1184 TemplateArgs = CTSD->getTemplateArgs().asArray();
1185 PrimaryTemplate = CTSD->getSpecializedTemplate();
1186 if (isTULocal(PrimaryTemplate))
1188 }
else if (
auto *VTSD = dyn_cast<VarTemplateSpecializationDecl>(
D)) {
1189 TemplateArgs = VTSD->getTemplateArgs().asArray();
1190 PrimaryTemplate = VTSD->getSpecializedTemplate();
1191 if (isTULocal(PrimaryTemplate))
1193 }
else if (
auto *FD = dyn_cast<FunctionDecl>(
D)) {
1194 if (
auto *TAList = FD->getTemplateSpecializationArgs())
1195 TemplateArgs = TAList->asArray();
1197 PrimaryTemplate = FD->getPrimaryTemplate();
1198 if (isTULocal(PrimaryTemplate))
1202 if (!PrimaryTemplate)
1206 if (KnownNonExposureSet.count(
D))
1209 for (
auto &TA : TemplateArgs) {
1210 switch (TA.getKind()) {
1212 if (isTULocal(TA.getAsType()))
1216 if (isTULocal(TA.getAsDecl()))
1227 if (ExposureSet.count(PrimaryTemplate) ||
1228 checkExposure(PrimaryTemplate,
false))
1232 KnownNonExposureSet.insert(
D);
1236bool ExposureChecker::isTULocal(
const Expr *
E) {
1254 if (
const auto *DRE = dyn_cast<DeclRefExpr>(
E)) {
1255 if (
auto *FD = dyn_cast_or_null<FunctionDecl>(DRE->getFoundDecl()))
1256 return isTULocal(FD);
1257 else if (
auto *VD = dyn_cast_or_null<VarDecl>(DRE->getFoundDecl()))
1258 return isTULocal(VD);
1259 else if (
auto *RD = dyn_cast_or_null<CXXRecordDecl>(DRE->getFoundDecl()))
1260 return isTULocal(RD);
1270bool ExposureChecker::isExposureCandidate(
const NamedDecl *
D) {
1298bool ExposureChecker::checkExposure(
const NamedDecl *
D,
bool Diag) {
1299 if (!isExposureCandidate(
D))
1302 if (
auto *FD = dyn_cast<FunctionDecl>(
D))
1303 return checkExposure(FD,
Diag);
1304 if (
auto *FTD = dyn_cast<FunctionTemplateDecl>(
D))
1305 return checkExposure(FTD->getTemplatedDecl(),
Diag);
1307 if (
auto *VD = dyn_cast<VarDecl>(
D))
1308 return checkExposure(VD,
Diag);
1309 if (
auto *VTD = dyn_cast<VarTemplateDecl>(
D))
1310 return checkExposure(VTD->getTemplatedDecl(),
Diag);
1312 if (
auto *RD = dyn_cast<CXXRecordDecl>(
D))
1313 return checkExposure(RD,
Diag);
1315 if (
auto *CTD = dyn_cast<ClassTemplateDecl>(
D))
1316 return checkExposure(CTD->getTemplatedDecl(),
Diag);
1322 bool IsExposure =
false;
1327 diag::warn_exposure)
1332 if (isTULocal(Parms->getType())) {
1335 SemaRef.Diag(Parms->getLocation(), diag::warn_exposure)
1336 << Parms->getType();
1339 bool IsImplicitInstantiation =
1355 ExposureSet.insert(FD);
1360bool ExposureChecker::checkExposure(
const VarDecl *VD,
bool Diag) {
1361 bool IsExposure =
false;
1375 if (isTULocal(VD->
getType())) {
1392 ExposureSet.insert(VD);
1401 bool IsExposure =
false;
1406 if (isTULocal(FD->
getType())) {
1414 if (isTULocal(
Base.getType())) {
1417 SemaRef.Diag(
Base.getBaseTypeLoc(), diag::warn_exposure)
1423 ExposureSet.insert(RD);
1432 ReferenceTULocalChecker(ExposureChecker &
C, CallbackTy &&Callback)
1433 : Checker(
C), Callback(
std::move(Callback)) {}
1435 bool VisitDeclRefExpr(
DeclRefExpr *DRE)
override {
1440 if (!Checker.isTULocal(Referenced))
1460 if (DRE->
isNonOdrUse() && (L == Linkage::Internal || L == Linkage::None))
1461 if (
auto *VD = dyn_cast<VarDecl>(Referenced);
1466 Callback(DRE, Referenced);
1470 ExposureChecker &Checker;
1471 CallbackTy Callback;
1474bool ExposureChecker::checkExposure(
const Stmt *S,
bool Diag) {
1478 bool HasReferencedTULocals =
false;
1479 ReferenceTULocalChecker Checker(
1483 SemaRef.Diag(DRE->
getExprLoc(), diag::warn_exposure) << Referenced;
1485 HasReferencedTULocals =
true;
1487 Checker.TraverseStmt(
const_cast<Stmt *
>(S));
1488 return HasReferencedTULocals;
1491void ExposureChecker::checkExposureInContext(
const DeclContext *DC) {
1493 auto *TopND = dyn_cast<NamedDecl>(TopD);
1497 if (
auto *Namespace = dyn_cast<NamespaceDecl>(TopND)) {
1498 checkExposureInContext(Namespace);
1507 if (!TopND->isFromASTFile() && isExposureCandidate(TopND) &&
1509 checkExposure(TopND,
true);
1519 ExposureChecker Checker(*
this);
1523 Checker.checkExposureInContext(TU);
1529 for (
auto FDAndInstantiationLocPair : PendingCheckReferenceForTULocal) {
1531 SourceLocation PointOfInstantiation = FDAndInstantiationLocPair.second;
1536 ReferenceTULocalChecker(Checker, [&,
this](
DeclRefExpr *DRE,
1555 isa<FunctionDecl>(Referenced))
1558 Diag(PointOfInstantiation,
1559 diag::warn_reference_tu_local_entity_in_other_tu)
1562 }).TraverseStmt(FD->
getBody());
1566void Sema::checkReferenceToTULocalFromOtherTU(
1570 if (!FD || !HadImportedNamedModules)
1573 PendingCheckReferenceForTULocal.push_back(
1574 std::make_pair(FD, PointOfInstantiation));
llvm::DenseSet< const void * > Visited
static DiagnosticBuilder Diag(DiagnosticsEngine *Diags, const LangOptions &Features, FullSourceLoc TokLoc, const char *TokBegin, const char *TokRangeBegin, const char *TokRangeEnd, unsigned DiagID)
Produce a diagnostic highlighting some portion of a literal.
llvm::MachO::Target Target
Defines the clang::Preprocessor interface.
static void makeTransitiveImportsVisible(ASTContext &Ctx, VisibleModuleSet &VisibleModules, Module *Imported, Module *CurrentModule, SourceLocation ImportLoc, bool IsImportingPrimaryModuleInterface=false)
[module.import]p7: Additionally, when a module-import-declaration in a module unit of some module M i...
static bool DiagReservedModuleName(Sema &S, const IdentifierInfo *II, SourceLocation Loc)
Tests whether the given identifier is reserved as a module name and diagnoses if it is.
static const ExportDecl * getEnclosingExportDecl(const Decl *D)
Determine whether D is lexically within an export-declaration.
static bool checkExportedDecl(Sema &, Decl *, SourceLocation)
Check that it's valid to export D.
static std::string stringFromPath(ModuleIdPath Path)
static void checkModuleImportContext(Sema &S, Module *M, SourceLocation ImportLoc, DeclContext *DC, bool FromInclude=false)
static bool checkExportedDeclContext(Sema &S, DeclContext *DC, SourceLocation BlockStart)
Check that it's valid to export all the declarations in DC.
static bool isImportingModuleUnitFromSameModule(ASTContext &Ctx, Module *Imported, Module *CurrentModule, Module *&FoundPrimaryModuleInterface)
Helper function for makeTransitiveImportsVisible to decide whether the.
virtual void HandleImplicitImportDecl(ImportDecl *D)
Handle an ImportDecl that was implicitly created due to an inclusion directive.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
TranslationUnitDecl * getTranslationUnitDecl() const
void setCurrentNamedModule(Module *M)
Set the (C++20) module we are building.
void addModuleInitializer(Module *M, Decl *Init)
Add a declaration to the list of declarations that are initialized for a module.
bool isInSameModule(const Module *M1, const Module *M2) const
If the two module M1 and M2 are in the same module.
The result of parsing/analyzing an expression, statement etc.
Represents a base class of a C++ class.
Represents a static or instance method of a struct/union/class.
Represents a C++ struct/union/class.
method_range methods() const
bool hasDefinition() const
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
DeclContext * getParent()
getParent - Returns the containing DeclContext.
bool isDependentContext() const
Determines whether this context is dependent on a template parameter.
DeclContext * getLexicalParent()
getLexicalParent - Returns the containing lexical DeclContext.
void addDecl(Decl *D)
Add the declaration D into this context.
decl_range noload_decls() const
noload_decls_begin/end - Iterate over the declarations stored in this context that are currently load...
decl_range decls() const
decls_begin/decls_end - Iterate over the declarations stored in this context.
A reference to a declared variable, function, enum, etc.
NonOdrUseReason isNonOdrUse() const
Is this expression a non-odr-use reference, and if so, why?
Decl - This represents one declaration (or definition), e.g.
FriendObjectKind getFriendObjectKind() const
Determines whether this declaration is the object of a friend declaration and, if so,...
ASTContext & getASTContext() const LLVM_READONLY
bool isImplicit() const
isImplicit - Indicates whether the declaration was implicitly generated by the implementation.
void setInvalidDecl(bool Invalid=true)
setInvalidDecl - Indicates the Decl had a semantic error.
bool isInAnotherModuleUnit() const
Whether this declaration comes from another module unit.
Module * getOwningModule() const
Get the module that owns this declaration (for visibility purposes).
bool isFromASTFile() const
Determine whether this declaration came from an AST file (such as a precompiled header or module) rat...
bool isInvalidDecl() const
SourceLocation getLocation() const
DeclContext * getDeclContext()
bool isInAnonymousNamespace() const
SourceLocation getBeginLoc() const LLVM_READONLY
DeclContext * getLexicalDeclContext()
getLexicalDeclContext - The declaration context where this Decl was lexically declared (LexicalDC).
@ VisibleWhenImported
This declaration has an owning module, and is visible when that module is imported.
@ Unowned
This declaration is not owned by a module.
@ ReachableWhenImported
This declaration has an owning module, and is visible to lookups that occurs within that module.
@ ModulePrivate
This declaration has an owning module, but is only visible to lookups that occur within that module.
@ Visible
This declaration has an owning module, but is globally visible (typically because its owning module i...
void setModuleOwnershipKind(ModuleOwnershipKind MOK)
Set whether this declaration is hidden from name lookup.
Recursive AST visitor that supports extension via dynamic dispatch.
Represents a standard C++ module export declaration.
static ExportDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation ExportLoc)
This represents one expression.
bool isValueDependent() const
Determines whether the value of this expression depends on.
Expr * IgnoreParenImpCasts() LLVM_READONLY
Skip past any parentheses and implicit casts which might surround this expression until reaching a fi...
bool isConstantInitializer(ASTContext &Ctx, bool ForRef, const Expr **Culprit=nullptr) const
isConstantInitializer - Returns true if this expression can be emitted to IR as a constant,...
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
Represents a member of a struct/union/class.
StringRef getName() const
The name of this FileEntry.
An opaque identifier used by SourceManager which refers to a source file (MemoryBuffer) along with it...
OptionalFileEntryRef getOptionalFileRef(StringRef Filename, bool OpenFile=false, bool CacheFailure=true)
Get a FileEntryRef if it exists, without doing anything on error.
static FixItHint CreateInsertion(SourceLocation InsertionLoc, StringRef Code, bool BeforePreviousInsertions=false)
Create a code modification hint that inserts the given code string at a specific location.
Represents a function declaration or definition.
Stmt * getBody(const FunctionDecl *&Definition) const
Retrieve the body (definition) of the function.
SourceRange getReturnTypeSourceRange() const
Attempt to compute an informative source range covering the function return type.
bool isInlined() const
Determine whether this function should be inlined, because it is either marked "inline" or "constexpr...
QualType getReturnType() const
ArrayRef< ParmVarDecl * > parameters() const
TemplateSpecializationKind getTemplateSpecializationKind() const
Determine what kind of template instantiation this function represents.
bool hasBody(const FunctionDecl *&Definition) const
Returns true if the function has a body.
One of these records is kept for each identifier that is lexed.
ReservedIdentifierStatus isReserved(const LangOptions &LangOpts) const
Determine whether this is a name reserved for the implementation (C99 7.1.3, C++ [lib....
bool isStr(const char(&Str)[StrLen]) const
Return true if this is the identifier for the specified string.
A simple pair of identifier info and location.
Describes a module import declaration, which makes the contents of the named module visible in the cu...
static ImportDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, Module *Imported, ArrayRef< SourceLocation > IdentifierLocs)
Create a new module import declaration.
static ImportDecl * CreateImplicit(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, Module *Imported, SourceLocation EndLoc)
Create a new module import declaration for an implicitly-generated import.
@ CMK_None
Not compiling a module interface at all.
@ CMK_HeaderUnit
Compiling a module header unit.
@ CMK_ModuleMap
Compiling a module from a module map.
@ CMK_ModuleInterface
Compiling a C++ modules interface unit.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
std::string CurrentModule
The name of the current module, of which the main source file is a part.
virtual ModuleLoadResult loadModule(SourceLocation ImportLoc, ModuleIdPath Path, Module::NameVisibilityKind Visibility, bool IsInclusionDirective)=0
Attempt to load the given module.
virtual void makeModuleVisible(Module *Mod, Module::NameVisibilityKind Visibility, SourceLocation ImportLoc)=0
Make the given module visible.
Module * createGlobalModuleFragmentForModuleUnit(SourceLocation Loc, Module *Parent=nullptr)
Create a global module fragment for a C++ module unit.
Module * createImplicitGlobalModuleFragmentForModuleUnit(SourceLocation Loc, Module *Parent)
Describes a module or submodule.
StringRef getTopLevelModuleName() const
Retrieve the name of the top-level module.
SmallVector< ExportDecl, 2 > Exports
The set of export declarations.
bool isForBuilding(const LangOptions &LangOpts) const
Determine whether this module can be built in this compilation.
bool isInterfaceOrPartition() const
bool isModulePartitionImplementation() const
Is this a module partition implementation unit.
@ AllVisible
All of the names in this module are visible.
Module * Parent
The parent of this module.
ModuleKind Kind
The kind of this module.
llvm::SmallSetVector< Module *, 2 > Imports
The set of modules imported by this module, and on which this module depends.
std::string Name
The name of this module.
unsigned IsExternC
Whether this is an 'extern "C"' module (which implicitly puts all headers in it within an 'extern "C"...
StringRef getPrimaryModuleInterfaceName() const
Get the primary module interface name from a partition.
bool isModulePartition() const
Is this a module partition.
bool isExplicitGlobalModule() const
bool isHeaderUnit() const
Is this module a header unit.
@ ModuleImplementationUnit
This is a C++20 module implementation unit.
@ ModuleMapModule
This is a module that was defined by a module map and built out of header files.
@ ImplicitGlobalModuleFragment
This is an implicit fragment of the global module which contains only language linkage declarations (...
@ ModulePartitionInterface
This is a C++20 module partition interface.
@ ModuleInterfaceUnit
This is a C++20 module interface unit.
@ ModuleHeaderUnit
This is a C++20 header unit.
@ ModulePartitionImplementation
This is a C++20 module partition implementation.
@ PrivateModuleFragment
This is the private module fragment within some C++ module.
@ ExplicitGlobalModuleFragment
This is the explicit Global Module Fragment of a modular TU.
std::string getFullModuleName(bool AllowStringLiterals=false) const
Retrieve the full name of this module, including the path from its top-level module.
bool isNamedModule() const
Does this Module is a named module of a standard named module?
This represents a decl that may have a name.
NamedDecl * getUnderlyingDecl()
Looks through UsingDecls and ObjCCompatibleAliasDecls for the underlying named decl.
Linkage getLinkageInternal() const
Determine what kind of linkage this entity has.
Linkage getFormalLinkage() const
Get the linkage from a semantic point of view.
Wrapper for void* pointer.
Represents a parameter to a function.
IdentifierInfo * getIdentifierInfo(StringRef Name) const
Return information about the specified preprocessor identifier token.
HeaderSearch & getHeaderSearchInfo() const
SourceLocation getMainFileFirstPPTokenLoc() const
Get the start location of the first pp-token in main file.
A (possibly-)qualified type.
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
The collection of all-type qualifiers we support.
field_range fields() const
Scope - A scope is a transient data structure that is used while parsing the program.
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID, bool DeferHint=false)
Emit a diagnostic.
Sema - This implements semantic analysis and AST building for C.
void ActOnAnnotModuleBegin(SourceLocation DirectiveLoc, Module *Mod)
The parsed has entered a submodule.
void ActOnAnnotModuleInclude(SourceLocation DirectiveLoc, Module *Mod)
The parser has processed a module import translated from a #include or similar preprocessing directiv...
const TranslationUnitKind TUKind
The kind of translation unit we are processing.
@ PartitionImplementation
'module X:Y;'
@ Interface
'export module X;'
@ Implementation
'module X;'
@ PartitionInterface
'export module X:Y;'
llvm::DenseMap< NamedDecl *, NamedDecl * > VisibleNamespaceCache
Map from the most recent declaration of a namespace to the most recent visible declaration of that na...
void ActOnAnnotModuleEnd(SourceLocation DirectiveLoc, Module *Mod)
The parser has left a submodule.
bool currentModuleIsImplementation() const
Is the module scope we are an implementation unit?
DeclResult ActOnModuleImport(SourceLocation StartLoc, SourceLocation ExportLoc, SourceLocation ImportLoc, ModuleIdPath Path, bool IsPartition=false)
The parser has processed a module import declaration.
DeclGroupPtrTy ConvertDeclToDeclGroup(Decl *Ptr, Decl *OwnedType=nullptr)
ASTContext & getASTContext() const
Decl * ActOnStartExportDecl(Scope *S, SourceLocation ExportLoc, SourceLocation LBraceLoc)
We have parsed the start of an export declaration, including the '{' (if present).
const LangOptions & getLangOpts() const
void ActOnEndOfTranslationUnitFragment(TUFragmentKind Kind)
DeclGroupPtrTy ActOnGlobalModuleFragmentDecl(SourceLocation ModuleLoc)
The parser has processed a global-module-fragment declaration that begins the definition of the globa...
std::optional< sema::TemplateDeductionInfo * > isSFINAEContext() const
Determines whether we are currently in a context where template argument substitution failures are no...
DeclGroupPtrTy ActOnModuleDecl(SourceLocation StartLoc, SourceLocation ModuleLoc, ModuleDeclKind MDK, ModuleIdPath Path, ModuleIdPath Partition, ModuleImportState &ImportState, bool SeenNoTrivialPPDirective)
The parser has processed a module-declaration that begins the definition of a module interface or imp...
Module * getCurrentModule() const
Get the module unit whose scope we are currently within.
DeclContext * CurContext
CurContext - This is the current declaration context of parsing.
DeclGroupPtrTy ActOnPrivateModuleFragmentDecl(SourceLocation ModuleLoc, SourceLocation PrivateLoc)
The parser has processed a private-module-fragment declaration that begins the definition of the priv...
SourceManager & getSourceManager() const
void BuildModuleInclude(SourceLocation DirectiveLoc, Module *Mod)
bool isModuleVisible(const Module *M, bool ModulePrivate=false)
ModuleImportState
An enumeration to represent the transition of states in parsing module fragments and imports.
@ FirstDecl
Parsing the first decl in a TU.
@ GlobalFragment
after 'module;' but before 'module X;'
@ NotACXX20Module
Not a C++20 TU, or an invalid state was found.
@ ImportAllowed
after 'module X;' but before any non-import decl.
ModuleLoader & getModuleLoader() const
Retrieve the module loader associated with the preprocessor.
void PushDeclContext(Scope *S, DeclContext *DC)
Set the current declaration context until it gets popped.
SourceManager & SourceMgr
Decl * ActOnFinishExportDecl(Scope *S, Decl *ExportDecl, SourceLocation RBraceLoc)
Complete the definition of an export declaration.
ASTMutationListener * getASTMutationListener() const
void createImplicitModuleImportForErrorRecovery(SourceLocation Loc, Module *Mod)
Create an implicit import of the given module at the given source location, for error recovery,...
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
FileID getFileID(SourceLocation SpellingLoc) const
Return the FileID for a SourceLocation.
OptionalFileEntryRef getFileEntryRefForID(FileID FID) const
Returns the FileEntryRef for the provided FileID.
FileManager & getFileManager() const
FileID getMainFileID() const
Returns the FileID of the main source file.
SourceLocation getIncludeLoc(FileID FID) const
Returns the include location if FID is a #include'd file otherwise it returns an invalid location.
bool isInSystemHeader(SourceLocation Loc) const
Returns if a SourceLocation is in a system header.
SourceLocation getLocForStartOfFile(FileID FID) const
Return the source location corresponding to the first byte of the specified file.
bool isWrittenInMainFile(SourceLocation Loc) const
Returns true if the spelling location for the given location is in the main file buffer.
A trivial tuple used to represent a source range.
SourceLocation getBegin() const
Stmt - This represents one statement.
@ Declaration
The template argument is a declaration that was provided for a pointer, reference,...
@ Type
The template argument is a type.
The top declaration context.
Linkage getLinkage() const
Determine the linkage of this type.
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Represents a variable declaration or definition.
bool isConstexpr() const
Whether this variable is (C++11) constexpr.
bool isInline() const
Whether this variable is (C++1z) inline.
const Expr * getInit() const
A set of visible modules.
void setVisible(Module *M, SourceLocation Loc, bool IncludeExports=true, VisibleCallback Vis=[](Module *) {}, ConflictCallback Cb=[](ArrayRef< Module * >, Module *, StringRef) {})
Make a specific module visible.
SourceLocation getImportLoc(const Module *M) const
Get the location at which the import of a module was triggered.
bool isVisible(const Module *M) const
Determine whether a module is visible.
The JSON file list parser is used to communicate input to InstallAPI.
if(T->getSizeExpr()) TRY_TO(TraverseStmt(const_cast< Expr * >(T -> getSizeExpr())))
Linkage
Describes the different kinds of linkage (C++ [basic.link], C99 6.2.2) that an entity may have.
@ None
No linkage, which means that the entity is unique and can only be referred to from within its scope.
@ Internal
Internal linkage, which indicates that the entity can be referred to from within the translation unit...
@ Module
Module linkage, which indicates that the entity can be referred to from other translation units withi...
@ Global
The global module fragment, between 'module;' and a module-declaration.
@ Normal
A normal translation unit fragment.
@ TU_ClangModule
The translation unit is a clang module.
@ TSK_ImplicitInstantiation
This template specialization was implicitly instantiated from a template.
ArrayRef< IdentifierLoc > ModuleIdPath
A sequence of identifier/location pairs used to describe a particular module or submodule,...
int const char * function