[PATCH] D28350: [Sema] Avoid -Wshadow warning when a "redefinition of " error is presented

2017-01-10 Thread Alex Lorenz via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL291564: [Sema] Avoid -Wshadow warning when a "redefinition 
of " error is presented (authored by arphaman).

Changed prior to commit:
  https://reviews.llvm.org/D28350?vs=83214=83806#toc

Repository:
  rL LLVM

https://reviews.llvm.org/D28350

Files:
  cfe/trunk/include/clang/Sema/Sema.h
  cfe/trunk/lib/Sema/SemaDecl.cpp
  cfe/trunk/test/SemaCXX/warn-shadow-in-lambdas.cpp
  cfe/trunk/test/SemaCXX/warn-shadow.cpp

Index: cfe/trunk/test/SemaCXX/warn-shadow.cpp
===
--- cfe/trunk/test/SemaCXX/warn-shadow.cpp
+++ cfe/trunk/test/SemaCXX/warn-shadow.cpp
@@ -97,3 +97,13 @@
 void test8() {
   int bob; // expected-warning {{declaration shadows a variable in the global namespace}}
 }
+
+namespace rdar29067894 {
+
+void avoidWarningWhenRedefining(int b) { // expected-note {{previous definition is here}}
+  int a = 0; // expected-note {{previous definition is here}}
+  int a = 1; // expected-error {{redefinition of 'a'}}
+  int b = 2; // expected-error {{redefinition of 'b'}}
+}
+
+}
Index: cfe/trunk/test/SemaCXX/warn-shadow-in-lambdas.cpp
===
--- cfe/trunk/test/SemaCXX/warn-shadow-in-lambdas.cpp
+++ cfe/trunk/test/SemaCXX/warn-shadow-in-lambdas.cpp
@@ -137,3 +137,11 @@
   auto g3 = [param] // expected-note {{variable 'param' is explicitly captured here}}
(auto param) { ; }; // expected-warning {{declaration shadows a local variable}}
 }
+
+void avoidWarningWhenRedefining() {
+  int a = 1;
+  auto l = [b = a] { // expected-note {{previous definition is here}}
+// Don't warn on redefinitions.
+int b = 0; // expected-error {{redefinition of 'b'}}
+  };
+}
Index: cfe/trunk/lib/Sema/SemaDecl.cpp
===
--- cfe/trunk/lib/Sema/SemaDecl.cpp
+++ cfe/trunk/lib/Sema/SemaDecl.cpp
@@ -6426,9 +6426,10 @@
 }
   }
 
-  // Diagnose shadowed variables before filtering for scope.
-  if (D.getCXXScopeSpec().isEmpty())
-CheckShadow(S, NewVD, Previous);
+  // Find the shadowed declaration before filtering for scope.
+  NamedDecl *ShadowedDecl = D.getCXXScopeSpec().isEmpty()
+? getShadowedDeclaration(NewVD, Previous)
+: nullptr;
 
   // Don't consider existing declarations that are in a different
   // scope and are out-of-semantic-context declarations (if the new
@@ -6523,6 +6524,10 @@
 }
   }
 
+  // Diagnose shadowed variables iff this isn't a redeclaration.
+  if (ShadowedDecl && !D.isRedeclaration())
+CheckShadow(NewVD, ShadowedDecl, Previous);
+
   ProcessPragmaWeak(S, NewVD);
 
   // If this is the first declaration of an extern C variable, update
@@ -6596,33 +6601,40 @@
   return SourceLocation();
 }
 
