Implement a more sensible strategy for ObjC built-in types (addressing a long standing FIXME in Sema::GetObjcIdType()).

This removes several gross hacks to work around the previous "lazy" behavior.

Two notes:
- MinimalActions still needs to be taught about the built-in types (This breaks one of the -noop test cases). I started this, then added a FIXME.
- I didn't convert Sema::GetObjcProtoType() yet.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@43567 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/Sema/SemaDecl.cpp b/Sema/SemaDecl.cpp
index 32e5d12..ea73db5 100644
--- a/Sema/SemaDecl.cpp
+++ b/Sema/SemaDecl.cpp
@@ -25,6 +25,7 @@
 #include "llvm/ADT/SmallString.h"
 #include "llvm/ADT/SmallSet.h"
 #include "llvm/ADT/DenseSet.h"
+#include "clang/Lex/Preprocessor.h"
 using namespace clang;
 
 Sema::DeclTy *Sema::isTypeName(const IdentifierInfo &II, Scope *S) const {
@@ -210,6 +211,11 @@
     return New;
   }
   
+  // Allow multiple definitions for ObjC built-in typedefs.
+  // 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; ...
@@ -1193,17 +1199,7 @@
   /// Check that class of this category is already completely declared.
   if (!IDecl || IDecl->isForwardDecl())
     Diag(ClassLoc, diag::err_undef_interface, ClassName->getName());
-  
-  // We cannot build type 'id' lazily. It is needed when checking if a 
-  // type is an 'id' (via call to isObjcIdType) even if there is no
-  // need for the default 'id' type.
-  // FIXME: Depending on the need to compare to 'id', this may have to go
-  // somewhere else. At this time, this is a good enough place to do type
-  // encoding of methods and ivars for the rewrite client.
-  GetObjcIdType(AtCatImplLoc);
-  GetObjcClassType(AtCatImplLoc);
-  GetObjcSelType(AtCatImplLoc);
-  
+
   /// TODO: Check that CatName, category name, is not used in another
   // implementation.
   return CDecl;
@@ -1273,16 +1269,6 @@
   if (!ObjcImplementations.insert(ClassName))
     Diag(ClassLoc, diag::err_dup_implementation_class, ClassName->getName());
 
-  // We cannot build type 'id' laziliy. It is needed when checking if a 
-  // type is an 'id' (via call to isObjcIdType) even if there is no
-  // need for the dafult 'id' type.
-  // FIXME: Depending on the need to compare to 'id', this may have to go
-  // somewhere else. At this time, this is a good enough place to do type
-  // encoding of methods and ivars for the rewrite client.
-  GetObjcIdType(AtClassImplLoc);
-  GetObjcClassType(AtClassImplLoc); 
-  GetObjcSelType(AtClassImplLoc);
-  
   return IMPDecl;
 }
 
@@ -1992,7 +1978,7 @@
     if (ArgTypes[i])
       argType = QualType::getFromOpaquePtr(ArgTypes[i]);
     else
-      argType = GetObjcIdType(MethodLoc);
+      argType = Context.getObjcIdType();
     ParmVarDecl* Param = new ParmVarDecl(SourceLocation(/*FIXME*/), ArgNames[i], 
                                          argType, VarDecl::None, 0);
     Params.push_back(Param);
@@ -2002,7 +1988,7 @@
   if (ReturnType)
     resultDeclType = QualType::getFromOpaquePtr(ReturnType);
   else // get the type for "id".
-    resultDeclType = GetObjcIdType(MethodLoc);
+    resultDeclType = Context.getObjcIdType();
 
   ObjcMethodDecl* ObjcMethod =  new ObjcMethodDecl(MethodLoc, EndLoc, Sel,
                                       resultDeclType, 0, -1, AttrList,