This patch includes a conceptually simple, but very intrusive/pervasive change. 

The idea is to segregate Objective-C "object" pointers from general C pointers (utilizing the recently added ObjCObjectPointerType). The fun starts in Sema::GetTypeForDeclarator(), where "SomeInterface *" is now represented by a single AST node (rather than a PointerType whose Pointee is an ObjCInterfaceType). Since a significant amount of code assumed ObjC object pointers where based on C pointers/structs, this patch is very tedious. It should also explain why it is hard to accomplish this in smaller, self-contained patches.

This patch does most of the "heavy lifting" related to moving from PointerType->ObjCObjectPointerType. It doesn't include all potential "cleanups". The good news is additional cleanups can be done later (some are noted in the code). This patch is so large that I didn't want to include any changes that are purely aesthetic.

By making the ObjC types truly built-in, they are much easier to work with (and require fewer "hacks"). For example, there is no need for ASTContext::isObjCIdStructType() or ASTContext::isObjCClassStructType()! We believe this change (and the follow-up cleanups) will pay dividends over time. 

Given the amount of code change, I do expect some fallout from this change (though it does pass all of the clang tests). If you notice any problems, please let us know asap! Thanks.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@75314 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Analysis/BasicObjCFoundationChecks.cpp b/lib/Analysis/BasicObjCFoundationChecks.cpp
index aa85769..b454a36 100644
--- a/lib/Analysis/BasicObjCFoundationChecks.cpp
+++ b/lib/Analysis/BasicObjCFoundationChecks.cpp
@@ -31,26 +31,21 @@
 
 using namespace clang;
 
-static ObjCInterfaceType* GetReceiverType(ObjCMessageExpr* ME) {
-  Expr* Receiver = ME->getReceiver();
+static const ObjCInterfaceType* GetReceiverType(const ObjCMessageExpr* ME) {
+  const Expr* Receiver = ME->getReceiver();
   
   if (!Receiver)
     return NULL;
   
-  QualType X = Receiver->getType();
-  
-  if (X->isPointerType()) {
-    Type* TP = X.getTypePtr();
-    const PointerType* T = TP->getAsPointerType();    
-    return dyn_cast<ObjCInterfaceType>(T->getPointeeType().getTypePtr());
-  }
+  if (const ObjCObjectPointerType *PT =
+      Receiver->getType()->getAsObjCObjectPointerType())
+    return PT->getInterfaceType();
 
-  // FIXME: Support ObjCQualifiedIdType?
   return NULL;
 }
 
-static const char* GetReceiverNameType(ObjCMessageExpr* ME) {
-  ObjCInterfaceType* ReceiverType = GetReceiverType(ME);
+static const char* GetReceiverNameType(const ObjCMessageExpr* ME) {
+  const ObjCInterfaceType *ReceiverType = GetReceiverType(ME);
   return ReceiverType ? ReceiverType->getDecl()->getIdentifier()->getName()
                       : NULL;
 }
@@ -67,7 +62,7 @@
   BugReporter& BR;
   ASTContext &Ctx;
       
-  bool isNSString(ObjCInterfaceType* T, const char* suffix);
+  bool isNSString(const ObjCInterfaceType *T, const char* suffix);
   bool AuditNSString(NodeTy* N, ObjCMessageExpr* ME);
       
   void Warn(NodeTy* N, Expr* E, const std::string& s);  
@@ -114,7 +109,7 @@
   ObjCMessageExpr* ME =
     cast<ObjCMessageExpr>(cast<PostStmt>(N->getLocation()).getStmt());
 
-  ObjCInterfaceType* ReceiverType = GetReceiverType(ME);
+  const ObjCInterfaceType *ReceiverType = GetReceiverType(ME);
   
   if (!ReceiverType)
     return false;
@@ -129,8 +124,7 @@
       
   name += 2;
   
-  // FIXME: Make all of this faster.
-  
+  // FIXME: Make all of this faster.  
   if (isNSString(ReceiverType, name))
     return AuditNSString(N, ME);
 
@@ -163,9 +157,8 @@
 // NSString checking.
 //===----------------------------------------------------------------------===//
 
-bool BasicObjCFoundationChecks::isNSString(ObjCInterfaceType* T,
-                                           const char* suffix) {
-  
+bool BasicObjCFoundationChecks::isNSString(const ObjCInterfaceType *T,
+                                           const char* suffix) {  
   return !strcmp("String", suffix) || !strcmp("MutableString", suffix);
 }