Encode Class, SEL and Objective-C objects.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@43540 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/Sema/Sema.cpp b/Sema/Sema.cpp
index 2be198d..92d17e1 100644
--- a/Sema/Sema.cpp
+++ b/Sema/Sema.cpp
@@ -82,6 +82,25 @@
   return Context.getObjcProtoType();
 }
 
+/// GetObjcClassType - See comments for Sema::GetObjcIdType above; replace "id"
+/// with "Protocol".
+QualType Sema::GetObjcClassType(SourceLocation Loc) {
+  assert(TUScope && "GetObjcClassType(): Top-level scope is null");
+  if (!Context.getObjcClassType().isNull())
+    return Context.getObjcClassType();
+    
+  IdentifierInfo *ClassIdent = &Context.Idents.get("Class");
+  ScopedDecl *ClassDecl = LookupScopedDecl(ClassIdent, Decl::IDNS_Ordinary, 
+                                        SourceLocation(), TUScope);
+  TypedefDecl *ObjcClassTypedef = dyn_cast_or_null<TypedefDecl>(ClassDecl);
+  if (!ObjcClassTypedef) {
+    Diag(Loc, diag::err_missing_class_definition);
+    return QualType();
+  }
+  Context.setObjcClassType(ObjcClassTypedef);
+  return Context.getObjcClassType();
+}
+
 Sema::Sema(Preprocessor &pp, ASTContext &ctxt, std::vector<Decl*> &prevInGroup)
   : PP(pp), Context(ctxt), CurFunctionDecl(0), LastInGroupList(prevInGroup) {
   
diff --git a/Sema/Sema.h b/Sema/Sema.h
index 9db00fb..13ba636 100644
--- a/Sema/Sema.h
+++ b/Sema/Sema.h
@@ -284,6 +284,9 @@
   /// GetObjcSelType - Getter for the build-in "Protocol *" type.
   QualType GetObjcProtoType(SourceLocation Loc = SourceLocation());
   
+  // GetObjcClassType - Getter for the built-in "Class" type.
+  QualType GetObjcClassType(SourceLocation Loc = SourceLocation());
+
   /// AddInstanceMethodToGlobalPool - All instance methods in a translation
   /// unit are added to a global pool. This allows us to efficiently associate
   /// a selector with a method declaraation for purposes of typechecking
diff --git a/Sema/SemaExpr.cpp b/Sema/SemaExpr.cpp
index ee35107..aac6ca3 100644
--- a/Sema/SemaExpr.cpp
+++ b/Sema/SemaExpr.cpp
@@ -1959,6 +1959,17 @@
                                                  SourceLocation RParenLoc) {
   QualType EncodedType = QualType::getFromOpaquePtr(Ty);
 
+  // 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.
+  // The same is true for the 'Class' and 'SEL' types.
+  GetObjcIdType(EncodeLoc);
+  GetObjcClassType(EncodeLoc);
+  GetObjcSelType(EncodeLoc);
+  
   QualType t = Context.getPointerType(Context.CharTy);
   return new ObjCEncodeExpr(t, EncodedType, AtLoc, RParenLoc);
 }