aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/AST/Decl.cpp
diff options
context:
space:
mode:
authorCorentin Jabot <corentinjabot@gmail.com>2023-06-22 14:18:38 +0200
committerCorentin Jabot <corentinjabot@gmail.com>2023-08-04 16:51:15 +0200
commita8bef8865e4a4226ee608df327fddd380870c620 (patch)
tree837eee1377d6363b5d8b07091b147e586c906a60 /clang/lib/AST/Decl.cpp
parent1e92e25cb4a96d4997028632bb577c1698694891 (diff)
downloadllvm-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.cpp36
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();