aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Sema/Sema.cpp
diff options
context:
space:
mode:
authorIain Sandoe <iain@sandoe.co.uk>2022-06-22 09:15:53 +0100
committerIain Sandoe <iain@sandoe.co.uk>2022-08-21 10:19:46 +0100
commitfee3cccc6cdabdeddc688cf7a15b144c814dd93d (patch)
tree1f47837db92f41cfe58b77b7cc56d76f59dfc96a /clang/lib/Sema/Sema.cpp
parent9a764ffeb6f06a87c7ad482ae39f8a38b3160c5e (diff)
downloadllvm-fee3cccc6cdabdeddc688cf7a15b144c814dd93d.zip
llvm-fee3cccc6cdabdeddc688cf7a15b144c814dd93d.tar.gz
llvm-fee3cccc6cdabdeddc688cf7a15b144c814dd93d.tar.bz2
[C++20][Modules] Improve handing of Private Module Fragment diagnostics.
This adds a check for exported inline functions, that there is a definition in the definition domain (which, in practice, can only be the module purview but before any PMF starts) since the PMF definition domain cannot contain exports. This is: [dcl.inline]/7 If an inline function or variable that is attached to a named module is declared in a definition domain, it shall be defined in that domain. The patch also amends diagnostic output by excluding the PMF sub-module from the set considered as sources of missing decls. There is no point in telling the user that the import of a PMF object is missing - since such objects are never reachable to an importer. We still show the definition (as unreachable), to help point out this. Differential Revision: https://reviews.llvm.org/D128328
Diffstat (limited to 'clang/lib/Sema/Sema.cpp')
-rw-r--r--clang/lib/Sema/Sema.cpp27
1 files changed, 27 insertions, 0 deletions
diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp
index 1d27f74..0410032 100644
--- a/clang/lib/Sema/Sema.cpp
+++ b/clang/lib/Sema/Sema.cpp
@@ -1251,6 +1251,33 @@ void Sema::ActOnEndOfTranslationUnit() {
emitAndClearUnusedLocalTypedefWarnings();
}
+ // C++ standard modules. Diagnose cases where a function is declared inline
+ // in the module purview but has no definition before the end of the TU or
+ // the start of a Private Module Fragment (if one is present).
+ if (!PendingInlineFuncDecls.empty()) {
+ for (auto *D : PendingInlineFuncDecls) {
+ if (auto *FD = dyn_cast<FunctionDecl>(D)) {
+ bool DefInPMF = false;
+ if (auto *FDD = FD->getDefinition()) {
+ assert(FDD->getOwningModule() &&
+ FDD->getOwningModule()->isModulePurview());
+ DefInPMF = FDD->getOwningModule()->isPrivateModule();
+ if (!DefInPMF)
+ continue;
+ }
+ Diag(FD->getLocation(), diag::err_export_inline_not_defined)
+ << DefInPMF;
+ // If we have a PMF it should be at the end of the ModuleScopes.
+ if (DefInPMF &&
+ ModuleScopes.back().Module->Kind == Module::PrivateModuleFragment) {
+ Diag(ModuleScopes.back().BeginLoc,
+ diag::note_private_module_fragment);
+ }
+ }
+ }
+ PendingInlineFuncDecls.clear();
+ }
+
// C99 6.9.2p2:
// A declaration of an identifier for an object that has file
// scope without an initializer, and without a storage-class