Add an opt-in -Wheader-hygiene, which current diagnoses the use of

global using directives in C++ headers, from Elliot Glaysher!

llvm-svn: 127881
This commit is contained in:
Douglas Gregor 2011-03-18 16:10:52 +00:00
parent 6b314b3d94
commit 96a4bddefb
5 changed files with 34 additions and 0 deletions

View File

@ -109,6 +109,7 @@ def : DiagGroup<"stack-protector">;
def : DiagGroup<"switch-default">;
def : DiagGroup<"synth">;
def TautologicalCompare : DiagGroup<"tautological-compare">;
def HeaderHygiene : DiagGroup<"header-hygiene">;
// Preprocessor warnings.
def : DiagGroup<"builtin-macro-redefined">;

View File

@ -2928,6 +2928,9 @@ def warn_overloaded_virtual : Warning<
InGroup<OverloadedVirtual>, DefaultIgnore;
def note_hidden_overloaded_virtual_declared_here : Note<
"hidden overloaded virtual function %q0 declared here">;
def warn_using_directive_in_header : Warning<
"using namespace directive in global context in header">,
InGroup<HeaderHygiene>, DefaultIgnore;
def err_conditional_void_nonvoid : Error<
"%select{left|right}1 operand to ? is void, but %select{right|left}1 operand "

View File

@ -3922,6 +3922,12 @@ Decl *Sema::ActOnUsingDirective(Scope *S,
UDir = UsingDirectiveDecl::Create(Context, CurContext, UsingLoc, NamespcLoc,
SS.getWithLocInContext(Context),
IdentLoc, Named, CommonAncestor);
if (CurContext->getDeclKind() == Decl::TranslationUnit &&
!SourceMgr.isFromMainFile(IdentLoc)) {
Diag(IdentLoc, diag::warn_using_directive_in_header);
}
PushUsingDirective(S, UDir);
} else {
Diag(IdentLoc, diag::err_expected_namespace_name) << SS.getRange();

View File

@ -0,0 +1,9 @@
// RUN: %clang_cc1 -fsyntax-only -Wheader-hygiene -verify %s
#include "warn-using-namespace-in-header.h"
namespace dont_warn {}
using namespace dont_warn;
// Warning is actually in the header but only the cpp file gets scanned.
// expected-warning {{using namespace directive in global context in header}}

View File

@ -0,0 +1,15 @@
// Lots of vertical space to make the error line match up with the line of the
// expected line in the source file.
namespace warn_in_header_in_global_context {}
using namespace warn_in_header_in_global_context;
// While we want to error on the previous using directive, we don't when we are
// inside a namespace
namespace dont_warn_here {
using namespace warn_in_header_in_global_context;
}