-/// \brief Diagnose variable or built-in function shadowing.  Implements
-/// -Wshadow.
-///
-/// This method is called whenever a VarDecl is added to a "useful"
-/// scope.
-///
-/// \param S the scope in which the shadowing name is being declared
-/// \param R the lookup of the name
-///
-void Sema::CheckShadow(Scope *S, VarDecl *D, const LookupResult& R) {
+/// \brief Return the declaration shadowed by the given variable \p D, or null
+/// if it doesn't shadow any declaration or shadowing warnings are disabled.
+NamedDecl *Sema::getShadowedDeclaration(const VarDecl *D,
+const LookupResult ) {
   // Return if warning is ignored.
   if (Diags.isIgnored(diag::warn_decl_shadow, R.getNameLoc()))
-return;
+return nullptr;
 
   // Don't diagnose declarations at file scope.
   if (D->hasGlobalStorage())
-return;
-
-  DeclContext *NewDC = D->getDeclContext();
+return nullptr;
 
   // Only diagnose if we're shadowing an unambiguous field or variable.
   if (R.getResultKind() != LookupResult::Found)
-return;
+return nullptr;
 
-  NamedDecl* ShadowedDecl = R.getFoundDecl();
-  if (!isa(ShadowedDecl) && !isa(ShadowedDecl))
-return;
+  NamedDecl *ShadowedDecl = R.getFoundDecl();
+  return isa(ShadowedDecl) || isa(ShadowedDecl)
+ ? ShadowedDecl
+ : nullptr;
+}
+
+/// \brief Diagnose variable or built-in function shadowing.  Implements
+/// -Wshadow.
+///
+/// This method is called whenever a VarDecl is added to a "useful"
+/// scope.
+///
+/// \param ShadowedDecl the declaration that is shadowed by the given variable
+/// \param R the lookup of the name
+///
+void Sema::CheckShadow(VarDecl *D, NamedDecl *ShadowedDecl,
+   const LookupResult ) {
+  DeclContext *NewDC = D->getDeclContext();
 
   if (FieldDecl *FD = dyn_cast(ShadowedDecl)) {
 // Fields are not shadowed by variables in C++ static methods.
@@ -6733,7 +6745,8 @@
   LookupResult R(*this, D->getDeclName(), D->getLocation(),
  Sema::LookupOrdinaryName, Sema::ForRedeclaration);
   

[PATCH] D28350: [Sema] Avoid -Wshadow warning when a "redefinition of " error is presented

2017-01-09 Thread Reid Kleckner via Phabricator via cfe-commits
rnk accepted this revision.
rnk added a comment.
This revision is now accepted and ready to land.

lgtm


Repository:
  rL LLVM

https://reviews.llvm.org/D28350



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D28350: [Sema] Avoid -Wshadow warning when a "redefinition of " error is presented

2017-01-05 Thread Alex Lorenz via Phabricator via cfe-commits
arphaman created this revision.
arphaman added reviewers: rsmith, rnk, bruno.
arphaman added a subscriber: cfe-commits.
arphaman set the repository for this revision to rL LLVM.

This patch ensures that clang avoids the redundant -Wshadow warning for 
variables that already get a "redefinition of " error.


Repository:
  rL LLVM

https://reviews.llvm.org/D28350

Files:
  include/clang/Sema/Sema.h
  lib/Sema/SemaDecl.cpp
  test/SemaCXX/warn-shadow-in-lambdas.cpp
  test/SemaCXX/warn-shadow.cpp

Index: test/SemaCXX/warn-shadow.cpp
===
--- test/SemaCXX/warn-shadow.cpp
+++ test/SemaCXX/warn-shadow.cpp
@@ -97,3 +97,13 @@
 void test8() {
   int bob; // expected-warning {{declaration shadows a variable in the global namespace}}
 }
+
+namespace rdar29067894 {
+
+void avoidWarningWhenRedefining(int b) { // expected-note {{previous definition is here}}
+  int a = 0; // expected-note {{previous definition is here}}
+  int a = 1; // expected-error {{redefinition of 'a'}}
+  int b = 2; // expected-error {{redefinition of 'b'}}
+}
+
+}
Index: test/SemaCXX/warn-shadow-in-lambdas.cpp
===
--- test/SemaCXX/warn-shadow-in-lambdas.cpp
+++ test/SemaCXX/warn-shadow-in-lambdas.cpp
@@ -137,3 +137,11 @@
   auto g3 = [param] // expected-note {{variable 'param' is explicitly captured here}}
(auto param) { ; }; // expected-warning {{declaration shadows a local variable}}
 }
+
+void avoidWarningWhenRedefining() {
+  int a = 1;
+  auto l = [b = a] { // expected-note {{previous definition is here}}
+// Don't warn on redefinitions.
+int b = 0; // expected-error {{redefinition of 'b'}}
+  };
+}
Index: lib/Sema/SemaDecl.cpp
===
--- lib/Sema/SemaDecl.cpp
+++ lib/Sema/SemaDecl.cpp
@@ -6425,9 +6425,10 @@
 }
   }
 
