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,
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);
}
// 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}}
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;
+}