Tweak implementation for allowing ObjC builtin type redefinitions.

- Replace string comparisons with pre-defined idents.
- Avoid calling isBuiltinObjCType() to avoid two checks. 
- Remove isBuiltinObjCType(), since it was only used in Sema::MergeTypeDefDecl().
- Have Sema::MergeTypeDefDecl() set the new type.

This is a moidified version of an patch by David Chisnall.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@55990 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index cf84bcc..4000857 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -230,6 +230,25 @@
 /// situation, merging decls or emitting diagnostics as appropriate.
 ///
 TypedefDecl *Sema::MergeTypeDefDecl(TypedefDecl *New, Decl *OldD) {
+  // Allow multiple definitions for ObjC built-in typedefs.
+  // FIXME: Verify the underlying types are equivalent!
+  if (getLangOptions().ObjC1) {
+    const IdentifierInfo *typeIdent = New->getIdentifier();
+    if (typeIdent == Ident_id) {
+      Context.setObjCIdType(New);
+      return New;
+    } else if (typeIdent == Ident_Class) {
+      Context.setObjCClassType(New);
+      return New;
+    } else if (typeIdent == Ident_SEL) {
+      Context.setObjCSelType(New);
+      return New;
+    } else if (typeIdent == Ident_Protocol) {
+      Context.setObjCProtoType(New->getUnderlyingType());
+      return New;
+    }
+    // Fall through - the typedef name was not a builtin type.
+  }
   // Verify the old decl was also a typedef.
   TypedefDecl *Old = dyn_cast<TypedefDecl>(OldD);
   if (!Old) {
@@ -251,11 +270,6 @@
     return Old;
   }
   
-  // Allow multiple definitions for ObjC built-in typedefs.
-  // FIXME: Verify the underlying types are equivalent!
-  if (getLangOptions().ObjC1 && isBuiltinObjCType(New))
-    return Old;
-
   if (getLangOptions().Microsoft) return New;
 
   // Redeclaration of a type is a constraint violation (6.7.2.3p1).