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);
72 Module *&FoundPrimaryModuleInterface) {
83 if (FoundPrimaryModuleInterface)
84 return Imported == FoundPrimaryModuleInterface;
99 assert(!FoundPrimaryModuleInterface ||
100 FoundPrimaryModuleInterface == Imported);
101 FoundPrimaryModuleInterface = Imported;
118 bool IsImportingPrimaryModuleInterface =
false) {
120 "'makeTransitiveImportsVisible()' is intended for standard C++ named "
125 Worklist.push_back(Imported);
127 Module *FoundPrimaryModuleInterface =
128 IsImportingPrimaryModuleInterface ? Imported :
nullptr;
130 while (!Worklist.empty()) {
131 Module *Importing = Worklist.pop_back_val();
133 if (Visited.count(Importing))
135 Visited.insert(Importing);
139 VisibleModules.
setVisible(Importing, ImportLoc);
142 FoundPrimaryModuleInterface)) {
144 Worklist.push_back(TransImported);
146 for (
auto [Exports, _] : Importing->
Exports)
147 Worklist.push_back(Exports);
156 PushGlobalModuleFragment(ModuleLoc);
159 auto *TU =
Context.getTranslationUnitDecl();
168 TU->setLocalOwningModule(GlobalModule);
174void Sema::HandleStartOfHeaderUnit() {
176 "Header units are only valid for C++20 modules");
178 SourceMgr.getLocForStartOfFile(SourceMgr.getMainFileID());
181 if (HUName.empty()) {
183 SourceMgr.getFileEntryRefForID(SourceMgr.getMainFileID())->getName();
190 auto F = SourceMgr.getFileManager().getOptionalFileRef(HUName);
195 F = SourceMgr.getFileEntryRefForID(SourceMgr.getMainFileID());
196 assert(F &&
"failed to find the header unit source?");
198 auto &Map =
PP.getHeaderSearchInfo().getModuleMap();
199 Module *Mod = Map.createHeaderUnit(StartOfTU, HUName, H);
200 assert(Mod &&
"module creation should not fail");
201 ModuleScopes.push_back({});
202 ModuleScopes.back().BeginLoc = StartOfTU;
203 ModuleScopes.back().Module = Mod;
204 VisibleModules.setVisible(Mod, StartOfTU);
208 auto *TU =
Context.getTranslationUnitDecl();
210 TU->setLocalOwningModule(Mod);
224 if (II->
isStr(
"module") || II->
isStr(
"import"))
240 return S.
Diag(Loc, diag::err_invalid_module_name) << II;
242 S.
Diag(Loc, diag::warn_reserved_module_name) << II;
245 llvm_unreachable(
"fell off a fully covered switch");
252 bool SeenNoTrivialPPDirective) {
254 "should only have module decl in standard C++ modules");
262 bool IsPartition = !Partition.empty();
272 llvm_unreachable(
"how did we get a partition type set?");
291 Diag(ModuleLoc, diag::err_module_interface_implementation_mismatch)
297 Diag(ModuleLoc, diag::err_module_decl_in_module_map_module);
301 Diag(ModuleLoc, diag::err_module_decl_in_header_unit);
305 assert(ModuleScopes.size() <= 1 &&
"expected to be at global module scope");
311 if (isCurrentModulePurview()) {
312 Diag(ModuleLoc, diag::err_module_redeclaration);
313 Diag(VisibleModules.getImportLoc(ModuleScopes.back().Module),
314 diag::note_prev_module_declaration);
319 SeenGMF == (
bool)this->TheGlobalModuleFragment) &&
320 "mismatched global module state");
325 (!IsFirstDecl || SeenNoTrivialPPDirective) && !SeenGMF) {
326 Diag(ModuleLoc, diag::err_module_decl_not_at_start);
328 Diag(BeginLoc, diag::note_global_module_introducer_missing)
341 StringRef FirstComponentName = Path[0].getIdentifierInfo()->getName();
343 (FirstComponentName ==
"std" ||
344 (FirstComponentName.starts_with(
"std") &&
345 llvm::all_of(FirstComponentName.drop_front(3), &llvm::isDigit))))
346 Diag(Path[0].getLoc(), diag::warn_reserved_module_name)
347 << Path[0].getIdentifierInfo();
351 for (
auto Part : Path) {
368 Diag(Path.front().getLoc(), diag::err_current_module_name_mismatch)
370 ? Partition.back().getLoc()
371 : Path.back().getLoc())
377 auto &Map =
PP.getHeaderSearchInfo().getModuleMap();
385 if (
auto *M = Map.findOrLoadModule(ModuleName)) {
386 Diag(Path[0].getLoc(), diag::err_module_redefinition) << ModuleName;
387 if (M->DefinitionLoc.isValid())
388 Diag(M->DefinitionLoc, diag::note_prev_module_definition);
390 Diag(M->DefinitionLoc, diag::note_prev_module_definition_from_ast_file)
395 if (!M->isNamedModule())
402 Mod = Map.createModuleForInterfaceUnit(ModuleLoc, ModuleName);
405 assert(Mod &&
"module creation should not fail");
415 PP.getIdentifierInfo(ModuleName));
430 Diag(ModuleLoc, diag::err_module_not_defined) << ModuleName;
435 Diag(ModuleLoc, diag::err_module_not_defined) << ModuleName;
437 Mod = Map.createModuleForInterfaceUnit(ModuleLoc, ModuleName);
439 Mod = Map.createModuleForImplementationUnit(ModuleLoc, ModuleName);
446 Mod = Map.createModuleForInterfaceUnit(ModuleLoc, ModuleName);
451 if (!this->TheGlobalModuleFragment) {
452 ModuleScopes.push_back({});
454 ModuleScopes.back().OuterVisibleModules = std::move(VisibleModules);
461 ModuleScopes.back().BeginLoc = StartLoc;
462 ModuleScopes.back().Module = Mod;
463 VisibleModules.setVisible(Mod, ModuleLoc);
470 auto *TU =
Context.getTranslationUnitDecl();
472 TU->setLocalOwningModule(Mod);
484 HadImportedNamedModules =
true;
497 Context.addModuleInitializer(ModuleScopes.back().Module, Import);
516 : ModuleScopes.back().Module->Kind) {
523 Diag(PrivateLoc, diag::err_private_module_fragment_not_module);
527 Diag(PrivateLoc, diag::err_private_module_fragment_redefined);
528 Diag(ModuleScopes.back().BeginLoc, diag::note_previous_definition);
532 Diag(PrivateLoc, diag::err_private_module_fragment_not_module_interface);
533 Diag(ModuleScopes.back().BeginLoc,
534 diag::note_not_module_interface_add_export)
549 auto &Map =
PP.getHeaderSearchInfo().getModuleMap();
550 Module *PrivateModuleFragment =
551 Map.createPrivateModuleFragmentForInterfaceUnit(
552 ModuleScopes.back().Module, PrivateLoc);
553 assert(PrivateModuleFragment &&
"module creation should not fail");
556 ModuleScopes.push_back({});
557 ModuleScopes.back().BeginLoc = ModuleLoc;
558 ModuleScopes.back().Module = PrivateModuleFragment;
559 VisibleModules.setVisible(PrivateModuleFragment, ModuleLoc);
564 auto *TU =
Context.getTranslationUnitDecl();
566 TU->setLocalOwningModule(PrivateModuleFragment);
577 assert((!IsPartition ||
getLangOpts().CPlusPlusModules) &&
578 "partition seen in non-C++20 code?");
584 std::string ModuleName;
587 assert(!ModuleScopes.empty() &&
"in a module purview, but no module?");
611 if (
getLangOpts().CPlusPlusModules && isCurrentModulePurview() &&
613 Diag(ImportLoc, diag::err_module_self_import_cxx20)
625 Diag(ImportLoc, diag::err_module_import_non_interface_nor_parition)
636 if (
auto *ED = dyn_cast<ExportDecl>(DC))
646 Diag(ImportLoc, diag::warn_experimental_header_unit);
652 VisibleModules.setVisible(Mod, ImportLoc);
655 "We can only import a partition unit in a named module.");
659 diag::warn_import_implementation_partition_unit_in_interface_unit)
670 ? diag::err_module_self_import
671 : diag::err_module_import_in_implementation)
681 for (
Module *ModCheck = Mod; ModCheck; ModCheck = ModCheck->
Parent)
685 IdentifierLocs.push_back(Path[0].getLoc());
688 for (
unsigned I = 0, N = Path.size(); I != N; ++I) {
693 ModCheck = ModCheck->
Parent;
695 IdentifierLocs.push_back(Path[I].getLoc());
700 Mod, IdentifierLocs);
705 if (!ModuleScopes.empty())
706 Context.addModuleInitializer(ModuleScopes.back().Module, Import);
711 Diag(ExportLoc, diag::err_export_partition_impl)
713 }
else if (ExportLoc.
isValid() &&
718 Diag(ExportLoc, diag::err_export_not_in_module_interface);
719 }
else if (!ModuleScopes.empty()) {
729 HadImportedNamedModules =
true;
745 bool IsInModuleIncludes =
751 if (
getLangOpts().Modules && !IsInModuleIncludes) {
756 if (!ModuleScopes.empty())
757 Context.addModuleInitializer(ModuleScopes.back().Module, ImportD);
759 Consumer.HandleImplicitImportDecl(ImportD);
763 VisibleModules.setVisible(Mod, DirectiveLoc);
766 Module *ThisModule =
PP.getHeaderSearchInfo().lookupModule(
767 getLangOpts().CurrentModule, DirectiveLoc,
false,
false);
774 "was expecting a module if building a Clang module");
781 ModuleScopes.push_back({});
782 ModuleScopes.back().Module = Mod;
784 ModuleScopes.back().OuterVisibleModules = std::move(VisibleModules);
786 VisibleModules.setVisible(Mod, DirectiveLoc);
792 for (
auto *DC =
CurContext; DC; DC = DC->getLexicalParent()) {
804 VisibleModules = std::move(ModuleScopes.back().OuterVisibleModules);
810 assert(!ModuleScopes.empty() && ModuleScopes.back().Module == Mod &&
811 "left the wrong module scope");
812 ModuleScopes.pop_back();
821 "end of submodule in main source file");
825 DirectiveLoc = EomLoc;
833 for (
auto *DC =
CurContext; DC; DC = DC->getLexicalParent()) {
846 VisibleModules.isVisible(Mod))
854 Consumer.HandleImplicitImportDecl(ImportD);
858 VisibleModules.setVisible(Mod, Loc);
876 if (!isCurrentModulePurview()) {
877 Diag(ExportLoc, diag::err_export_not_in_module_interface) << 0;
881 Diag(ExportLoc, diag::err_export_not_in_module_interface) << 1;
882 Diag(ModuleScopes.back().BeginLoc,
883 diag::note_not_module_interface_add_export)
887 }
else if (ModuleScopes.back().Module->Kind ==
889 Diag(ExportLoc, diag::err_export_in_private_module_fragment);
890 Diag(ModuleScopes.back().BeginLoc, diag::note_private_module_fragment);
897 if (
const auto *ND = dyn_cast<NamespaceDecl>(DC)) {
900 if (ND->isAnonymousNamespace()) {
901 Diag(ExportLoc, diag::err_export_within_anonymous_namespace);
902 Diag(ND->getLocation(), diag::note_anonymous_namespace);
913 if (!
getLangOpts().
HLSL && !DeferredExportedNamespaces.insert(ND).second)
921 Diag(ExportLoc, diag::err_export_within_export);
923 Diag(ED->getLocation(), diag::note_export);
939 bool AllUnnamed =
true;
940 for (
auto *D : DC->
decls())
960 if (PVD->hasAttr<HLSLGroupSharedAddressSpaceAttr>()) {
962 <<
"'export'" <<
"'groupshared' parameter";
972 bool HasName =
false;
973 if (
auto *ND = dyn_cast<NamedDecl>(D)) {
976 HasName = (
bool)ND->getDeclName();
978 S.
Diag(ND->getLocation(), diag::err_export_internal) << ND;
980 S.
Diag(BlockStart, diag::note_export);
988 if (
auto *USD = dyn_cast<UsingShadowDecl>(D)) {
992 S.
Diag(USD->getLocation(), diag::err_export_using_internal)
994 S.
Diag(
Target->getLocation(), diag::note_using_decl_target);
996 S.
Diag(BlockStart, diag::note_export);
1003 if (
auto *DC = dyn_cast<DeclContext>(D)) {
1007 if (
auto *ND = dyn_cast<NamedDecl>(D)) {
1008 if (!ND->getDeclName()) {
1009 S.
Diag(ND->getLocation(), diag::err_export_anon_ns_internal);
1011 S.
Diag(BlockStart, diag::note_export);
1013 }
else if (!DC->decls().empty() &&
1014 DC->getRedeclContext()->isFileContext()) {
1025 ED->setRBraceLoc(RBraceLoc);
1032 for (
auto *Child : ED->decls()) {
1034 if (
auto *FD = dyn_cast<FunctionDecl>(Child)) {
1042 if (FD->isInlineSpecified() && !FD->isDefined())
1043 PendingInlineFuncDecls.insert(FD);
1049 for (
auto *Exported : ED->decls())
1058 if (!TheGlobalModuleFragment) {
1064 assert(TheGlobalModuleFragment &&
"module creation should not fail");
1067 ModuleScopes.push_back({BeginLoc, TheGlobalModuleFragment,
1069 VisibleModules.setVisible(TheGlobalModuleFragment, BeginLoc);
1071 return TheGlobalModuleFragment;
1074void Sema::PopGlobalModuleFragment() {
1075 assert(!ModuleScopes.empty() &&
1077 "left the wrong module scope, which is not global module fragment");
1078 ModuleScopes.pop_back();
1082 if (!TheImplicitGlobalModuleFragment) {
1083 ModuleMap &Map =
PP.getHeaderSearchInfo().getModuleMap();
1084 TheImplicitGlobalModuleFragment =
1088 assert(TheImplicitGlobalModuleFragment &&
"module creation should not fail");
1091 ModuleScopes.push_back({BeginLoc, TheImplicitGlobalModuleFragment,
1093 VisibleModules.setVisible(TheImplicitGlobalModuleFragment, BeginLoc);
1094 return TheImplicitGlobalModuleFragment;
1097void Sema::PopImplicitGlobalModuleFragment() {
1098 assert(!ModuleScopes.empty() &&
1100 "left the wrong module scope, which is not global module fragment");
1101 ModuleScopes.pop_back();
1104bool Sema::isCurrentModulePurview()
const {
1128class ExposureChecker {
1130 ExposureChecker(Sema &S) : SemaRef(S) {}
1132 bool checkExposure(
const VarDecl *D,
bool Diag);
1133 bool checkExposure(
const CXXRecordDecl *D,
bool Diag);
1134 bool checkExposure(
const Stmt *S,
bool Diag);
1135 bool checkExposure(
const FunctionDecl *D,
bool Diag);
1136 bool checkExposure(
const NamedDecl *D,
bool Diag);
1137 void checkExposureInContext(
const DeclContext *DC);
1138 bool isExposureCandidate(
const NamedDecl *D);
1140 bool isTULocal(QualType Ty);
1141 bool isTULocal(
const NamedDecl *ND);
1142 bool isTULocal(
const Expr *E);
1147 llvm::DenseSet<const NamedDecl *> ExposureSet;
1148 llvm::DenseSet<const NamedDecl *> KnownNonExposureSet;
1149 llvm::DenseSet<const NamedDecl *> CheckingDecls;
1152bool ExposureChecker::isTULocal(
QualType Ty) {
1167bool ExposureChecker::isTULocal(
const NamedDecl *D) {
1187 ND && isTULocal(ND))
1195 if (
auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
1196 TemplateArgs = CTSD->getTemplateArgs().asArray();
1197 PrimaryTemplate = CTSD->getSpecializedTemplate();
1198 if (isTULocal(PrimaryTemplate))
1200 }
else if (
auto *VTSD = dyn_cast<VarTemplateSpecializationDecl>(D)) {
1201 TemplateArgs = VTSD->getTemplateArgs().asArray();
1202 PrimaryTemplate = VTSD->getSpecializedTemplate();
1203 if (isTULocal(PrimaryTemplate))
1205 }
else if (
auto *FD = dyn_cast<FunctionDecl>(D)) {
1206 if (
auto *TAList = FD->getTemplateSpecializationArgs())
1207 TemplateArgs = TAList->asArray();
1209 PrimaryTemplate = FD->getPrimaryTemplate();
1210 if (isTULocal(PrimaryTemplate))
1214 if (!PrimaryTemplate)
1218 if (KnownNonExposureSet.count(D))
1221 for (
auto &TA : TemplateArgs) {
1222 switch (TA.getKind()) {
1224 if (isTULocal(TA.getAsType()))
1228 if (isTULocal(TA.getAsDecl()))
1237 if (CheckingDecls.count(D))
1239 CheckingDecls.insert(D);
1240 llvm::scope_exit RemoveCheckingDecls([&] { CheckingDecls.erase(D); });
1245 if (ExposureSet.count(PrimaryTemplate) ||
1246 checkExposure(PrimaryTemplate,
false))
1250 KnownNonExposureSet.insert(D);
1254bool ExposureChecker::isTULocal(
const Expr *E) {
1272 if (
const auto *DRE = dyn_cast<DeclRefExpr>(E)) {
1273 if (
auto *FD = dyn_cast_or_null<FunctionDecl>(DRE->getFoundDecl()))
1274 return isTULocal(FD);
1275 else if (
auto *VD = dyn_cast_or_null<VarDecl>(DRE->getFoundDecl()))
1276 return isTULocal(VD);
1277 else if (
auto *RD = dyn_cast_or_null<CXXRecordDecl>(DRE->getFoundDecl()))
1278 return isTULocal(RD);
1288bool ExposureChecker::isExposureCandidate(
const NamedDecl *D) {
1304 assert(M &&
"Implicit global module must have a parent");
1325bool ExposureChecker::checkExposure(
const NamedDecl *D,
bool Diag) {
1326 if (!isExposureCandidate(D))
1329 if (
auto *FD = dyn_cast<FunctionDecl>(D))
1330 return checkExposure(FD,
Diag);
1331 if (
auto *FTD = dyn_cast<FunctionTemplateDecl>(D))
1332 return checkExposure(FTD->getTemplatedDecl(),
Diag);
1334 if (
auto *VD = dyn_cast<VarDecl>(D))
1335 return checkExposure(VD,
Diag);
1336 if (
auto *VTD = dyn_cast<VarTemplateDecl>(D))
1337 return checkExposure(VTD->getTemplatedDecl(),
Diag);
1339 if (
auto *RD = dyn_cast<CXXRecordDecl>(D))
1340 return checkExposure(RD,
Diag);
1342 if (
auto *CTD = dyn_cast<ClassTemplateDecl>(D))
1343 return checkExposure(CTD->getTemplatedDecl(),
Diag);
1349 bool IsExposure =
false;
1354 diag::warn_exposure)
1359 if (isTULocal(Parms->getType())) {
1362 SemaRef.Diag(Parms->getLocation(), diag::warn_exposure)
1363 << Parms->getType();
1366 bool IsImplicitInstantiation =
1382 ExposureSet.insert(FD);
1387bool ExposureChecker::checkExposure(
const VarDecl *VD,
bool Diag) {
1388 bool IsExposure =
false;
1402 if (isTULocal(VD->
getType())) {
1419 ExposureSet.insert(VD);
1428 bool IsExposure =
false;
1433 if (isTULocal(FD->
getType())) {
1441 if (isTULocal(
Base.getType())) {
1444 SemaRef.Diag(
Base.getBaseTypeLoc(), diag::warn_exposure)
1450 ExposureSet.insert(RD);
1457 using CallbackTy =
std::function<void(SourceLocation, NamedDecl *)>;
1459 ReferenceTULocalChecker(ExposureChecker &
C, CallbackTy &&
Callback)
1462 bool VisitDeclRefExpr(DeclRefExpr *DRE)
override {
1463 ValueDecl *Referenced = DRE->
getDecl();
1467 if (!Checker.isTULocal(Referenced))
1487 if (DRE->
isNonOdrUse() && (L == Linkage::Internal || L == Linkage::None))
1488 if (
auto *VD = dyn_cast<VarDecl>(Referenced);
1497 bool VisitTagTypeLoc(TagTypeLoc TL)
override {
1498 TagDecl *Referenced = TL.
getDecl();
1499 if (Checker.isTULocal(Referenced))
1504 ExposureChecker &Checker;
1508bool ExposureChecker::checkExposure(
const Stmt *S,
bool Diag) {
1512 bool HasReferencedTULocals =
false;
1513 ReferenceTULocalChecker Checker(
1517 SemaRef.Diag(Loc, diag::warn_exposure) << Referenced;
1519 HasReferencedTULocals =
true;
1521 Checker.TraverseStmt(
const_cast<Stmt *
>(S));
1522 return HasReferencedTULocals;
1525void ExposureChecker::checkExposureInContext(
const DeclContext *DC) {
1527 if (
auto *Export = dyn_cast<ExportDecl>(TopD)) {
1528 checkExposureInContext(Export);
1532 if (
auto *LinkageSpec = dyn_cast<LinkageSpecDecl>(TopD)) {
1533 checkExposureInContext(LinkageSpec);
1537 auto *TopND = dyn_cast<NamedDecl>(TopD);
1541 if (
auto *Namespace = dyn_cast<NamespaceDecl>(TopND)) {
1542 checkExposureInContext(Namespace);
1551 if (!TopND->isFromASTFile() && isExposureCandidate(TopND) &&
1553 checkExposure(TopND,
true);
1563 ExposureChecker Checker(*
this);
1567 Checker.checkExposureInContext(TU);
1573 for (
auto FDAndInstantiationLocPair : PendingCheckReferenceForTULocal) {
1574 FunctionDecl *FD = FDAndInstantiationLocPair.first;
1575 SourceLocation PointOfInstantiation = FDAndInstantiationLocPair.second;
1580 const FunctionDecl *BodyOwner = FD;
1583 if (!BodyOwner || !BodyOwner->
hasBody())
1586 ReferenceTULocalChecker(Checker, [&,
this](SourceLocation,
1587 NamedDecl *Referenced) {
1608 Diag(PointOfInstantiation,
1609 diag::warn_reference_tu_local_entity_in_other_tu)
1612 }).TraverseStmt(BodyOwner->
getBody());
1616void Sema::checkReferenceToTULocalFromOtherTU(
1620 if (!FD || !HadImportedNamedModules)
1623 PendingCheckReferenceForTULocal.push_back(
1624 std::make_pair(FD, PointOfInstantiation));
1637 if (PrevOffset != NewOffset)
1641 if (*PrevFileRef != *NewFileRef)
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 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.
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=false, const Expr **Culprit=nullptr) const
Returns true if this expression can be emitted to IR as a constant, and thus can be used as a constan...
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
FunctionDecl * getTemplateInstantiationPattern(bool ForDefinition=true) const
Retrieve the function declaration from which this function could be instantiated, if it is an instant...
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.
bool isValid() const
Whether this pointer is non-NULL.
Identifies a module file to be loaded.
virtual ModuleLoadResult loadModule(SourceLocation ImportLoc, ModuleIdPath Path, Module::NameVisibilityKind Visibility, bool IsInclusionDirective)=0
Attempt to load the given module.
static std::string getFlatNameFromPath(ModuleIdPath Path)
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.
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?
llvm::SmallVector< ModuleRef, 2 > Imports
The set of modules imported by this module, and on which this module depends.
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.
bool isFromSameSingleIncludeHeader(const Decl *PrevD, SourceLocation NewLoc)
Determine if a definition at NewLoc coincides with PrevD.
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;'
Preprocessor & getPreprocessor() const
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
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.
This class handles loading and caching of source files into memory.
FileIDAndOffset getDecomposedExpansionLoc(SourceLocation Loc) const
Decompose the specified location into a raw FileID + Offset pair.
FileID getFileID(SourceLocation SpellingLoc) const
Return the FileID for a SourceLocation.
OptionalFileEntryRef getFileEntryRefForID(FileID FID) const
Returns the FileEntryRef for the provided FileID.
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.
TagDecl * getDecl() const
SourceLocation getNameLoc() const
@ 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.
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.
Top level wrappers for InstallAPI frontend operations.
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