Skip to content

Commit 7bc878e

Browse files
committed
fixup! narrow heuristic for ignoring CallExpr
1 parent f61bde6 commit 7bc878e

File tree

1 file changed

+35
-9
lines changed

1 file changed

+35
-9
lines changed

clang/lib/AST/Expr.cpp

Lines changed: 35 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2544,6 +2544,19 @@ Stmt *BlockExpr::getBody() {
25442544
//===----------------------------------------------------------------------===//
25452545
// Generic Expression Routines
25462546
//===----------------------------------------------------------------------===//
2547+
namespace {
2548+
/// Helper to determine wether \c E is a CXXConstructExpr constructing
2549+
/// a DecompositionDecl. Used to skip Clang-generated calls to std::get
2550+
/// for structured bindings.
2551+
bool IsDecompositionDeclRefExpr(const Expr *E) {
2552+
const Expr *Unrwapped = E->IgnoreUnlessSpelledInSource();
2553+
const DeclRefExpr *Ref = llvm::dyn_cast_or_null<DeclRefExpr>(Unrwapped);
2554+
if (!Ref)
2555+
return false;
2556+
2557+
return llvm::isa_and_nonnull<DecompositionDecl *>(Ref->getDecl());
2558+
}
2559+
} // namespace
25472560

25482561
bool Expr::isReadIfDiscardedInCPlusPlus11() const {
25492562
// In C++11, discarded-value expressions of a certain form are special,
@@ -3163,15 +3176,28 @@ Expr *Expr::IgnoreUnlessSpelledInSource() {
31633176
// Used when Clang generates calls to std::get for decomposing
31643177
// structured bindings.
31653178
auto IgnoreImplicitCallSingleStep = [](Expr *E) {
3166-
if (auto *C = dyn_cast<CallExpr>(E)) {
3167-
auto NumArgs = C->getNumArgs();
3168-
if (NumArgs == 1 ||
3169-
(NumArgs > 1 && isa<CXXDefaultArgExpr>(C->getArg(1)))) {
3170-
Expr *A = C->getArg(0);
3171-
if (A->getSourceRange() == E->getSourceRange())
3172-
return A;
3173-
}
3174-
}
3179+
auto *C = dyn_cast<CallExpr>(E);
3180+
if (!C)
3181+
return E;
3182+
3183+
// Looking for calls to a std::get, which usually just takes
3184+
// 1 argument (i.e., the structure being decomposed). If it has
3185+
// more than 1 argument, the others need to be defaulted.
3186+
unsigned NumArgs = C->getNumArgs();
3187+
if (NumArgs > 1 && !isa<CXXDefaultArgExpr>(C->getArg(1)))
3188+
return E;
3189+
3190+
Expr *A = C->getArg(0);
3191+
3192+
// This was spelled out in source. Don't ignore.
3193+
if (A->getSourceRange() != E->getSourceRange())
3194+
return E;
3195+
3196+
// If the argument refers to a DecompositionDecl construction,
3197+
// ignore it.
3198+
if (IsDecompositionDeclRefExpr(A))
3199+
return A;
3200+
31753201
return E;
31763202
};
31773203

0 commit comments

Comments
 (0)