forked from OSchip/llvm-project
Improve -Wheader-hygiene to warn about using directives inside linkage
specifications within the global scope, from Elliot Glaysher. llvm-svn: 128352
This commit is contained in:
parent
e466345675
commit
a172e08824
|
@ -3817,6 +3817,19 @@ NamespaceDecl *Sema::getOrCreateStdNamespace() {
|
|||
return getStdNamespace();
|
||||
}
|
||||
|
||||
/// \brief Determine whether a using statement is in a context where it will be
|
||||
/// apply in all contexts.
|
||||
static bool IsUsingDirectiveInToplevelContext(DeclContext *CurContext) {
|
||||
switch (CurContext->getDeclKind()) {
|
||||
case Decl::TranslationUnit:
|
||||
return true;
|
||||
case Decl::LinkageSpec:
|
||||
return IsUsingDirectiveInToplevelContext(CurContext->getParent());
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Decl *Sema::ActOnUsingDirective(Scope *S,
|
||||
SourceLocation UsingLoc,
|
||||
SourceLocation NamespcLoc,
|
||||
|
@ -3902,7 +3915,7 @@ Decl *Sema::ActOnUsingDirective(Scope *S,
|
|||
SS.getWithLocInContext(Context),
|
||||
IdentLoc, Named, CommonAncestor);
|
||||
|
||||
if (CurContext->getDeclKind() == Decl::TranslationUnit &&
|
||||
if (IsUsingDirectiveInToplevelContext(CurContext) &&
|
||||
!SourceMgr.isFromMainFile(IdentLoc)) {
|
||||
Diag(IdentLoc, diag::warn_using_directive_in_header);
|
||||
}
|
||||
|
|
|
@ -7,3 +7,21 @@ 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}}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Warn inside linkage specs too.
|
||||
// expected-warning {{using namespace directive in global context in header}}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// expected-warning {{using namespace directive in global context in header}}
|
||||
|
|
|
@ -13,3 +13,30 @@ using namespace warn_in_header_in_global_context;
|
|||
namespace dont_warn_here {
|
||||
using namespace warn_in_header_in_global_context;
|
||||
}
|
||||
|
||||
// We should warn in toplevel extern contexts.
|
||||
namespace warn_inside_linkage {}
|
||||
extern "C++" {
|
||||
using namespace warn_inside_linkage;
|
||||
}
|
||||
|
||||
// This is really silly, but we should warn on it:
|
||||
extern "C++" {
|
||||
extern "C" {
|
||||
extern "C++" {
|
||||
using namespace warn_inside_linkage;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// But we shouldn't warn in extern contexts inside namespaces.
|
||||
namespace dont_warn_here {
|
||||
extern "C++" {
|
||||
using namespace warn_in_header_in_global_context;
|
||||
}
|
||||
}
|
||||
|
||||
// We also shouldn't warn in case of functions.
|
||||
inline void foo() {
|
||||
using namespace warn_in_header_in_global_context;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue