Index: Sema/SemaDecl.cpp
===================================================================
--- Sema/SemaDecl.cpp	(revision 44490)
+++ Sema/SemaDecl.cpp	(working copy)
@@ -199,6 +199,32 @@
 /// situation, merging decls or emitting diagnostics as appropriate.
 ///
 TypedefDecl *Sema::MergeTypeDefDecl(TypedefDecl *New, ScopedDecl *OldD) {
+
+  // FIXME: Does CPlusPlus0x langoption inplie CPlusPlus?
+  if(PP.getLangOptions().CPlusPlus || PP.getLangOptions().CPlusPlus0x) {
+    // see C++ 7.1.3 [dcl.typedef]
+    // FIXME: only valid in non-class scope, detect class-scope
+    QualType oldQT;
+    if( TagDecl* oldTag = dyn_cast<TagDecl>(OldD) ) {
+      oldQT = Context.getTagDeclType( oldTag );
+    } else if( TypedefDecl* oldTypeDef = dyn_cast<TypedefDecl>(OldD) ) {
+      oldQT = oldTypeDef->getUnderlyingType().getCanonicalType();
+    } else {
+      Diag(New->getLocation(), diag::err_redefinition_different_kind,
+           New->getName());
+      Diag(OldD->getLocation(), diag::err_previous_definition);
+      return New;
+    }
+    if( oldQT != New->getUnderlyingType().getCanonicalType() ) {
+      Diag(New->getLocation(), diag::err_redefinition, New->getName());
+      Diag(OldD->getLocation(), diag::err_previous_definition);
+      return New;
+    }
+    // FIXME: should we return Old if Old is a typedef?
+    return New;
+  }
+
+
   // Verify the old decl was also a typedef.
   TypedefDecl *Old = dyn_cast<TypedefDecl>(OldD);
   if (!Old) {
@@ -212,7 +238,7 @@
   // FIXME: Verify the underlying types are equivalent!
   if (PP.getLangOptions().ObjC1 && isBuiltinObjcType(New))
     return Old;
-    
+  
   // TODO: CHECK FOR CONFLICTS, multiple decls with same name in one scope.
   // TODO: This is totally simplistic.  It should handle merging functions
   // together etc, merging extern int X; int X; ...
