21#include "llvm/ADT/ScopeExit.h"
22#include "llvm/ADT/StringExtras.h"
29 bool FromInclude =
false) {
32 if (
auto *LSD = dyn_cast<LinkageSpecDecl>(DC)) {
33 switch (LSD->getLanguage()) {
36 ExternCLoc = LSD->getBeginLoc();
49 ? diag::ext_module_import_not_at_top_level_noop
50 : diag::err_module_import_not_at_top_level_fatal)
53 diag::note_module_import_not_at_top_level)
56 S.
Diag(ImportLoc, diag::ext_module_import_in_extern_c)
58 S.
Diag(ExternCLoc, diag::note_extern_c_begins_here);
71 for (
auto &Piece : Path) {
74 Name += Piece.getIdentifierInfo()->getName();
89 Module *&FoundPrimaryModuleInterface) {
100 if (FoundPrimaryModuleInterface)
101 return Imported == FoundPrimaryModuleInterface;
116 assert(!FoundPrimaryModuleInterface ||
117 FoundPrimaryModuleInterface == Imported);
118 FoundPrimaryModuleInterface = Imported;
135 bool IsImportingPrimaryModuleInterface =
false) {
137 "'makeTransitiveImportsVisible()' is intended for standard C++ named "
142 Worklist.push_back(Imported);
144 Module *FoundPrimaryModuleInterface =
145 IsImportingPrimaryModuleInterface ? Imported :
nullptr;
147 while (!Worklist.empty()) {
148 Module *Importing = Worklist.pop_back_val();
150 if (Visited.count(Importing))
152 Visited.insert(Importing);
156 VisibleModules.
setVisible(Importing, ImportLoc);
159 FoundPrimaryModuleInterface)) {
161 Worklist.push_back(TransImported);
163 for (
auto [Exports, _] : Importing->
Exports)
164 Worklist.push_back(Exports);
173 PushGlobalModuleFragment(ModuleLoc);
176 auto *TU =
Context.getTranslationUnitDecl();
185 TU->setLocalOwningModule(GlobalModule);
191void Sema::HandleStartOfHeaderUnit() {
193 "Header units are only valid for C++20 modules");
195 SourceMgr.getLocForStartOfFile(SourceMgr.getMainFileID());
198 if (HUName.empty()) {
200 SourceMgr.getFileEntryRefForID(SourceMgr.getMainFileID())->getName();
207 auto F = SourceMgr.getFileManager().getOptionalFileRef(HUName);
212 F = SourceMgr.getFileEntryRefForID(SourceMgr.getMainFileID());
213 assert(F &&
"failed to find the header unit source?");
215 auto &Map =
PP.getHeaderSearchInfo().getModuleMap();
216 Module *Mod = Map.createHeaderUnit(StartOfTU, HUName, H);
217 assert(Mod &&
"module creation should not fail");
218 ModuleScopes.push_back({});
219 ModuleScopes.back().BeginLoc = StartOfTU;
220 ModuleScopes.back().Module = Mod;
221 VisibleModules.setVisible(Mod, StartOfTU);
225 auto *TU =
Context.getTranslationUnitDecl();
227 TU->setLocalOwningModule(Mod);
241 if (II->
isStr(
"module") || II->
isStr(
"import"))
257 return S.
Diag(Loc, diag::err_invalid_module_name) << II;
259 S.
Diag(Loc, diag::warn_reserved_module_name) << II;
262 llvm_unreachable(
"fell off a fully covered switch");
269 bool SeenNoTrivialPPDirective) {
271 "should only have module decl in standard C++ modules");
279 bool IsPartition = !Partition.empty();
289 llvm_unreachable(
"how did we get a partition type set?");
308 Diag(ModuleLoc, diag::err_module_interface_implementation_mismatch)
314 Diag(ModuleLoc, diag::err_module_decl_in_module_map_module);
318 Diag(ModuleLoc, diag::err_module_decl_in_header_unit);
322 assert(ModuleScopes.size() <= 1 &&
"expected to be at global module scope");
328 if (isCurrentModulePurview()) {
329 Diag(ModuleLoc, diag::err_module_redeclaration);
330 Diag(VisibleModules.getImportLoc(ModuleScopes.back().Module),
331 diag::note_prev_module_declaration);
336 SeenGMF == (
bool)this->TheGlobalModuleFragment) &&
337 "mismatched global module state");
342 (!IsFirstDecl || SeenNoTrivialPPDirective) && !SeenGMF) {
343 Diag(ModuleLoc, diag::err_module_decl_not_at_start);
345 Diag(BeginLoc, diag::note_global_module_introducer_missing)
358 StringRef FirstComponentName = Path[0].getIdentifierInfo()->getName();
360 (FirstComponentName ==
"std" ||
361 (FirstComponentName.starts_with(
"std") &&
362 llvm::all_of(FirstComponentName.drop_front(3), &llvm::isDigit))))
363 Diag(Path[0].getLoc(), diag::warn_reserved_module_name)
364 << Path[0].getIdentifierInfo();
368 for (
auto Part : Path) {
385 Diag(Path.front().getLoc(), diag::err_current_module_name_mismatch)
387 ? Partition.back().getLoc()
388 : Path.back().getLoc())
394 auto &Map =
PP.getHeaderSearchInfo().getModuleMap();
402 if (
auto *M = Map.findOrLoadModule(ModuleName)) {
403 Diag(Path[0].getLoc(), diag::err_module_redefinition) << ModuleName;
404 if (M->DefinitionLoc.isValid())
405 Diag(M->DefinitionLoc, diag::note_prev_module_definition);
407 Diag(M->DefinitionLoc, diag::note_prev_module_definition_from_ast_file)
414 Mod = Map.createModuleForInterfaceUnit(ModuleLoc, ModuleName);
417 assert(Mod &&
"module creation should not fail");
427 PP.getIdentifierInfo(ModuleName));
440 Diag(ModuleLoc, diag::err_module_not_defined) << ModuleName;
442 Mod = Map.createModuleForInterfaceUnit(ModuleLoc, ModuleName);
444 Mod = Map.createModuleForImplementationUnit(ModuleLoc, ModuleName);
451 Mod = Map.createModuleForInterfaceUnit(ModuleLoc, ModuleName);
456 if (!this->TheGlobalModuleFragment) {
457 ModuleScopes.push_back({});
459 ModuleScopes.back().OuterVisibleModules = std::move(VisibleModules);
466 ModuleScopes.back().BeginLoc = StartLoc;
467 ModuleScopes.back().Module = Mod;
468 VisibleModules.setVisible(Mod, ModuleLoc);
475 auto *TU =
Context.getTranslationUnitDecl();
477 TU->setLocalOwningModule(Mod);
486 Listener->EnteringModulePurview();
492 HadImportedNamedModules =
true;
505 Context.addModuleInitializer(ModuleScopes.back().Module, Import);
524 : ModuleScopes.back().Module->Kind) {
531 Diag(PrivateLoc, diag::err_private_module_fragment_not_module);
535 Diag(PrivateLoc, diag::err_private_module_fragment_redefined);
536 Diag(ModuleScopes.back().BeginLoc, diag::note_previous_definition);
540 Diag(PrivateLoc, diag::err_private_module_fragment_not_module_interface);
541 Diag(ModuleScopes.back().BeginLoc,
542 diag::note_not_module_interface_add_export)
557 auto &Map =
PP.getHeaderSearchInfo().getModuleMap();
558 Module *PrivateModuleFragment =
559 Map.createPrivateModuleFragmentForInterfaceUnit(
560 ModuleScopes.back().Module, PrivateLoc);
561 assert(PrivateModuleFragment &&
"module creation should not fail");
564 ModuleScopes.push_back({});
565 ModuleScopes.back().BeginLoc = ModuleLoc;
566 ModuleScopes.back().Module = PrivateModuleFragment;
567 VisibleModules.setVisible(PrivateModuleFragment, ModuleLoc);
572 auto *TU =
Context.getTranslationUnitDecl();
574 TU->setLocalOwningModule(PrivateModuleFragment);
584 assert((!IsPartition ||
getLangOpts().CPlusPlusModules) &&
585 "partition seen in non-C++20 code?");
591 std::string ModuleName;
594 assert(!ModuleScopes.empty() &&
"in a module purview, but no module?");
618 if (
getLangOpts().CPlusPlusModules && isCurrentModulePurview() &&
620 Diag(ImportLoc, diag::err_module_self_import_cxx20)
632 Diag(ImportLoc, diag::err_module_import_non_interface_nor_parition)
643 if (
auto *ED = dyn_cast<ExportDecl>(DC))
653 Diag(ImportLoc, diag::warn_experimental_header_unit);
659 VisibleModules.setVisible(Mod, ImportLoc);
662 "We can only import a partition unit in a named module.");
666 diag::warn_import_implementation_partition_unit_in_interface_unit)
677 ? diag::err_module_self_import
678 : diag::err_module_import_in_implementation)
688 for (
Module *ModCheck = Mod; ModCheck; ModCheck = ModCheck->
Parent)
692 IdentifierLocs.push_back(Path[0].getLoc());
695 for (
unsigned I = 0, N = Path.size(); I != N; ++I) {
700 ModCheck = ModCheck->
Parent;
702 IdentifierLocs.push_back(Path[I].getLoc());
707 Mod, IdentifierLocs);
712 if (!ModuleScopes.empty())
713 Context.addModuleInitializer(ModuleScopes.back().Module, Import);
718 Diag(ExportLoc, diag::err_export_partition_impl)
720 }
else if (ExportLoc.
isValid() &&
725 Diag(ExportLoc, diag::err_export_not_in_module_interface);
726 }
else if (!ModuleScopes.empty()) {
736 HadImportedNamedModules =
true;
752 bool IsInModuleIncludes =
758 if (
getLangOpts().Modules && !IsInModuleIncludes) {
763 if (!ModuleScopes.empty())
764 Context.addModuleInitializer(ModuleScopes.back().Module, ImportD);
766 Consumer.HandleImplicitImportDecl(ImportD);
770 VisibleModules.setVisible(Mod, DirectiveLoc);
773 Module *ThisModule =
PP.getHeaderSearchInfo().lookupModule(
774 getLangOpts().CurrentModule, DirectiveLoc,
false,
false);
781 "was expecting a module if building a Clang module");
788 ModuleScopes.push_back({});
789 ModuleScopes.back().Module = Mod;
791 ModuleScopes.back().OuterVisibleModules = std::move(VisibleModules);
793 VisibleModules.setVisible(Mod, DirectiveLoc);
799 for (
auto *DC =
CurContext; DC; DC = DC->getLexicalParent()) {
811 VisibleModules = std::move(ModuleScopes.back().OuterVisibleModules);
817 assert(!ModuleScopes.empty() && ModuleScopes.back().Module == Mod &&
818 "left the wrong module scope");
819 ModuleScopes.pop_back();
828 "end of submodule in main source file");
832 DirectiveLoc = EomLoc;
840 for (
auto *DC =
CurContext; DC; DC = DC->getLexicalParent()) {
853 VisibleModules.isVisible(Mod))
861 Consumer.HandleImplicitImportDecl(ImportD);
865 VisibleModules.setVisible(Mod, Loc);
883 if (!isCurrentModulePurview()) {
884 Diag(ExportLoc, diag::err_export_not_in_module_interface) << 0;
888 Diag(ExportLoc, diag::err_export_not_in_module_interface) << 1;
889 Diag(ModuleScopes.back().BeginLoc,
890 diag::note_not_module_interface_add_export)
894 }
else if (ModuleScopes.back().Module->Kind ==
896 Diag(ExportLoc, diag::err_export_in_private_module_fragment);
897 Diag(ModuleScopes.back().BeginLoc, diag::note_private_module_fragment);
904 if (
const auto *ND = dyn_cast<NamespaceDecl>(DC)) {
907 if (ND->isAnonymousNamespace()) {
908 Diag(ExportLoc, diag::err_export_within_anonymous_namespace);
909 Diag(ND->getLocation(), diag::note_anonymous_namespace);
920 if (!
getLangOpts().
HLSL && !DeferredExportedNamespaces.insert(ND).second)
928 Diag(ExportLoc, diag::err_export_within_export);
930 Diag(ED->getLocation(), diag::note_export);
946 bool AllUnnamed =
true;
947 for (
auto *D : DC->
decls())
967 bool HasName =
false;
968 if (
auto *ND = dyn_cast<NamedDecl>(D)) {
971 HasName = (
bool)ND->getDeclName();
973 S.
Diag(ND->getLocation(), diag::err_export_internal) << ND;
975 S.
Diag(BlockStart, diag::note_export);
983 if (
auto *USD = dyn_cast<UsingShadowDecl>(D)) {
987 S.
Diag(USD->getLocation(), diag::err_export_using_internal)
989 S.
Diag(
Target->getLocation(), diag::note_using_decl_target);
991 S.
Diag(BlockStart, diag::note_export);
998 if (
auto *DC = dyn_cast<DeclContext>(D)) {
1002 if (
auto *ND = dyn_cast<NamedDecl>(D)) {
1003 if (!ND->getDeclName()) {
1004 S.
Diag(ND->getLocation(), diag::err_export_anon_ns_internal);
1006 S.
Diag(BlockStart, diag::note_export);
1008 }
else if (!DC->decls().empty() &&
1009 DC->getRedeclContext()->isFileContext()) {
1020 ED->setRBraceLoc(RBraceLoc);
1027 for (
auto *Child : ED->decls()) {
1029 if (
auto *FD = dyn_cast<FunctionDecl>(Child)) {
1037 if (FD->isInlineSpecified() && !FD->isDefined())
1038 PendingInlineFuncDecls.insert(FD);
1044 for (
auto *Exported : ED->decls())
1053 if (!TheGlobalModuleFragment) {
1059 assert(TheGlobalModuleFragment &&
"module creation should not fail");
1062 ModuleScopes.push_back({BeginLoc, TheGlobalModuleFragment,
1064 VisibleModules.setVisible(TheGlobalModuleFragment, BeginLoc);
1066 return TheGlobalModuleFragment;
1069void Sema::PopGlobalModuleFragment() {
1070 assert(!ModuleScopes.empty() &&
1072 "left the wrong module scope, which is not global module fragment");
1073 ModuleScopes.pop_back();
1077 if (!TheImplicitGlobalModuleFragment) {
1078 ModuleMap &Map =
PP.getHeaderSearchInfo().getModuleMap();
1079 TheImplicitGlobalModuleFragment =
1083 assert(TheImplicitGlobalModuleFragment &&
"module creation should not fail");
1086 ModuleScopes.push_back({BeginLoc, TheImplicitGlobalModuleFragment,
1088 VisibleModules.setVisible(TheImplicitGlobalModuleFragment, BeginLoc);
1089 return TheImplicitGlobalModuleFragment;
1092void Sema::PopImplicitGlobalModuleFragment() {
1093 assert(!ModuleScopes.empty() &&
1095 "left the wrong module scope, which is not global module fragment");
1096 ModuleScopes.pop_back();
1099bool Sema::isCurrentModulePurview()
const {
1123class ExposureChecker {
1125 ExposureChecker(Sema &S) : SemaRef(S) {}
1127 bool checkExposure(
const VarDecl *D,
bool Diag);
1128 bool checkExposure(
const CXXRecordDecl *D,
bool Diag);
1129 bool checkExposure(
const Stmt *S,
bool Diag);
1130 bool checkExposure(
const FunctionDecl *D,
bool Diag);
1131 bool checkExposure(
const NamedDecl *D,
bool Diag);
1132 void checkExposureInContext(
const DeclContext *DC);
1133 bool isExposureCandidate(
const NamedDecl *D);
1135 bool isTULocal(QualType Ty);
1136 bool isTULocal(
const NamedDecl *ND);
1137 bool isTULocal(
const Expr *E);
1142 llvm::DenseSet<const NamedDecl *> ExposureSet;
1143 llvm::DenseSet<const NamedDecl *> KnownNonExposureSet;
1144 llvm::DenseSet<const NamedDecl *> CheckingDecls;
1147bool ExposureChecker::isTULocal(
QualType Ty) {
1162bool ExposureChecker::isTULocal(
const NamedDecl *D) {
1182 ND && isTULocal(ND))
1190 if (
auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
1191 TemplateArgs = CTSD->getTemplateArgs().asArray();
1192 PrimaryTemplate = CTSD->getSpecializedTemplate();
1193 if (isTULocal(PrimaryTemplate))
1195 }
else if (
auto *VTSD = dyn_cast<VarTemplateSpecializationDecl>(D)) {
1196 TemplateArgs = VTSD->getTemplateArgs().asArray();
1197 PrimaryTemplate = VTSD->getSpecializedTemplate();
1198 if (isTULocal(PrimaryTemplate))
1200 }
else if (
auto *FD = dyn_cast<FunctionDecl>(D)) {
1201 if (
auto *TAList = FD->getTemplateSpecializationArgs())
1202 TemplateArgs = TAList->asArray();
1204 PrimaryTemplate = FD->getPrimaryTemplate();
1205 if (isTULocal(PrimaryTemplate))
1209 if (!PrimaryTemplate)
1213 if (KnownNonExposureSet.count(D))
1216 for (
auto &TA : TemplateArgs) {
1217 switch (TA.getKind()) {
1219 if (isTULocal(TA.getAsType()))
1223 if (isTULocal(TA.getAsDecl()))
1232 if (CheckingDecls.count(D))
1234 CheckingDecls.insert(D);
1235 llvm::scope_exit RemoveCheckingDecls([&] { CheckingDecls.erase(D); });
1240 if (ExposureSet.count(PrimaryTemplate) ||
1241 checkExposure(PrimaryTemplate,
false))
1245 KnownNonExposureSet.insert(D);
1249bool ExposureChecker::isTULocal(
const Expr *E) {
1267 if (
const auto *DRE = dyn_cast<DeclRefExpr>(E)) {
1268 if (
auto *FD = dyn_cast_or_null<FunctionDecl>(DRE->getFoundDecl()))
1269 return isTULocal(FD);
1270 else if (
auto *VD = dyn_cast_or_null<VarDecl>(DRE->getFoundDecl()))
1271 return isTULocal(VD);
1272 else if (
auto *RD = dyn_cast_or_null<CXXRecordDecl>(DRE->getFoundDecl()))
1273 return isTULocal(RD);
1283bool ExposureChecker::isExposureCandidate(
const NamedDecl *D) {
1299 assert(M &&
"Implicit global module must have a parent");
1320bool ExposureChecker::checkExposure(
const NamedDecl *D,
bool Diag) {
1321 if (!isExposureCandidate(D))
1324 if (
auto *FD = dyn_cast<FunctionDecl>(D))
1325 return checkExposure(FD,
Diag);
1326 if (
auto *FTD = dyn_cast<FunctionTemplateDecl>(D))
1327 return checkExposure(FTD->getTemplatedDecl(),
Diag);
1329 if (
auto *VD = dyn_cast<VarDecl>(D))
1330 return checkExposure(VD,
Diag);
1331 if (
auto *VTD = dyn_cast<VarTemplateDecl>(D))
1332 return checkExposure(VTD->getTemplatedDecl(),
Diag);
1334 if (
auto *RD = dyn_cast<CXXRecordDecl>(D))
1335 return checkExposure(RD,
Diag);
1337 if (
auto *CTD = dyn_cast<ClassTemplateDecl>(D))
1338 return checkExposure(CTD->getTemplatedDecl(),
Diag);
1344 bool IsExposure =
false;
1349 diag::warn_exposure)
1354 if (isTULocal(Parms->getType())) {
1357 SemaRef.Diag(Parms->getLocation(), diag::warn_exposure)
1358 << Parms->getType();
1361 bool IsImplicitInstantiation =
1377 ExposureSet.insert(FD);
1382bool ExposureChecker::checkExposure(
const VarDecl *VD,
bool Diag) {
1383 bool IsExposure =
false;
1397 if (isTULocal(VD->
getType())) {
1414 ExposureSet.insert(VD);
1423 bool IsExposure =
false;
1428 if (isTULocal(FD->
getType())) {
1436 if (isTULocal(
Base.getType())) {
1439 SemaRef.Diag(
Base.getBaseTypeLoc(), diag::warn_exposure)
1445 ExposureSet.insert(RD);
1452 using CallbackTy =
std::function<void(DeclRefExpr *, ValueDecl *)>;
1454 ReferenceTULocalChecker(ExposureChecker &
C, CallbackTy &&Callback)
1455 : Checker(
C), Callback(std::move(Callback)) {}
1457 bool VisitDeclRefExpr(DeclRefExpr *DRE)
override {
1458 ValueDecl *Referenced = DRE->
getDecl();
1462 if (!Checker.isTULocal(Referenced))
1482 if (DRE->
isNonOdrUse() && (L == Linkage::Internal || L == Linkage::None))
1483 if (
auto *VD = dyn_cast<VarDecl>(Referenced);
1488 Callback(DRE, Referenced);
1492 ExposureChecker &Checker;
1493 CallbackTy Callback;
1496bool ExposureChecker::checkExposure(
const Stmt *S,
bool Diag) {
1500 bool HasReferencedTULocals =
false;
1501 ReferenceTULocalChecker Checker(
1505 SemaRef.Diag(DRE->
getExprLoc(), diag::warn_exposure) << Referenced;
1507 HasReferencedTULocals =
true;
1509 Checker.TraverseStmt(
const_cast<Stmt *
>(S));
1510 return HasReferencedTULocals;
1513void ExposureChecker::checkExposureInContext(
const DeclContext *DC) {
1515 if (
auto *Export = dyn_cast<ExportDecl>(TopD)) {
1516 checkExposureInContext(Export);
1520 if (
auto *LinkageSpec = dyn_cast<LinkageSpecDecl>(TopD)) {
1521 checkExposureInContext(LinkageSpec);
1525 auto *TopND = dyn_cast<NamedDecl>(TopD);
1529 if (
auto *Namespace = dyn_cast<NamespaceDecl>(TopND)) {
1530 checkExposureInContext(Namespace);
1539 if (!TopND->isFromASTFile() && isExposureCandidate(TopND) &&
1541 checkExposure(TopND,
true);
1551 ExposureChecker Checker(*
this);
1555 Checker.checkExposureInContext(TU);
1561 for (
auto FDAndInstantiationLocPair : PendingCheckReferenceForTULocal) {
1562 FunctionDecl *FD = FDAndInstantiationLocPair.first;
1563 SourceLocation PointOfInstantiation = FDAndInstantiationLocPair.second;
1568 ReferenceTULocalChecker(Checker, [&,
this](DeclRefExpr *DRE,
1569 ValueDecl *Referenced) {
1590 Diag(PointOfInstantiation,
1591 diag::warn_reference_tu_local_entity_in_other_tu)
1594 }).TraverseStmt(FD->
getBody());
1598void Sema::checkReferenceToTULocalFromOtherTU(
1602 if (!FD || !HadImportedNamedModules)
1605 PendingCheckReferenceForTULocal.push_back(
1606 std::make_pair(FD, PointOfInstantiation));
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.
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.
bool isInSameModule(const Module *M1, const Module *M2) const
If the two module M1 and M2 are in the same module.
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.
Represents a standard C++ module export declaration.
static ExportDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation ExportLoc)
void setRBraceLoc(SourceLocation L)
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.
An opaque identifier used by SourceManager which refers to a source file (MemoryBuffer) along with it...
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(ModuleConstructorTag, StringRef Name, SourceLocation DefinitionLoc, Module *Parent, bool IsFramework, bool IsExplicit, unsigned VisibilityID)
Construct a new module or submodule.
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 isImplicitGlobalModule() 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.
Linkage getLinkageInternal() const
Determine what kind of linkage this entity has.
Represents a parameter to a function.
HeaderSearch & getHeaderSearchInfo() const
A (possibly-)qualified type.
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
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)
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 directive...
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...
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)
bool isSFINAEContext() const
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.
Decl * ActOnFinishExportDecl(Scope *S, Decl *ExportDecl, SourceLocation RBraceLoc)
Complete the definition of an export declaration.
OpaquePtr< DeclGroupRef > DeclGroupPtrTy
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.
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.
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.
The JSON file list parser is used to communicate input to InstallAPI.
bool isa(CodeGen::Address addr)
CustomizableOptional< FileEntryRef > OptionalFileEntryRef
ArrayRef< IdentifierLoc > ModuleIdPath
A sequence of identifier/location pairs used to describe a particular module or submodule,...
ActionResult< Decl * > DeclResult
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.
DynamicRecursiveASTVisitorBase< false > DynamicRecursiveASTVisitor
@ TSK_ImplicitInstantiation
This template specialization was implicitly instantiated from a template.
U cast(CodeGen::Address addr)
int const char * function