[cfe-commits] r64669 - /cfe/branches/Apple/objective-rewrite/tools/clang/Driver/RewriteObjC.cpp

Steve Naroff snaroff at apple.com
Mon Feb 16 13:29:15 PST 2009


Author: snaroff
Date: Mon Feb 16 15:29:14 2009
New Revision: 64669

URL: http://llvm.org/viewvc/llvm-project?rev=64669&view=rev
Log:
Finish changing RewriteObjC::RewriteObjCProtocolExpr() from a functional ABI (objc_getProtocol()) to a data driven ABI. This code generation doesn't rely on any fancy linker support.

This completes the fix for <rdar://problem/6562121> clang ObjC rewriter: @protocol(foo) returns nil.

Modified:
    cfe/branches/Apple/objective-rewrite/tools/clang/Driver/RewriteObjC.cpp

Modified: cfe/branches/Apple/objective-rewrite/tools/clang/Driver/RewriteObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/Apple/objective-rewrite/tools/clang/Driver/RewriteObjC.cpp?rev=64669&r1=64668&r2=64669&view=diff

==============================================================================
--- cfe/branches/Apple/objective-rewrite/tools/clang/Driver/RewriteObjC.cpp (original)
+++ cfe/branches/Apple/objective-rewrite/tools/clang/Driver/RewriteObjC.cpp Mon Feb 16 15:29:14 2009
@@ -73,7 +73,6 @@
     FunctionDecl *GetMetaClassFunctionDecl;
     FunctionDecl *SelGetUidFunctionDecl;
     FunctionDecl *CFStringFunctionDecl;
-    FunctionDecl *GetProtocolFunctionDecl;
     FunctionDecl *SuperContructorFunctionDecl;
       
     // ObjC string constant support.
@@ -88,6 +87,9 @@
     RecordDecl *SuperStructDecl;
     RecordDecl *ConstantStringDecl;
     
+    TypeDecl *ProtocolTypeDecl;
+    QualType getProtocolType();
+    
     // Needed for header files being rewritten
     bool IsHeader;
     
@@ -281,7 +283,6 @@
     void SynthGetClassFunctionDecl();
     void SynthGetMetaClassFunctionDecl();
     void SynthSelGetUidFunctionDecl();
-    void SynthGetProtocolFunctionDecl();
     void SynthSuperContructorFunctionDecl();
       
     // Metadata emission.
@@ -438,13 +439,13 @@
   GetMetaClassFunctionDecl = 0;
   SelGetUidFunctionDecl = 0;
   CFStringFunctionDecl = 0;
-  GetProtocolFunctionDecl = 0;
   ConstantStringClassReference = 0;
   NSStringRecord = 0;
   CurMethodDef = 0;
   CurFunctionDef = 0;
   GlobalVarDecl = 0;
   SuperStructDecl = 0;
+  ProtocolTypeDecl = 0;
   ConstantStringDecl = 0;
   BcLabelCount = 0;
   SuperContructorFunctionDecl = 0;
@@ -1929,21 +1930,6 @@
                                            FunctionDecl::Extern, false);
 }
 
-// SynthGetProtocolFunctionDecl - Protocol objc_getProtocol(const char *proto);
-void RewriteObjC::SynthGetProtocolFunctionDecl() {
-  IdentifierInfo *SelGetProtoIdent = &Context->Idents.get("objc_getProtocol");
-  llvm::SmallVector<QualType, 16> ArgTys;
-  ArgTys.push_back(Context->getPointerType(
-    Context->CharTy.getQualifiedType(QualType::Const)));
-  QualType getFuncType = Context->getFunctionType(Context->getObjCProtoType(),
-                                                  &ArgTys[0], ArgTys.size(),
-                                                  false /*isVariadic*/, 0);
-  GetProtocolFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
-                                             SourceLocation(), 
-                                             SelGetProtoIdent, getFuncType,
-                                             FunctionDecl::Extern, false);
-}
-
 void RewriteObjC::RewriteFunctionDecl(FunctionDecl *FD) {
   // declared in <objc/objc.h>
   if (FD->getIdentifier() &&
@@ -2571,25 +2557,37 @@
   return ReplacingStmt;
 }
 
+// typedef struct objc_object Protocol;
+QualType RewriteObjC::getProtocolType() {
+  if (!ProtocolTypeDecl) {
+    ProtocolTypeDecl = TypedefDecl::Create(*Context, TUDecl,
+                                           SourceLocation(), 
+                                           &Context->Idents.get("Protocol"),
+                                           Context->getObjCIdType());
+  }
+  return Context->getTypeDeclType(ProtocolTypeDecl);
+}
+
 /// RewriteObjCProtocolExpr - Rewrite a protocol expression into
-/// call to objc_getProtocol("proto-name").
+/// a synthesized/forward data reference (to the protocol's metadata).
+/// The forward references (and metadata) are generated in
+/// RewriteObjC::HandleTranslationUnit().
 Stmt *RewriteObjC::RewriteObjCProtocolExpr(ObjCProtocolExpr *Exp) {
-  if (!GetProtocolFunctionDecl)
-    SynthGetProtocolFunctionDecl();
-  // Create a call to objc_getProtocol("ProtocolName").
-  llvm::SmallVector<Expr*, 8> ProtoExprs;
-  QualType argType = Context->getPointerType(Context->CharTy);
-  ProtoExprs.push_back(new StringLiteral(Exp->getProtocol()->getNameAsCString(),
-                                       strlen(Exp->getProtocol()->getNameAsCString()),
-                                       false, argType, SourceLocation(),
-                                       SourceLocation()));
-  CallExpr *ProtoExp = SynthesizeCallToFunctionDecl(GetProtocolFunctionDecl,
-                                                    &ProtoExprs[0], 
-                                                    ProtoExprs.size());
-  ReplaceStmt(Exp, ProtoExp);
+  std::string Name = "_OBJC_PROTOCOL_" + Exp->getProtocol()->getNameAsString();
+  IdentifierInfo *ID = &Context->Idents.get(Name);
+  VarDecl *VD = VarDecl::Create(*Context, TUDecl, SourceLocation(), 
+                          ID, QualType()/*UNUSED*/, VarDecl::Extern);
+  DeclRefExpr *DRE = new DeclRefExpr(VD, getProtocolType(), SourceLocation());
+  Expr *DerefExpr = new UnaryOperator(DRE, UnaryOperator::AddrOf,
+                             Context->getPointerType(DRE->getType()),
+                             SourceLocation());
+  CastExpr *castExpr = new CStyleCastExpr(DerefExpr->getType(), DerefExpr, 
+                                          DerefExpr->getType(), 
+                                          SourceLocation(), SourceLocation());
+  ReplaceStmt(Exp, castExpr);
   ProtocolExprDecls.insert(Exp->getProtocol());
   // delete Exp; leak for now, see RewritePropertySetter() usage for more info. 
-  return ProtoExp;
+  return castExpr;
   
 }
 





More information about the cfe-commits mailing list