-  // Diagnose shadowed variables before filtering for scope.
-  if (D.getCXXScopeSpec().isEmpty())
-CheckShadow(S, NewVD, Previous);
+  // Find the shadowed declaration before filtering for scope.
+  NamedDecl *ShadowedDecl = D.getCXXScopeSpec().isEmpty()
+? getShadowedDeclaration(NewVD, Previous)
+: nullptr;
 
   // Don't consider existing declarations that are in a different
   // scope and are out-of-semantic-context declarations (if the new
@@ -6522,6 +6523,10 @@
 }
   }
 
+  // Diagnose shadowed variables iff this isn't a redeclaration.
+  if (ShadowedDecl && !D.isRedeclaration())
+CheckShadow(NewVD, ShadowedDecl, Previous);
+
   ProcessPragmaWeak(S, NewVD);
 
   // If this is the first declaration of an extern C variable, update
@@ -6595,33 +6600,40 @@
   return SourceLocation();
 }
 
-/// \brief Diagnose variable or built-in function shadowing.  Implements
-/// -Wshadow.
-///
-/// This method is called whenever a VarDecl is added to a "useful"
-/// scope.
-///
-/// \param S the scope in which the shadowing name is being declared
-/// \param R the lookup of the name
-///
-void Sema::CheckShadow(Scope *S, VarDecl *D, const LookupResult& R) {
+/// \brief Return the declaration shadowed by the given variable \p D, or null
+/// if it doesn't shadow any declaration or shadowing warnings are disabled.
+NamedDecl *Sema::getShadowedDeclaration(const VarDecl *D,
+const LookupResult ) {
   // Return if warning is ignored.
   if (Diags.isIgnored(diag::warn_decl_shadow, R.getNameLoc()))
-return;
+return nullptr;
 
   // Don't diagnose declarations at file scope.
   if (D->hasGlobalStorage())
-return;
-
-  DeclContext *NewDC = D->getDeclContext();
+return nullptr;
 
   // Only diagnose if we're shadowing an unambiguous field or variable.
   if (R.getResultKind() != LookupResult::Found)
-return;
+return nullptr;
 
-  NamedDecl* ShadowedDecl = R.getFoundDecl();
-  if (!isa(ShadowedDecl) && !isa(ShadowedDecl))
-return;
+  NamedDecl *ShadowedDecl = R.getFoundDecl();
+  return isa(ShadowedDecl) || isa(ShadowedDecl)
+ ? ShadowedDecl
+ : nullptr;
+}
+
+/// \brief Diagnose variable or built-in function shadowing.  Implements
+/// -Wshadow.
+///
+/// This method is called whenever a VarDecl is added to a "useful"
+/// scope.
+///
+/// \param ShadowedDecl the declaration that is shadowed by the given variable
+/// \param R the lookup of the name
+///
+void Sema::CheckShadow(VarDecl *D, NamedDecl *ShadowedDecl,
+   const LookupResult ) {
+  DeclContext *NewDC = D->getDeclContext();
 
   if (FieldDecl *FD = dyn_cast(ShadowedDecl)) {
 // Fields are not shadowed by variables in C++ static methods.
@@ -6732,7 +6744,8 @@
   LookupResult R(*this, D->getDeclName(), D->getLocation(),
  Sema::LookupOrdinaryName, Sema::ForRedeclaration);
   LookupName(R, S);
-  CheckShadow(S, D, R);
+  if (NamedDecl *ShadowedDecl = getShadowedDeclaration(D, R))
+