Index: Sema/SemaDecl.cpp
===================================================================
--- Sema/SemaDecl.cpp	(revision 45058)
+++ Sema/SemaDecl.cpp	(working copy)
@@ -17,6 +17,7 @@
 #include "clang/AST/Decl.h"
 #include "clang/AST/Expr.h"
 #include "clang/AST/Type.h"
+#include "clang/Lex/Preprocessor.h"
 #include "clang/Parse/DeclSpec.h"
 #include "clang/Parse/Scope.h"
 #include "clang/Basic/LangOptions.h"
@@ -197,6 +198,39 @@
 /// situation, merging decls or emitting diagnostics as appropriate.
 ///
 TypedefDecl *Sema::MergeTypeDefDecl(TypedefDecl *New, ScopedDecl *OldD) {
+
+  // Redefinitions of typedef are ok in C++ as long as the subsequent defi-
+  // nition is the same type as the first definition: C++ 7.1.3 [dcl.typedef]
+  if(PP.getLangOptions().CPlusPlus) {
+    // 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(OldD->getLocation(), diag::err_previous_definition);
+      return New;
+    }
+    if(!oldQT.isNull() &&
+      oldQT == New->getUnderlyingType().getCanonicalType()) {
+      return New; // Ok, new typedef don't change the canonical type, valid C++
+    }
+    // If we are here, then there is an error: emit the appropriate diagnostic
+    if(oldQT.isNull()) {
+      Diag(New->getLocation(),
+           diag::err_redefinition_different_kind,New->getName());
+    } else {
+      Diag(New->getLocation(), diag::err_redefinition, New->getName());
+    }
+    Diag(OldD->getLocation(), diag::err_previous_definition);
+    // we must return somethings, to allow the parsing to continue.
+    // The easiest and probably best error recovery is to simply return
+    // the new typedef.
+    return New; 
+  }
+
+
   // Verify the old decl was also a typedef.
   TypedefDecl *Old = dyn_cast<TypedefDecl>(OldD);
   if (!Old) {
