196a4bddeSDouglas Gregor // RUN: %clang_cc1 -fsyntax-only -Wheader-hygiene -verify %s
296a4bddeSDouglas Gregor 
321343877SNico Weber #ifdef BE_THE_HEADER
421343877SNico Weber namespace warn_in_header_in_global_context {}
521343877SNico Weber using namespace warn_in_header_in_global_context; // expected-warning {{using namespace directive in global context in header}}
621343877SNico Weber 
721343877SNico Weber // While we want to error on the previous using directive, we don't when we are
821343877SNico Weber // inside a namespace
921343877SNico Weber namespace dont_warn_here {
1021343877SNico Weber using namespace warn_in_header_in_global_context;
1121343877SNico Weber }
1221343877SNico Weber 
1321343877SNico Weber // We should warn in toplevel extern contexts.
1421343877SNico Weber namespace warn_inside_linkage {}
1521343877SNico Weber extern "C++" {
1621343877SNico Weber using namespace warn_inside_linkage; // expected-warning {{using namespace directive in global context in header}}
1721343877SNico Weber }
1821343877SNico Weber 
1921343877SNico Weber // This is really silly, but we should warn on it:
2021343877SNico Weber extern "C++" {
2121343877SNico Weber extern "C" {
2221343877SNico Weber extern "C++" {
2321343877SNico Weber using namespace warn_inside_linkage; // expected-warning {{using namespace directive in global context in header}}
2421343877SNico Weber }
2521343877SNico Weber }
2621343877SNico Weber }
2721343877SNico Weber 
2821343877SNico Weber // But we shouldn't warn in extern contexts inside namespaces.
2921343877SNico Weber namespace dont_warn_here {
3021343877SNico Weber extern "C++" {
3121343877SNico Weber using namespace warn_in_header_in_global_context;
3221343877SNico Weber }
3321343877SNico Weber }
3421343877SNico Weber 
3521343877SNico Weber // We also shouldn't warn in case of functions.
foo()3621343877SNico Weber inline void foo() {
3721343877SNico Weber   using namespace warn_in_header_in_global_context;
3821343877SNico Weber }
3921343877SNico Weber 
4021343877SNico Weber 
4121343877SNico Weber namespace macronamespace {}
4221343877SNico Weber #define USING_MACRO using namespace macronamespace;
4321343877SNico Weber 
4421343877SNico Weber // |using namespace| through a macro should warn if the instantiation is in a
4521343877SNico Weber // header.
4621343877SNico Weber USING_MACRO // expected-warning {{using namespace directive in global context in header}}
4721343877SNico Weber 
4821343877SNico Weber #else
4921343877SNico Weber 
5021343877SNico Weber #define BE_THE_HEADER
5121343877SNico Weber #include __FILE__
5296a4bddeSDouglas Gregor 
5396a4bddeSDouglas Gregor namespace dont_warn {}
5496a4bddeSDouglas Gregor using namespace dont_warn;
5596a4bddeSDouglas Gregor 
56cc2b8717SNico Weber // |using namespace| through a macro shouldn't warn if the instantiation is in a
57cc2b8717SNico Weber // cc file.
58cc2b8717SNico Weber USING_MACRO
5921343877SNico Weber 
60*5ba37d52SEli Friedman // Check behavior of line markers.
61*5ba37d52SEli Friedman namespace warn_header_with_line_marker {}
62*5ba37d52SEli Friedman # 1 "XXX.h" 1
63*5ba37d52SEli Friedman using namespace warn_header_with_line_marker; // expected-warning {{using namespace directive in global context in header}}
64*5ba37d52SEli Friedman # 70 "warn-using-namespace-in-header.cpp" 2
65*5ba37d52SEli Friedman 
66*5ba37d52SEli Friedman namespace nowarn_after_line_marker {}
67*5ba37d52SEli Friedman using namespace nowarn_after_line_marker;
68*5ba37d52SEli Friedman 
6921343877SNico Weber #endif
70