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)
397 Mod = Map.createModuleForInterfaceUnit(ModuleLoc, ModuleName);
400 assert(Mod &&
"module creation should not fail");
410 PP.getIdentifierInfo(ModuleName));
423 Diag(ModuleLoc, diag::err_module_not_defined) << ModuleName;
425 Mod = Map.createModuleForInterfaceUnit(ModuleLoc, ModuleName);
427 Mod = Map.createModuleForImplementationUnit(ModuleLoc, ModuleName);
434 Mod = Map.createModuleForInterfaceUnit(ModuleLoc, ModuleName);
439 if (!this->TheGlobalModuleFragment) {
440 ModuleScopes.push_back({});
442 ModuleScopes.back().OuterVisibleModules = std::move(VisibleModules);
449 ModuleScopes.back().BeginLoc = StartLoc;
450 ModuleScopes.back().Module = Mod;
451 VisibleModules.setVisible(Mod, ModuleLoc);
458 auto *TU =
Context.getTranslationUnitDecl();
460 TU->setLocalOwningModule(Mod);
472 HadImportedNamedModules =
true;
485 Context.addModuleInitializer(ModuleScopes.back().Module, Import);
504 : ModuleScopes.back().Module->Kind) {
511 Diag(PrivateLoc, diag::err_private_module_fragment_not_module);
515 Diag(PrivateLoc, diag::err_private_module_fragment_redefined);
516 Diag(ModuleScopes.back().BeginLoc, diag::note_previous_definition);
520 Diag(PrivateLoc, diag::err_private_module_fragment_not_module_interface);
521 Diag(ModuleScopes.back().BeginLoc,
522 diag::note_not_module_interface_add_export)
537 auto &Map =
PP.getHeaderSearchInfo().getModuleMap();
538 Module *PrivateModuleFragment =
539 Map.createPrivateModuleFragmentForInterfaceUnit(
540 ModuleScopes.back().Module, PrivateLoc);
541 assert(PrivateModuleFragment &&
"module creation should not fail");
544 ModuleScopes.push_back({});
545 ModuleScopes.back().BeginLoc = ModuleLoc;
546 ModuleScopes.back().Module = PrivateModuleFragment;
547 VisibleModules.setVisible(PrivateModuleFragment, ModuleLoc);
552 auto *TU =
Context.getTranslationUnitDecl();
554 TU->setLocalOwningModule(PrivateModuleFragment);
564 assert((!IsPartition ||
getLangOpts().CPlusPlusModules) &&
565 "partition seen in non-C++20 code?");
571 std::string ModuleName;
574 assert(!ModuleScopes.empty() &&
"in a module purview, but no module?");
598 if (
getLangOpts().CPlusPlusModules && isCurrentModulePurview() &&
600 Diag(ImportLoc, diag::err_module_self_import_cxx20)
612 Diag(ImportLoc, diag::err_module_import_non_interface_nor_parition)
623 if (
auto *ED = dyn_cast<ExportDecl>(DC))
633 Diag(ImportLoc, diag::warn_experimental_header_unit);
639 VisibleModules.setVisible(Mod, ImportLoc);
642 "We can only import a partition unit in a named module.");
646 diag::warn_import_implementation_partition_unit_in_interface_unit)
657 ? diag::err_module_self_import
658 : diag::err_module_import_in_implementation)
668 for (
Module *ModCheck = Mod; ModCheck; ModCheck = ModCheck->
Parent)
672 IdentifierLocs.push_back(Path[0].getLoc());
675 for (
unsigned I = 0, N = Path.size(); I != N; ++I) {
680 ModCheck = ModCheck->
Parent;
682 IdentifierLocs.push_back(Path[I].getLoc());
687 Mod, IdentifierLocs);
692 if (!ModuleScopes.empty())
693 Context.addModuleInitializer(ModuleScopes.back().Module, Import);
698 Diag(ExportLoc, diag::err_export_partition_impl)
700 }
else if (ExportLoc.
isValid() &&
705 Diag(ExportLoc, diag::err_export_not_in_module_interface);
706 }
else if (!ModuleScopes.empty()) {
716 HadImportedNamedModules =
true;
732 bool IsInModuleIncludes =
738 if (
getLangOpts().Modules && !IsInModuleIncludes) {
743 if (!ModuleScopes.empty())
744 Context.addModuleInitializer(ModuleScopes.back().Module, ImportD);
746 Consumer.HandleImplicitImportDecl(ImportD);
750 VisibleModules.setVisible(Mod, DirectiveLoc);
753 Module *ThisModule =
PP.getHeaderSearchInfo().lookupModule(
754 getLangOpts().CurrentModule, DirectiveLoc,
false,
false);
761 "was expecting a module if building a Clang module");
768 ModuleScopes.push_back({});
769 ModuleScopes.back().Module = Mod;
771 ModuleScopes.back().OuterVisibleModules = std::move(VisibleModules);
773 VisibleModules.setVisible(Mod, DirectiveLoc);
779 for (
auto *DC =
CurContext; DC; DC = DC->getLexicalParent()) {
791 VisibleModules = std::move(ModuleScopes.back().OuterVisibleModules);
797 assert(!ModuleScopes.empty() && ModuleScopes.back().Module == Mod &&
798 "left the wrong module scope");
799 ModuleScopes.pop_back();
808 "end of submodule in main source file");
812 DirectiveLoc = EomLoc;
820 for (
auto *DC =
CurContext; DC; DC = DC->getLexicalParent()) {
833 VisibleModules.isVisible(Mod))
841 Consumer.HandleImplicitImportDecl(ImportD);
845 VisibleModules.setVisible(Mod, Loc);
863 if (!isCurrentModulePurview()) {
864 Diag(ExportLoc, diag::err_export_not_in_module_interface) << 0;
868 Diag(ExportLoc, diag::err_export_not_in_module_interface) << 1;
869 Diag(ModuleScopes.back().BeginLoc,
870 diag::note_not_module_interface_add_export)
874 }
else if (ModuleScopes.back().Module->Kind ==
876 Diag(ExportLoc, diag::err_export_in_private_module_fragment);
877 Diag(ModuleScopes.back().BeginLoc, diag::note_private_module_fragment);
884 if (
const auto *ND = dyn_cast<NamespaceDecl>(DC)) {
887 if (ND->isAnonymousNamespace()) {
888 Diag(ExportLoc, diag::err_export_within_anonymous_namespace);
889 Diag(ND->getLocation(), diag::note_anonymous_namespace);
900 if (!
getLangOpts().
HLSL && !DeferredExportedNamespaces.insert(ND).second)
908 Diag(ExportLoc, diag::err_export_within_export);
910 Diag(ED->getLocation(), diag::note_export);
926 bool AllUnnamed =
true;
927 for (
auto *D : DC->
decls())
947 if (PVD->hasAttr<HLSLGroupSharedAddressSpaceAttr>()) {
949 <<
"'export'" <<
"'groupshared' parameter";
959 bool HasName =
false;
960 if (
auto *ND = dyn_cast<NamedDecl>(D)) {
963 HasName = (
bool)ND->getDeclName();
965 S.
Diag(ND->getLocation(), diag::err_export_internal) << ND;
967 S.
Diag(BlockStart, diag::note_export);
975 if (
auto *USD = dyn_cast<UsingShadowDecl>(D)) {
979 S.
Diag(USD->getLocation(), diag::err_export_using_internal)
981 S.
Diag(
Target->getLocation(), diag::note_using_decl_target);
983 S.
Diag(BlockStart, diag::note_export);
990 if (
auto *DC = dyn_cast<DeclContext>(D)) {
994 if (
auto *ND = dyn_cast<NamedDecl>(D)) {
995 if (!ND->getDeclName()) {
996 S.
Diag(ND->getLocation(), diag::err_export_anon_ns_internal);
998 S.
Diag(BlockStart, diag::note_export);
1000 }
else if (!DC->decls().empty() &&
1001 DC->getRedeclContext()->isFileContext()) {
1012 ED->setRBraceLoc(RBraceLoc);
1019 for (
auto *Child : ED->decls()) {
1021 if (
auto *FD = dyn_cast<FunctionDecl>(Child)) {
1029 if (FD->isInlineSpecified() && !FD->isDefined())
1030 PendingInlineFuncDecls.insert(FD);
1036 for (
auto *Exported : ED->decls())
1045 if (!TheGlobalModuleFragment) {
1051 assert(TheGlobalModuleFragment &&
"module creation should not fail");
1054 ModuleScopes.push_back({BeginLoc, TheGlobalModuleFragment,
1056 VisibleModules.setVisible(TheGlobalModuleFragment, BeginLoc);
1058 return TheGlobalModuleFragment;
1061void Sema::PopGlobalModuleFragment() {
1062 assert(!ModuleScopes.empty() &&
1064 "left the wrong module scope, which is not global module fragment");
1065 ModuleScopes.pop_back();
1069 if (!TheImplicitGlobalModuleFragment) {
1070 ModuleMap &Map =
PP.getHeaderSearchInfo().getModuleMap();
1071 TheImplicitGlobalModuleFragment =
1075 assert(TheImplicitGlobalModuleFragment &&
"module creation should not fail");
1078 ModuleScopes.push_back({BeginLoc, TheImplicitGlobalModuleFragment,
1080 VisibleModules.setVisible(TheImplicitGlobalModuleFragment, BeginLoc);
1081 return TheImplicitGlobalModuleFragment;
1084void Sema::PopImplicitGlobalModuleFragment() {
1085 assert(!ModuleScopes.empty() &&
1087 "left the wrong module scope, which is not global module fragment");
1088 ModuleScopes.pop_back();
1091bool Sema::isCurrentModulePurview()
const {
1115class ExposureChecker {
1117 ExposureChecker(Sema &S) : SemaRef(S) {}
1119 bool checkExposure(
const VarDecl *D,
bool Diag);
1120 bool checkExposure(
const CXXRecordDecl *D,
bool Diag);
1121 bool checkExposure(
const Stmt *S,
bool Diag);
1122 bool checkExposure(
const FunctionDecl *D,
bool Diag);
1123 bool checkExposure(
const NamedDecl *D,
bool Diag);
1124 void checkExposureInContext(
const DeclContext *DC);
1125 bool isExposureCandidate(
const NamedDecl *D);
1127 bool isTULocal(QualType Ty);
1128 bool isTULocal(
const NamedDecl *ND);
1129 bool isTULocal(
const Expr *E);
1134 llvm::DenseSet<const NamedDecl *> ExposureSet;
1135 llvm::DenseSet<const NamedDecl *> KnownNonExposureSet;
1136 llvm::DenseSet<const NamedDecl *> CheckingDecls;
1139bool ExposureChecker::isTULocal(
QualType Ty) {
1154bool ExposureChecker::isTULocal(
const NamedDecl *D) {
1174 ND && isTULocal(ND))
1182 if (
auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
1183 TemplateArgs = CTSD->getTemplateArgs().asArray();
1184 PrimaryTemplate = CTSD->getSpecializedTemplate();
1185 if (isTULocal(PrimaryTemplate))
1187 }
else if (
auto *VTSD = dyn_cast<VarTemplateSpecializationDecl>(D)) {
1188 TemplateArgs = VTSD->getTemplateArgs().asArray();
1189 PrimaryTemplate = VTSD->getSpecializedTemplate();
1190 if (isTULocal(PrimaryTemplate))
1192 }
else if (
auto *FD = dyn_cast<FunctionDecl>(D)) {
1193 if (
auto *TAList = FD->getTemplateSpecializationArgs())
1194 TemplateArgs = TAList->asArray();
1196 PrimaryTemplate = FD->getPrimaryTemplate();
1197 if (isTULocal(PrimaryTemplate))
1201 if (!PrimaryTemplate)
1205 if (KnownNonExposureSet.count(D))
1208 for (
auto &TA : TemplateArgs) {
1209 switch (TA.getKind()) {
1211 if (isTULocal(TA.getAsType()))
1215 if (isTULocal(TA.getAsDecl()))
1224 if (CheckingDecls.count(D))
1226 CheckingDecls.insert(D);
1227 llvm::scope_exit RemoveCheckingDecls([&] { CheckingDecls.erase(D); });
1232 if (ExposureSet.count(PrimaryTemplate) ||
1233 checkExposure(PrimaryTemplate,
false))
1237 KnownNonExposureSet.insert(D);
1241bool ExposureChecker::isTULocal(
const Expr *E) {
1259 if (
const auto *DRE = dyn_cast<DeclRefExpr>(E)) {
1260 if (
auto *FD = dyn_cast_or_null<FunctionDecl>(DRE->getFoundDecl()))
1261 return isTULocal(FD);
1262 else if (
auto *VD = dyn_cast_or_null<VarDecl>(DRE->getFoundDecl()))
1263 return isTULocal(VD);
1264 else if (
auto *RD = dyn_cast_or_null<CXXRecordDecl>(DRE->getFoundDecl()))
1265 return isTULocal(RD);
1275bool ExposureChecker::isExposureCandidate(
const NamedDecl *D) {
1291 assert(M &&
"Implicit global module must have a parent");
1312bool ExposureChecker::checkExposure(
const NamedDecl *D,
bool Diag) {
1313 if (!isExposureCandidate(D))
1316 if (
auto *FD = dyn_cast<FunctionDecl>(D))
1317 return checkExposure(FD,
Diag);
1318 if (
auto *FTD = dyn_cast<FunctionTemplateDecl>(D))
1319 return checkExposure(FTD->getTemplatedDecl(),
Diag);
1321 if (
auto *VD = dyn_cast<VarDecl>(D))
1322 return checkExposure(VD,
Diag);
1323 if (
auto *VTD = dyn_cast<VarTemplateDecl>(D))
1324 return checkExposure(VTD->getTemplatedDecl(),
Diag);
1326 if (
auto *RD = dyn_cast<CXXRecordDecl>(D))
1327 return checkExposure(RD,
Diag);
1329 if (
auto *CTD = dyn_cast<ClassTemplateDecl>(D))
1330 return checkExposure(CTD->getTemplatedDecl(),
Diag);
1336 bool IsExposure =
false;
1341 diag::warn_exposure)
1346 if (isTULocal(Parms->getType())) {
1349 SemaRef.Diag(Parms->getLocation(), diag::warn_exposure)
1350 << Parms->getType();
1353 bool IsImplicitInstantiation =
1369 ExposureSet.insert(FD);
1374bool ExposureChecker::checkExposure(
const VarDecl *VD,
bool Diag) {
1375 bool IsExposure =
false;
1389 if (isTULocal(VD->
getType())) {
1406 ExposureSet.insert(VD);
1415 bool IsExposure =
false;
1420 if (isTULocal(FD->
getType())) {
1428 if (isTULocal(
Base.getType())) {
1431 SemaRef.Diag(
Base.getBaseTypeLoc(), diag::warn_exposure)
1437 ExposureSet.insert(RD);
1444 using CallbackTy =
std::function<void(DeclRefExpr *, ValueDecl *)>;
1446 ReferenceTULocalChecker(ExposureChecker &
C, CallbackTy &&Callback)
1447 : Checker(
C), Callback(std::move(Callback)) {}
1449 bool VisitDeclRefExpr(DeclRefExpr *DRE)
override {
1450 ValueDecl *Referenced = DRE->
getDecl();
1454 if (!Checker.isTULocal(Referenced))
1474 if (DRE->
isNonOdrUse() && (L == Linkage::Internal || L == Linkage::None))
1475 if (
auto *VD = dyn_cast<VarDecl>(Referenced);
1480 Callback(DRE, Referenced);
1484 ExposureChecker &Checker;
1485 CallbackTy Callback;
1488bool ExposureChecker::checkExposure(
const Stmt *S,
bool Diag) {
1492 bool HasReferencedTULocals =
false;
1493 ReferenceTULocalChecker Checker(
1497 SemaRef.Diag(DRE->
getExprLoc(), diag::warn_exposure) << Referenced;
1499 HasReferencedTULocals =
true;
1501 Checker.TraverseStmt(
const_cast<Stmt *
>(S));
1502 return HasReferencedTULocals;
1505void ExposureChecker::checkExposureInContext(
const DeclContext *DC) {
1507 if (
auto *Export = dyn_cast<ExportDecl>(TopD)) {
1508 checkExposureInContext(Export);
1512 if (
auto *LinkageSpec = dyn_cast<LinkageSpecDecl>(TopD)) {
1513 checkExposureInContext(LinkageSpec);
1517 auto *TopND = dyn_cast<NamedDecl>(TopD);
1521 if (
auto *Namespace = dyn_cast<NamespaceDecl>(TopND)) {
1522 checkExposureInContext(Namespace);
1531 if (!TopND->isFromASTFile() && isExposureCandidate(TopND) &&
1533 checkExposure(TopND,
true);
1543 ExposureChecker Checker(*
this);
1547 Checker.checkExposureInContext(TU);
1553 for (
auto FDAndInstantiationLocPair : PendingCheckReferenceForTULocal) {
1554 FunctionDecl *FD = FDAndInstantiationLocPair.first;
1555 SourceLocation PointOfInstantiation = FDAndInstantiationLocPair.second;
1560 ReferenceTULocalChecker(Checker, [&,
this](DeclRefExpr *DRE,
1561 ValueDecl *Referenced) {
1582 Diag(PointOfInstantiation,
1583 diag::warn_reference_tu_local_entity_in_other_tu)
1586 }).TraverseStmt(FD->
getBody());
1590void Sema::checkReferenceToTULocalFromOtherTU(
1594 if (!FD || !HadImportedNamedModules)
1597 PendingCheckReferenceForTULocal.push_back(
1598 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 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.
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.
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
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)
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