diff options
author | Corentin Jabot <corentinjabot@gmail.com> | 2023-06-22 14:18:38 +0200 |
---|---|---|
committer | Corentin Jabot <corentinjabot@gmail.com> | 2023-08-04 16:51:15 +0200 |
commit | a8bef8865e4a4226ee608df327fddd380870c620 (patch) | |
tree | 837eee1377d6363b5d8b07091b147e586c906a60 /clang/lib/AST/Decl.cpp | |
parent | 1e92e25cb4a96d4997028632bb577c1698694891 (diff) | |
download | llvm-a8bef8865e4a4226ee608df327fddd380870c620.zip llvm-a8bef8865e4a4226ee608df327fddd380870c620.tar.gz llvm-a8bef8865e4a4226ee608df327fddd380870c620.tar.bz2 |
[Clang] Implement P2169 A nice placeholder with no name
This is a C++ feature that allows the use of `_` to
declare multiple variable of that name in the same scope;
these variables can then not be referred to.
In addition, while P2169 does not extend to parameter
declarations, we stop warning on unused parameters of that name,
for consistency.
The feature is backported to all C++ language modes.
Reviewed By: #clang-language-wg, aaron.ballman
Differential Revision: https://reviews.llvm.org/D153536
Diffstat (limited to 'clang/lib/AST/Decl.cpp')
-rw-r--r-- | clang/lib/AST/Decl.cpp | 36 |
1 files changed, 36 insertions, 0 deletions
diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp index fbc45fb..7971a03 100644 --- a/clang/lib/AST/Decl.cpp +++ b/clang/lib/AST/Decl.cpp @@ -1096,6 +1096,42 @@ bool NamedDecl::isLinkageValid() const { return L == getCachedLinkage(); } +bool NamedDecl::isPlaceholderVar(const LangOptions &LangOpts) const { + // [C++2c] [basic.scope.scope]/p5 + // A declaration is name-independent if its name is _ and it declares + // - a variable with automatic storage duration, + // - a structured binding not inhabiting a namespace scope, + // - the variable introduced by an init-capture + // - or a non-static data member. + + if (!LangOpts.CPlusPlus || !getIdentifier() || + !getIdentifier()->isPlaceholder()) + return false; + if (isa<FieldDecl>(this)) + return true; + if (auto *IFD = dyn_cast<IndirectFieldDecl>(this)) { + if (!getDeclContext()->isFunctionOrMethod() && + !getDeclContext()->isRecord()) + return false; + VarDecl *VD = IFD->getVarDecl(); + return !VD || VD->getStorageDuration() == SD_Automatic; + } + // and it declares a variable with automatic storage duration + if (const auto *VD = dyn_cast<VarDecl>(this)) { + if (isa<ParmVarDecl>(VD)) + return false; + if (VD->isInitCapture()) + return true; + return VD->getStorageDuration() == StorageDuration::SD_Automatic; + } + if (const auto *BD = dyn_cast<BindingDecl>(this); + BD && getDeclContext()->isFunctionOrMethod()) { + VarDecl *VD = BD->getHoldingVar(); + return !VD || VD->getStorageDuration() == StorageDuration::SD_Automatic; + } + return false; +} + ReservedIdentifierStatus NamedDecl::isReserved(const LangOptions &LangOpts) const { const IdentifierInfo *II = getIdentifier(); |