[cfe-commits] r98684 - in /cfe/trunk: include/clang/Basic/DiagnosticGroups.td include/clang/Basic/DiagnosticSemaKinds.td lib/AST/Decl.cpp lib/Sema/Sema.h lib/Sema/SemaDecl.cpp
John McCall
rjmccall at apple.com
Tue Mar 16 14:48:18 PDT 2010
Author: rjmccall
Date: Tue Mar 16 16:48:18 2010
New Revision: 98684
URL: http://llvm.org/viewvc/llvm-project?rev=98684&view=rev
Log:
Implement -Wshadow. Based on a patch by Mike M.!
Modified:
cfe/trunk/include/clang/Basic/DiagnosticGroups.td
cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
cfe/trunk/lib/AST/Decl.cpp
cfe/trunk/lib/Sema/Sema.h
cfe/trunk/lib/Sema/SemaDecl.cpp
Modified: cfe/trunk/include/clang/Basic/DiagnosticGroups.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticGroups.td?rev=98684&r1=98683&r2=98684&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticGroups.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticGroups.td Tue Mar 16 16:48:18 2010
@@ -73,7 +73,7 @@
def ReturnType : DiagGroup<"return-type">;
def SemiBeforeMethodBody : DiagGroup<"semicolon-before-method-body">;
def : DiagGroup<"sequence-point">;
-def : DiagGroup<"shadow">;
+def Shadow : DiagGroup<"shadow">;
def : DiagGroup<"shorten-64-to-32">;
def SignCompare : DiagGroup<"sign-compare">;
def : DiagGroup<"synth">;
Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=98684&r1=98683&r2=98684&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Tue Mar 16 16:48:18 2010
@@ -107,7 +107,16 @@
"use of out-of-scope declaration of %0">;
def err_inline_non_function : Error<
"'inline' can only appear on functions">;
-
+
+def warn_decl_shadow :
+ Warning<"declaration shadows a %select{"
+ "local variable|"
+ "variable in %2|"
+ "static data member of %2|"
+ "field of %2|"
+ "global built-in function}1">,
+ InGroup<Shadow>, DefaultIgnore;
+
// C++ using declarations
def err_using_requires_qualname : Error<
"using declaration requires a qualified name">;
Modified: cfe/trunk/lib/AST/Decl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Decl.cpp?rev=98684&r1=98683&r2=98684&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Decl.cpp (original)
+++ cfe/trunk/lib/AST/Decl.cpp Tue Mar 16 16:48:18 2010
@@ -430,7 +430,10 @@
for (; I!=End; ++I)
QualName += *I + "::";
- QualName += getNameAsString();
+ if (getDeclName())
+ QualName += getNameAsString();
+ else
+ QualName += "<anonymous>";
return QualName;
}
Modified: cfe/trunk/lib/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=98684&r1=98683&r2=98684&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Tue Mar 16 16:48:18 2010
@@ -778,6 +778,7 @@
const LookupResult &Previous,
Scope *S);
void DiagnoseFunctionSpecifiers(Declarator& D);
+ void DiagnoseShadow(NamedDecl* D, const LookupResult& R);
NamedDecl* ActOnTypedefDeclarator(Scope* S, Declarator& D, DeclContext* DC,
QualType R, TypeSourceInfo *TInfo,
LookupResult &Previous, bool &Redeclaration);
Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=98684&r1=98683&r2=98684&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Tue Mar 16 16:48:18 2010
@@ -2403,6 +2403,9 @@
NewVD->addAttr(::new (Context) AsmLabelAttr(Context, SE->getString()));
}
+ // Diagnose shadowed variables before filtering for scope.
+ DiagnoseShadow(NewVD, Previous);
+
// Don't consider existing declarations that are in a different
// scope and are out-of-semantic-context declarations (if the new
// declaration has linkage).
@@ -2454,6 +2457,65 @@
return NewVD;
}
+/// \brief Diagnose variable or built-in function shadowing.
+///
+/// This method is called as soon as a NamedDecl materializes to check
+/// if it shadows another local or global variable, or a built-in function.
+///
+/// For performance reasons, the lookup results are reused from the calling
+/// context.
+///
+/// \param D variable decl to diagnose. Must be a variable.
+/// \param R cached previous lookup of \p D.
+///
+void Sema::DiagnoseShadow(NamedDecl* D, const LookupResult& R) {
+ assert(D->getKind() == Decl::Var && "Expecting variable.");
+
+ // Return if warning is ignored.
+ if (Diags.getDiagnosticLevel(diag::warn_decl_shadow) == Diagnostic::Ignored)
+ return;
+
+ // Return if not local decl.
+ if (!D->getDeclContext()->isFunctionOrMethod())
+ return;
+
+ DeclarationName Name = D->getDeclName();
+
+ // Return if lookup has no result.
+ if (R.getResultKind() != LookupResult::Found) {
+ // Emit warning for built-in shadowing.
+ if (Name.getAsIdentifierInfo() &&
+ Name.getAsIdentifierInfo()->getBuiltinID())
+ Diag(D->getLocation(), diag::warn_decl_shadow)
+ << Name
+ << 4 // global builtin
+ << Context.getTranslationUnitDecl();
+ return;
+ }
+
+ // Return if not variable decl.
+ NamedDecl* ShadowedDecl = R.getFoundDecl();
+ if (!isa<VarDecl>(ShadowedDecl) && !isa<FieldDecl>(ShadowedDecl))
+ return;
+
+ // Determine kind of declaration.
+ DeclContext *DC = ShadowedDecl->getDeclContext();
+ unsigned Kind;
+ if (isa<RecordDecl>(DC)) {
+ if (isa<FieldDecl>(ShadowedDecl))
+ Kind = 3; // field
+ else
+ Kind = 2; // static data member
+ } else if (DC->isFileContext())
+ Kind = 1; // global
+ else
+ Kind = 0; // local
+
+ // Emit warning and note.
+ Diag(D->getLocation(), diag::warn_decl_shadow) << Name << Kind << DC;
+ Diag(ShadowedDecl->getLocation(), diag::note_previous_declaration);
+}
+
/// \brief Perform semantic checking on a newly-created variable
/// declaration.
///
More information about the cfe-commits
mailing list