diff options
author | Alex Lorenz <arphaman@gmail.com> | 2016-11-09 10:38:57 +0000 |
---|---|---|
committer | Alex Lorenz <arphaman@gmail.com> | 2016-11-09 10:38:57 +0000 |
commit | 175388c00d0a39838a6d61c54ca6256b34e37dab (patch) | |
tree | 1579faf5c73e50ec8754bd18ae3e44c1d25925f5 /clang/lib/Sema/SemaDecl.cpp | |
parent | 8339bbd75929ad2d28b4a5a8777bf34f783cc131 (diff) | |
download | bcm5719-llvm-175388c00d0a39838a6d61c54ca6256b34e37dab.tar.gz bcm5719-llvm-175388c00d0a39838a6d61c54ca6256b34e37dab.zip |
[Sema] Avoid -Wshadow warnings for shadowed variables that aren't captured
by lambdas with an explicit capture list
This commit avoids the -Wshadow warning for variables which shadow variables
that aren't captured by lambdas with an explicit capture list. It provides an
additional note that points to location of the explicit capture.
The old behaviour is preserved with -Wshadow-all or -Wshadow-uncaptured-local.
rdar://17135966
Differential Revision: https://reviews.llvm.org/D26278
llvm-svn: 286354
Diffstat (limited to 'clang/lib/Sema/SemaDecl.cpp')
-rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 31 |
1 files changed, 30 insertions, 1 deletions
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index e20ae1a0151..1859b7f0116 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -6582,6 +6582,17 @@ static ShadowedDeclKind computeShadowedDeclKind(const NamedDecl *ShadowedDecl, return OldDC->isFileContext() ? SDK_Global : SDK_Local; } +/// Return the location of the capture if the given lambda captures the given +/// variable \p VD, or an invalid source location otherwise. +static SourceLocation getCaptureLocation(const LambdaScopeInfo *LSI, + const VarDecl *VD) { + for (const LambdaScopeInfo::Capture &Capture : LSI->Captures) { + if (Capture.isVariableCapture() && Capture.getVariable() == VD) + return Capture.getLocation(); + } + return SourceLocation(); +} + /// \brief Diagnose variable or built-in function shadowing. Implements /// -Wshadow. /// @@ -6640,6 +6651,22 @@ void Sema::CheckShadow(Scope *S, VarDecl *D, const LookupResult& R) { DeclContext *OldDC = ShadowedDecl->getDeclContext(); + unsigned WarningDiag = diag::warn_decl_shadow; + SourceLocation CaptureLoc; + if (isa<VarDecl>(ShadowedDecl) && NewDC && isa<CXXMethodDecl>(NewDC)) { + if (const auto *RD = dyn_cast<CXXRecordDecl>(NewDC->getParent())) { + // Try to avoid warnings for lambdas with an explicit capture list. + if (RD->isLambda() && OldDC->Encloses(NewDC->getLexicalParent()) && + RD->getLambdaCaptureDefault() == LCD_None) { + const auto *LSI = cast<LambdaScopeInfo>(getCurFunction()); + // Warn only when the lambda captures the shadowed decl explicitly. + CaptureLoc = getCaptureLocation(LSI, cast<VarDecl>(ShadowedDecl)); + if (CaptureLoc.isInvalid()) + WarningDiag = diag::warn_decl_shadow_uncaptured_local; + } + } + } + // Only warn about certain kinds of shadowing for class members. if (NewDC && NewDC->isRecord()) { // In particular, don't warn about shadowing non-class members. @@ -6661,7 +6688,9 @@ void Sema::CheckShadow(Scope *S, VarDecl *D, const LookupResult& R) { if (getSourceManager().isInSystemMacro(R.getNameLoc())) return; ShadowedDeclKind Kind = computeShadowedDeclKind(ShadowedDecl, OldDC); - Diag(R.getNameLoc(), diag::warn_decl_shadow) << Name << Kind << OldDC; + Diag(R.getNameLoc(), WarningDiag) << Name << Kind << OldDC; + if (!CaptureLoc.isInvalid()) + Diag(CaptureLoc, diag::note_var_explicitly_captured_here) << Name; Diag(ShadowedDecl->getLocation(), diag::note_previous_declaration); } |