Introduce an egregious hack to work around a bug in libstdc++ 4.2.x's
<tr1/hashtable> header, where a friend class template
std::tr1::__detail::_Map_base is declared with the wrong template
parameters. GCC doesn't catch the problem, so Clang does a little
back-flip to avoid diagnosing just this one instance of the problem.

llvm-svn: 100790
diff --git a/clang/test/SemaCXX/libstdcxx_is_pod_hack.cpp b/clang/test/SemaCXX/libstdcxx_is_pod_hack.cpp
index 7a4bebc..2e92032 100644
--- a/clang/test/SemaCXX/libstdcxx_is_pod_hack.cpp
+++ b/clang/test/SemaCXX/libstdcxx_is_pod_hack.cpp
@@ -1,5 +1,11 @@
 // RUN: %clang_cc1 -fsyntax-only %s
 
+// This is a test for an egregious hack in Clang that works around
+// issues with GCC's evolution. libstdc++ 4.2.x uses __is_pod as an
+// identifier (to declare a struct template like the one below), while
+// GCC 4.3 and newer make __is_pod a keyword. Clang treats __is_pod as
+// a keyword *unless* it is introduced following the struct keyword.
+
 template<typename T>
 struct __is_pod {
 };
diff --git a/clang/test/SemaCXX/libstdcxx_map_base_hack.cpp b/clang/test/SemaCXX/libstdcxx_map_base_hack.cpp
new file mode 100644
index 0000000..a556281
--- /dev/null
+++ b/clang/test/SemaCXX/libstdcxx_map_base_hack.cpp
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 -fsyntax-only %s
+
+// libstdc++ 4.2.x contains a bug where a friend struct template
+// declaration for std::tr1::__detail::_Map base has different
+// template arguments than the real declaration. Clang has an
+// egregious hack to work around this problem, since we can't modify
+// all of the world's libstdc++'s.
+
+namespace std { namespace tr1 { namespace __detail {
+  template<typename _Key, typename _Value, typename _Ex, bool __unique,
+	   typename _Hashtable>
+    struct _Map_base { };
+
+} } } 
+
+namespace std { namespace tr1 {
+  template<typename T>
+  struct X1 {
+    template<typename _Key2, typename _Pair, typename _Hashtable>
+    friend struct __detail::_Map_base;
+  };
+
+} }
+
+std::tr1::X1<int> x1i;