Index: configure.ac
===================================================================
--- configure.ac	(revision 166782)
+++ configure.ac	(working copy)
@@ -909,6 +909,18 @@ AC_CHECK_HEADER(pthread.h, [have_pthread
 gcc_AC_C_CHAR_BIT
 AC_C_BIGENDIAN
 
+# --------------------
+# Checks for C++ headers
+# --------------------
+
+AC_LANG_PUSH(C++)
+
+AC_CHECK_HEADERS(unordered_map)
+AC_CHECK_HEADERS(tr1/unordered_map)
+AC_CHECK_HEADERS(ext/hash_map)
+
+AC_LANG_POP(C++)
+
 # --------
 # UNSORTED
 # --------
Index: go/go-system.h
===================================================================
--- go/go-system.h	(revision 166822)
+++ go/go-system.h	(working copy)
@@ -26,7 +26,72 @@
 
 #include <string>
 #include <vector>
-#include <tr1/unordered_map>
+
+#if defined(HAVE_UNORDERED_MAP)
+
+# include <unordered_map>
+
+# define Unordered_map(KEYTYPE, VALTYPE) \
+	std::unordered_map<KEYTYPE, VALTYPE>
+
+# define Unordered_map_hash(KEYTYPE, VALTYPE, HASHFN, EQFN) \
+	std::unordered_map<KEYTYPE, VALTYPE, HASHFN, EQFN>
+
+#elif defined(HAVE_TR1_UNORDERED_MAP)
+
+# include <tr1/unordered_map>
+
+# define Unordered_map(KEYTYPE, VALTYPE) \
+	std::tr1::unordered_map<KEYTYPE, VALTYPE>
+
+# define Unordered_map_hash(KEYTYPE, VALTYPE, HASHFN, EQFN) \
+	std::tr1::unordered_map<KEYTYPE, VALTYPE, HASHFN, EQFN>
+
+#elif defined(HAVE_EXT_HASH_MAP)
+
+# include <ext/hash_map>
+
+# define Unordered_map(KEYTYPE, VALTYPE) \
+	__gnu_cxx::hash_map<KEYTYPE, VALTYPE>
+
+# define Unordered_map_hash(KEYTYPE, VALTYPE, HASHFN, EQFN) \
+	__gnu_cxx::hash_map<KEYTYPE, VALTYPE, HASHFN, EQFN>
+
+// Provide hash functions for strings and pointers.
+
+namespace __gnu_cxx
+{
+
+template<>
+struct hash<std::string>
+{
+  size_t
+  operator()(std::string s) const
+  { return __stl_hash_string(s.c_str()); }
+};
+
+template<typename T>
+struct hash<T*>
+{
+  size_t
+  operator()(T* p) const
+  { return reinterpret_cast<size_t>(p); }
+};
+
+}
+
+#else
+
+# include <map>
+
+# define Unordered_map(KEYTYPE, VALTYPE) \
+	std::map<KEYTYPE, VALTYPE>
+
+// We could make this work by writing an adapter class which
+// implemented operator< in terms of the hash function.
+# error "requires hash table type"
+
+#endif
 
 // We don't really need iostream, but some versions of gmp.h include
 // it when compiled with C++, which means that we need to include it
diff -r ca804e7183fe go/export.h
--- a/go/export.h	Tue Nov 16 12:48:08 2010 -0800
+++ b/go/export.h	Tue Nov 16 14:36:13 2010 -0800
@@ -163,7 +163,7 @@
   register_builtin_type(Gogo*, const char* name, Builtin_code);
 
   // Mapping from Type objects to a constant index.
-  typedef std::tr1::unordered_map<const Type*, int> Type_refs;
+  typedef Unordered_map(const Type*, int) Type_refs;
 
   // The stream to which we are writing data.
   Stream* stream_;
diff -r ca804e7183fe go/gogo.h
--- a/go/gogo.h	Tue Nov 16 12:48:08 2010 -0800
+++ b/go/gogo.h	Tue Nov 16 14:36:13 2010 -0800
@@ -612,12 +612,12 @@
   typedef std::map<std::string, std::string> Sys_names;
 
   // Hash table mapping map types to map descriptor decls.
-  typedef std::tr1::unordered_map<const Map_type*, tree, Type_hash_identical,
-				  Type_identical> Map_descriptors;
+  typedef Unordered_map_hash(const Map_type*, tree, Type_hash_identical,
+			     Type_identical) Map_descriptors;
 
   // Map unnamed types to type descriptor decls.
-  typedef std::tr1::unordered_map<const Type*, tree, Type_hash_identical,
-				  Type_identical> Type_descriptor_decls;
+  typedef Unordered_map_hash(const Type*, tree, Type_hash_identical,
+			     Type_identical) Type_descriptor_decls;
 
   // The package we are compiling.
   Package* package_;
@@ -932,7 +932,7 @@
 
  private:
   // Type for mapping from label names to Label objects.
-  typedef std::tr1::unordered_map<std::string, Label*> Labels;
+  typedef Unordered_map(std::string, Label*) Labels;
 
   tree
   make_receiver_parm_decl(Gogo*, Named_object*, tree);
@@ -1846,7 +1846,7 @@
 {
  public:
   // Type for mapping from names to objects.
-  typedef std::tr1::unordered_map<std::string, Named_object*> Contour;
+  typedef Unordered_map(std::string, Named_object*) Contour;
 
   Bindings(Bindings* enclosing);
 
diff -r ca804e7183fe go/types.cc
--- a/go/types.cc	Tue Nov 16 12:48:08 2010 -0800
+++ b/go/types.cc	Tue Nov 16 14:36:13 2010 -0800
@@ -3167,7 +3167,7 @@
 Pointer_type*
 Type::make_pointer_type(Type* to_type)
 {
-  typedef std::tr1::unordered_map<Type*, Pointer_type*> Hashtable;
+  typedef Unordered_map(Type*, Pointer_type*) Hashtable;
   static Hashtable pointer_types;
   Hashtable::const_iterator p = pointer_types.find(to_type);
   if (p != pointer_types.end())
diff -r ca804e7183fe go/types.h
--- a/go/types.h	Tue Nov 16 12:48:08 2010 -0800
+++ b/go/types.h	Tue Nov 16 14:36:13 2010 -0800
@@ -308,7 +308,7 @@
 class Methods
 {
  private:
-  typedef std::tr1::unordered_map<std::string, Method*> Method_map;
+  typedef Unordered_map(std::string, Method*) Method_map;
 
  public:
   typedef Method_map::const_iterator const_iterator;
@@ -1078,8 +1078,8 @@
 
   // A mapping from Type to tree, used to ensure that the GIMPLE
   // representation of identical types is identical.
-  typedef std::tr1::unordered_map<const Type*, tree, Type_hash_identical,
-				  Type_identical> Type_trees;
+  typedef Unordered_map_hash(const Type*, tree, Type_hash_identical,
+			     Type_identical) Type_trees;
 
   static Type_trees type_trees;
 
@@ -2577,9 +2577,8 @@
  private:
   // A mapping from interfaces to the associated interface method
   // tables for this type.  This maps to a decl.
-  typedef std::tr1::unordered_map<const Interface_type*, tree,
-				  Type_hash_identical,
-				  Type_identical> Interface_method_tables;
+  typedef Unordered_map_hash(const Interface_type*, tree, Type_hash_identical,
+			     Type_identical) Interface_method_tables;
 
   // A pointer back to the Named_object for this type.
   Named_object* named_object_;
