diff options
author | Iain Sandoe <iain@sandoe.co.uk> | 2022-06-22 09:15:53 +0100 |
---|---|---|
committer | Iain Sandoe <iain@sandoe.co.uk> | 2022-08-21 10:19:46 +0100 |
commit | fee3cccc6cdabdeddc688cf7a15b144c814dd93d (patch) | |
tree | 1f47837db92f41cfe58b77b7cc56d76f59dfc96a /clang/lib/Sema/Sema.cpp | |
parent | 9a764ffeb6f06a87c7ad482ae39f8a38b3160c5e (diff) | |
download | llvm-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.cpp | 27 |
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 |