Refinements to Sema::GetObjcIdType()...

- Cache the typedef, not the type (avoids importing AST/Type.h).
- Emit an error if "id" cannot be found.
- Comment the routine and add a FIXME to reconsider how we emulate GCC's new fangled behavior. This isn't a priority for now, since almost no code depends on having "id" built-in.
- Add a test.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@42845 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/Sema/Sema.cpp b/Sema/Sema.cpp
index f34aa63..9487ed0 100644
--- a/Sema/Sema.cpp
+++ b/Sema/Sema.cpp
@@ -23,17 +23,25 @@
   TUScope = S;
 }
 
-QualType Sema::GetObjcIdType() {
+/// GetObjcIdType - The following method assumes that "id" is imported
+/// via <objc/objc.h>. This is the way GCC worked for almost 20 years.
+/// In GCC 4.0, "id" is now a built-in type. Unfortunately, typedefs *cannot* be
+/// redefined (even if they are identical). To allow a built-in types to coexist
+/// with <objc/objc.h>, GCC has a special hack on decls (DECL_IN_SYSTEM_HEADER).
+/// For now, we will *not* install id as a built-in. FIXME: reconsider this.
+QualType Sema::GetObjcIdType(SourceLocation Loc) {
   assert(TUScope && "GetObjcIdType(): Top-level scope is null");
-  if (ObjcIdType.isNull()) {
+  if (!ObjcIdTypedef) {
     IdentifierInfo *IdIdent = &Context.Idents.get("id");
     ScopedDecl *IdDecl = LookupScopedDecl(IdIdent, Decl::IDNS_Ordinary, 
                                           SourceLocation(), TUScope);
-    TypedefDecl *IdTypedef = dyn_cast_or_null<TypedefDecl>(IdDecl);
-    assert(IdTypedef && "GetObjcIdType(): Couldn't find 'id' type");
-    ObjcIdType = Context.getTypedefType(IdTypedef);
+    ObjcIdTypedef = dyn_cast_or_null<TypedefDecl>(IdDecl);
+    if (!ObjcIdTypedef) {
+      Diag(Loc, diag::err_missing_id_definition);
+      return QualType();
+    }
   }
-  return ObjcIdType;
+  return Context.getTypedefType(ObjcIdTypedef);
 }
 
 
@@ -56,7 +64,7 @@
   KnownFunctionIDs[ id_vprintf ] = &IT.get("vprintf");
   
   TUScope = 0;
-  ObjcIdType = QualType();
+  ObjcIdTypedef = 0;
 }
 
 void Sema::DeleteExpr(ExprTy *E) {