1 //===--- RewriteObjC.cpp - Playground for the code rewriter ---------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // Hacks and fun related to the code rewriter. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "clang/Rewrite/ASTConsumers.h" 15 #include "clang/Rewrite/Rewriter.h" 16 #include "clang/AST/AST.h" 17 #include "clang/AST/ASTConsumer.h" 18 #include "clang/AST/ParentMap.h" 19 #include "clang/Basic/SourceManager.h" 20 #include "clang/Basic/IdentifierTable.h" 21 #include "clang/Basic/Diagnostic.h" 22 #include "clang/Lex/Lexer.h" 23 #include "llvm/Support/MemoryBuffer.h" 24 #include "llvm/Support/raw_ostream.h" 25 #include "llvm/ADT/StringExtras.h" 26 #include "llvm/ADT/SmallPtrSet.h" 27 #include "llvm/ADT/OwningPtr.h" 28 #include "llvm/ADT/DenseSet.h" 29 30 using namespace clang; 31 using llvm::utostr; 32 33 namespace { 34 class RewriteObjC : public ASTConsumer { 35 protected: 36 37 enum { 38 BLOCK_FIELD_IS_OBJECT = 3, /* id, NSObject, __attribute__((NSObject)), 39 block, ... */ 40 BLOCK_FIELD_IS_BLOCK = 7, /* a block variable */ 41 BLOCK_FIELD_IS_BYREF = 8, /* the on stack structure holding the 42 __block variable */ 43 BLOCK_FIELD_IS_WEAK = 16, /* declared __weak, only used in byref copy 44 helpers */ 45 BLOCK_BYREF_CALLER = 128, /* called from __block (byref) copy/dispose 46 support routines */ 47 BLOCK_BYREF_CURRENT_MAX = 256 48 }; 49 50 enum { 51 BLOCK_NEEDS_FREE = (1 << 24), 52 BLOCK_HAS_COPY_DISPOSE = (1 << 25), 53 BLOCK_HAS_CXX_OBJ = (1 << 26), 54 BLOCK_IS_GC = (1 << 27), 55 BLOCK_IS_GLOBAL = (1 << 28), 56 BLOCK_HAS_DESCRIPTOR = (1 << 29) 57 }; 58 static const int OBJC_ABI_VERSION = 7; 59 60 Rewriter Rewrite; 61 DiagnosticsEngine &Diags; 62 const LangOptions &LangOpts; 63 ASTContext *Context; 64 SourceManager *SM; 65 TranslationUnitDecl *TUDecl; 66 FileID MainFileID; 67 const char *MainFileStart, *MainFileEnd; 68 Stmt *CurrentBody; 69 ParentMap *PropParentMap; // created lazily. 70 std::string InFileName; 71 raw_ostream* OutFile; 72 std::string Preamble; 73 74 TypeDecl *ProtocolTypeDecl; 75 VarDecl *GlobalVarDecl; 76 unsigned RewriteFailedDiag; 77 // ObjC string constant support. 78 unsigned NumObjCStringLiterals; 79 VarDecl *ConstantStringClassReference; 80 RecordDecl *NSStringRecord; 81 82 // ObjC foreach break/continue generation support. 83 int BcLabelCount; 84 85 unsigned TryFinallyContainsReturnDiag; 86 // Needed for super. 87 ObjCMethodDecl *CurMethodDef; 88 RecordDecl *SuperStructDecl; 89 RecordDecl *ConstantStringDecl; 90 91 FunctionDecl *MsgSendFunctionDecl; 92 FunctionDecl *MsgSendSuperFunctionDecl; 93 FunctionDecl *MsgSendStretFunctionDecl; 94 FunctionDecl *MsgSendSuperStretFunctionDecl; 95 FunctionDecl *MsgSendFpretFunctionDecl; 96 FunctionDecl *GetClassFunctionDecl; 97 FunctionDecl *GetMetaClassFunctionDecl; 98 FunctionDecl *GetSuperClassFunctionDecl; 99 FunctionDecl *SelGetUidFunctionDecl; 100 FunctionDecl *CFStringFunctionDecl; 101 FunctionDecl *SuperContructorFunctionDecl; 102 FunctionDecl *CurFunctionDef; 103 FunctionDecl *CurFunctionDeclToDeclareForBlock; 104 105 /* Misc. containers needed for meta-data rewrite. */ 106 SmallVector<ObjCImplementationDecl *, 8> ClassImplementation; 107 SmallVector<ObjCCategoryImplDecl *, 8> CategoryImplementation; 108 llvm::SmallPtrSet<ObjCInterfaceDecl*, 8> ObjCSynthesizedStructs; 109 llvm::SmallPtrSet<ObjCProtocolDecl*, 8> ObjCSynthesizedProtocols; 110 llvm::SmallPtrSet<ObjCInterfaceDecl*, 8> ObjCForwardDecls; 111 llvm::DenseMap<ObjCMethodDecl*, std::string> MethodInternalNames; 112 SmallVector<Stmt *, 32> Stmts; 113 SmallVector<int, 8> ObjCBcLabelNo; 114 // Remember all the @protocol(<expr>) expressions. 115 llvm::SmallPtrSet<ObjCProtocolDecl *, 32> ProtocolExprDecls; 116 117 llvm::DenseSet<uint64_t> CopyDestroyCache; 118 119 // Block expressions. 120 SmallVector<BlockExpr *, 32> Blocks; 121 SmallVector<int, 32> InnerDeclRefsCount; 122 SmallVector<DeclRefExpr *, 32> InnerDeclRefs; 123 124 SmallVector<DeclRefExpr *, 32> BlockDeclRefs; 125 126 // Block related declarations. 127 SmallVector<ValueDecl *, 8> BlockByCopyDecls; 128 llvm::SmallPtrSet<ValueDecl *, 8> BlockByCopyDeclsPtrSet; 129 SmallVector<ValueDecl *, 8> BlockByRefDecls; 130 llvm::SmallPtrSet<ValueDecl *, 8> BlockByRefDeclsPtrSet; 131 llvm::DenseMap<ValueDecl *, unsigned> BlockByRefDeclNo; 132 llvm::SmallPtrSet<ValueDecl *, 8> ImportedBlockDecls; 133 llvm::SmallPtrSet<VarDecl *, 8> ImportedLocalExternalDecls; 134 135 llvm::DenseMap<BlockExpr *, std::string> RewrittenBlockExprs; 136 137 // This maps an original source AST to it's rewritten form. This allows 138 // us to avoid rewriting the same node twice (which is very uncommon). 139 // This is needed to support some of the exotic property rewriting. 140 llvm::DenseMap<Stmt *, Stmt *> ReplacedNodes; 141 142 // Needed for header files being rewritten 143 bool IsHeader; 144 bool SilenceRewriteMacroWarning; 145 bool objc_impl_method; 146 147 bool DisableReplaceStmt; 148 class DisableReplaceStmtScope { 149 RewriteObjC &R; 150 bool SavedValue; 151 152 public: 153 DisableReplaceStmtScope(RewriteObjC &R) 154 : R(R), SavedValue(R.DisableReplaceStmt) { 155 R.DisableReplaceStmt = true; 156 } 157 ~DisableReplaceStmtScope() { 158 R.DisableReplaceStmt = SavedValue; 159 } 160 }; 161 void InitializeCommon(ASTContext &context); 162 163 public: 164 165 // Top Level Driver code. 166 virtual bool HandleTopLevelDecl(DeclGroupRef D) { 167 for (DeclGroupRef::iterator I = D.begin(), E = D.end(); I != E; ++I) { 168 if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(*I)) { 169 if (!Class->isThisDeclarationADefinition()) { 170 RewriteForwardClassDecl(D); 171 break; 172 } 173 } 174 175 if (ObjCProtocolDecl *Proto = dyn_cast<ObjCProtocolDecl>(*I)) { 176 if (!Proto->isThisDeclarationADefinition()) { 177 RewriteForwardProtocolDecl(D); 178 break; 179 } 180 } 181 182 HandleTopLevelSingleDecl(*I); 183 } 184 return true; 185 } 186 void HandleTopLevelSingleDecl(Decl *D); 187 void HandleDeclInMainFile(Decl *D); 188 RewriteObjC(std::string inFile, raw_ostream *OS, 189 DiagnosticsEngine &D, const LangOptions &LOpts, 190 bool silenceMacroWarn); 191 192 ~RewriteObjC() {} 193 194 virtual void HandleTranslationUnit(ASTContext &C); 195 196 void ReplaceStmt(Stmt *Old, Stmt *New) { 197 Stmt *ReplacingStmt = ReplacedNodes[Old]; 198 199 if (ReplacingStmt) 200 return; // We can't rewrite the same node twice. 201 202 if (DisableReplaceStmt) 203 return; 204 205 // If replacement succeeded or warning disabled return with no warning. 206 if (!Rewrite.ReplaceStmt(Old, New)) { 207 ReplacedNodes[Old] = New; 208 return; 209 } 210 if (SilenceRewriteMacroWarning) 211 return; 212 Diags.Report(Context->getFullLoc(Old->getLocStart()), RewriteFailedDiag) 213 << Old->getSourceRange(); 214 } 215 216 void ReplaceStmtWithRange(Stmt *Old, Stmt *New, SourceRange SrcRange) { 217 if (DisableReplaceStmt) 218 return; 219 220 // Measure the old text. 221 int Size = Rewrite.getRangeSize(SrcRange); 222 if (Size == -1) { 223 Diags.Report(Context->getFullLoc(Old->getLocStart()), RewriteFailedDiag) 224 << Old->getSourceRange(); 225 return; 226 } 227 // Get the new text. 228 std::string SStr; 229 llvm::raw_string_ostream S(SStr); 230 New->printPretty(S, *Context, 0, PrintingPolicy(LangOpts)); 231 const std::string &Str = S.str(); 232 233 // If replacement succeeded or warning disabled return with no warning. 234 if (!Rewrite.ReplaceText(SrcRange.getBegin(), Size, Str)) { 235 ReplacedNodes[Old] = New; 236 return; 237 } 238 if (SilenceRewriteMacroWarning) 239 return; 240 Diags.Report(Context->getFullLoc(Old->getLocStart()), RewriteFailedDiag) 241 << Old->getSourceRange(); 242 } 243 244 void InsertText(SourceLocation Loc, StringRef Str, 245 bool InsertAfter = true) { 246 // If insertion succeeded or warning disabled return with no warning. 247 if (!Rewrite.InsertText(Loc, Str, InsertAfter) || 248 SilenceRewriteMacroWarning) 249 return; 250 251 Diags.Report(Context->getFullLoc(Loc), RewriteFailedDiag); 252 } 253 254 void ReplaceText(SourceLocation Start, unsigned OrigLength, 255 StringRef Str) { 256 // If removal succeeded or warning disabled return with no warning. 257 if (!Rewrite.ReplaceText(Start, OrigLength, Str) || 258 SilenceRewriteMacroWarning) 259 return; 260 261 Diags.Report(Context->getFullLoc(Start), RewriteFailedDiag); 262 } 263 264 // Syntactic Rewriting. 265 void RewriteRecordBody(RecordDecl *RD); 266 void RewriteInclude(); 267 void RewriteForwardClassDecl(DeclGroupRef D); 268 void RewriteForwardClassDecl(const llvm::SmallVector<Decl*, 8> &DG); 269 void RewriteForwardClassEpilogue(ObjCInterfaceDecl *ClassDecl, 270 const std::string &typedefString); 271 void RewriteImplementations(); 272 void RewritePropertyImplDecl(ObjCPropertyImplDecl *PID, 273 ObjCImplementationDecl *IMD, 274 ObjCCategoryImplDecl *CID); 275 void RewriteInterfaceDecl(ObjCInterfaceDecl *Dcl); 276 void RewriteImplementationDecl(Decl *Dcl); 277 void RewriteObjCMethodDecl(const ObjCInterfaceDecl *IDecl, 278 ObjCMethodDecl *MDecl, std::string &ResultStr); 279 void RewriteTypeIntoString(QualType T, std::string &ResultStr, 280 const FunctionType *&FPRetType); 281 void RewriteByRefString(std::string &ResultStr, const std::string &Name, 282 ValueDecl *VD, bool def=false); 283 void RewriteCategoryDecl(ObjCCategoryDecl *Dcl); 284 void RewriteProtocolDecl(ObjCProtocolDecl *Dcl); 285 void RewriteForwardProtocolDecl(DeclGroupRef D); 286 void RewriteForwardProtocolDecl(const llvm::SmallVector<Decl*, 8> &DG); 287 void RewriteMethodDeclaration(ObjCMethodDecl *Method); 288 void RewriteProperty(ObjCPropertyDecl *prop); 289 void RewriteFunctionDecl(FunctionDecl *FD); 290 void RewriteBlockPointerType(std::string& Str, QualType Type); 291 void RewriteBlockPointerTypeVariable(std::string& Str, ValueDecl *VD); 292 void RewriteBlockLiteralFunctionDecl(FunctionDecl *FD); 293 void RewriteObjCQualifiedInterfaceTypes(Decl *Dcl); 294 void RewriteTypeOfDecl(VarDecl *VD); 295 void RewriteObjCQualifiedInterfaceTypes(Expr *E); 296 297 // Expression Rewriting. 298 Stmt *RewriteFunctionBodyOrGlobalInitializer(Stmt *S); 299 Stmt *RewriteAtEncode(ObjCEncodeExpr *Exp); 300 Stmt *RewritePropertyOrImplicitGetter(PseudoObjectExpr *Pseudo); 301 Stmt *RewritePropertyOrImplicitSetter(PseudoObjectExpr *Pseudo); 302 Stmt *RewriteAtSelector(ObjCSelectorExpr *Exp); 303 Stmt *RewriteMessageExpr(ObjCMessageExpr *Exp); 304 Stmt *RewriteObjCStringLiteral(ObjCStringLiteral *Exp); 305 Stmt *RewriteObjCProtocolExpr(ObjCProtocolExpr *Exp); 306 void RewriteTryReturnStmts(Stmt *S); 307 void RewriteSyncReturnStmts(Stmt *S, std::string buf); 308 Stmt *RewriteObjCTryStmt(ObjCAtTryStmt *S); 309 Stmt *RewriteObjCSynchronizedStmt(ObjCAtSynchronizedStmt *S); 310 Stmt *RewriteObjCThrowStmt(ObjCAtThrowStmt *S); 311 Stmt *RewriteObjCForCollectionStmt(ObjCForCollectionStmt *S, 312 SourceLocation OrigEnd); 313 Stmt *RewriteBreakStmt(BreakStmt *S); 314 Stmt *RewriteContinueStmt(ContinueStmt *S); 315 void RewriteCastExpr(CStyleCastExpr *CE); 316 317 // Block rewriting. 318 void RewriteBlocksInFunctionProtoType(QualType funcType, NamedDecl *D); 319 320 // Block specific rewrite rules. 321 void RewriteBlockPointerDecl(NamedDecl *VD); 322 void RewriteByRefVar(VarDecl *VD); 323 Stmt *RewriteBlockDeclRefExpr(DeclRefExpr *VD); 324 Stmt *RewriteLocalVariableExternalStorage(DeclRefExpr *DRE); 325 void RewriteBlockPointerFunctionArgs(FunctionDecl *FD); 326 327 void RewriteObjCInternalStruct(ObjCInterfaceDecl *CDecl, 328 std::string &Result); 329 330 virtual void Initialize(ASTContext &context) = 0; 331 332 // Metadata Rewriting. 333 virtual void RewriteMetaDataIntoBuffer(std::string &Result) = 0; 334 virtual void RewriteObjCProtocolListMetaData(const ObjCList<ObjCProtocolDecl> &Prots, 335 StringRef prefix, 336 StringRef ClassName, 337 std::string &Result) = 0; 338 virtual void RewriteObjCCategoryImplDecl(ObjCCategoryImplDecl *CDecl, 339 std::string &Result) = 0; 340 virtual void RewriteObjCProtocolMetaData(ObjCProtocolDecl *Protocol, 341 StringRef prefix, 342 StringRef ClassName, 343 std::string &Result) = 0; 344 virtual void RewriteObjCClassMetaData(ObjCImplementationDecl *IDecl, 345 std::string &Result) = 0; 346 347 // Rewriting ivar access 348 virtual Stmt *RewriteObjCIvarRefExpr(ObjCIvarRefExpr *IV) = 0; 349 virtual void RewriteIvarOffsetComputation(ObjCIvarDecl *ivar, 350 std::string &Result) = 0; 351 352 // Misc. AST transformation routines. Somtimes they end up calling 353 // rewriting routines on the new ASTs. 354 CallExpr *SynthesizeCallToFunctionDecl(FunctionDecl *FD, 355 Expr **args, unsigned nargs, 356 SourceLocation StartLoc=SourceLocation(), 357 SourceLocation EndLoc=SourceLocation()); 358 359 Stmt *SynthMessageExpr(ObjCMessageExpr *Exp, 360 SourceLocation StartLoc=SourceLocation(), 361 SourceLocation EndLoc=SourceLocation()); 362 363 void SynthCountByEnumWithState(std::string &buf); 364 void SynthMsgSendFunctionDecl(); 365 void SynthMsgSendSuperFunctionDecl(); 366 void SynthMsgSendStretFunctionDecl(); 367 void SynthMsgSendFpretFunctionDecl(); 368 void SynthMsgSendSuperStretFunctionDecl(); 369 void SynthGetClassFunctionDecl(); 370 void SynthGetMetaClassFunctionDecl(); 371 void SynthGetSuperClassFunctionDecl(); 372 void SynthSelGetUidFunctionDecl(); 373 void SynthSuperContructorFunctionDecl(); 374 375 std::string SynthesizeByrefCopyDestroyHelper(VarDecl *VD, int flag); 376 std::string SynthesizeBlockHelperFuncs(BlockExpr *CE, int i, 377 StringRef funcName, std::string Tag); 378 std::string SynthesizeBlockFunc(BlockExpr *CE, int i, 379 StringRef funcName, std::string Tag); 380 std::string SynthesizeBlockImpl(BlockExpr *CE, 381 std::string Tag, std::string Desc); 382 std::string SynthesizeBlockDescriptor(std::string DescTag, 383 std::string ImplTag, 384 int i, StringRef funcName, 385 unsigned hasCopy); 386 Stmt *SynthesizeBlockCall(CallExpr *Exp, const Expr* BlockExp); 387 void SynthesizeBlockLiterals(SourceLocation FunLocStart, 388 StringRef FunName); 389 FunctionDecl *SynthBlockInitFunctionDecl(StringRef name); 390 Stmt *SynthBlockInitExpr(BlockExpr *Exp, 391 const SmallVector<DeclRefExpr *, 8> &InnerBlockDeclRefs); 392 393 // Misc. helper routines. 394 QualType getProtocolType(); 395 void WarnAboutReturnGotoStmts(Stmt *S); 396 void HasReturnStmts(Stmt *S, bool &hasReturns); 397 void CheckFunctionPointerDecl(QualType dType, NamedDecl *ND); 398 void InsertBlockLiteralsWithinFunction(FunctionDecl *FD); 399 void InsertBlockLiteralsWithinMethod(ObjCMethodDecl *MD); 400 401 bool IsDeclStmtInForeachHeader(DeclStmt *DS); 402 void CollectBlockDeclRefInfo(BlockExpr *Exp); 403 void GetBlockDeclRefExprs(Stmt *S); 404 void GetInnerBlockDeclRefExprs(Stmt *S, 405 SmallVector<DeclRefExpr *, 8> &InnerBlockDeclRefs, 406 llvm::SmallPtrSet<const DeclContext *, 8> &InnerContexts); 407 408 // We avoid calling Type::isBlockPointerType(), since it operates on the 409 // canonical type. We only care if the top-level type is a closure pointer. 410 bool isTopLevelBlockPointerType(QualType T) { 411 return isa<BlockPointerType>(T); 412 } 413 414 /// convertBlockPointerToFunctionPointer - Converts a block-pointer type 415 /// to a function pointer type and upon success, returns true; false 416 /// otherwise. 417 bool convertBlockPointerToFunctionPointer(QualType &T) { 418 if (isTopLevelBlockPointerType(T)) { 419 const BlockPointerType *BPT = T->getAs<BlockPointerType>(); 420 T = Context->getPointerType(BPT->getPointeeType()); 421 return true; 422 } 423 return false; 424 } 425 426 bool needToScanForQualifiers(QualType T); 427 QualType getSuperStructType(); 428 QualType getConstantStringStructType(); 429 QualType convertFunctionTypeOfBlocks(const FunctionType *FT); 430 bool BufferContainsPPDirectives(const char *startBuf, const char *endBuf); 431 432 void convertToUnqualifiedObjCType(QualType &T) { 433 if (T->isObjCQualifiedIdType()) 434 T = Context->getObjCIdType(); 435 else if (T->isObjCQualifiedClassType()) 436 T = Context->getObjCClassType(); 437 else if (T->isObjCObjectPointerType() && 438 T->getPointeeType()->isObjCQualifiedInterfaceType()) { 439 if (const ObjCObjectPointerType * OBJPT = 440 T->getAsObjCInterfacePointerType()) { 441 const ObjCInterfaceType *IFaceT = OBJPT->getInterfaceType(); 442 T = QualType(IFaceT, 0); 443 T = Context->getPointerType(T); 444 } 445 } 446 } 447 448 // FIXME: This predicate seems like it would be useful to add to ASTContext. 449 bool isObjCType(QualType T) { 450 if (!LangOpts.ObjC1 && !LangOpts.ObjC2) 451 return false; 452 453 QualType OCT = Context->getCanonicalType(T).getUnqualifiedType(); 454 455 if (OCT == Context->getCanonicalType(Context->getObjCIdType()) || 456 OCT == Context->getCanonicalType(Context->getObjCClassType())) 457 return true; 458 459 if (const PointerType *PT = OCT->getAs<PointerType>()) { 460 if (isa<ObjCInterfaceType>(PT->getPointeeType()) || 461 PT->getPointeeType()->isObjCQualifiedIdType()) 462 return true; 463 } 464 return false; 465 } 466 bool PointerTypeTakesAnyBlockArguments(QualType QT); 467 bool PointerTypeTakesAnyObjCQualifiedType(QualType QT); 468 void GetExtentOfArgList(const char *Name, const char *&LParen, 469 const char *&RParen); 470 471 void QuoteDoublequotes(std::string &From, std::string &To) { 472 for (unsigned i = 0; i < From.length(); i++) { 473 if (From[i] == '"') 474 To += "\\\""; 475 else 476 To += From[i]; 477 } 478 } 479 480 QualType getSimpleFunctionType(QualType result, 481 const QualType *args, 482 unsigned numArgs, 483 bool variadic = false) { 484 if (result == Context->getObjCInstanceType()) 485 result = Context->getObjCIdType(); 486 FunctionProtoType::ExtProtoInfo fpi; 487 fpi.Variadic = variadic; 488 return Context->getFunctionType(result, args, numArgs, fpi); 489 } 490 491 // Helper function: create a CStyleCastExpr with trivial type source info. 492 CStyleCastExpr* NoTypeInfoCStyleCastExpr(ASTContext *Ctx, QualType Ty, 493 CastKind Kind, Expr *E) { 494 TypeSourceInfo *TInfo = Ctx->getTrivialTypeSourceInfo(Ty, SourceLocation()); 495 return CStyleCastExpr::Create(*Ctx, Ty, VK_RValue, Kind, E, 0, TInfo, 496 SourceLocation(), SourceLocation()); 497 } 498 }; 499 500 class RewriteObjCFragileABI : public RewriteObjC { 501 public: 502 503 RewriteObjCFragileABI(std::string inFile, raw_ostream *OS, 504 DiagnosticsEngine &D, const LangOptions &LOpts, 505 bool silenceMacroWarn) : RewriteObjC(inFile, OS, 506 D, LOpts, 507 silenceMacroWarn) {} 508 509 ~RewriteObjCFragileABI() {} 510 virtual void Initialize(ASTContext &context); 511 512 // Rewriting metadata 513 template<typename MethodIterator> 514 void RewriteObjCMethodsMetaData(MethodIterator MethodBegin, 515 MethodIterator MethodEnd, 516 bool IsInstanceMethod, 517 StringRef prefix, 518 StringRef ClassName, 519 std::string &Result); 520 virtual void RewriteObjCProtocolMetaData(ObjCProtocolDecl *Protocol, 521 StringRef prefix, 522 StringRef ClassName, 523 std::string &Result); 524 virtual void RewriteObjCProtocolListMetaData( 525 const ObjCList<ObjCProtocolDecl> &Prots, 526 StringRef prefix, StringRef ClassName, std::string &Result); 527 virtual void RewriteObjCClassMetaData(ObjCImplementationDecl *IDecl, 528 std::string &Result); 529 virtual void RewriteMetaDataIntoBuffer(std::string &Result); 530 virtual void RewriteObjCCategoryImplDecl(ObjCCategoryImplDecl *CDecl, 531 std::string &Result); 532 533 // Rewriting ivar 534 virtual void RewriteIvarOffsetComputation(ObjCIvarDecl *ivar, 535 std::string &Result); 536 virtual Stmt *RewriteObjCIvarRefExpr(ObjCIvarRefExpr *IV); 537 }; 538 } 539 540 void RewriteObjC::RewriteBlocksInFunctionProtoType(QualType funcType, 541 NamedDecl *D) { 542 if (const FunctionProtoType *fproto 543 = dyn_cast<FunctionProtoType>(funcType.IgnoreParens())) { 544 for (FunctionProtoType::arg_type_iterator I = fproto->arg_type_begin(), 545 E = fproto->arg_type_end(); I && (I != E); ++I) 546 if (isTopLevelBlockPointerType(*I)) { 547 // All the args are checked/rewritten. Don't call twice! 548 RewriteBlockPointerDecl(D); 549 break; 550 } 551 } 552 } 553 554 void RewriteObjC::CheckFunctionPointerDecl(QualType funcType, NamedDecl *ND) { 555 const PointerType *PT = funcType->getAs<PointerType>(); 556 if (PT && PointerTypeTakesAnyBlockArguments(funcType)) 557 RewriteBlocksInFunctionProtoType(PT->getPointeeType(), ND); 558 } 559 560 static bool IsHeaderFile(const std::string &Filename) { 561 std::string::size_type DotPos = Filename.rfind('.'); 562 563 if (DotPos == std::string::npos) { 564 // no file extension 565 return false; 566 } 567 568 std::string Ext = std::string(Filename.begin()+DotPos+1, Filename.end()); 569 // C header: .h 570 // C++ header: .hh or .H; 571 return Ext == "h" || Ext == "hh" || Ext == "H"; 572 } 573 574 RewriteObjC::RewriteObjC(std::string inFile, raw_ostream* OS, 575 DiagnosticsEngine &D, const LangOptions &LOpts, 576 bool silenceMacroWarn) 577 : Diags(D), LangOpts(LOpts), InFileName(inFile), OutFile(OS), 578 SilenceRewriteMacroWarning(silenceMacroWarn) { 579 IsHeader = IsHeaderFile(inFile); 580 RewriteFailedDiag = Diags.getCustomDiagID(DiagnosticsEngine::Warning, 581 "rewriting sub-expression within a macro (may not be correct)"); 582 TryFinallyContainsReturnDiag = Diags.getCustomDiagID( 583 DiagnosticsEngine::Warning, 584 "rewriter doesn't support user-specified control flow semantics " 585 "for @try/@finally (code may not execute properly)"); 586 } 587 588 ASTConsumer *clang::CreateObjCRewriter(const std::string& InFile, 589 raw_ostream* OS, 590 DiagnosticsEngine &Diags, 591 const LangOptions &LOpts, 592 bool SilenceRewriteMacroWarning) { 593 return new RewriteObjCFragileABI(InFile, OS, Diags, LOpts, SilenceRewriteMacroWarning); 594 } 595 596 void RewriteObjC::InitializeCommon(ASTContext &context) { 597 Context = &context; 598 SM = &Context->getSourceManager(); 599 TUDecl = Context->getTranslationUnitDecl(); 600 MsgSendFunctionDecl = 0; 601 MsgSendSuperFunctionDecl = 0; 602 MsgSendStretFunctionDecl = 0; 603 MsgSendSuperStretFunctionDecl = 0; 604 MsgSendFpretFunctionDecl = 0; 605 GetClassFunctionDecl = 0; 606 GetMetaClassFunctionDecl = 0; 607 GetSuperClassFunctionDecl = 0; 608 SelGetUidFunctionDecl = 0; 609 CFStringFunctionDecl = 0; 610 ConstantStringClassReference = 0; 611 NSStringRecord = 0; 612 CurMethodDef = 0; 613 CurFunctionDef = 0; 614 CurFunctionDeclToDeclareForBlock = 0; 615 GlobalVarDecl = 0; 616 SuperStructDecl = 0; 617 ProtocolTypeDecl = 0; 618 ConstantStringDecl = 0; 619 BcLabelCount = 0; 620 SuperContructorFunctionDecl = 0; 621 NumObjCStringLiterals = 0; 622 PropParentMap = 0; 623 CurrentBody = 0; 624 DisableReplaceStmt = false; 625 objc_impl_method = false; 626 627 // Get the ID and start/end of the main file. 628 MainFileID = SM->getMainFileID(); 629 const llvm::MemoryBuffer *MainBuf = SM->getBuffer(MainFileID); 630 MainFileStart = MainBuf->getBufferStart(); 631 MainFileEnd = MainBuf->getBufferEnd(); 632 633 Rewrite.setSourceMgr(Context->getSourceManager(), Context->getLangOpts()); 634 } 635 636 //===----------------------------------------------------------------------===// 637 // Top Level Driver Code 638 //===----------------------------------------------------------------------===// 639 640 void RewriteObjC::HandleTopLevelSingleDecl(Decl *D) { 641 if (Diags.hasErrorOccurred()) 642 return; 643 644 // Two cases: either the decl could be in the main file, or it could be in a 645 // #included file. If the former, rewrite it now. If the later, check to see 646 // if we rewrote the #include/#import. 647 SourceLocation Loc = D->getLocation(); 648 Loc = SM->getExpansionLoc(Loc); 649 650 // If this is for a builtin, ignore it. 651 if (Loc.isInvalid()) return; 652 653 // Look for built-in declarations that we need to refer during the rewrite. 654 if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { 655 RewriteFunctionDecl(FD); 656 } else if (VarDecl *FVD = dyn_cast<VarDecl>(D)) { 657 // declared in <Foundation/NSString.h> 658 if (FVD->getName() == "_NSConstantStringClassReference") { 659 ConstantStringClassReference = FVD; 660 return; 661 } 662 } else if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(D)) { 663 if (ID->isThisDeclarationADefinition()) 664 RewriteInterfaceDecl(ID); 665 } else if (ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(D)) { 666 RewriteCategoryDecl(CD); 667 } else if (ObjCProtocolDecl *PD = dyn_cast<ObjCProtocolDecl>(D)) { 668 if (PD->isThisDeclarationADefinition()) 669 RewriteProtocolDecl(PD); 670 } else if (LinkageSpecDecl *LSD = dyn_cast<LinkageSpecDecl>(D)) { 671 // Recurse into linkage specifications 672 for (DeclContext::decl_iterator DI = LSD->decls_begin(), 673 DIEnd = LSD->decls_end(); 674 DI != DIEnd; ) { 675 if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>((*DI))) { 676 if (!IFace->isThisDeclarationADefinition()) { 677 SmallVector<Decl *, 8> DG; 678 SourceLocation StartLoc = IFace->getLocStart(); 679 do { 680 if (isa<ObjCInterfaceDecl>(*DI) && 681 !cast<ObjCInterfaceDecl>(*DI)->isThisDeclarationADefinition() && 682 StartLoc == (*DI)->getLocStart()) 683 DG.push_back(*DI); 684 else 685 break; 686 687 ++DI; 688 } while (DI != DIEnd); 689 RewriteForwardClassDecl(DG); 690 continue; 691 } 692 } 693 694 if (ObjCProtocolDecl *Proto = dyn_cast<ObjCProtocolDecl>((*DI))) { 695 if (!Proto->isThisDeclarationADefinition()) { 696 SmallVector<Decl *, 8> DG; 697 SourceLocation StartLoc = Proto->getLocStart(); 698 do { 699 if (isa<ObjCProtocolDecl>(*DI) && 700 !cast<ObjCProtocolDecl>(*DI)->isThisDeclarationADefinition() && 701 StartLoc == (*DI)->getLocStart()) 702 DG.push_back(*DI); 703 else 704 break; 705 706 ++DI; 707 } while (DI != DIEnd); 708 RewriteForwardProtocolDecl(DG); 709 continue; 710 } 711 } 712 713 HandleTopLevelSingleDecl(*DI); 714 ++DI; 715 } 716 } 717 // If we have a decl in the main file, see if we should rewrite it. 718 if (SM->isFromMainFile(Loc)) 719 return HandleDeclInMainFile(D); 720 } 721 722 //===----------------------------------------------------------------------===// 723 // Syntactic (non-AST) Rewriting Code 724 //===----------------------------------------------------------------------===// 725 726 void RewriteObjC::RewriteInclude() { 727 SourceLocation LocStart = SM->getLocForStartOfFile(MainFileID); 728 StringRef MainBuf = SM->getBufferData(MainFileID); 729 const char *MainBufStart = MainBuf.begin(); 730 const char *MainBufEnd = MainBuf.end(); 731 size_t ImportLen = strlen("import"); 732 733 // Loop over the whole file, looking for includes. 734 for (const char *BufPtr = MainBufStart; BufPtr < MainBufEnd; ++BufPtr) { 735 if (*BufPtr == '#') { 736 if (++BufPtr == MainBufEnd) 737 return; 738 while (*BufPtr == ' ' || *BufPtr == '\t') 739 if (++BufPtr == MainBufEnd) 740 return; 741 if (!strncmp(BufPtr, "import", ImportLen)) { 742 // replace import with include 743 SourceLocation ImportLoc = 744 LocStart.getLocWithOffset(BufPtr-MainBufStart); 745 ReplaceText(ImportLoc, ImportLen, "include"); 746 BufPtr += ImportLen; 747 } 748 } 749 } 750 } 751 752 static std::string getIvarAccessString(ObjCIvarDecl *OID) { 753 const ObjCInterfaceDecl *ClassDecl = OID->getContainingInterface(); 754 std::string S; 755 S = "((struct "; 756 S += ClassDecl->getIdentifier()->getName(); 757 S += "_IMPL *)self)->"; 758 S += OID->getName(); 759 return S; 760 } 761 762 void RewriteObjC::RewritePropertyImplDecl(ObjCPropertyImplDecl *PID, 763 ObjCImplementationDecl *IMD, 764 ObjCCategoryImplDecl *CID) { 765 static bool objcGetPropertyDefined = false; 766 static bool objcSetPropertyDefined = false; 767 SourceLocation startLoc = PID->getLocStart(); 768 InsertText(startLoc, "// "); 769 const char *startBuf = SM->getCharacterData(startLoc); 770 assert((*startBuf == '@') && "bogus @synthesize location"); 771 const char *semiBuf = strchr(startBuf, ';'); 772 assert((*semiBuf == ';') && "@synthesize: can't find ';'"); 773 SourceLocation onePastSemiLoc = 774 startLoc.getLocWithOffset(semiBuf-startBuf+1); 775 776 if (PID->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic) 777 return; // FIXME: is this correct? 778 779 // Generate the 'getter' function. 780 ObjCPropertyDecl *PD = PID->getPropertyDecl(); 781 ObjCIvarDecl *OID = PID->getPropertyIvarDecl(); 782 783 if (!OID) 784 return; 785 unsigned Attributes = PD->getPropertyAttributes(); 786 if (!PD->getGetterMethodDecl()->isDefined()) { 787 bool GenGetProperty = !(Attributes & ObjCPropertyDecl::OBJC_PR_nonatomic) && 788 (Attributes & (ObjCPropertyDecl::OBJC_PR_retain | 789 ObjCPropertyDecl::OBJC_PR_copy)); 790 std::string Getr; 791 if (GenGetProperty && !objcGetPropertyDefined) { 792 objcGetPropertyDefined = true; 793 // FIXME. Is this attribute correct in all cases? 794 Getr = "\nextern \"C\" __declspec(dllimport) " 795 "id objc_getProperty(id, SEL, long, bool);\n"; 796 } 797 RewriteObjCMethodDecl(OID->getContainingInterface(), 798 PD->getGetterMethodDecl(), Getr); 799 Getr += "{ "; 800 // Synthesize an explicit cast to gain access to the ivar. 801 // See objc-act.c:objc_synthesize_new_getter() for details. 802 if (GenGetProperty) { 803 // return objc_getProperty(self, _cmd, offsetof(ClassDecl, OID), 1) 804 Getr += "typedef "; 805 const FunctionType *FPRetType = 0; 806 RewriteTypeIntoString(PD->getGetterMethodDecl()->getResultType(), Getr, 807 FPRetType); 808 Getr += " _TYPE"; 809 if (FPRetType) { 810 Getr += ")"; // close the precedence "scope" for "*". 811 812 // Now, emit the argument types (if any). 813 if (const FunctionProtoType *FT = dyn_cast<FunctionProtoType>(FPRetType)){ 814 Getr += "("; 815 for (unsigned i = 0, e = FT->getNumArgs(); i != e; ++i) { 816 if (i) Getr += ", "; 817 std::string ParamStr = FT->getArgType(i).getAsString( 818 Context->getPrintingPolicy()); 819 Getr += ParamStr; 820 } 821 if (FT->isVariadic()) { 822 if (FT->getNumArgs()) Getr += ", "; 823 Getr += "..."; 824 } 825 Getr += ")"; 826 } else 827 Getr += "()"; 828 } 829 Getr += ";\n"; 830 Getr += "return (_TYPE)"; 831 Getr += "objc_getProperty(self, _cmd, "; 832 RewriteIvarOffsetComputation(OID, Getr); 833 Getr += ", 1)"; 834 } 835 else 836 Getr += "return " + getIvarAccessString(OID); 837 Getr += "; }"; 838 InsertText(onePastSemiLoc, Getr); 839 } 840 841 if (PD->isReadOnly() || PD->getSetterMethodDecl()->isDefined()) 842 return; 843 844 // Generate the 'setter' function. 845 std::string Setr; 846 bool GenSetProperty = Attributes & (ObjCPropertyDecl::OBJC_PR_retain | 847 ObjCPropertyDecl::OBJC_PR_copy); 848 if (GenSetProperty && !objcSetPropertyDefined) { 849 objcSetPropertyDefined = true; 850 // FIXME. Is this attribute correct in all cases? 851 Setr = "\nextern \"C\" __declspec(dllimport) " 852 "void objc_setProperty (id, SEL, long, id, bool, bool);\n"; 853 } 854 855 RewriteObjCMethodDecl(OID->getContainingInterface(), 856 PD->getSetterMethodDecl(), Setr); 857 Setr += "{ "; 858 // Synthesize an explicit cast to initialize the ivar. 859 // See objc-act.c:objc_synthesize_new_setter() for details. 860 if (GenSetProperty) { 861 Setr += "objc_setProperty (self, _cmd, "; 862 RewriteIvarOffsetComputation(OID, Setr); 863 Setr += ", (id)"; 864 Setr += PD->getName(); 865 Setr += ", "; 866 if (Attributes & ObjCPropertyDecl::OBJC_PR_nonatomic) 867 Setr += "0, "; 868 else 869 Setr += "1, "; 870 if (Attributes & ObjCPropertyDecl::OBJC_PR_copy) 871 Setr += "1)"; 872 else 873 Setr += "0)"; 874 } 875 else { 876 Setr += getIvarAccessString(OID) + " = "; 877 Setr += PD->getName(); 878 } 879 Setr += "; }"; 880 InsertText(onePastSemiLoc, Setr); 881 } 882 883 static void RewriteOneForwardClassDecl(ObjCInterfaceDecl *ForwardDecl, 884 std::string &typedefString) { 885 typedefString += "#ifndef _REWRITER_typedef_"; 886 typedefString += ForwardDecl->getNameAsString(); 887 typedefString += "\n"; 888 typedefString += "#define _REWRITER_typedef_"; 889 typedefString += ForwardDecl->getNameAsString(); 890 typedefString += "\n"; 891 typedefString += "typedef struct objc_object "; 892 typedefString += ForwardDecl->getNameAsString(); 893 typedefString += ";\n#endif\n"; 894 } 895 896 void RewriteObjC::RewriteForwardClassEpilogue(ObjCInterfaceDecl *ClassDecl, 897 const std::string &typedefString) { 898 SourceLocation startLoc = ClassDecl->getLocStart(); 899 const char *startBuf = SM->getCharacterData(startLoc); 900 const char *semiPtr = strchr(startBuf, ';'); 901 // Replace the @class with typedefs corresponding to the classes. 902 ReplaceText(startLoc, semiPtr-startBuf+1, typedefString); 903 } 904 905 void RewriteObjC::RewriteForwardClassDecl(DeclGroupRef D) { 906 std::string typedefString; 907 for (DeclGroupRef::iterator I = D.begin(), E = D.end(); I != E; ++I) { 908 ObjCInterfaceDecl *ForwardDecl = cast<ObjCInterfaceDecl>(*I); 909 if (I == D.begin()) { 910 // Translate to typedef's that forward reference structs with the same name 911 // as the class. As a convenience, we include the original declaration 912 // as a comment. 913 typedefString += "// @class "; 914 typedefString += ForwardDecl->getNameAsString(); 915 typedefString += ";\n"; 916 } 917 RewriteOneForwardClassDecl(ForwardDecl, typedefString); 918 } 919 DeclGroupRef::iterator I = D.begin(); 920 RewriteForwardClassEpilogue(cast<ObjCInterfaceDecl>(*I), typedefString); 921 } 922 923 void RewriteObjC::RewriteForwardClassDecl( 924 const llvm::SmallVector<Decl*, 8> &D) { 925 std::string typedefString; 926 for (unsigned i = 0; i < D.size(); i++) { 927 ObjCInterfaceDecl *ForwardDecl = cast<ObjCInterfaceDecl>(D[i]); 928 if (i == 0) { 929 typedefString += "// @class "; 930 typedefString += ForwardDecl->getNameAsString(); 931 typedefString += ";\n"; 932 } 933 RewriteOneForwardClassDecl(ForwardDecl, typedefString); 934 } 935 RewriteForwardClassEpilogue(cast<ObjCInterfaceDecl>(D[0]), typedefString); 936 } 937 938 void RewriteObjC::RewriteMethodDeclaration(ObjCMethodDecl *Method) { 939 // When method is a synthesized one, such as a getter/setter there is 940 // nothing to rewrite. 941 if (Method->isImplicit()) 942 return; 943 SourceLocation LocStart = Method->getLocStart(); 944 SourceLocation LocEnd = Method->getLocEnd(); 945 946 if (SM->getExpansionLineNumber(LocEnd) > 947 SM->getExpansionLineNumber(LocStart)) { 948 InsertText(LocStart, "#if 0\n"); 949 ReplaceText(LocEnd, 1, ";\n#endif\n"); 950 } else { 951 InsertText(LocStart, "// "); 952 } 953 } 954 955 void RewriteObjC::RewriteProperty(ObjCPropertyDecl *prop) { 956 SourceLocation Loc = prop->getAtLoc(); 957 958 ReplaceText(Loc, 0, "// "); 959 // FIXME: handle properties that are declared across multiple lines. 960 } 961 962 void RewriteObjC::RewriteCategoryDecl(ObjCCategoryDecl *CatDecl) { 963 SourceLocation LocStart = CatDecl->getLocStart(); 964 965 // FIXME: handle category headers that are declared across multiple lines. 966 ReplaceText(LocStart, 0, "// "); 967 968 for (ObjCCategoryDecl::prop_iterator I = CatDecl->prop_begin(), 969 E = CatDecl->prop_end(); I != E; ++I) 970 RewriteProperty(*I); 971 972 for (ObjCCategoryDecl::instmeth_iterator 973 I = CatDecl->instmeth_begin(), E = CatDecl->instmeth_end(); 974 I != E; ++I) 975 RewriteMethodDeclaration(*I); 976 for (ObjCCategoryDecl::classmeth_iterator 977 I = CatDecl->classmeth_begin(), E = CatDecl->classmeth_end(); 978 I != E; ++I) 979 RewriteMethodDeclaration(*I); 980 981 // Lastly, comment out the @end. 982 ReplaceText(CatDecl->getAtEndRange().getBegin(), 983 strlen("@end"), "/* @end */"); 984 } 985 986 void RewriteObjC::RewriteProtocolDecl(ObjCProtocolDecl *PDecl) { 987 SourceLocation LocStart = PDecl->getLocStart(); 988 assert(PDecl->isThisDeclarationADefinition()); 989 990 // FIXME: handle protocol headers that are declared across multiple lines. 991 ReplaceText(LocStart, 0, "// "); 992 993 for (ObjCProtocolDecl::instmeth_iterator 994 I = PDecl->instmeth_begin(), E = PDecl->instmeth_end(); 995 I != E; ++I) 996 RewriteMethodDeclaration(*I); 997 for (ObjCProtocolDecl::classmeth_iterator 998 I = PDecl->classmeth_begin(), E = PDecl->classmeth_end(); 999 I != E; ++I) 1000 RewriteMethodDeclaration(*I); 1001 1002 for (ObjCInterfaceDecl::prop_iterator I = PDecl->prop_begin(), 1003 E = PDecl->prop_end(); I != E; ++I) 1004 RewriteProperty(*I); 1005 1006 // Lastly, comment out the @end. 1007 SourceLocation LocEnd = PDecl->getAtEndRange().getBegin(); 1008 ReplaceText(LocEnd, strlen("@end"), "/* @end */"); 1009 1010 // Must comment out @optional/@required 1011 const char *startBuf = SM->getCharacterData(LocStart); 1012 const char *endBuf = SM->getCharacterData(LocEnd); 1013 for (const char *p = startBuf; p < endBuf; p++) { 1014 if (*p == '@' && !strncmp(p+1, "optional", strlen("optional"))) { 1015 SourceLocation OptionalLoc = LocStart.getLocWithOffset(p-startBuf); 1016 ReplaceText(OptionalLoc, strlen("@optional"), "/* @optional */"); 1017 1018 } 1019 else if (*p == '@' && !strncmp(p+1, "required", strlen("required"))) { 1020 SourceLocation OptionalLoc = LocStart.getLocWithOffset(p-startBuf); 1021 ReplaceText(OptionalLoc, strlen("@required"), "/* @required */"); 1022 1023 } 1024 } 1025 } 1026 1027 void RewriteObjC::RewriteForwardProtocolDecl(DeclGroupRef D) { 1028 SourceLocation LocStart = (*D.begin())->getLocStart(); 1029 if (LocStart.isInvalid()) 1030 llvm_unreachable("Invalid SourceLocation"); 1031 // FIXME: handle forward protocol that are declared across multiple lines. 1032 ReplaceText(LocStart, 0, "// "); 1033 } 1034 1035 void 1036 RewriteObjC::RewriteForwardProtocolDecl(const llvm::SmallVector<Decl*, 8> &DG) { 1037 SourceLocation LocStart = DG[0]->getLocStart(); 1038 if (LocStart.isInvalid()) 1039 llvm_unreachable("Invalid SourceLocation"); 1040 // FIXME: handle forward protocol that are declared across multiple lines. 1041 ReplaceText(LocStart, 0, "// "); 1042 } 1043 1044 void RewriteObjC::RewriteTypeIntoString(QualType T, std::string &ResultStr, 1045 const FunctionType *&FPRetType) { 1046 if (T->isObjCQualifiedIdType()) 1047 ResultStr += "id"; 1048 else if (T->isFunctionPointerType() || 1049 T->isBlockPointerType()) { 1050 // needs special handling, since pointer-to-functions have special 1051 // syntax (where a decaration models use). 1052 QualType retType = T; 1053 QualType PointeeTy; 1054 if (const PointerType* PT = retType->getAs<PointerType>()) 1055 PointeeTy = PT->getPointeeType(); 1056 else if (const BlockPointerType *BPT = retType->getAs<BlockPointerType>()) 1057 PointeeTy = BPT->getPointeeType(); 1058 if ((FPRetType = PointeeTy->getAs<FunctionType>())) { 1059 ResultStr += FPRetType->getResultType().getAsString( 1060 Context->getPrintingPolicy()); 1061 ResultStr += "(*"; 1062 } 1063 } else 1064 ResultStr += T.getAsString(Context->getPrintingPolicy()); 1065 } 1066 1067 void RewriteObjC::RewriteObjCMethodDecl(const ObjCInterfaceDecl *IDecl, 1068 ObjCMethodDecl *OMD, 1069 std::string &ResultStr) { 1070 //fprintf(stderr,"In RewriteObjCMethodDecl\n"); 1071 const FunctionType *FPRetType = 0; 1072 ResultStr += "\nstatic "; 1073 RewriteTypeIntoString(OMD->getResultType(), ResultStr, FPRetType); 1074 ResultStr += " "; 1075 1076 // Unique method name 1077 std::string NameStr; 1078 1079 if (OMD->isInstanceMethod()) 1080 NameStr += "_I_"; 1081 else 1082 NameStr += "_C_"; 1083 1084 NameStr += IDecl->getNameAsString(); 1085 NameStr += "_"; 1086 1087 if (ObjCCategoryImplDecl *CID = 1088 dyn_cast<ObjCCategoryImplDecl>(OMD->getDeclContext())) { 1089 NameStr += CID->getNameAsString(); 1090 NameStr += "_"; 1091 } 1092 // Append selector names, replacing ':' with '_' 1093 { 1094 std::string selString = OMD->getSelector().getAsString(); 1095 int len = selString.size(); 1096 for (int i = 0; i < len; i++) 1097 if (selString[i] == ':') 1098 selString[i] = '_'; 1099 NameStr += selString; 1100 } 1101 // Remember this name for metadata emission 1102 MethodInternalNames[OMD] = NameStr; 1103 ResultStr += NameStr; 1104 1105 // Rewrite arguments 1106 ResultStr += "("; 1107 1108 // invisible arguments 1109 if (OMD->isInstanceMethod()) { 1110 QualType selfTy = Context->getObjCInterfaceType(IDecl); 1111 selfTy = Context->getPointerType(selfTy); 1112 if (!LangOpts.MicrosoftExt) { 1113 if (ObjCSynthesizedStructs.count(const_cast<ObjCInterfaceDecl*>(IDecl))) 1114 ResultStr += "struct "; 1115 } 1116 // When rewriting for Microsoft, explicitly omit the structure name. 1117 ResultStr += IDecl->getNameAsString(); 1118 ResultStr += " *"; 1119 } 1120 else 1121 ResultStr += Context->getObjCClassType().getAsString( 1122 Context->getPrintingPolicy()); 1123 1124 ResultStr += " self, "; 1125 ResultStr += Context->getObjCSelType().getAsString(Context->getPrintingPolicy()); 1126 ResultStr += " _cmd"; 1127 1128 // Method arguments. 1129 for (ObjCMethodDecl::param_iterator PI = OMD->param_begin(), 1130 E = OMD->param_end(); PI != E; ++PI) { 1131 ParmVarDecl *PDecl = *PI; 1132 ResultStr += ", "; 1133 if (PDecl->getType()->isObjCQualifiedIdType()) { 1134 ResultStr += "id "; 1135 ResultStr += PDecl->getNameAsString(); 1136 } else { 1137 std::string Name = PDecl->getNameAsString(); 1138 QualType QT = PDecl->getType(); 1139 // Make sure we convert "t (^)(...)" to "t (*)(...)". 1140 (void)convertBlockPointerToFunctionPointer(QT); 1141 QT.getAsStringInternal(Name, Context->getPrintingPolicy()); 1142 ResultStr += Name; 1143 } 1144 } 1145 if (OMD->isVariadic()) 1146 ResultStr += ", ..."; 1147 ResultStr += ") "; 1148 1149 if (FPRetType) { 1150 ResultStr += ")"; // close the precedence "scope" for "*". 1151 1152 // Now, emit the argument types (if any). 1153 if (const FunctionProtoType *FT = dyn_cast<FunctionProtoType>(FPRetType)) { 1154 ResultStr += "("; 1155 for (unsigned i = 0, e = FT->getNumArgs(); i != e; ++i) { 1156 if (i) ResultStr += ", "; 1157 std::string ParamStr = FT->getArgType(i).getAsString( 1158 Context->getPrintingPolicy()); 1159 ResultStr += ParamStr; 1160 } 1161 if (FT->isVariadic()) { 1162 if (FT->getNumArgs()) ResultStr += ", "; 1163 ResultStr += "..."; 1164 } 1165 ResultStr += ")"; 1166 } else { 1167 ResultStr += "()"; 1168 } 1169 } 1170 } 1171 void RewriteObjC::RewriteImplementationDecl(Decl *OID) { 1172 ObjCImplementationDecl *IMD = dyn_cast<ObjCImplementationDecl>(OID); 1173 ObjCCategoryImplDecl *CID = dyn_cast<ObjCCategoryImplDecl>(OID); 1174 1175 InsertText(IMD ? IMD->getLocStart() : CID->getLocStart(), "// "); 1176 1177 for (ObjCCategoryImplDecl::instmeth_iterator 1178 I = IMD ? IMD->instmeth_begin() : CID->instmeth_begin(), 1179 E = IMD ? IMD->instmeth_end() : CID->instmeth_end(); 1180 I != E; ++I) { 1181 std::string ResultStr; 1182 ObjCMethodDecl *OMD = *I; 1183 RewriteObjCMethodDecl(OMD->getClassInterface(), OMD, ResultStr); 1184 SourceLocation LocStart = OMD->getLocStart(); 1185 SourceLocation LocEnd = OMD->getCompoundBody()->getLocStart(); 1186 1187 const char *startBuf = SM->getCharacterData(LocStart); 1188 const char *endBuf = SM->getCharacterData(LocEnd); 1189 ReplaceText(LocStart, endBuf-startBuf, ResultStr); 1190 } 1191 1192 for (ObjCCategoryImplDecl::classmeth_iterator 1193 I = IMD ? IMD->classmeth_begin() : CID->classmeth_begin(), 1194 E = IMD ? IMD->classmeth_end() : CID->classmeth_end(); 1195 I != E; ++I) { 1196 std::string ResultStr; 1197 ObjCMethodDecl *OMD = *I; 1198 RewriteObjCMethodDecl(OMD->getClassInterface(), OMD, ResultStr); 1199 SourceLocation LocStart = OMD->getLocStart(); 1200 SourceLocation LocEnd = OMD->getCompoundBody()->getLocStart(); 1201 1202 const char *startBuf = SM->getCharacterData(LocStart); 1203 const char *endBuf = SM->getCharacterData(LocEnd); 1204 ReplaceText(LocStart, endBuf-startBuf, ResultStr); 1205 } 1206 for (ObjCCategoryImplDecl::propimpl_iterator 1207 I = IMD ? IMD->propimpl_begin() : CID->propimpl_begin(), 1208 E = IMD ? IMD->propimpl_end() : CID->propimpl_end(); 1209 I != E; ++I) { 1210 RewritePropertyImplDecl(*I, IMD, CID); 1211 } 1212 1213 InsertText(IMD ? IMD->getLocEnd() : CID->getLocEnd(), "// "); 1214 } 1215 1216 void RewriteObjC::RewriteInterfaceDecl(ObjCInterfaceDecl *ClassDecl) { 1217 std::string ResultStr; 1218 if (!ObjCForwardDecls.count(ClassDecl->getCanonicalDecl())) { 1219 // we haven't seen a forward decl - generate a typedef. 1220 ResultStr = "#ifndef _REWRITER_typedef_"; 1221 ResultStr += ClassDecl->getNameAsString(); 1222 ResultStr += "\n"; 1223 ResultStr += "#define _REWRITER_typedef_"; 1224 ResultStr += ClassDecl->getNameAsString(); 1225 ResultStr += "\n"; 1226 ResultStr += "typedef struct objc_object "; 1227 ResultStr += ClassDecl->getNameAsString(); 1228 ResultStr += ";\n#endif\n"; 1229 // Mark this typedef as having been generated. 1230 ObjCForwardDecls.insert(ClassDecl->getCanonicalDecl()); 1231 } 1232 RewriteObjCInternalStruct(ClassDecl, ResultStr); 1233 1234 for (ObjCInterfaceDecl::prop_iterator I = ClassDecl->prop_begin(), 1235 E = ClassDecl->prop_end(); I != E; ++I) 1236 RewriteProperty(*I); 1237 for (ObjCInterfaceDecl::instmeth_iterator 1238 I = ClassDecl->instmeth_begin(), E = ClassDecl->instmeth_end(); 1239 I != E; ++I) 1240 RewriteMethodDeclaration(*I); 1241 for (ObjCInterfaceDecl::classmeth_iterator 1242 I = ClassDecl->classmeth_begin(), E = ClassDecl->classmeth_end(); 1243 I != E; ++I) 1244 RewriteMethodDeclaration(*I); 1245 1246 // Lastly, comment out the @end. 1247 ReplaceText(ClassDecl->getAtEndRange().getBegin(), strlen("@end"), 1248 "/* @end */"); 1249 } 1250 1251 Stmt *RewriteObjC::RewritePropertyOrImplicitSetter(PseudoObjectExpr *PseudoOp) { 1252 SourceRange OldRange = PseudoOp->getSourceRange(); 1253 1254 // We just magically know some things about the structure of this 1255 // expression. 1256 ObjCMessageExpr *OldMsg = 1257 cast<ObjCMessageExpr>(PseudoOp->getSemanticExpr( 1258 PseudoOp->getNumSemanticExprs() - 1)); 1259 1260 // Because the rewriter doesn't allow us to rewrite rewritten code, 1261 // we need to suppress rewriting the sub-statements. 1262 Expr *Base, *RHS; 1263 { 1264 DisableReplaceStmtScope S(*this); 1265 1266 // Rebuild the base expression if we have one. 1267 Base = 0; 1268 if (OldMsg->getReceiverKind() == ObjCMessageExpr::Instance) { 1269 Base = OldMsg->getInstanceReceiver(); 1270 Base = cast<OpaqueValueExpr>(Base)->getSourceExpr(); 1271 Base = cast<Expr>(RewriteFunctionBodyOrGlobalInitializer(Base)); 1272 } 1273 1274 // Rebuild the RHS. 1275 RHS = cast<BinaryOperator>(PseudoOp->getSyntacticForm())->getRHS(); 1276 RHS = cast<OpaqueValueExpr>(RHS)->getSourceExpr(); 1277 RHS = cast<Expr>(RewriteFunctionBodyOrGlobalInitializer(RHS)); 1278 } 1279 1280 // TODO: avoid this copy. 1281 SmallVector<SourceLocation, 1> SelLocs; 1282 OldMsg->getSelectorLocs(SelLocs); 1283 1284 ObjCMessageExpr *NewMsg = 0; 1285 switch (OldMsg->getReceiverKind()) { 1286 case ObjCMessageExpr::Class: 1287 NewMsg = ObjCMessageExpr::Create(*Context, OldMsg->getType(), 1288 OldMsg->getValueKind(), 1289 OldMsg->getLeftLoc(), 1290 OldMsg->getClassReceiverTypeInfo(), 1291 OldMsg->getSelector(), 1292 SelLocs, 1293 OldMsg->getMethodDecl(), 1294 RHS, 1295 OldMsg->getRightLoc(), 1296 OldMsg->isImplicit()); 1297 break; 1298 1299 case ObjCMessageExpr::Instance: 1300 NewMsg = ObjCMessageExpr::Create(*Context, OldMsg->getType(), 1301 OldMsg->getValueKind(), 1302 OldMsg->getLeftLoc(), 1303 Base, 1304 OldMsg->getSelector(), 1305 SelLocs, 1306 OldMsg->getMethodDecl(), 1307 RHS, 1308 OldMsg->getRightLoc(), 1309 OldMsg->isImplicit()); 1310 break; 1311 1312 case ObjCMessageExpr::SuperClass: 1313 case ObjCMessageExpr::SuperInstance: 1314 NewMsg = ObjCMessageExpr::Create(*Context, OldMsg->getType(), 1315 OldMsg->getValueKind(), 1316 OldMsg->getLeftLoc(), 1317 OldMsg->getSuperLoc(), 1318 OldMsg->getReceiverKind() == ObjCMessageExpr::SuperInstance, 1319 OldMsg->getSuperType(), 1320 OldMsg->getSelector(), 1321 SelLocs, 1322 OldMsg->getMethodDecl(), 1323 RHS, 1324 OldMsg->getRightLoc(), 1325 OldMsg->isImplicit()); 1326 break; 1327 } 1328 1329 Stmt *Replacement = SynthMessageExpr(NewMsg); 1330 ReplaceStmtWithRange(PseudoOp, Replacement, OldRange); 1331 return Replacement; 1332 } 1333 1334 Stmt *RewriteObjC::RewritePropertyOrImplicitGetter(PseudoObjectExpr *PseudoOp) { 1335 SourceRange OldRange = PseudoOp->getSourceRange(); 1336 1337 // We just magically know some things about the structure of this 1338 // expression. 1339 ObjCMessageExpr *OldMsg = 1340 cast<ObjCMessageExpr>(PseudoOp->getResultExpr()->IgnoreImplicit()); 1341 1342 // Because the rewriter doesn't allow us to rewrite rewritten code, 1343 // we need to suppress rewriting the sub-statements. 1344 Expr *Base = 0; 1345 { 1346 DisableReplaceStmtScope S(*this); 1347 1348 // Rebuild the base expression if we have one. 1349 if (OldMsg->getReceiverKind() == ObjCMessageExpr::Instance) { 1350 Base = OldMsg->getInstanceReceiver(); 1351 Base = cast<OpaqueValueExpr>(Base)->getSourceExpr(); 1352 Base = cast<Expr>(RewriteFunctionBodyOrGlobalInitializer(Base)); 1353 } 1354 } 1355 1356 // Intentionally empty. 1357 SmallVector<SourceLocation, 1> SelLocs; 1358 SmallVector<Expr*, 1> Args; 1359 1360 ObjCMessageExpr *NewMsg = 0; 1361 switch (OldMsg->getReceiverKind()) { 1362 case ObjCMessageExpr::Class: 1363 NewMsg = ObjCMessageExpr::Create(*Context, OldMsg->getType(), 1364 OldMsg->getValueKind(), 1365 OldMsg->getLeftLoc(), 1366 OldMsg->getClassReceiverTypeInfo(), 1367 OldMsg->getSelector(), 1368 SelLocs, 1369 OldMsg->getMethodDecl(), 1370 Args, 1371 OldMsg->getRightLoc(), 1372 OldMsg->isImplicit()); 1373 break; 1374 1375 case ObjCMessageExpr::Instance: 1376 NewMsg = ObjCMessageExpr::Create(*Context, OldMsg->getType(), 1377 OldMsg->getValueKind(), 1378 OldMsg->getLeftLoc(), 1379 Base, 1380 OldMsg->getSelector(), 1381 SelLocs, 1382 OldMsg->getMethodDecl(), 1383 Args, 1384 OldMsg->getRightLoc(), 1385 OldMsg->isImplicit()); 1386 break; 1387 1388 case ObjCMessageExpr::SuperClass: 1389 case ObjCMessageExpr::SuperInstance: 1390 NewMsg = ObjCMessageExpr::Create(*Context, OldMsg->getType(), 1391 OldMsg->getValueKind(), 1392 OldMsg->getLeftLoc(), 1393 OldMsg->getSuperLoc(), 1394 OldMsg->getReceiverKind() == ObjCMessageExpr::SuperInstance, 1395 OldMsg->getSuperType(), 1396 OldMsg->getSelector(), 1397 SelLocs, 1398 OldMsg->getMethodDecl(), 1399 Args, 1400 OldMsg->getRightLoc(), 1401 OldMsg->isImplicit()); 1402 break; 1403 } 1404 1405 Stmt *Replacement = SynthMessageExpr(NewMsg); 1406 ReplaceStmtWithRange(PseudoOp, Replacement, OldRange); 1407 return Replacement; 1408 } 1409 1410 /// SynthCountByEnumWithState - To print: 1411 /// ((unsigned int (*) 1412 /// (id, SEL, struct __objcFastEnumerationState *, id *, unsigned int)) 1413 /// (void *)objc_msgSend)((id)l_collection, 1414 /// sel_registerName( 1415 /// "countByEnumeratingWithState:objects:count:"), 1416 /// &enumState, 1417 /// (id *)__rw_items, (unsigned int)16) 1418 /// 1419 void RewriteObjC::SynthCountByEnumWithState(std::string &buf) { 1420 buf += "((unsigned int (*) (id, SEL, struct __objcFastEnumerationState *, " 1421 "id *, unsigned int))(void *)objc_msgSend)"; 1422 buf += "\n\t\t"; 1423 buf += "((id)l_collection,\n\t\t"; 1424 buf += "sel_registerName(\"countByEnumeratingWithState:objects:count:\"),"; 1425 buf += "\n\t\t"; 1426 buf += "&enumState, " 1427 "(id *)__rw_items, (unsigned int)16)"; 1428 } 1429 1430 /// RewriteBreakStmt - Rewrite for a break-stmt inside an ObjC2's foreach 1431 /// statement to exit to its outer synthesized loop. 1432 /// 1433 Stmt *RewriteObjC::RewriteBreakStmt(BreakStmt *S) { 1434 if (Stmts.empty() || !isa<ObjCForCollectionStmt>(Stmts.back())) 1435 return S; 1436 // replace break with goto __break_label 1437 std::string buf; 1438 1439 SourceLocation startLoc = S->getLocStart(); 1440 buf = "goto __break_label_"; 1441 buf += utostr(ObjCBcLabelNo.back()); 1442 ReplaceText(startLoc, strlen("break"), buf); 1443 1444 return 0; 1445 } 1446 1447 /// RewriteContinueStmt - Rewrite for a continue-stmt inside an ObjC2's foreach 1448 /// statement to continue with its inner synthesized loop. 1449 /// 1450 Stmt *RewriteObjC::RewriteContinueStmt(ContinueStmt *S) { 1451 if (Stmts.empty() || !isa<ObjCForCollectionStmt>(Stmts.back())) 1452 return S; 1453 // replace continue with goto __continue_label 1454 std::string buf; 1455 1456 SourceLocation startLoc = S->getLocStart(); 1457 buf = "goto __continue_label_"; 1458 buf += utostr(ObjCBcLabelNo.back()); 1459 ReplaceText(startLoc, strlen("continue"), buf); 1460 1461 return 0; 1462 } 1463 1464 /// RewriteObjCForCollectionStmt - Rewriter for ObjC2's foreach statement. 1465 /// It rewrites: 1466 /// for ( type elem in collection) { stmts; } 1467 1468 /// Into: 1469 /// { 1470 /// type elem; 1471 /// struct __objcFastEnumerationState enumState = { 0 }; 1472 /// id __rw_items[16]; 1473 /// id l_collection = (id)collection; 1474 /// unsigned long limit = [l_collection countByEnumeratingWithState:&enumState 1475 /// objects:__rw_items count:16]; 1476 /// if (limit) { 1477 /// unsigned long startMutations = *enumState.mutationsPtr; 1478 /// do { 1479 /// unsigned long counter = 0; 1480 /// do { 1481 /// if (startMutations != *enumState.mutationsPtr) 1482 /// objc_enumerationMutation(l_collection); 1483 /// elem = (type)enumState.itemsPtr[counter++]; 1484 /// stmts; 1485 /// __continue_label: ; 1486 /// } while (counter < limit); 1487 /// } while (limit = [l_collection countByEnumeratingWithState:&enumState 1488 /// objects:__rw_items count:16]); 1489 /// elem = nil; 1490 /// __break_label: ; 1491 /// } 1492 /// else 1493 /// elem = nil; 1494 /// } 1495 /// 1496 Stmt *RewriteObjC::RewriteObjCForCollectionStmt(ObjCForCollectionStmt *S, 1497 SourceLocation OrigEnd) { 1498 assert(!Stmts.empty() && "ObjCForCollectionStmt - Statement stack empty"); 1499 assert(isa<ObjCForCollectionStmt>(Stmts.back()) && 1500 "ObjCForCollectionStmt Statement stack mismatch"); 1501 assert(!ObjCBcLabelNo.empty() && 1502 "ObjCForCollectionStmt - Label No stack empty"); 1503 1504 SourceLocation startLoc = S->getLocStart(); 1505 const char *startBuf = SM->getCharacterData(startLoc); 1506 StringRef elementName; 1507 std::string elementTypeAsString; 1508 std::string buf; 1509 buf = "\n{\n\t"; 1510 if (DeclStmt *DS = dyn_cast<DeclStmt>(S->getElement())) { 1511 // type elem; 1512 NamedDecl* D = cast<NamedDecl>(DS->getSingleDecl()); 1513 QualType ElementType = cast<ValueDecl>(D)->getType(); 1514 if (ElementType->isObjCQualifiedIdType() || 1515 ElementType->isObjCQualifiedInterfaceType()) 1516 // Simply use 'id' for all qualified types. 1517 elementTypeAsString = "id"; 1518 else 1519 elementTypeAsString = ElementType.getAsString(Context->getPrintingPolicy()); 1520 buf += elementTypeAsString; 1521 buf += " "; 1522 elementName = D->getName(); 1523 buf += elementName; 1524 buf += ";\n\t"; 1525 } 1526 else { 1527 DeclRefExpr *DR = cast<DeclRefExpr>(S->getElement()); 1528 elementName = DR->getDecl()->getName(); 1529 ValueDecl *VD = cast<ValueDecl>(DR->getDecl()); 1530 if (VD->getType()->isObjCQualifiedIdType() || 1531 VD->getType()->isObjCQualifiedInterfaceType()) 1532 // Simply use 'id' for all qualified types. 1533 elementTypeAsString = "id"; 1534 else 1535 elementTypeAsString = VD->getType().getAsString(Context->getPrintingPolicy()); 1536 } 1537 1538 // struct __objcFastEnumerationState enumState = { 0 }; 1539 buf += "struct __objcFastEnumerationState enumState = { 0 };\n\t"; 1540 // id __rw_items[16]; 1541 buf += "id __rw_items[16];\n\t"; 1542 // id l_collection = (id) 1543 buf += "id l_collection = (id)"; 1544 // Find start location of 'collection' the hard way! 1545 const char *startCollectionBuf = startBuf; 1546 startCollectionBuf += 3; // skip 'for' 1547 startCollectionBuf = strchr(startCollectionBuf, '('); 1548 startCollectionBuf++; // skip '(' 1549 // find 'in' and skip it. 1550 while (*startCollectionBuf != ' ' || 1551 *(startCollectionBuf+1) != 'i' || *(startCollectionBuf+2) != 'n' || 1552 (*(startCollectionBuf+3) != ' ' && 1553 *(startCollectionBuf+3) != '[' && *(startCollectionBuf+3) != '(')) 1554 startCollectionBuf++; 1555 startCollectionBuf += 3; 1556 1557 // Replace: "for (type element in" with string constructed thus far. 1558 ReplaceText(startLoc, startCollectionBuf - startBuf, buf); 1559 // Replace ')' in for '(' type elem in collection ')' with ';' 1560 SourceLocation rightParenLoc = S->getRParenLoc(); 1561 const char *rparenBuf = SM->getCharacterData(rightParenLoc); 1562 SourceLocation lparenLoc = startLoc.getLocWithOffset(rparenBuf-startBuf); 1563 buf = ";\n\t"; 1564 1565 // unsigned long limit = [l_collection countByEnumeratingWithState:&enumState 1566 // objects:__rw_items count:16]; 1567 // which is synthesized into: 1568 // unsigned int limit = 1569 // ((unsigned int (*) 1570 // (id, SEL, struct __objcFastEnumerationState *, id *, unsigned int)) 1571 // (void *)objc_msgSend)((id)l_collection, 1572 // sel_registerName( 1573 // "countByEnumeratingWithState:objects:count:"), 1574 // (struct __objcFastEnumerationState *)&state, 1575 // (id *)__rw_items, (unsigned int)16); 1576 buf += "unsigned long limit =\n\t\t"; 1577 SynthCountByEnumWithState(buf); 1578 buf += ";\n\t"; 1579 /// if (limit) { 1580 /// unsigned long startMutations = *enumState.mutationsPtr; 1581 /// do { 1582 /// unsigned long counter = 0; 1583 /// do { 1584 /// if (startMutations != *enumState.mutationsPtr) 1585 /// objc_enumerationMutation(l_collection); 1586 /// elem = (type)enumState.itemsPtr[counter++]; 1587 buf += "if (limit) {\n\t"; 1588 buf += "unsigned long startMutations = *enumState.mutationsPtr;\n\t"; 1589 buf += "do {\n\t\t"; 1590 buf += "unsigned long counter = 0;\n\t\t"; 1591 buf += "do {\n\t\t\t"; 1592 buf += "if (startMutations != *enumState.mutationsPtr)\n\t\t\t\t"; 1593 buf += "objc_enumerationMutation(l_collection);\n\t\t\t"; 1594 buf += elementName; 1595 buf += " = ("; 1596 buf += elementTypeAsString; 1597 buf += ")enumState.itemsPtr[counter++];"; 1598 // Replace ')' in for '(' type elem in collection ')' with all of these. 1599 ReplaceText(lparenLoc, 1, buf); 1600 1601 /// __continue_label: ; 1602 /// } while (counter < limit); 1603 /// } while (limit = [l_collection countByEnumeratingWithState:&enumState 1604 /// objects:__rw_items count:16]); 1605 /// elem = nil; 1606 /// __break_label: ; 1607 /// } 1608 /// else 1609 /// elem = nil; 1610 /// } 1611 /// 1612 buf = ";\n\t"; 1613 buf += "__continue_label_"; 1614 buf += utostr(ObjCBcLabelNo.back()); 1615 buf += ": ;"; 1616 buf += "\n\t\t"; 1617 buf += "} while (counter < limit);\n\t"; 1618 buf += "} while (limit = "; 1619 SynthCountByEnumWithState(buf); 1620 buf += ");\n\t"; 1621 buf += elementName; 1622 buf += " = (("; 1623 buf += elementTypeAsString; 1624 buf += ")0);\n\t"; 1625 buf += "__break_label_"; 1626 buf += utostr(ObjCBcLabelNo.back()); 1627 buf += ": ;\n\t"; 1628 buf += "}\n\t"; 1629 buf += "else\n\t\t"; 1630 buf += elementName; 1631 buf += " = (("; 1632 buf += elementTypeAsString; 1633 buf += ")0);\n\t"; 1634 buf += "}\n"; 1635 1636 // Insert all these *after* the statement body. 1637 // FIXME: If this should support Obj-C++, support CXXTryStmt 1638 if (isa<CompoundStmt>(S->getBody())) { 1639 SourceLocation endBodyLoc = OrigEnd.getLocWithOffset(1); 1640 InsertText(endBodyLoc, buf); 1641 } else { 1642 /* Need to treat single statements specially. For example: 1643 * 1644 * for (A *a in b) if (stuff()) break; 1645 * for (A *a in b) xxxyy; 1646 * 1647 * The following code simply scans ahead to the semi to find the actual end. 1648 */ 1649 const char *stmtBuf = SM->getCharacterData(OrigEnd); 1650 const char *semiBuf = strchr(stmtBuf, ';'); 1651 assert(semiBuf && "Can't find ';'"); 1652 SourceLocation endBodyLoc = OrigEnd.getLocWithOffset(semiBuf-stmtBuf+1); 1653 InsertText(endBodyLoc, buf); 1654 } 1655 Stmts.pop_back(); 1656 ObjCBcLabelNo.pop_back(); 1657 return 0; 1658 } 1659 1660 /// RewriteObjCSynchronizedStmt - 1661 /// This routine rewrites @synchronized(expr) stmt; 1662 /// into: 1663 /// objc_sync_enter(expr); 1664 /// @try stmt @finally { objc_sync_exit(expr); } 1665 /// 1666 Stmt *RewriteObjC::RewriteObjCSynchronizedStmt(ObjCAtSynchronizedStmt *S) { 1667 // Get the start location and compute the semi location. 1668 SourceLocation startLoc = S->getLocStart(); 1669 const char *startBuf = SM->getCharacterData(startLoc); 1670 1671 assert((*startBuf == '@') && "bogus @synchronized location"); 1672 1673 std::string buf; 1674 buf = "objc_sync_enter((id)"; 1675 const char *lparenBuf = startBuf; 1676 while (*lparenBuf != '(') lparenBuf++; 1677 ReplaceText(startLoc, lparenBuf-startBuf+1, buf); 1678 // We can't use S->getSynchExpr()->getLocEnd() to find the end location, since 1679 // the sync expression is typically a message expression that's already 1680 // been rewritten! (which implies the SourceLocation's are invalid). 1681 SourceLocation endLoc = S->getSynchBody()->getLocStart(); 1682 const char *endBuf = SM->getCharacterData(endLoc); 1683 while (*endBuf != ')') endBuf--; 1684 SourceLocation rparenLoc = startLoc.getLocWithOffset(endBuf-startBuf); 1685 buf = ");\n"; 1686 // declare a new scope with two variables, _stack and _rethrow. 1687 buf += "/* @try scope begin */ \n{ struct _objc_exception_data {\n"; 1688 buf += "int buf[18/*32-bit i386*/];\n"; 1689 buf += "char *pointers[4];} _stack;\n"; 1690 buf += "id volatile _rethrow = 0;\n"; 1691 buf += "objc_exception_try_enter(&_stack);\n"; 1692 buf += "if (!_setjmp(_stack.buf)) /* @try block continue */\n"; 1693 ReplaceText(rparenLoc, 1, buf); 1694 startLoc = S->getSynchBody()->getLocEnd(); 1695 startBuf = SM->getCharacterData(startLoc); 1696 1697 assert((*startBuf == '}') && "bogus @synchronized block"); 1698 SourceLocation lastCurlyLoc = startLoc; 1699 buf = "}\nelse {\n"; 1700 buf += " _rethrow = objc_exception_extract(&_stack);\n"; 1701 buf += "}\n"; 1702 buf += "{ /* implicit finally clause */\n"; 1703 buf += " if (!_rethrow) objc_exception_try_exit(&_stack);\n"; 1704 1705 std::string syncBuf; 1706 syncBuf += " objc_sync_exit("; 1707 1708 Expr *syncExpr = S->getSynchExpr(); 1709 CastKind CK = syncExpr->getType()->isObjCObjectPointerType() 1710 ? CK_BitCast : 1711 syncExpr->getType()->isBlockPointerType() 1712 ? CK_BlockPointerToObjCPointerCast 1713 : CK_CPointerToObjCPointerCast; 1714 syncExpr = NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(), 1715 CK, syncExpr); 1716 std::string syncExprBufS; 1717 llvm::raw_string_ostream syncExprBuf(syncExprBufS); 1718 syncExpr->printPretty(syncExprBuf, *Context, 0, 1719 PrintingPolicy(LangOpts)); 1720 syncBuf += syncExprBuf.str(); 1721 syncBuf += ");"; 1722 1723 buf += syncBuf; 1724 buf += "\n if (_rethrow) objc_exception_throw(_rethrow);\n"; 1725 buf += "}\n"; 1726 buf += "}"; 1727 1728 ReplaceText(lastCurlyLoc, 1, buf); 1729 1730 bool hasReturns = false; 1731 HasReturnStmts(S->getSynchBody(), hasReturns); 1732 if (hasReturns) 1733 RewriteSyncReturnStmts(S->getSynchBody(), syncBuf); 1734 1735 return 0; 1736 } 1737 1738 void RewriteObjC::WarnAboutReturnGotoStmts(Stmt *S) 1739 { 1740 // Perform a bottom up traversal of all children. 1741 for (Stmt::child_range CI = S->children(); CI; ++CI) 1742 if (*CI) 1743 WarnAboutReturnGotoStmts(*CI); 1744 1745 if (isa<ReturnStmt>(S) || isa<GotoStmt>(S)) { 1746 Diags.Report(Context->getFullLoc(S->getLocStart()), 1747 TryFinallyContainsReturnDiag); 1748 } 1749 return; 1750 } 1751 1752 void RewriteObjC::HasReturnStmts(Stmt *S, bool &hasReturns) 1753 { 1754 // Perform a bottom up traversal of all children. 1755 for (Stmt::child_range CI = S->children(); CI; ++CI) 1756 if (*CI) 1757 HasReturnStmts(*CI, hasReturns); 1758 1759 if (isa<ReturnStmt>(S)) 1760 hasReturns = true; 1761 return; 1762 } 1763 1764 void RewriteObjC::RewriteTryReturnStmts(Stmt *S) { 1765 // Perform a bottom up traversal of all children. 1766 for (Stmt::child_range CI = S->children(); CI; ++CI) 1767 if (*CI) { 1768 RewriteTryReturnStmts(*CI); 1769 } 1770 if (isa<ReturnStmt>(S)) { 1771 SourceLocation startLoc = S->getLocStart(); 1772 const char *startBuf = SM->getCharacterData(startLoc); 1773 1774 const char *semiBuf = strchr(startBuf, ';'); 1775 assert((*semiBuf == ';') && "RewriteTryReturnStmts: can't find ';'"); 1776 SourceLocation onePastSemiLoc = startLoc.getLocWithOffset(semiBuf-startBuf+1); 1777 1778 std::string buf; 1779 buf = "{ objc_exception_try_exit(&_stack); return"; 1780 1781 ReplaceText(startLoc, 6, buf); 1782 InsertText(onePastSemiLoc, "}"); 1783 } 1784 return; 1785 } 1786 1787 void RewriteObjC::RewriteSyncReturnStmts(Stmt *S, std::string syncExitBuf) { 1788 // Perform a bottom up traversal of all children. 1789 for (Stmt::child_range CI = S->children(); CI; ++CI) 1790 if (*CI) { 1791 RewriteSyncReturnStmts(*CI, syncExitBuf); 1792 } 1793 if (isa<ReturnStmt>(S)) { 1794 SourceLocation startLoc = S->getLocStart(); 1795 const char *startBuf = SM->getCharacterData(startLoc); 1796 1797 const char *semiBuf = strchr(startBuf, ';'); 1798 assert((*semiBuf == ';') && "RewriteSyncReturnStmts: can't find ';'"); 1799 SourceLocation onePastSemiLoc = startLoc.getLocWithOffset(semiBuf-startBuf+1); 1800 1801 std::string buf; 1802 buf = "{ objc_exception_try_exit(&_stack);"; 1803 buf += syncExitBuf; 1804 buf += " return"; 1805 1806 ReplaceText(startLoc, 6, buf); 1807 InsertText(onePastSemiLoc, "}"); 1808 } 1809 return; 1810 } 1811 1812 Stmt *RewriteObjC::RewriteObjCTryStmt(ObjCAtTryStmt *S) { 1813 // Get the start location and compute the semi location. 1814 SourceLocation startLoc = S->getLocStart(); 1815 const char *startBuf = SM->getCharacterData(startLoc); 1816 1817 assert((*startBuf == '@') && "bogus @try location"); 1818 1819 std::string buf; 1820 // declare a new scope with two variables, _stack and _rethrow. 1821 buf = "/* @try scope begin */ { struct _objc_exception_data {\n"; 1822 buf += "int buf[18/*32-bit i386*/];\n"; 1823 buf += "char *pointers[4];} _stack;\n"; 1824 buf += "id volatile _rethrow = 0;\n"; 1825 buf += "objc_exception_try_enter(&_stack);\n"; 1826 buf += "if (!_setjmp(_stack.buf)) /* @try block continue */\n"; 1827 1828 ReplaceText(startLoc, 4, buf); 1829 1830 startLoc = S->getTryBody()->getLocEnd(); 1831 startBuf = SM->getCharacterData(startLoc); 1832 1833 assert((*startBuf == '}') && "bogus @try block"); 1834 1835 SourceLocation lastCurlyLoc = startLoc; 1836 if (S->getNumCatchStmts()) { 1837 startLoc = startLoc.getLocWithOffset(1); 1838 buf = " /* @catch begin */ else {\n"; 1839 buf += " id _caught = objc_exception_extract(&_stack);\n"; 1840 buf += " objc_exception_try_enter (&_stack);\n"; 1841 buf += " if (_setjmp(_stack.buf))\n"; 1842 buf += " _rethrow = objc_exception_extract(&_stack);\n"; 1843 buf += " else { /* @catch continue */"; 1844 1845 InsertText(startLoc, buf); 1846 } else { /* no catch list */ 1847 buf = "}\nelse {\n"; 1848 buf += " _rethrow = objc_exception_extract(&_stack);\n"; 1849 buf += "}"; 1850 ReplaceText(lastCurlyLoc, 1, buf); 1851 } 1852 Stmt *lastCatchBody = 0; 1853 for (unsigned I = 0, N = S->getNumCatchStmts(); I != N; ++I) { 1854 ObjCAtCatchStmt *Catch = S->getCatchStmt(I); 1855 VarDecl *catchDecl = Catch->getCatchParamDecl(); 1856 1857 if (I == 0) 1858 buf = "if ("; // we are generating code for the first catch clause 1859 else 1860 buf = "else if ("; 1861 startLoc = Catch->getLocStart(); 1862 startBuf = SM->getCharacterData(startLoc); 1863 1864 assert((*startBuf == '@') && "bogus @catch location"); 1865 1866 const char *lParenLoc = strchr(startBuf, '('); 1867 1868 if (Catch->hasEllipsis()) { 1869 // Now rewrite the body... 1870 lastCatchBody = Catch->getCatchBody(); 1871 SourceLocation bodyLoc = lastCatchBody->getLocStart(); 1872 const char *bodyBuf = SM->getCharacterData(bodyLoc); 1873 assert(*SM->getCharacterData(Catch->getRParenLoc()) == ')' && 1874 "bogus @catch paren location"); 1875 assert((*bodyBuf == '{') && "bogus @catch body location"); 1876 1877 buf += "1) { id _tmp = _caught;"; 1878 Rewrite.ReplaceText(startLoc, bodyBuf-startBuf+1, buf); 1879 } else if (catchDecl) { 1880 QualType t = catchDecl->getType(); 1881 if (t == Context->getObjCIdType()) { 1882 buf += "1) { "; 1883 ReplaceText(startLoc, lParenLoc-startBuf+1, buf); 1884 } else if (const ObjCObjectPointerType *Ptr = 1885 t->getAs<ObjCObjectPointerType>()) { 1886 // Should be a pointer to a class. 1887 ObjCInterfaceDecl *IDecl = Ptr->getObjectType()->getInterface(); 1888 if (IDecl) { 1889 buf += "objc_exception_match((struct objc_class *)objc_getClass(\""; 1890 buf += IDecl->getNameAsString(); 1891 buf += "\"), (struct objc_object *)_caught)) { "; 1892 ReplaceText(startLoc, lParenLoc-startBuf+1, buf); 1893 } 1894 } 1895 // Now rewrite the body... 1896 lastCatchBody = Catch->getCatchBody(); 1897 SourceLocation rParenLoc = Catch->getRParenLoc(); 1898 SourceLocation bodyLoc = lastCatchBody->getLocStart(); 1899 const char *bodyBuf = SM->getCharacterData(bodyLoc); 1900 const char *rParenBuf = SM->getCharacterData(rParenLoc); 1901 assert((*rParenBuf == ')') && "bogus @catch paren location"); 1902 assert((*bodyBuf == '{') && "bogus @catch body location"); 1903 1904 // Here we replace ") {" with "= _caught;" (which initializes and 1905 // declares the @catch parameter). 1906 ReplaceText(rParenLoc, bodyBuf-rParenBuf+1, " = _caught;"); 1907 } else { 1908 llvm_unreachable("@catch rewrite bug"); 1909 } 1910 } 1911 // Complete the catch list... 1912 if (lastCatchBody) { 1913 SourceLocation bodyLoc = lastCatchBody->getLocEnd(); 1914 assert(*SM->getCharacterData(bodyLoc) == '}' && 1915 "bogus @catch body location"); 1916 1917 // Insert the last (implicit) else clause *before* the right curly brace. 1918 bodyLoc = bodyLoc.getLocWithOffset(-1); 1919 buf = "} /* last catch end */\n"; 1920 buf += "else {\n"; 1921 buf += " _rethrow = _caught;\n"; 1922 buf += " objc_exception_try_exit(&_stack);\n"; 1923 buf += "} } /* @catch end */\n"; 1924 if (!S->getFinallyStmt()) 1925 buf += "}\n"; 1926 InsertText(bodyLoc, buf); 1927 1928 // Set lastCurlyLoc 1929 lastCurlyLoc = lastCatchBody->getLocEnd(); 1930 } 1931 if (ObjCAtFinallyStmt *finalStmt = S->getFinallyStmt()) { 1932 startLoc = finalStmt->getLocStart(); 1933 startBuf = SM->getCharacterData(startLoc); 1934 assert((*startBuf == '@') && "bogus @finally start"); 1935 1936 ReplaceText(startLoc, 8, "/* @finally */"); 1937 1938 Stmt *body = finalStmt->getFinallyBody(); 1939 SourceLocation startLoc = body->getLocStart(); 1940 SourceLocation endLoc = body->getLocEnd(); 1941 assert(*SM->getCharacterData(startLoc) == '{' && 1942 "bogus @finally body location"); 1943 assert(*SM->getCharacterData(endLoc) == '}' && 1944 "bogus @finally body location"); 1945 1946 startLoc = startLoc.getLocWithOffset(1); 1947 InsertText(startLoc, " if (!_rethrow) objc_exception_try_exit(&_stack);\n"); 1948 endLoc = endLoc.getLocWithOffset(-1); 1949 InsertText(endLoc, " if (_rethrow) objc_exception_throw(_rethrow);\n"); 1950 1951 // Set lastCurlyLoc 1952 lastCurlyLoc = body->getLocEnd(); 1953 1954 // Now check for any return/continue/go statements within the @try. 1955 WarnAboutReturnGotoStmts(S->getTryBody()); 1956 } else { /* no finally clause - make sure we synthesize an implicit one */ 1957 buf = "{ /* implicit finally clause */\n"; 1958 buf += " if (!_rethrow) objc_exception_try_exit(&_stack);\n"; 1959 buf += " if (_rethrow) objc_exception_throw(_rethrow);\n"; 1960 buf += "}"; 1961 ReplaceText(lastCurlyLoc, 1, buf); 1962 1963 // Now check for any return/continue/go statements within the @try. 1964 // The implicit finally clause won't called if the @try contains any 1965 // jump statements. 1966 bool hasReturns = false; 1967 HasReturnStmts(S->getTryBody(), hasReturns); 1968 if (hasReturns) 1969 RewriteTryReturnStmts(S->getTryBody()); 1970 } 1971 // Now emit the final closing curly brace... 1972 lastCurlyLoc = lastCurlyLoc.getLocWithOffset(1); 1973 InsertText(lastCurlyLoc, " } /* @try scope end */\n"); 1974 return 0; 1975 } 1976 1977 // This can't be done with ReplaceStmt(S, ThrowExpr), since 1978 // the throw expression is typically a message expression that's already 1979 // been rewritten! (which implies the SourceLocation's are invalid). 1980 Stmt *RewriteObjC::RewriteObjCThrowStmt(ObjCAtThrowStmt *S) { 1981 // Get the start location and compute the semi location. 1982 SourceLocation startLoc = S->getLocStart(); 1983 const char *startBuf = SM->getCharacterData(startLoc); 1984 1985 assert((*startBuf == '@') && "bogus @throw location"); 1986 1987 std::string buf; 1988 /* void objc_exception_throw(id) __attribute__((noreturn)); */ 1989 if (S->getThrowExpr()) 1990 buf = "objc_exception_throw("; 1991 else // add an implicit argument 1992 buf = "objc_exception_throw(_caught"; 1993 1994 // handle "@ throw" correctly. 1995 const char *wBuf = strchr(startBuf, 'w'); 1996 assert((*wBuf == 'w') && "@throw: can't find 'w'"); 1997 ReplaceText(startLoc, wBuf-startBuf+1, buf); 1998 1999 const char *semiBuf = strchr(startBuf, ';'); 2000 assert((*semiBuf == ';') && "@throw: can't find ';'"); 2001 SourceLocation semiLoc = startLoc.getLocWithOffset(semiBuf-startBuf); 2002 ReplaceText(semiLoc, 1, ");"); 2003 return 0; 2004 } 2005 2006 Stmt *RewriteObjC::RewriteAtEncode(ObjCEncodeExpr *Exp) { 2007 // Create a new string expression. 2008 QualType StrType = Context->getPointerType(Context->CharTy); 2009 std::string StrEncoding; 2010 Context->getObjCEncodingForType(Exp->getEncodedType(), StrEncoding); 2011 Expr *Replacement = StringLiteral::Create(*Context, StrEncoding, 2012 StringLiteral::Ascii, false, 2013 StrType, SourceLocation()); 2014 ReplaceStmt(Exp, Replacement); 2015 2016 // Replace this subexpr in the parent. 2017 // delete Exp; leak for now, see RewritePropertyOrImplicitSetter() usage for more info. 2018 return Replacement; 2019 } 2020 2021 Stmt *RewriteObjC::RewriteAtSelector(ObjCSelectorExpr *Exp) { 2022 if (!SelGetUidFunctionDecl) 2023 SynthSelGetUidFunctionDecl(); 2024 assert(SelGetUidFunctionDecl && "Can't find sel_registerName() decl"); 2025 // Create a call to sel_registerName("selName"). 2026 SmallVector<Expr*, 8> SelExprs; 2027 QualType argType = Context->getPointerType(Context->CharTy); 2028 SelExprs.push_back(StringLiteral::Create(*Context, 2029 Exp->getSelector().getAsString(), 2030 StringLiteral::Ascii, false, 2031 argType, SourceLocation())); 2032 CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl, 2033 &SelExprs[0], SelExprs.size()); 2034 ReplaceStmt(Exp, SelExp); 2035 // delete Exp; leak for now, see RewritePropertyOrImplicitSetter() usage for more info. 2036 return SelExp; 2037 } 2038 2039 CallExpr *RewriteObjC::SynthesizeCallToFunctionDecl( 2040 FunctionDecl *FD, Expr **args, unsigned nargs, SourceLocation StartLoc, 2041 SourceLocation EndLoc) { 2042 // Get the type, we will need to reference it in a couple spots. 2043 QualType msgSendType = FD->getType(); 2044 2045 // Create a reference to the objc_msgSend() declaration. 2046 DeclRefExpr *DRE = new (Context) DeclRefExpr(FD, false, msgSendType, 2047 VK_LValue, SourceLocation()); 2048 2049 // Now, we cast the reference to a pointer to the objc_msgSend type. 2050 QualType pToFunc = Context->getPointerType(msgSendType); 2051 ImplicitCastExpr *ICE = 2052 ImplicitCastExpr::Create(*Context, pToFunc, CK_FunctionToPointerDecay, 2053 DRE, 0, VK_RValue); 2054 2055 const FunctionType *FT = msgSendType->getAs<FunctionType>(); 2056 2057 CallExpr *Exp = 2058 new (Context) CallExpr(*Context, ICE, args, nargs, 2059 FT->getCallResultType(*Context), 2060 VK_RValue, EndLoc); 2061 return Exp; 2062 } 2063 2064 static bool scanForProtocolRefs(const char *startBuf, const char *endBuf, 2065 const char *&startRef, const char *&endRef) { 2066 while (startBuf < endBuf) { 2067 if (*startBuf == '<') 2068 startRef = startBuf; // mark the start. 2069 if (*startBuf == '>') { 2070 if (startRef && *startRef == '<') { 2071 endRef = startBuf; // mark the end. 2072 return true; 2073 } 2074 return false; 2075 } 2076 startBuf++; 2077 } 2078 return false; 2079 } 2080 2081 static void scanToNextArgument(const char *&argRef) { 2082 int angle = 0; 2083 while (*argRef != ')' && (*argRef != ',' || angle > 0)) { 2084 if (*argRef == '<') 2085 angle++; 2086 else if (*argRef == '>') 2087 angle--; 2088 argRef++; 2089 } 2090 assert(angle == 0 && "scanToNextArgument - bad protocol type syntax"); 2091 } 2092 2093 bool RewriteObjC::needToScanForQualifiers(QualType T) { 2094 if (T->isObjCQualifiedIdType()) 2095 return true; 2096 if (const PointerType *PT = T->getAs<PointerType>()) { 2097 if (PT->getPointeeType()->isObjCQualifiedIdType()) 2098 return true; 2099 } 2100 if (T->isObjCObjectPointerType()) { 2101 T = T->getPointeeType(); 2102 return T->isObjCQualifiedInterfaceType(); 2103 } 2104 if (T->isArrayType()) { 2105 QualType ElemTy = Context->getBaseElementType(T); 2106 return needToScanForQualifiers(ElemTy); 2107 } 2108 return false; 2109 } 2110 2111 void RewriteObjC::RewriteObjCQualifiedInterfaceTypes(Expr *E) { 2112 QualType Type = E->getType(); 2113 if (needToScanForQualifiers(Type)) { 2114 SourceLocation Loc, EndLoc; 2115 2116 if (const CStyleCastExpr *ECE = dyn_cast<CStyleCastExpr>(E)) { 2117 Loc = ECE->getLParenLoc(); 2118 EndLoc = ECE->getRParenLoc(); 2119 } else { 2120 Loc = E->getLocStart(); 2121 EndLoc = E->getLocEnd(); 2122 } 2123 // This will defend against trying to rewrite synthesized expressions. 2124 if (Loc.isInvalid() || EndLoc.isInvalid()) 2125 return; 2126 2127 const char *startBuf = SM->getCharacterData(Loc); 2128 const char *endBuf = SM->getCharacterData(EndLoc); 2129 const char *startRef = 0, *endRef = 0; 2130 if (scanForProtocolRefs(startBuf, endBuf, startRef, endRef)) { 2131 // Get the locations of the startRef, endRef. 2132 SourceLocation LessLoc = Loc.getLocWithOffset(startRef-startBuf); 2133 SourceLocation GreaterLoc = Loc.getLocWithOffset(endRef-startBuf+1); 2134 // Comment out the protocol references. 2135 InsertText(LessLoc, "/*"); 2136 InsertText(GreaterLoc, "*/"); 2137 } 2138 } 2139 } 2140 2141 void RewriteObjC::RewriteObjCQualifiedInterfaceTypes(Decl *Dcl) { 2142 SourceLocation Loc; 2143 QualType Type; 2144 const FunctionProtoType *proto = 0; 2145 if (VarDecl *VD = dyn_cast<VarDecl>(Dcl)) { 2146 Loc = VD->getLocation(); 2147 Type = VD->getType(); 2148 } 2149 else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(Dcl)) { 2150 Loc = FD->getLocation(); 2151 // Check for ObjC 'id' and class types that have been adorned with protocol 2152 // information (id<p>, C<p>*). The protocol references need to be rewritten! 2153 const FunctionType *funcType = FD->getType()->getAs<FunctionType>(); 2154 assert(funcType && "missing function type"); 2155 proto = dyn_cast<FunctionProtoType>(funcType); 2156 if (!proto) 2157 return; 2158 Type = proto->getResultType(); 2159 } 2160 else if (FieldDecl *FD = dyn_cast<FieldDecl>(Dcl)) { 2161 Loc = FD->getLocation(); 2162 Type = FD->getType(); 2163 } 2164 else 2165 return; 2166 2167 if (needToScanForQualifiers(Type)) { 2168 // Since types are unique, we need to scan the buffer. 2169 2170 const char *endBuf = SM->getCharacterData(Loc); 2171 const char *startBuf = endBuf; 2172 while (*startBuf != ';' && *startBuf != '<' && startBuf != MainFileStart) 2173 startBuf--; // scan backward (from the decl location) for return type. 2174 const char *startRef = 0, *endRef = 0; 2175 if (scanForProtocolRefs(startBuf, endBuf, startRef, endRef)) { 2176 // Get the locations of the startRef, endRef. 2177 SourceLocation LessLoc = Loc.getLocWithOffset(startRef-endBuf); 2178 SourceLocation GreaterLoc = Loc.getLocWithOffset(endRef-endBuf+1); 2179 // Comment out the protocol references. 2180 InsertText(LessLoc, "/*"); 2181 InsertText(GreaterLoc, "*/"); 2182 } 2183 } 2184 if (!proto) 2185 return; // most likely, was a variable 2186 // Now check arguments. 2187 const char *startBuf = SM->getCharacterData(Loc); 2188 const char *startFuncBuf = startBuf; 2189 for (unsigned i = 0; i < proto->getNumArgs(); i++) { 2190 if (needToScanForQualifiers(proto->getArgType(i))) { 2191 // Since types are unique, we need to scan the buffer. 2192 2193 const char *endBuf = startBuf; 2194 // scan forward (from the decl location) for argument types. 2195 scanToNextArgument(endBuf); 2196 const char *startRef = 0, *endRef = 0; 2197 if (scanForProtocolRefs(startBuf, endBuf, startRef, endRef)) { 2198 // Get the locations of the startRef, endRef. 2199 SourceLocation LessLoc = 2200 Loc.getLocWithOffset(startRef-startFuncBuf); 2201 SourceLocation GreaterLoc = 2202 Loc.getLocWithOffset(endRef-startFuncBuf+1); 2203 // Comment out the protocol references. 2204 InsertText(LessLoc, "/*"); 2205 InsertText(GreaterLoc, "*/"); 2206 } 2207 startBuf = ++endBuf; 2208 } 2209 else { 2210 // If the function name is derived from a macro expansion, then the 2211 // argument buffer will not follow the name. Need to speak with Chris. 2212 while (*startBuf && *startBuf != ')' && *startBuf != ',') 2213 startBuf++; // scan forward (from the decl location) for argument types. 2214 startBuf++; 2215 } 2216 } 2217 } 2218 2219 void RewriteObjC::RewriteTypeOfDecl(VarDecl *ND) { 2220 QualType QT = ND->getType(); 2221 const Type* TypePtr = QT->getAs<Type>(); 2222 if (!isa<TypeOfExprType>(TypePtr)) 2223 return; 2224 while (isa<TypeOfExprType>(TypePtr)) { 2225 const TypeOfExprType *TypeOfExprTypePtr = cast<TypeOfExprType>(TypePtr); 2226 QT = TypeOfExprTypePtr->getUnderlyingExpr()->getType(); 2227 TypePtr = QT->getAs<Type>(); 2228 } 2229 // FIXME. This will not work for multiple declarators; as in: 2230 // __typeof__(a) b,c,d; 2231 std::string TypeAsString(QT.getAsString(Context->getPrintingPolicy())); 2232 SourceLocation DeclLoc = ND->getTypeSpecStartLoc(); 2233 const char *startBuf = SM->getCharacterData(DeclLoc); 2234 if (ND->getInit()) { 2235 std::string Name(ND->getNameAsString()); 2236 TypeAsString += " " + Name + " = "; 2237 Expr *E = ND->getInit(); 2238 SourceLocation startLoc; 2239 if (const CStyleCastExpr *ECE = dyn_cast<CStyleCastExpr>(E)) 2240 startLoc = ECE->getLParenLoc(); 2241 else 2242 startLoc = E->getLocStart(); 2243 startLoc = SM->getExpansionLoc(startLoc); 2244 const char *endBuf = SM->getCharacterData(startLoc); 2245 ReplaceText(DeclLoc, endBuf-startBuf-1, TypeAsString); 2246 } 2247 else { 2248 SourceLocation X = ND->getLocEnd(); 2249 X = SM->getExpansionLoc(X); 2250 const char *endBuf = SM->getCharacterData(X); 2251 ReplaceText(DeclLoc, endBuf-startBuf-1, TypeAsString); 2252 } 2253 } 2254 2255 // SynthSelGetUidFunctionDecl - SEL sel_registerName(const char *str); 2256 void RewriteObjC::SynthSelGetUidFunctionDecl() { 2257 IdentifierInfo *SelGetUidIdent = &Context->Idents.get("sel_registerName"); 2258 SmallVector<QualType, 16> ArgTys; 2259 ArgTys.push_back(Context->getPointerType(Context->CharTy.withConst())); 2260 QualType getFuncType = 2261 getSimpleFunctionType(Context->getObjCSelType(), &ArgTys[0], ArgTys.size()); 2262 SelGetUidFunctionDecl = FunctionDecl::Create(*Context, TUDecl, 2263 SourceLocation(), 2264 SourceLocation(), 2265 SelGetUidIdent, getFuncType, 0, 2266 SC_Extern, 2267 SC_None, false); 2268 } 2269 2270 void RewriteObjC::RewriteFunctionDecl(FunctionDecl *FD) { 2271 // declared in <objc/objc.h> 2272 if (FD->getIdentifier() && 2273 FD->getName() == "sel_registerName") { 2274 SelGetUidFunctionDecl = FD; 2275 return; 2276 } 2277 RewriteObjCQualifiedInterfaceTypes(FD); 2278 } 2279 2280 void RewriteObjC::RewriteBlockPointerType(std::string& Str, QualType Type) { 2281 std::string TypeString(Type.getAsString(Context->getPrintingPolicy())); 2282 const char *argPtr = TypeString.c_str(); 2283 if (!strchr(argPtr, '^')) { 2284 Str += TypeString; 2285 return; 2286 } 2287 while (*argPtr) { 2288 Str += (*argPtr == '^' ? '*' : *argPtr); 2289 argPtr++; 2290 } 2291 } 2292 2293 // FIXME. Consolidate this routine with RewriteBlockPointerType. 2294 void RewriteObjC::RewriteBlockPointerTypeVariable(std::string& Str, 2295 ValueDecl *VD) { 2296 QualType Type = VD->getType(); 2297 std::string TypeString(Type.getAsString(Context->getPrintingPolicy())); 2298 const char *argPtr = TypeString.c_str(); 2299 int paren = 0; 2300 while (*argPtr) { 2301 switch (*argPtr) { 2302 case '(': 2303 Str += *argPtr; 2304 paren++; 2305 break; 2306 case ')': 2307 Str += *argPtr; 2308 paren--; 2309 break; 2310 case '^': 2311 Str += '*'; 2312 if (paren == 1) 2313 Str += VD->getNameAsString(); 2314 break; 2315 default: 2316 Str += *argPtr; 2317 break; 2318 } 2319 argPtr++; 2320 } 2321 } 2322 2323 2324 void RewriteObjC::RewriteBlockLiteralFunctionDecl(FunctionDecl *FD) { 2325 SourceLocation FunLocStart = FD->getTypeSpecStartLoc(); 2326 const FunctionType *funcType = FD->getType()->getAs<FunctionType>(); 2327 const FunctionProtoType *proto = dyn_cast<FunctionProtoType>(funcType); 2328 if (!proto) 2329 return; 2330 QualType Type = proto->getResultType(); 2331 std::string FdStr = Type.getAsString(Context->getPrintingPolicy()); 2332 FdStr += " "; 2333 FdStr += FD->getName(); 2334 FdStr += "("; 2335 unsigned numArgs = proto->getNumArgs(); 2336 for (unsigned i = 0; i < numArgs; i++) { 2337 QualType ArgType = proto->getArgType(i); 2338 RewriteBlockPointerType(FdStr, ArgType); 2339 if (i+1 < numArgs) 2340 FdStr += ", "; 2341 } 2342 FdStr += ");\n"; 2343 InsertText(FunLocStart, FdStr); 2344 CurFunctionDeclToDeclareForBlock = 0; 2345 } 2346 2347 // SynthSuperContructorFunctionDecl - id objc_super(id obj, id super); 2348 void RewriteObjC::SynthSuperContructorFunctionDecl() { 2349 if (SuperContructorFunctionDecl) 2350 return; 2351 IdentifierInfo *msgSendIdent = &Context->Idents.get("__rw_objc_super"); 2352 SmallVector<QualType, 16> ArgTys; 2353 QualType argT = Context->getObjCIdType(); 2354 assert(!argT.isNull() && "Can't find 'id' type"); 2355 ArgTys.push_back(argT); 2356 ArgTys.push_back(argT); 2357 QualType msgSendType = getSimpleFunctionType(Context->getObjCIdType(), 2358 &ArgTys[0], ArgTys.size()); 2359 SuperContructorFunctionDecl = FunctionDecl::Create(*Context, TUDecl, 2360 SourceLocation(), 2361 SourceLocation(), 2362 msgSendIdent, msgSendType, 0, 2363 SC_Extern, 2364 SC_None, false); 2365 } 2366 2367 // SynthMsgSendFunctionDecl - id objc_msgSend(id self, SEL op, ...); 2368 void RewriteObjC::SynthMsgSendFunctionDecl() { 2369 IdentifierInfo *msgSendIdent = &Context->Idents.get("objc_msgSend"); 2370 SmallVector<QualType, 16> ArgTys; 2371 QualType argT = Context->getObjCIdType(); 2372 assert(!argT.isNull() && "Can't find 'id' type"); 2373 ArgTys.push_back(argT); 2374 argT = Context->getObjCSelType(); 2375 assert(!argT.isNull() && "Can't find 'SEL' type"); 2376 ArgTys.push_back(argT); 2377 QualType msgSendType = getSimpleFunctionType(Context->getObjCIdType(), 2378 &ArgTys[0], ArgTys.size(), 2379 true /*isVariadic*/); 2380 MsgSendFunctionDecl = FunctionDecl::Create(*Context, TUDecl, 2381 SourceLocation(), 2382 SourceLocation(), 2383 msgSendIdent, msgSendType, 0, 2384 SC_Extern, 2385 SC_None, false); 2386 } 2387 2388 // SynthMsgSendSuperFunctionDecl - id objc_msgSendSuper(struct objc_super *, SEL op, ...); 2389 void RewriteObjC::SynthMsgSendSuperFunctionDecl() { 2390 IdentifierInfo *msgSendIdent = &Context->Idents.get("objc_msgSendSuper"); 2391 SmallVector<QualType, 16> ArgTys; 2392 RecordDecl *RD = RecordDecl::Create(*Context, TTK_Struct, TUDecl, 2393 SourceLocation(), SourceLocation(), 2394 &Context->Idents.get("objc_super")); 2395 QualType argT = Context->getPointerType(Context->getTagDeclType(RD)); 2396 assert(!argT.isNull() && "Can't build 'struct objc_super *' type"); 2397 ArgTys.push_back(argT); 2398 argT = Context->getObjCSelType(); 2399 assert(!argT.isNull() && "Can't find 'SEL' type"); 2400 ArgTys.push_back(argT); 2401 QualType msgSendType = getSimpleFunctionType(Context->getObjCIdType(), 2402 &ArgTys[0], ArgTys.size(), 2403 true /*isVariadic*/); 2404 MsgSendSuperFunctionDecl = FunctionDecl::Create(*Context, TUDecl, 2405 SourceLocation(), 2406 SourceLocation(), 2407 msgSendIdent, msgSendType, 0, 2408 SC_Extern, 2409 SC_None, false); 2410 } 2411 2412 // SynthMsgSendStretFunctionDecl - id objc_msgSend_stret(id self, SEL op, ...); 2413 void RewriteObjC::SynthMsgSendStretFunctionDecl() { 2414 IdentifierInfo *msgSendIdent = &Context->Idents.get("objc_msgSend_stret"); 2415 SmallVector<QualType, 16> ArgTys; 2416 QualType argT = Context->getObjCIdType(); 2417 assert(!argT.isNull() && "Can't find 'id' type"); 2418 ArgTys.push_back(argT); 2419 argT = Context->getObjCSelType(); 2420 assert(!argT.isNull() && "Can't find 'SEL' type"); 2421 ArgTys.push_back(argT); 2422 QualType msgSendType = getSimpleFunctionType(Context->getObjCIdType(), 2423 &ArgTys[0], ArgTys.size(), 2424 true /*isVariadic*/); 2425 MsgSendStretFunctionDecl = FunctionDecl::Create(*Context, TUDecl, 2426 SourceLocation(), 2427 SourceLocation(), 2428 msgSendIdent, msgSendType, 0, 2429 SC_Extern, 2430 SC_None, false); 2431 } 2432 2433 // SynthMsgSendSuperStretFunctionDecl - 2434 // id objc_msgSendSuper_stret(struct objc_super *, SEL op, ...); 2435 void RewriteObjC::SynthMsgSendSuperStretFunctionDecl() { 2436 IdentifierInfo *msgSendIdent = 2437 &Context->Idents.get("objc_msgSendSuper_stret"); 2438 SmallVector<QualType, 16> ArgTys; 2439 RecordDecl *RD = RecordDecl::Create(*Context, TTK_Struct, TUDecl, 2440 SourceLocation(), SourceLocation(), 2441 &Context->Idents.get("objc_super")); 2442 QualType argT = Context->getPointerType(Context->getTagDeclType(RD)); 2443 assert(!argT.isNull() && "Can't build 'struct objc_super *' type"); 2444 ArgTys.push_back(argT); 2445 argT = Context->getObjCSelType(); 2446 assert(!argT.isNull() && "Can't find 'SEL' type"); 2447 ArgTys.push_back(argT); 2448 QualType msgSendType = getSimpleFunctionType(Context->getObjCIdType(), 2449 &ArgTys[0], ArgTys.size(), 2450 true /*isVariadic*/); 2451 MsgSendSuperStretFunctionDecl = FunctionDecl::Create(*Context, TUDecl, 2452 SourceLocation(), 2453 SourceLocation(), 2454 msgSendIdent, msgSendType, 0, 2455 SC_Extern, 2456 SC_None, false); 2457 } 2458 2459 // SynthMsgSendFpretFunctionDecl - double objc_msgSend_fpret(id self, SEL op, ...); 2460 void RewriteObjC::SynthMsgSendFpretFunctionDecl() { 2461 IdentifierInfo *msgSendIdent = &Context->Idents.get("objc_msgSend_fpret"); 2462 SmallVector<QualType, 16> ArgTys; 2463 QualType argT = Context->getObjCIdType(); 2464 assert(!argT.isNull() && "Can't find 'id' type"); 2465 ArgTys.push_back(argT); 2466 argT = Context->getObjCSelType(); 2467 assert(!argT.isNull() && "Can't find 'SEL' type"); 2468 ArgTys.push_back(argT); 2469 QualType msgSendType = getSimpleFunctionType(Context->DoubleTy, 2470 &ArgTys[0], ArgTys.size(), 2471 true /*isVariadic*/); 2472 MsgSendFpretFunctionDecl = FunctionDecl::Create(*Context, TUDecl, 2473 SourceLocation(), 2474 SourceLocation(), 2475 msgSendIdent, msgSendType, 0, 2476 SC_Extern, 2477 SC_None, false); 2478 } 2479 2480 // SynthGetClassFunctionDecl - id objc_getClass(const char *name); 2481 void RewriteObjC::SynthGetClassFunctionDecl() { 2482 IdentifierInfo *getClassIdent = &Context->Idents.get("objc_getClass"); 2483 SmallVector<QualType, 16> ArgTys; 2484 ArgTys.push_back(Context->getPointerType(Context->CharTy.withConst())); 2485 QualType getClassType = getSimpleFunctionType(Context->getObjCIdType(), 2486 &ArgTys[0], ArgTys.size()); 2487 GetClassFunctionDecl = FunctionDecl::Create(*Context, TUDecl, 2488 SourceLocation(), 2489 SourceLocation(), 2490 getClassIdent, getClassType, 0, 2491 SC_Extern, 2492 SC_None, false); 2493 } 2494 2495 // SynthGetSuperClassFunctionDecl - Class class_getSuperclass(Class cls); 2496 void RewriteObjC::SynthGetSuperClassFunctionDecl() { 2497 IdentifierInfo *getSuperClassIdent = 2498 &Context->Idents.get("class_getSuperclass"); 2499 SmallVector<QualType, 16> ArgTys; 2500 ArgTys.push_back(Context->getObjCClassType()); 2501 QualType getClassType = getSimpleFunctionType(Context->getObjCClassType(), 2502 &ArgTys[0], ArgTys.size()); 2503 GetSuperClassFunctionDecl = FunctionDecl::Create(*Context, TUDecl, 2504 SourceLocation(), 2505 SourceLocation(), 2506 getSuperClassIdent, 2507 getClassType, 0, 2508 SC_Extern, 2509 SC_None, 2510 false); 2511 } 2512 2513 // SynthGetMetaClassFunctionDecl - id objc_getMetaClass(const char *name); 2514 void RewriteObjC::SynthGetMetaClassFunctionDecl() { 2515 IdentifierInfo *getClassIdent = &Context->Idents.get("objc_getMetaClass"); 2516 SmallVector<QualType, 16> ArgTys; 2517 ArgTys.push_back(Context->getPointerType(Context->CharTy.withConst())); 2518 QualType getClassType = getSimpleFunctionType(Context->getObjCIdType(), 2519 &ArgTys[0], ArgTys.size()); 2520 GetMetaClassFunctionDecl = FunctionDecl::Create(*Context, TUDecl, 2521 SourceLocation(), 2522 SourceLocation(), 2523 getClassIdent, getClassType, 0, 2524 SC_Extern, 2525 SC_None, false); 2526 } 2527 2528 Stmt *RewriteObjC::RewriteObjCStringLiteral(ObjCStringLiteral *Exp) { 2529 QualType strType = getConstantStringStructType(); 2530 2531 std::string S = "__NSConstantStringImpl_"; 2532 2533 std::string tmpName = InFileName; 2534 unsigned i; 2535 for (i=0; i < tmpName.length(); i++) { 2536 char c = tmpName.at(i); 2537 // replace any non alphanumeric characters with '_'. 2538 if (!isalpha(c) && (c < '0' || c > '9')) 2539 tmpName[i] = '_'; 2540 } 2541 S += tmpName; 2542 S += "_"; 2543 S += utostr(NumObjCStringLiterals++); 2544 2545 Preamble += "static __NSConstantStringImpl " + S; 2546 Preamble += " __attribute__ ((section (\"__DATA, __cfstring\"))) = {__CFConstantStringClassReference,"; 2547 Preamble += "0x000007c8,"; // utf8_str 2548 // The pretty printer for StringLiteral handles escape characters properly. 2549 std::string prettyBufS; 2550 llvm::raw_string_ostream prettyBuf(prettyBufS); 2551 Exp->getString()->printPretty(prettyBuf, *Context, 0, 2552 PrintingPolicy(LangOpts)); 2553 Preamble += prettyBuf.str(); 2554 Preamble += ","; 2555 Preamble += utostr(Exp->getString()->getByteLength()) + "};\n"; 2556 2557 VarDecl *NewVD = VarDecl::Create(*Context, TUDecl, SourceLocation(), 2558 SourceLocation(), &Context->Idents.get(S), 2559 strType, 0, SC_Static, SC_None); 2560 DeclRefExpr *DRE = new (Context) DeclRefExpr(NewVD, false, strType, VK_LValue, 2561 SourceLocation()); 2562 Expr *Unop = new (Context) UnaryOperator(DRE, UO_AddrOf, 2563 Context->getPointerType(DRE->getType()), 2564 VK_RValue, OK_Ordinary, 2565 SourceLocation()); 2566 // cast to NSConstantString * 2567 CastExpr *cast = NoTypeInfoCStyleCastExpr(Context, Exp->getType(), 2568 CK_CPointerToObjCPointerCast, Unop); 2569 ReplaceStmt(Exp, cast); 2570 // delete Exp; leak for now, see RewritePropertyOrImplicitSetter() usage for more info. 2571 return cast; 2572 } 2573 2574 // struct objc_super { struct objc_object *receiver; struct objc_class *super; }; 2575 QualType RewriteObjC::getSuperStructType() { 2576 if (!SuperStructDecl) { 2577 SuperStructDecl = RecordDecl::Create(*Context, TTK_Struct, TUDecl, 2578 SourceLocation(), SourceLocation(), 2579 &Context->Idents.get("objc_super")); 2580 QualType FieldTypes[2]; 2581 2582 // struct objc_object *receiver; 2583 FieldTypes[0] = Context->getObjCIdType(); 2584 // struct objc_class *super; 2585 FieldTypes[1] = Context->getObjCClassType(); 2586 2587 // Create fields 2588 for (unsigned i = 0; i < 2; ++i) { 2589 SuperStructDecl->addDecl(FieldDecl::Create(*Context, SuperStructDecl, 2590 SourceLocation(), 2591 SourceLocation(), 0, 2592 FieldTypes[i], 0, 2593 /*BitWidth=*/0, 2594 /*Mutable=*/false, 2595 /*HasInit=*/false)); 2596 } 2597 2598 SuperStructDecl->completeDefinition(); 2599 } 2600 return Context->getTagDeclType(SuperStructDecl); 2601 } 2602 2603 QualType RewriteObjC::getConstantStringStructType() { 2604 if (!ConstantStringDecl) { 2605 ConstantStringDecl = RecordDecl::Create(*Context, TTK_Struct, TUDecl, 2606 SourceLocation(), SourceLocation(), 2607 &Context->Idents.get("__NSConstantStringImpl")); 2608 QualType FieldTypes[4]; 2609 2610 // struct objc_object *receiver; 2611 FieldTypes[0] = Context->getObjCIdType(); 2612 // int flags; 2613 FieldTypes[1] = Context->IntTy; 2614 // char *str; 2615 FieldTypes[2] = Context->getPointerType(Context->CharTy); 2616 // long length; 2617 FieldTypes[3] = Context->LongTy; 2618 2619 // Create fields 2620 for (unsigned i = 0; i < 4; ++i) { 2621 ConstantStringDecl->addDecl(FieldDecl::Create(*Context, 2622 ConstantStringDecl, 2623 SourceLocation(), 2624 SourceLocation(), 0, 2625 FieldTypes[i], 0, 2626 /*BitWidth=*/0, 2627 /*Mutable=*/true, 2628 /*HasInit=*/false)); 2629 } 2630 2631 ConstantStringDecl->completeDefinition(); 2632 } 2633 return Context->getTagDeclType(ConstantStringDecl); 2634 } 2635 2636 Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp, 2637 SourceLocation StartLoc, 2638 SourceLocation EndLoc) { 2639 if (!SelGetUidFunctionDecl) 2640 SynthSelGetUidFunctionDecl(); 2641 if (!MsgSendFunctionDecl) 2642 SynthMsgSendFunctionDecl(); 2643 if (!MsgSendSuperFunctionDecl) 2644 SynthMsgSendSuperFunctionDecl(); 2645 if (!MsgSendStretFunctionDecl) 2646 SynthMsgSendStretFunctionDecl(); 2647 if (!MsgSendSuperStretFunctionDecl) 2648 SynthMsgSendSuperStretFunctionDecl(); 2649 if (!MsgSendFpretFunctionDecl) 2650 SynthMsgSendFpretFunctionDecl(); 2651 if (!GetClassFunctionDecl) 2652 SynthGetClassFunctionDecl(); 2653 if (!GetSuperClassFunctionDecl) 2654 SynthGetSuperClassFunctionDecl(); 2655 if (!GetMetaClassFunctionDecl) 2656 SynthGetMetaClassFunctionDecl(); 2657 2658 // default to objc_msgSend(). 2659 FunctionDecl *MsgSendFlavor = MsgSendFunctionDecl; 2660 // May need to use objc_msgSend_stret() as well. 2661 FunctionDecl *MsgSendStretFlavor = 0; 2662 if (ObjCMethodDecl *mDecl = Exp->getMethodDecl()) { 2663 QualType resultType = mDecl->getResultType(); 2664 if (resultType->isRecordType()) 2665 MsgSendStretFlavor = MsgSendStretFunctionDecl; 2666 else if (resultType->isRealFloatingType()) 2667 MsgSendFlavor = MsgSendFpretFunctionDecl; 2668 } 2669 2670 // Synthesize a call to objc_msgSend(). 2671 SmallVector<Expr*, 8> MsgExprs; 2672 switch (Exp->getReceiverKind()) { 2673 case ObjCMessageExpr::SuperClass: { 2674 MsgSendFlavor = MsgSendSuperFunctionDecl; 2675 if (MsgSendStretFlavor) 2676 MsgSendStretFlavor = MsgSendSuperStretFunctionDecl; 2677 assert(MsgSendFlavor && "MsgSendFlavor is NULL!"); 2678 2679 ObjCInterfaceDecl *ClassDecl = CurMethodDef->getClassInterface(); 2680 2681 SmallVector<Expr*, 4> InitExprs; 2682 2683 // set the receiver to self, the first argument to all methods. 2684 InitExprs.push_back( 2685 NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(), 2686 CK_BitCast, 2687 new (Context) DeclRefExpr(CurMethodDef->getSelfDecl(), 2688 false, 2689 Context->getObjCIdType(), 2690 VK_RValue, 2691 SourceLocation())) 2692 ); // set the 'receiver'. 2693 2694 // (id)class_getSuperclass((Class)objc_getClass("CurrentClass")) 2695 SmallVector<Expr*, 8> ClsExprs; 2696 QualType argType = Context->getPointerType(Context->CharTy); 2697 ClsExprs.push_back(StringLiteral::Create(*Context, 2698 ClassDecl->getIdentifier()->getName(), 2699 StringLiteral::Ascii, false, 2700 argType, SourceLocation())); 2701 CallExpr *Cls = SynthesizeCallToFunctionDecl(GetMetaClassFunctionDecl, 2702 &ClsExprs[0], 2703 ClsExprs.size(), 2704 StartLoc, 2705 EndLoc); 2706 // (Class)objc_getClass("CurrentClass") 2707 CastExpr *ArgExpr = NoTypeInfoCStyleCastExpr(Context, 2708 Context->getObjCClassType(), 2709 CK_BitCast, Cls); 2710 ClsExprs.clear(); 2711 ClsExprs.push_back(ArgExpr); 2712 Cls = SynthesizeCallToFunctionDecl(GetSuperClassFunctionDecl, 2713 &ClsExprs[0], ClsExprs.size(), 2714 StartLoc, EndLoc); 2715 2716 // (id)class_getSuperclass((Class)objc_getClass("CurrentClass")) 2717 // To turn off a warning, type-cast to 'id' 2718 InitExprs.push_back( // set 'super class', using class_getSuperclass(). 2719 NoTypeInfoCStyleCastExpr(Context, 2720 Context->getObjCIdType(), 2721 CK_BitCast, Cls)); 2722 // struct objc_super 2723 QualType superType = getSuperStructType(); 2724 Expr *SuperRep; 2725 2726 if (LangOpts.MicrosoftExt) { 2727 SynthSuperContructorFunctionDecl(); 2728 // Simulate a contructor call... 2729 DeclRefExpr *DRE = new (Context) DeclRefExpr(SuperContructorFunctionDecl, 2730 false, superType, VK_LValue, 2731 SourceLocation()); 2732 SuperRep = new (Context) CallExpr(*Context, DRE, &InitExprs[0], 2733 InitExprs.size(), 2734 superType, VK_LValue, 2735 SourceLocation()); 2736 // The code for super is a little tricky to prevent collision with 2737 // the structure definition in the header. The rewriter has it's own 2738 // internal definition (__rw_objc_super) that is uses. This is why 2739 // we need the cast below. For example: 2740 // (struct objc_super *)&__rw_objc_super((id)self, (id)objc_getClass("SUPER")) 2741 // 2742 SuperRep = new (Context) UnaryOperator(SuperRep, UO_AddrOf, 2743 Context->getPointerType(SuperRep->getType()), 2744 VK_RValue, OK_Ordinary, 2745 SourceLocation()); 2746 SuperRep = NoTypeInfoCStyleCastExpr(Context, 2747 Context->getPointerType(superType), 2748 CK_BitCast, SuperRep); 2749 } else { 2750 // (struct objc_super) { <exprs from above> } 2751 InitListExpr *ILE = 2752 new (Context) InitListExpr(*Context, SourceLocation(), 2753 &InitExprs[0], InitExprs.size(), 2754 SourceLocation()); 2755 TypeSourceInfo *superTInfo 2756 = Context->getTrivialTypeSourceInfo(superType); 2757 SuperRep = new (Context) CompoundLiteralExpr(SourceLocation(), superTInfo, 2758 superType, VK_LValue, 2759 ILE, false); 2760 // struct objc_super * 2761 SuperRep = new (Context) UnaryOperator(SuperRep, UO_AddrOf, 2762 Context->getPointerType(SuperRep->getType()), 2763 VK_RValue, OK_Ordinary, 2764 SourceLocation()); 2765 } 2766 MsgExprs.push_back(SuperRep); 2767 break; 2768 } 2769 2770 case ObjCMessageExpr::Class: { 2771 SmallVector<Expr*, 8> ClsExprs; 2772 QualType argType = Context->getPointerType(Context->CharTy); 2773 ObjCInterfaceDecl *Class 2774 = Exp->getClassReceiver()->getAs<ObjCObjectType>()->getInterface(); 2775 IdentifierInfo *clsName = Class->getIdentifier(); 2776 ClsExprs.push_back(StringLiteral::Create(*Context, 2777 clsName->getName(), 2778 StringLiteral::Ascii, false, 2779 argType, SourceLocation())); 2780 CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl, 2781 &ClsExprs[0], 2782 ClsExprs.size(), 2783 StartLoc, EndLoc); 2784 MsgExprs.push_back(Cls); 2785 break; 2786 } 2787 2788 case ObjCMessageExpr::SuperInstance:{ 2789 MsgSendFlavor = MsgSendSuperFunctionDecl; 2790 if (MsgSendStretFlavor) 2791 MsgSendStretFlavor = MsgSendSuperStretFunctionDecl; 2792 assert(MsgSendFlavor && "MsgSendFlavor is NULL!"); 2793 ObjCInterfaceDecl *ClassDecl = CurMethodDef->getClassInterface(); 2794 SmallVector<Expr*, 4> InitExprs; 2795 2796 InitExprs.push_back( 2797 NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(), 2798 CK_BitCast, 2799 new (Context) DeclRefExpr(CurMethodDef->getSelfDecl(), 2800 false, 2801 Context->getObjCIdType(), 2802 VK_RValue, SourceLocation())) 2803 ); // set the 'receiver'. 2804 2805 // (id)class_getSuperclass((Class)objc_getClass("CurrentClass")) 2806 SmallVector<Expr*, 8> ClsExprs; 2807 QualType argType = Context->getPointerType(Context->CharTy); 2808 ClsExprs.push_back(StringLiteral::Create(*Context, 2809 ClassDecl->getIdentifier()->getName(), 2810 StringLiteral::Ascii, false, argType, 2811 SourceLocation())); 2812 CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl, 2813 &ClsExprs[0], 2814 ClsExprs.size(), 2815 StartLoc, EndLoc); 2816 // (Class)objc_getClass("CurrentClass") 2817 CastExpr *ArgExpr = NoTypeInfoCStyleCastExpr(Context, 2818 Context->getObjCClassType(), 2819 CK_BitCast, Cls); 2820 ClsExprs.clear(); 2821 ClsExprs.push_back(ArgExpr); 2822 Cls = SynthesizeCallToFunctionDecl(GetSuperClassFunctionDecl, 2823 &ClsExprs[0], ClsExprs.size(), 2824 StartLoc, EndLoc); 2825 2826 // (id)class_getSuperclass((Class)objc_getClass("CurrentClass")) 2827 // To turn off a warning, type-cast to 'id' 2828 InitExprs.push_back( 2829 // set 'super class', using class_getSuperclass(). 2830 NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(), 2831 CK_BitCast, Cls)); 2832 // struct objc_super 2833 QualType superType = getSuperStructType(); 2834 Expr *SuperRep; 2835 2836 if (LangOpts.MicrosoftExt) { 2837 SynthSuperContructorFunctionDecl(); 2838 // Simulate a contructor call... 2839 DeclRefExpr *DRE = new (Context) DeclRefExpr(SuperContructorFunctionDecl, 2840 false, superType, VK_LValue, 2841 SourceLocation()); 2842 SuperRep = new (Context) CallExpr(*Context, DRE, &InitExprs[0], 2843 InitExprs.size(), 2844 superType, VK_LValue, SourceLocation()); 2845 // The code for super is a little tricky to prevent collision with 2846 // the structure definition in the header. The rewriter has it's own 2847 // internal definition (__rw_objc_super) that is uses. This is why 2848 // we need the cast below. For example: 2849 // (struct objc_super *)&__rw_objc_super((id)self, (id)objc_getClass("SUPER")) 2850 // 2851 SuperRep = new (Context) UnaryOperator(SuperRep, UO_AddrOf, 2852 Context->getPointerType(SuperRep->getType()), 2853 VK_RValue, OK_Ordinary, 2854 SourceLocation()); 2855 SuperRep = NoTypeInfoCStyleCastExpr(Context, 2856 Context->getPointerType(superType), 2857 CK_BitCast, SuperRep); 2858 } else { 2859 // (struct objc_super) { <exprs from above> } 2860 InitListExpr *ILE = 2861 new (Context) InitListExpr(*Context, SourceLocation(), 2862 &InitExprs[0], InitExprs.size(), 2863 SourceLocation()); 2864 TypeSourceInfo *superTInfo 2865 = Context->getTrivialTypeSourceInfo(superType); 2866 SuperRep = new (Context) CompoundLiteralExpr(SourceLocation(), superTInfo, 2867 superType, VK_RValue, ILE, 2868 false); 2869 } 2870 MsgExprs.push_back(SuperRep); 2871 break; 2872 } 2873 2874 case ObjCMessageExpr::Instance: { 2875 // Remove all type-casts because it may contain objc-style types; e.g. 2876 // Foo<Proto> *. 2877 Expr *recExpr = Exp->getInstanceReceiver(); 2878 while (CStyleCastExpr *CE = dyn_cast<CStyleCastExpr>(recExpr)) 2879 recExpr = CE->getSubExpr(); 2880 CastKind CK = recExpr->getType()->isObjCObjectPointerType() 2881 ? CK_BitCast : recExpr->getType()->isBlockPointerType() 2882 ? CK_BlockPointerToObjCPointerCast 2883 : CK_CPointerToObjCPointerCast; 2884 2885 recExpr = NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(), 2886 CK, recExpr); 2887 MsgExprs.push_back(recExpr); 2888 break; 2889 } 2890 } 2891 2892 // Create a call to sel_registerName("selName"), it will be the 2nd argument. 2893 SmallVector<Expr*, 8> SelExprs; 2894 QualType argType = Context->getPointerType(Context->CharTy); 2895 SelExprs.push_back(StringLiteral::Create(*Context, 2896 Exp->getSelector().getAsString(), 2897 StringLiteral::Ascii, false, 2898 argType, SourceLocation())); 2899 CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl, 2900 &SelExprs[0], SelExprs.size(), 2901 StartLoc, 2902 EndLoc); 2903 MsgExprs.push_back(SelExp); 2904 2905 // Now push any user supplied arguments. 2906 for (unsigned i = 0; i < Exp->getNumArgs(); i++) { 2907 Expr *userExpr = Exp->getArg(i); 2908 // Make all implicit casts explicit...ICE comes in handy:-) 2909 if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(userExpr)) { 2910 // Reuse the ICE type, it is exactly what the doctor ordered. 2911 QualType type = ICE->getType(); 2912 if (needToScanForQualifiers(type)) 2913 type = Context->getObjCIdType(); 2914 // Make sure we convert "type (^)(...)" to "type (*)(...)". 2915 (void)convertBlockPointerToFunctionPointer(type); 2916 const Expr *SubExpr = ICE->IgnoreParenImpCasts(); 2917 CastKind CK; 2918 if (SubExpr->getType()->isIntegralType(*Context) && 2919 type->isBooleanType()) { 2920 CK = CK_IntegralToBoolean; 2921 } else if (type->isObjCObjectPointerType()) { 2922 if (SubExpr->getType()->isBlockPointerType()) { 2923 CK = CK_BlockPointerToObjCPointerCast; 2924 } else if (SubExpr->getType()->isPointerType()) { 2925 CK = CK_CPointerToObjCPointerCast; 2926 } else { 2927 CK = CK_BitCast; 2928 } 2929 } else { 2930 CK = CK_BitCast; 2931 } 2932 2933 userExpr = NoTypeInfoCStyleCastExpr(Context, type, CK, userExpr); 2934 } 2935 // Make id<P...> cast into an 'id' cast. 2936 else if (CStyleCastExpr *CE = dyn_cast<CStyleCastExpr>(userExpr)) { 2937 if (CE->getType()->isObjCQualifiedIdType()) { 2938 while ((CE = dyn_cast<CStyleCastExpr>(userExpr))) 2939 userExpr = CE->getSubExpr(); 2940 CastKind CK; 2941 if (userExpr->getType()->isIntegralType(*Context)) { 2942 CK = CK_IntegralToPointer; 2943 } else if (userExpr->getType()->isBlockPointerType()) { 2944 CK = CK_BlockPointerToObjCPointerCast; 2945 } else if (userExpr->getType()->isPointerType()) { 2946 CK = CK_CPointerToObjCPointerCast; 2947 } else { 2948 CK = CK_BitCast; 2949 } 2950 userExpr = NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(), 2951 CK, userExpr); 2952 } 2953 } 2954 MsgExprs.push_back(userExpr); 2955 // We've transferred the ownership to MsgExprs. For now, we *don't* null 2956 // out the argument in the original expression (since we aren't deleting 2957 // the ObjCMessageExpr). See RewritePropertyOrImplicitSetter() usage for more info. 2958 //Exp->setArg(i, 0); 2959 } 2960 // Generate the funky cast. 2961 CastExpr *cast; 2962 SmallVector<QualType, 8> ArgTypes; 2963 QualType returnType; 2964 2965 // Push 'id' and 'SEL', the 2 implicit arguments. 2966 if (MsgSendFlavor == MsgSendSuperFunctionDecl) 2967 ArgTypes.push_back(Context->getPointerType(getSuperStructType())); 2968 else 2969 ArgTypes.push_back(Context->getObjCIdType()); 2970 ArgTypes.push_back(Context->getObjCSelType()); 2971 if (ObjCMethodDecl *OMD = Exp->getMethodDecl()) { 2972 // Push any user argument types. 2973 for (ObjCMethodDecl::param_iterator PI = OMD->param_begin(), 2974 E = OMD->param_end(); PI != E; ++PI) { 2975 QualType t = (*PI)->getType()->isObjCQualifiedIdType() 2976 ? Context->getObjCIdType() 2977 : (*PI)->getType(); 2978 // Make sure we convert "t (^)(...)" to "t (*)(...)". 2979 (void)convertBlockPointerToFunctionPointer(t); 2980 ArgTypes.push_back(t); 2981 } 2982 returnType = Exp->getType(); 2983 convertToUnqualifiedObjCType(returnType); 2984 (void)convertBlockPointerToFunctionPointer(returnType); 2985 } else { 2986 returnType = Context->getObjCIdType(); 2987 } 2988 // Get the type, we will need to reference it in a couple spots. 2989 QualType msgSendType = MsgSendFlavor->getType(); 2990 2991 // Create a reference to the objc_msgSend() declaration. 2992 DeclRefExpr *DRE = new (Context) DeclRefExpr(MsgSendFlavor, false, msgSendType, 2993 VK_LValue, SourceLocation()); 2994 2995 // Need to cast objc_msgSend to "void *" (to workaround a GCC bandaid). 2996 // If we don't do this cast, we get the following bizarre warning/note: 2997 // xx.m:13: warning: function called through a non-compatible type 2998 // xx.m:13: note: if this code is reached, the program will abort 2999 cast = NoTypeInfoCStyleCastExpr(Context, 3000 Context->getPointerType(Context->VoidTy), 3001 CK_BitCast, DRE); 3002 3003 // Now do the "normal" pointer to function cast. 3004 QualType castType = 3005 getSimpleFunctionType(returnType, &ArgTypes[0], ArgTypes.size(), 3006 // If we don't have a method decl, force a variadic cast. 3007 Exp->getMethodDecl() ? Exp->getMethodDecl()->isVariadic() : true); 3008 castType = Context->getPointerType(castType); 3009 cast = NoTypeInfoCStyleCastExpr(Context, castType, CK_BitCast, 3010 cast); 3011 3012 // Don't forget the parens to enforce the proper binding. 3013 ParenExpr *PE = new (Context) ParenExpr(StartLoc, EndLoc, cast); 3014 3015 const FunctionType *FT = msgSendType->getAs<FunctionType>(); 3016 CallExpr *CE = new (Context) CallExpr(*Context, PE, &MsgExprs[0], 3017 MsgExprs.size(), 3018 FT->getResultType(), VK_RValue, 3019 EndLoc); 3020 Stmt *ReplacingStmt = CE; 3021 if (MsgSendStretFlavor) { 3022 // We have the method which returns a struct/union. Must also generate 3023 // call to objc_msgSend_stret and hang both varieties on a conditional 3024 // expression which dictate which one to envoke depending on size of 3025 // method's return type. 3026 3027 // Create a reference to the objc_msgSend_stret() declaration. 3028 DeclRefExpr *STDRE = new (Context) DeclRefExpr(MsgSendStretFlavor, 3029 false, msgSendType, 3030 VK_LValue, SourceLocation()); 3031 // Need to cast objc_msgSend_stret to "void *" (see above comment). 3032 cast = NoTypeInfoCStyleCastExpr(Context, 3033 Context->getPointerType(Context->VoidTy), 3034 CK_BitCast, STDRE); 3035 // Now do the "normal" pointer to function cast. 3036 castType = getSimpleFunctionType(returnType, &ArgTypes[0], ArgTypes.size(), 3037 Exp->getMethodDecl() ? Exp->getMethodDecl()->isVariadic() : false); 3038 castType = Context->getPointerType(castType); 3039 cast = NoTypeInfoCStyleCastExpr(Context, castType, CK_BitCast, 3040 cast); 3041 3042 // Don't forget the parens to enforce the proper binding. 3043 PE = new (Context) ParenExpr(SourceLocation(), SourceLocation(), cast); 3044 3045 FT = msgSendType->getAs<FunctionType>(); 3046 CallExpr *STCE = new (Context) CallExpr(*Context, PE, &MsgExprs[0], 3047 MsgExprs.size(), 3048 FT->getResultType(), VK_RValue, 3049 SourceLocation()); 3050 3051 // Build sizeof(returnType) 3052 UnaryExprOrTypeTraitExpr *sizeofExpr = 3053 new (Context) UnaryExprOrTypeTraitExpr(UETT_SizeOf, 3054 Context->getTrivialTypeSourceInfo(returnType), 3055 Context->getSizeType(), SourceLocation(), 3056 SourceLocation()); 3057 // (sizeof(returnType) <= 8 ? objc_msgSend(...) : objc_msgSend_stret(...)) 3058 // FIXME: Value of 8 is base on ppc32/x86 ABI for the most common cases. 3059 // For X86 it is more complicated and some kind of target specific routine 3060 // is needed to decide what to do. 3061 unsigned IntSize = 3062 static_cast<unsigned>(Context->getTypeSize(Context->IntTy)); 3063 IntegerLiteral *limit = IntegerLiteral::Create(*Context, 3064 llvm::APInt(IntSize, 8), 3065 Context->IntTy, 3066 SourceLocation()); 3067 BinaryOperator *lessThanExpr = 3068 new (Context) BinaryOperator(sizeofExpr, limit, BO_LE, Context->IntTy, 3069 VK_RValue, OK_Ordinary, SourceLocation()); 3070 // (sizeof(returnType) <= 8 ? objc_msgSend(...) : objc_msgSend_stret(...)) 3071 ConditionalOperator *CondExpr = 3072 new (Context) ConditionalOperator(lessThanExpr, 3073 SourceLocation(), CE, 3074 SourceLocation(), STCE, 3075 returnType, VK_RValue, OK_Ordinary); 3076 ReplacingStmt = new (Context) ParenExpr(SourceLocation(), SourceLocation(), 3077 CondExpr); 3078 } 3079 // delete Exp; leak for now, see RewritePropertyOrImplicitSetter() usage for more info. 3080 return ReplacingStmt; 3081 } 3082 3083 Stmt *RewriteObjC::RewriteMessageExpr(ObjCMessageExpr *Exp) { 3084 Stmt *ReplacingStmt = SynthMessageExpr(Exp, Exp->getLocStart(), 3085 Exp->getLocEnd()); 3086 3087 // Now do the actual rewrite. 3088 ReplaceStmt(Exp, ReplacingStmt); 3089 3090 // delete Exp; leak for now, see RewritePropertyOrImplicitSetter() usage for more info. 3091 return ReplacingStmt; 3092 } 3093 3094 // typedef struct objc_object Protocol; 3095 QualType RewriteObjC::getProtocolType() { 3096 if (!ProtocolTypeDecl) { 3097 TypeSourceInfo *TInfo 3098 = Context->getTrivialTypeSourceInfo(Context->getObjCIdType()); 3099 ProtocolTypeDecl = TypedefDecl::Create(*Context, TUDecl, 3100 SourceLocation(), SourceLocation(), 3101 &Context->Idents.get("Protocol"), 3102 TInfo); 3103 } 3104 return Context->getTypeDeclType(ProtocolTypeDecl); 3105 } 3106 3107 /// RewriteObjCProtocolExpr - Rewrite a protocol expression into 3108 /// a synthesized/forward data reference (to the protocol's metadata). 3109 /// The forward references (and metadata) are generated in 3110 /// RewriteObjC::HandleTranslationUnit(). 3111 Stmt *RewriteObjC::RewriteObjCProtocolExpr(ObjCProtocolExpr *Exp) { 3112 std::string Name = "_OBJC_PROTOCOL_" + Exp->getProtocol()->getNameAsString(); 3113 IdentifierInfo *ID = &Context->Idents.get(Name); 3114 VarDecl *VD = VarDecl::Create(*Context, TUDecl, SourceLocation(), 3115 SourceLocation(), ID, getProtocolType(), 0, 3116 SC_Extern, SC_None); 3117 DeclRefExpr *DRE = new (Context) DeclRefExpr(VD, false, getProtocolType(), 3118 VK_LValue, SourceLocation()); 3119 Expr *DerefExpr = new (Context) UnaryOperator(DRE, UO_AddrOf, 3120 Context->getPointerType(DRE->getType()), 3121 VK_RValue, OK_Ordinary, SourceLocation()); 3122 CastExpr *castExpr = NoTypeInfoCStyleCastExpr(Context, DerefExpr->getType(), 3123 CK_BitCast, 3124 DerefExpr); 3125 ReplaceStmt(Exp, castExpr); 3126 ProtocolExprDecls.insert(Exp->getProtocol()->getCanonicalDecl()); 3127 // delete Exp; leak for now, see RewritePropertyOrImplicitSetter() usage for more info. 3128 return castExpr; 3129 3130 } 3131 3132 bool RewriteObjC::BufferContainsPPDirectives(const char *startBuf, 3133 const char *endBuf) { 3134 while (startBuf < endBuf) { 3135 if (*startBuf == '#') { 3136 // Skip whitespace. 3137 for (++startBuf; startBuf[0] == ' ' || startBuf[0] == '\t'; ++startBuf) 3138 ; 3139 if (!strncmp(startBuf, "if", strlen("if")) || 3140 !strncmp(startBuf, "ifdef", strlen("ifdef")) || 3141 !strncmp(startBuf, "ifndef", strlen("ifndef")) || 3142 !strncmp(startBuf, "define", strlen("define")) || 3143 !strncmp(startBuf, "undef", strlen("undef")) || 3144 !strncmp(startBuf, "else", strlen("else")) || 3145 !strncmp(startBuf, "elif", strlen("elif")) || 3146 !strncmp(startBuf, "endif", strlen("endif")) || 3147 !strncmp(startBuf, "pragma", strlen("pragma")) || 3148 !strncmp(startBuf, "include", strlen("include")) || 3149 !strncmp(startBuf, "import", strlen("import")) || 3150 !strncmp(startBuf, "include_next", strlen("include_next"))) 3151 return true; 3152 } 3153 startBuf++; 3154 } 3155 return false; 3156 } 3157 3158 /// RewriteObjCInternalStruct - Rewrite one internal struct corresponding to 3159 /// an objective-c class with ivars. 3160 void RewriteObjC::RewriteObjCInternalStruct(ObjCInterfaceDecl *CDecl, 3161 std::string &Result) { 3162 assert(CDecl && "Class missing in SynthesizeObjCInternalStruct"); 3163 assert(CDecl->getName() != "" && 3164 "Name missing in SynthesizeObjCInternalStruct"); 3165 // Do not synthesize more than once. 3166 if (ObjCSynthesizedStructs.count(CDecl)) 3167 return; 3168 ObjCInterfaceDecl *RCDecl = CDecl->getSuperClass(); 3169 int NumIvars = CDecl->ivar_size(); 3170 SourceLocation LocStart = CDecl->getLocStart(); 3171 SourceLocation LocEnd = CDecl->getEndOfDefinitionLoc(); 3172 3173 const char *startBuf = SM->getCharacterData(LocStart); 3174 const char *endBuf = SM->getCharacterData(LocEnd); 3175 3176 // If no ivars and no root or if its root, directly or indirectly, 3177 // have no ivars (thus not synthesized) then no need to synthesize this class. 3178 if ((!CDecl->isThisDeclarationADefinition() || NumIvars == 0) && 3179 (!RCDecl || !ObjCSynthesizedStructs.count(RCDecl))) { 3180 endBuf += Lexer::MeasureTokenLength(LocEnd, *SM, LangOpts); 3181 ReplaceText(LocStart, endBuf-startBuf, Result); 3182 return; 3183 } 3184 3185 // FIXME: This has potential of causing problem. If 3186 // SynthesizeObjCInternalStruct is ever called recursively. 3187 Result += "\nstruct "; 3188 Result += CDecl->getNameAsString(); 3189 if (LangOpts.MicrosoftExt) 3190 Result += "_IMPL"; 3191 3192 if (NumIvars > 0) { 3193 const char *cursor = strchr(startBuf, '{'); 3194 assert((cursor && endBuf) 3195 && "SynthesizeObjCInternalStruct - malformed @interface"); 3196 // If the buffer contains preprocessor directives, we do more fine-grained 3197 // rewrites. This is intended to fix code that looks like (which occurs in 3198 // NSURL.h, for example): 3199 // 3200 // #ifdef XYZ 3201 // @interface Foo : NSObject 3202 // #else 3203 // @interface FooBar : NSObject 3204 // #endif 3205 // { 3206 // int i; 3207 // } 3208 // @end 3209 // 3210 // This clause is segregated to avoid breaking the common case. 3211 if (BufferContainsPPDirectives(startBuf, cursor)) { 3212 SourceLocation L = RCDecl ? CDecl->getSuperClassLoc() : 3213 CDecl->getAtStartLoc(); 3214 const char *endHeader = SM->getCharacterData(L); 3215 endHeader += Lexer::MeasureTokenLength(L, *SM, LangOpts); 3216 3217 if (CDecl->protocol_begin() != CDecl->protocol_end()) { 3218 // advance to the end of the referenced protocols. 3219 while (endHeader < cursor && *endHeader != '>') endHeader++; 3220 endHeader++; 3221 } 3222 // rewrite the original header 3223 ReplaceText(LocStart, endHeader-startBuf, Result); 3224 } else { 3225 // rewrite the original header *without* disturbing the '{' 3226 ReplaceText(LocStart, cursor-startBuf, Result); 3227 } 3228 if (RCDecl && ObjCSynthesizedStructs.count(RCDecl)) { 3229 Result = "\n struct "; 3230 Result += RCDecl->getNameAsString(); 3231 Result += "_IMPL "; 3232 Result += RCDecl->getNameAsString(); 3233 Result += "_IVARS;\n"; 3234 3235 // insert the super class structure definition. 3236 SourceLocation OnePastCurly = 3237 LocStart.getLocWithOffset(cursor-startBuf+1); 3238 InsertText(OnePastCurly, Result); 3239 } 3240 cursor++; // past '{' 3241 3242 // Now comment out any visibility specifiers. 3243 while (cursor < endBuf) { 3244 if (*cursor == '@') { 3245 SourceLocation atLoc = LocStart.getLocWithOffset(cursor-startBuf); 3246 // Skip whitespace. 3247 for (++cursor; cursor[0] == ' ' || cursor[0] == '\t'; ++cursor) 3248 /*scan*/; 3249 3250 // FIXME: presence of @public, etc. inside comment results in 3251 // this transformation as well, which is still correct c-code. 3252 if (!strncmp(cursor, "public", strlen("public")) || 3253 !strncmp(cursor, "private", strlen("private")) || 3254 !strncmp(cursor, "package", strlen("package")) || 3255 !strncmp(cursor, "protected", strlen("protected"))) 3256 InsertText(atLoc, "// "); 3257 } 3258 // FIXME: If there are cases where '<' is used in ivar declaration part 3259 // of user code, then scan the ivar list and use needToScanForQualifiers 3260 // for type checking. 3261 else if (*cursor == '<') { 3262 SourceLocation atLoc = LocStart.getLocWithOffset(cursor-startBuf); 3263 InsertText(atLoc, "/* "); 3264 cursor = strchr(cursor, '>'); 3265 cursor++; 3266 atLoc = LocStart.getLocWithOffset(cursor-startBuf); 3267 InsertText(atLoc, " */"); 3268 } else if (*cursor == '^') { // rewrite block specifier. 3269 SourceLocation caretLoc = LocStart.getLocWithOffset(cursor-startBuf); 3270 ReplaceText(caretLoc, 1, "*"); 3271 } 3272 cursor++; 3273 } 3274 // Don't forget to add a ';'!! 3275 InsertText(LocEnd.getLocWithOffset(1), ";"); 3276 } else { // we don't have any instance variables - insert super struct. 3277 endBuf += Lexer::MeasureTokenLength(LocEnd, *SM, LangOpts); 3278 Result += " {\n struct "; 3279 Result += RCDecl->getNameAsString(); 3280 Result += "_IMPL "; 3281 Result += RCDecl->getNameAsString(); 3282 Result += "_IVARS;\n};\n"; 3283 ReplaceText(LocStart, endBuf-startBuf, Result); 3284 } 3285 // Mark this struct as having been generated. 3286 if (!ObjCSynthesizedStructs.insert(CDecl)) 3287 llvm_unreachable("struct already synthesize- SynthesizeObjCInternalStruct"); 3288 } 3289 3290 //===----------------------------------------------------------------------===// 3291 // Meta Data Emission 3292 //===----------------------------------------------------------------------===// 3293 3294 3295 /// RewriteImplementations - This routine rewrites all method implementations 3296 /// and emits meta-data. 3297 3298 void RewriteObjC::RewriteImplementations() { 3299 int ClsDefCount = ClassImplementation.size(); 3300 int CatDefCount = CategoryImplementation.size(); 3301 3302 // Rewrite implemented methods 3303 for (int i = 0; i < ClsDefCount; i++) 3304 RewriteImplementationDecl(ClassImplementation[i]); 3305 3306 for (int i = 0; i < CatDefCount; i++) 3307 RewriteImplementationDecl(CategoryImplementation[i]); 3308 } 3309 3310 void RewriteObjC::RewriteByRefString(std::string &ResultStr, 3311 const std::string &Name, 3312 ValueDecl *VD, bool def) { 3313 assert(BlockByRefDeclNo.count(VD) && 3314 "RewriteByRefString: ByRef decl missing"); 3315 if (def) 3316 ResultStr += "struct "; 3317 ResultStr += "__Block_byref_" + Name + 3318 "_" + utostr(BlockByRefDeclNo[VD]) ; 3319 } 3320 3321 static bool HasLocalVariableExternalStorage(ValueDecl *VD) { 3322 if (VarDecl *Var = dyn_cast<VarDecl>(VD)) 3323 return (Var->isFunctionOrMethodVarDecl() && !Var->hasLocalStorage()); 3324 return false; 3325 } 3326 3327 std::string RewriteObjC::SynthesizeBlockFunc(BlockExpr *CE, int i, 3328 StringRef funcName, 3329 std::string Tag) { 3330 const FunctionType *AFT = CE->getFunctionType(); 3331 QualType RT = AFT->getResultType(); 3332 std::string StructRef = "struct " + Tag; 3333 std::string S = "static " + RT.getAsString(Context->getPrintingPolicy()) + " __" + 3334 funcName.str() + "_" + "block_func_" + utostr(i); 3335 3336 BlockDecl *BD = CE->getBlockDecl(); 3337 3338 if (isa<FunctionNoProtoType>(AFT)) { 3339 // No user-supplied arguments. Still need to pass in a pointer to the 3340 // block (to reference imported block decl refs). 3341 S += "(" + StructRef + " *__cself)"; 3342 } else if (BD->param_empty()) { 3343 S += "(" + StructRef + " *__cself)"; 3344 } else { 3345 const FunctionProtoType *FT = cast<FunctionProtoType>(AFT); 3346 assert(FT && "SynthesizeBlockFunc: No function proto"); 3347 S += '('; 3348 // first add the implicit argument. 3349 S += StructRef + " *__cself, "; 3350 std::string ParamStr; 3351 for (BlockDecl::param_iterator AI = BD->param_begin(), 3352 E = BD->param_end(); AI != E; ++AI) { 3353 if (AI != BD->param_begin()) S += ", "; 3354 ParamStr = (*AI)->getNameAsString(); 3355 QualType QT = (*AI)->getType(); 3356 (void)convertBlockPointerToFunctionPointer(QT); 3357 QT.getAsStringInternal(ParamStr, Context->getPrintingPolicy()); 3358 S += ParamStr; 3359 } 3360 if (FT->isVariadic()) { 3361 if (!BD->param_empty()) S += ", "; 3362 S += "..."; 3363 } 3364 S += ')'; 3365 } 3366 S += " {\n"; 3367 3368 // Create local declarations to avoid rewriting all closure decl ref exprs. 3369 // First, emit a declaration for all "by ref" decls. 3370 for (SmallVector<ValueDecl*,8>::iterator I = BlockByRefDecls.begin(), 3371 E = BlockByRefDecls.end(); I != E; ++I) { 3372 S += " "; 3373 std::string Name = (*I)->getNameAsString(); 3374 std::string TypeString; 3375 RewriteByRefString(TypeString, Name, (*I)); 3376 TypeString += " *"; 3377 Name = TypeString + Name; 3378 S += Name + " = __cself->" + (*I)->getNameAsString() + "; // bound by ref\n"; 3379 } 3380 // Next, emit a declaration for all "by copy" declarations. 3381 for (SmallVector<ValueDecl*,8>::iterator I = BlockByCopyDecls.begin(), 3382 E = BlockByCopyDecls.end(); I != E; ++I) { 3383 S += " "; 3384 // Handle nested closure invocation. For example: 3385 // 3386 // void (^myImportedClosure)(void); 3387 // myImportedClosure = ^(void) { setGlobalInt(x + y); }; 3388 // 3389 // void (^anotherClosure)(void); 3390 // anotherClosure = ^(void) { 3391 // myImportedClosure(); // import and invoke the closure 3392 // }; 3393 // 3394 if (isTopLevelBlockPointerType((*I)->getType())) { 3395 RewriteBlockPointerTypeVariable(S, (*I)); 3396 S += " = ("; 3397 RewriteBlockPointerType(S, (*I)->getType()); 3398 S += ")"; 3399 S += "__cself->" + (*I)->getNameAsString() + "; // bound by copy\n"; 3400 } 3401 else { 3402 std::string Name = (*I)->getNameAsString(); 3403 QualType QT = (*I)->getType(); 3404 if (HasLocalVariableExternalStorage(*I)) 3405 QT = Context->getPointerType(QT); 3406 QT.getAsStringInternal(Name, Context->getPrintingPolicy()); 3407 S += Name + " = __cself->" + 3408 (*I)->getNameAsString() + "; // bound by copy\n"; 3409 } 3410 } 3411 std::string RewrittenStr = RewrittenBlockExprs[CE]; 3412 const char *cstr = RewrittenStr.c_str(); 3413 while (*cstr++ != '{') ; 3414 S += cstr; 3415 S += "\n"; 3416 return S; 3417 } 3418 3419 std::string RewriteObjC::SynthesizeBlockHelperFuncs(BlockExpr *CE, int i, 3420 StringRef funcName, 3421 std::string Tag) { 3422 std::string StructRef = "struct " + Tag; 3423 std::string S = "static void __"; 3424 3425 S += funcName; 3426 S += "_block_copy_" + utostr(i); 3427 S += "(" + StructRef; 3428 S += "*dst, " + StructRef; 3429 S += "*src) {"; 3430 for (llvm::SmallPtrSet<ValueDecl*,8>::iterator I = ImportedBlockDecls.begin(), 3431 E = ImportedBlockDecls.end(); I != E; ++I) { 3432 ValueDecl *VD = (*I); 3433 S += "_Block_object_assign((void*)&dst->"; 3434 S += (*I)->getNameAsString(); 3435 S += ", (void*)src->"; 3436 S += (*I)->getNameAsString(); 3437 if (BlockByRefDeclsPtrSet.count((*I))) 3438 S += ", " + utostr(BLOCK_FIELD_IS_BYREF) + "/*BLOCK_FIELD_IS_BYREF*/);"; 3439 else if (VD->getType()->isBlockPointerType()) 3440 S += ", " + utostr(BLOCK_FIELD_IS_BLOCK) + "/*BLOCK_FIELD_IS_BLOCK*/);"; 3441 else 3442 S += ", " + utostr(BLOCK_FIELD_IS_OBJECT) + "/*BLOCK_FIELD_IS_OBJECT*/);"; 3443 } 3444 S += "}\n"; 3445 3446 S += "\nstatic void __"; 3447 S += funcName; 3448 S += "_block_dispose_" + utostr(i); 3449 S += "(" + StructRef; 3450 S += "*src) {"; 3451 for (llvm::SmallPtrSet<ValueDecl*,8>::iterator I = ImportedBlockDecls.begin(), 3452 E = ImportedBlockDecls.end(); I != E; ++I) { 3453 ValueDecl *VD = (*I); 3454 S += "_Block_object_dispose((void*)src->"; 3455 S += (*I)->getNameAsString(); 3456 if (BlockByRefDeclsPtrSet.count((*I))) 3457 S += ", " + utostr(BLOCK_FIELD_IS_BYREF) + "/*BLOCK_FIELD_IS_BYREF*/);"; 3458 else if (VD->getType()->isBlockPointerType()) 3459 S += ", " + utostr(BLOCK_FIELD_IS_BLOCK) + "/*BLOCK_FIELD_IS_BLOCK*/);"; 3460 else 3461 S += ", " + utostr(BLOCK_FIELD_IS_OBJECT) + "/*BLOCK_FIELD_IS_OBJECT*/);"; 3462 } 3463 S += "}\n"; 3464 return S; 3465 } 3466 3467 std::string RewriteObjC::SynthesizeBlockImpl(BlockExpr *CE, std::string Tag, 3468 std::string Desc) { 3469 std::string S = "\nstruct " + Tag; 3470 std::string Constructor = " " + Tag; 3471 3472 S += " {\n struct __block_impl impl;\n"; 3473 S += " struct " + Desc; 3474 S += "* Desc;\n"; 3475 3476 Constructor += "(void *fp, "; // Invoke function pointer. 3477 Constructor += "struct " + Desc; // Descriptor pointer. 3478 Constructor += " *desc"; 3479 3480 if (BlockDeclRefs.size()) { 3481 // Output all "by copy" declarations. 3482 for (SmallVector<ValueDecl*,8>::iterator I = BlockByCopyDecls.begin(), 3483 E = BlockByCopyDecls.end(); I != E; ++I) { 3484 S += " "; 3485 std::string FieldName = (*I)->getNameAsString(); 3486 std::string ArgName = "_" + FieldName; 3487 // Handle nested closure invocation. For example: 3488 // 3489 // void (^myImportedBlock)(void); 3490 // myImportedBlock = ^(void) { setGlobalInt(x + y); }; 3491 // 3492 // void (^anotherBlock)(void); 3493 // anotherBlock = ^(void) { 3494 // myImportedBlock(); // import and invoke the closure 3495 // }; 3496 // 3497 if (isTopLevelBlockPointerType((*I)->getType())) { 3498 S += "struct __block_impl *"; 3499 Constructor += ", void *" + ArgName; 3500 } else { 3501 QualType QT = (*I)->getType(); 3502 if (HasLocalVariableExternalStorage(*I)) 3503 QT = Context->getPointerType(QT); 3504 QT.getAsStringInternal(FieldName, Context->getPrintingPolicy()); 3505 QT.getAsStringInternal(ArgName, Context->getPrintingPolicy()); 3506 Constructor += ", " + ArgName; 3507 } 3508 S += FieldName + ";\n"; 3509 } 3510 // Output all "by ref" declarations. 3511 for (SmallVector<ValueDecl*,8>::iterator I = BlockByRefDecls.begin(), 3512 E = BlockByRefDecls.end(); I != E; ++I) { 3513 S += " "; 3514 std::string FieldName = (*I)->getNameAsString(); 3515 std::string ArgName = "_" + FieldName; 3516 { 3517 std::string TypeString; 3518 RewriteByRefString(TypeString, FieldName, (*I)); 3519 TypeString += " *"; 3520 FieldName = TypeString + FieldName; 3521 ArgName = TypeString + ArgName; 3522 Constructor += ", " + ArgName; 3523 } 3524 S += FieldName + "; // by ref\n"; 3525 } 3526 // Finish writing the constructor. 3527 Constructor += ", int flags=0)"; 3528 // Initialize all "by copy" arguments. 3529 bool firsTime = true; 3530 for (SmallVector<ValueDecl*,8>::iterator I = BlockByCopyDecls.begin(), 3531 E = BlockByCopyDecls.end(); I != E; ++I) { 3532 std::string Name = (*I)->getNameAsString(); 3533 if (firsTime) { 3534 Constructor += " : "; 3535 firsTime = false; 3536 } 3537 else 3538 Constructor += ", "; 3539 if (isTopLevelBlockPointerType((*I)->getType())) 3540 Constructor += Name + "((struct __block_impl *)_" + Name + ")"; 3541 else 3542 Constructor += Name + "(_" + Name + ")"; 3543 } 3544 // Initialize all "by ref" arguments. 3545 for (SmallVector<ValueDecl*,8>::iterator I = BlockByRefDecls.begin(), 3546 E = BlockByRefDecls.end(); I != E; ++I) { 3547 std::string Name = (*I)->getNameAsString(); 3548 if (firsTime) { 3549 Constructor += " : "; 3550 firsTime = false; 3551 } 3552 else 3553 Constructor += ", "; 3554 Constructor += Name + "(_" + Name + "->__forwarding)"; 3555 } 3556 3557 Constructor += " {\n"; 3558 if (GlobalVarDecl) 3559 Constructor += " impl.isa = &_NSConcreteGlobalBlock;\n"; 3560 else 3561 Constructor += " impl.isa = &_NSConcreteStackBlock;\n"; 3562 Constructor += " impl.Flags = flags;\n impl.FuncPtr = fp;\n"; 3563 3564 Constructor += " Desc = desc;\n"; 3565 } else { 3566 // Finish writing the constructor. 3567 Constructor += ", int flags=0) {\n"; 3568 if (GlobalVarDecl) 3569 Constructor += " impl.isa = &_NSConcreteGlobalBlock;\n"; 3570 else 3571 Constructor += " impl.isa = &_NSConcreteStackBlock;\n"; 3572 Constructor += " impl.Flags = flags;\n impl.FuncPtr = fp;\n"; 3573 Constructor += " Desc = desc;\n"; 3574 } 3575 Constructor += " "; 3576 Constructor += "}\n"; 3577 S += Constructor; 3578 S += "};\n"; 3579 return S; 3580 } 3581 3582 std::string RewriteObjC::SynthesizeBlockDescriptor(std::string DescTag, 3583 std::string ImplTag, int i, 3584 StringRef FunName, 3585 unsigned hasCopy) { 3586 std::string S = "\nstatic struct " + DescTag; 3587 3588 S += " {\n unsigned long reserved;\n"; 3589 S += " unsigned long Block_size;\n"; 3590 if (hasCopy) { 3591 S += " void (*copy)(struct "; 3592 S += ImplTag; S += "*, struct "; 3593 S += ImplTag; S += "*);\n"; 3594 3595 S += " void (*dispose)(struct "; 3596 S += ImplTag; S += "*);\n"; 3597 } 3598 S += "} "; 3599 3600 S += DescTag + "_DATA = { 0, sizeof(struct "; 3601 S += ImplTag + ")"; 3602 if (hasCopy) { 3603 S += ", __" + FunName.str() + "_block_copy_" + utostr(i); 3604 S += ", __" + FunName.str() + "_block_dispose_" + utostr(i); 3605 } 3606 S += "};\n"; 3607 return S; 3608 } 3609 3610 void RewriteObjC::SynthesizeBlockLiterals(SourceLocation FunLocStart, 3611 StringRef FunName) { 3612 // Insert declaration for the function in which block literal is used. 3613 if (CurFunctionDeclToDeclareForBlock && !Blocks.empty()) 3614 RewriteBlockLiteralFunctionDecl(CurFunctionDeclToDeclareForBlock); 3615 bool RewriteSC = (GlobalVarDecl && 3616 !Blocks.empty() && 3617 GlobalVarDecl->getStorageClass() == SC_Static && 3618 GlobalVarDecl->getType().getCVRQualifiers()); 3619 if (RewriteSC) { 3620 std::string SC(" void __"); 3621 SC += GlobalVarDecl->getNameAsString(); 3622 SC += "() {}"; 3623 InsertText(FunLocStart, SC); 3624 } 3625 3626 // Insert closures that were part of the function. 3627 for (unsigned i = 0, count=0; i < Blocks.size(); i++) { 3628 CollectBlockDeclRefInfo(Blocks[i]); 3629 // Need to copy-in the inner copied-in variables not actually used in this 3630 // block. 3631 for (int j = 0; j < InnerDeclRefsCount[i]; j++) { 3632 DeclRefExpr *Exp = InnerDeclRefs[count++]; 3633 ValueDecl *VD = Exp->getDecl(); 3634 BlockDeclRefs.push_back(Exp); 3635 if (!VD->hasAttr<BlocksAttr>() && !BlockByCopyDeclsPtrSet.count(VD)) { 3636 BlockByCopyDeclsPtrSet.insert(VD); 3637 BlockByCopyDecls.push_back(VD); 3638 } 3639 if (VD->hasAttr<BlocksAttr>() && !BlockByRefDeclsPtrSet.count(VD)) { 3640 BlockByRefDeclsPtrSet.insert(VD); 3641 BlockByRefDecls.push_back(VD); 3642 } 3643 // imported objects in the inner blocks not used in the outer 3644 // blocks must be copied/disposed in the outer block as well. 3645 if (VD->hasAttr<BlocksAttr>() || 3646 VD->getType()->isObjCObjectPointerType() || 3647 VD->getType()->isBlockPointerType()) 3648 ImportedBlockDecls.insert(VD); 3649 } 3650 3651 std::string ImplTag = "__" + FunName.str() + "_block_impl_" + utostr(i); 3652 std::string DescTag = "__" + FunName.str() + "_block_desc_" + utostr(i); 3653 3654 std::string CI = SynthesizeBlockImpl(Blocks[i], ImplTag, DescTag); 3655 3656 InsertText(FunLocStart, CI); 3657 3658 std::string CF = SynthesizeBlockFunc(Blocks[i], i, FunName, ImplTag); 3659 3660 InsertText(FunLocStart, CF); 3661 3662 if (ImportedBlockDecls.size()) { 3663 std::string HF = SynthesizeBlockHelperFuncs(Blocks[i], i, FunName, ImplTag); 3664 InsertText(FunLocStart, HF); 3665 } 3666 std::string BD = SynthesizeBlockDescriptor(DescTag, ImplTag, i, FunName, 3667 ImportedBlockDecls.size() > 0); 3668 InsertText(FunLocStart, BD); 3669 3670 BlockDeclRefs.clear(); 3671 BlockByRefDecls.clear(); 3672 BlockByRefDeclsPtrSet.clear(); 3673 BlockByCopyDecls.clear(); 3674 BlockByCopyDeclsPtrSet.clear(); 3675 ImportedBlockDecls.clear(); 3676 } 3677 if (RewriteSC) { 3678 // Must insert any 'const/volatile/static here. Since it has been 3679 // removed as result of rewriting of block literals. 3680 std::string SC; 3681 if (GlobalVarDecl->getStorageClass() == SC_Static) 3682 SC = "static "; 3683 if (GlobalVarDecl->getType().isConstQualified()) 3684 SC += "const "; 3685 if (GlobalVarDecl->getType().isVolatileQualified()) 3686 SC += "volatile "; 3687 if (GlobalVarDecl->getType().isRestrictQualified()) 3688 SC += "restrict "; 3689 InsertText(FunLocStart, SC); 3690 } 3691 3692 Blocks.clear(); 3693 InnerDeclRefsCount.clear(); 3694 InnerDeclRefs.clear(); 3695 RewrittenBlockExprs.clear(); 3696 } 3697 3698 void RewriteObjC::InsertBlockLiteralsWithinFunction(FunctionDecl *FD) { 3699 SourceLocation FunLocStart = FD->getTypeSpecStartLoc(); 3700 StringRef FuncName = FD->getName(); 3701 3702 SynthesizeBlockLiterals(FunLocStart, FuncName); 3703 } 3704 3705 static void BuildUniqueMethodName(std::string &Name, 3706 ObjCMethodDecl *MD) { 3707 ObjCInterfaceDecl *IFace = MD->getClassInterface(); 3708 Name = IFace->getName(); 3709 Name += "__" + MD->getSelector().getAsString(); 3710 // Convert colons to underscores. 3711 std::string::size_type loc = 0; 3712 while ((loc = Name.find(":", loc)) != std::string::npos) 3713 Name.replace(loc, 1, "_"); 3714 } 3715 3716 void RewriteObjC::InsertBlockLiteralsWithinMethod(ObjCMethodDecl *MD) { 3717 //fprintf(stderr,"In InsertBlockLiteralsWitinMethod\n"); 3718 //SourceLocation FunLocStart = MD->getLocStart(); 3719 SourceLocation FunLocStart = MD->getLocStart(); 3720 std::string FuncName; 3721 BuildUniqueMethodName(FuncName, MD); 3722 SynthesizeBlockLiterals(FunLocStart, FuncName); 3723 } 3724 3725 void RewriteObjC::GetBlockDeclRefExprs(Stmt *S) { 3726 for (Stmt::child_range CI = S->children(); CI; ++CI) 3727 if (*CI) { 3728 if (BlockExpr *CBE = dyn_cast<BlockExpr>(*CI)) 3729 GetBlockDeclRefExprs(CBE->getBody()); 3730 else 3731 GetBlockDeclRefExprs(*CI); 3732 } 3733 // Handle specific things. 3734 if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(S)) { 3735 if (DRE->refersToEnclosingLocal()) { 3736 // FIXME: Handle enums. 3737 if (!isa<FunctionDecl>(DRE->getDecl())) 3738 BlockDeclRefs.push_back(DRE); 3739 if (HasLocalVariableExternalStorage(DRE->getDecl())) 3740 BlockDeclRefs.push_back(DRE); 3741 } 3742 } 3743 3744 return; 3745 } 3746 3747 void RewriteObjC::GetInnerBlockDeclRefExprs(Stmt *S, 3748 SmallVector<DeclRefExpr *, 8> &InnerBlockDeclRefs, 3749 llvm::SmallPtrSet<const DeclContext *, 8> &InnerContexts) { 3750 for (Stmt::child_range CI = S->children(); CI; ++CI) 3751 if (*CI) { 3752 if (BlockExpr *CBE = dyn_cast<BlockExpr>(*CI)) { 3753 InnerContexts.insert(cast<DeclContext>(CBE->getBlockDecl())); 3754 GetInnerBlockDeclRefExprs(CBE->getBody(), 3755 InnerBlockDeclRefs, 3756 InnerContexts); 3757 } 3758 else 3759 GetInnerBlockDeclRefExprs(*CI, 3760 InnerBlockDeclRefs, 3761 InnerContexts); 3762 3763 } 3764 // Handle specific things. 3765 if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(S)) { 3766 if (DRE->refersToEnclosingLocal()) { 3767 if (!isa<FunctionDecl>(DRE->getDecl()) && 3768 !InnerContexts.count(DRE->getDecl()->getDeclContext())) 3769 InnerBlockDeclRefs.push_back(DRE); 3770 if (VarDecl *Var = dyn_cast<VarDecl>(DRE->getDecl())) 3771 if (Var->isFunctionOrMethodVarDecl()) 3772 ImportedLocalExternalDecls.insert(Var); 3773 } 3774 } 3775 3776 return; 3777 } 3778 3779 /// convertFunctionTypeOfBlocks - This routine converts a function type 3780 /// whose result type may be a block pointer or whose argument type(s) 3781 /// might be block pointers to an equivalent function type replacing 3782 /// all block pointers to function pointers. 3783 QualType RewriteObjC::convertFunctionTypeOfBlocks(const FunctionType *FT) { 3784 const FunctionProtoType *FTP = dyn_cast<FunctionProtoType>(FT); 3785 // FTP will be null for closures that don't take arguments. 3786 // Generate a funky cast. 3787 SmallVector<QualType, 8> ArgTypes; 3788 QualType Res = FT->getResultType(); 3789 bool HasBlockType = convertBlockPointerToFunctionPointer(Res); 3790 3791 if (FTP) { 3792 for (FunctionProtoType::arg_type_iterator I = FTP->arg_type_begin(), 3793 E = FTP->arg_type_end(); I && (I != E); ++I) { 3794 QualType t = *I; 3795 // Make sure we convert "t (^)(...)" to "t (*)(...)". 3796 if (convertBlockPointerToFunctionPointer(t)) 3797 HasBlockType = true; 3798 ArgTypes.push_back(t); 3799 } 3800 } 3801 QualType FuncType; 3802 // FIXME. Does this work if block takes no argument but has a return type 3803 // which is of block type? 3804 if (HasBlockType) 3805 FuncType = getSimpleFunctionType(Res, &ArgTypes[0], ArgTypes.size()); 3806 else FuncType = QualType(FT, 0); 3807 return FuncType; 3808 } 3809 3810 Stmt *RewriteObjC::SynthesizeBlockCall(CallExpr *Exp, const Expr *BlockExp) { 3811 // Navigate to relevant type information. 3812 const BlockPointerType *CPT = 0; 3813 3814 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(BlockExp)) { 3815 CPT = DRE->getType()->getAs<BlockPointerType>(); 3816 } else if (const MemberExpr *MExpr = dyn_cast<MemberExpr>(BlockExp)) { 3817 CPT = MExpr->getType()->getAs<BlockPointerType>(); 3818 } 3819 else if (const ParenExpr *PRE = dyn_cast<ParenExpr>(BlockExp)) { 3820 return SynthesizeBlockCall(Exp, PRE->getSubExpr()); 3821 } 3822 else if (const ImplicitCastExpr *IEXPR = dyn_cast<ImplicitCastExpr>(BlockExp)) 3823 CPT = IEXPR->getType()->getAs<BlockPointerType>(); 3824 else if (const ConditionalOperator *CEXPR = 3825 dyn_cast<ConditionalOperator>(BlockExp)) { 3826 Expr *LHSExp = CEXPR->getLHS(); 3827 Stmt *LHSStmt = SynthesizeBlockCall(Exp, LHSExp); 3828 Expr *RHSExp = CEXPR->getRHS(); 3829 Stmt *RHSStmt = SynthesizeBlockCall(Exp, RHSExp); 3830 Expr *CONDExp = CEXPR->getCond(); 3831 ConditionalOperator *CondExpr = 3832 new (Context) ConditionalOperator(CONDExp, 3833 SourceLocation(), cast<Expr>(LHSStmt), 3834 SourceLocation(), cast<Expr>(RHSStmt), 3835 Exp->getType(), VK_RValue, OK_Ordinary); 3836 return CondExpr; 3837 } else if (const ObjCIvarRefExpr *IRE = dyn_cast<ObjCIvarRefExpr>(BlockExp)) { 3838 CPT = IRE->getType()->getAs<BlockPointerType>(); 3839 } else if (const PseudoObjectExpr *POE 3840 = dyn_cast<PseudoObjectExpr>(BlockExp)) { 3841 CPT = POE->getType()->castAs<BlockPointerType>(); 3842 } else { 3843 assert(1 && "RewriteBlockClass: Bad type"); 3844 } 3845 assert(CPT && "RewriteBlockClass: Bad type"); 3846 const FunctionType *FT = CPT->getPointeeType()->getAs<FunctionType>(); 3847 assert(FT && "RewriteBlockClass: Bad type"); 3848 const FunctionProtoType *FTP = dyn_cast<FunctionProtoType>(FT); 3849 // FTP will be null for closures that don't take arguments. 3850 3851 RecordDecl *RD = RecordDecl::Create(*Context, TTK_Struct, TUDecl, 3852 SourceLocation(), SourceLocation(), 3853 &Context->Idents.get("__block_impl")); 3854 QualType PtrBlock = Context->getPointerType(Context->getTagDeclType(RD)); 3855 3856 // Generate a funky cast. 3857 SmallVector<QualType, 8> ArgTypes; 3858 3859 // Push the block argument type. 3860 ArgTypes.push_back(PtrBlock); 3861 if (FTP) { 3862 for (FunctionProtoType::arg_type_iterator I = FTP->arg_type_begin(), 3863 E = FTP->arg_type_end(); I && (I != E); ++I) { 3864 QualType t = *I; 3865 // Make sure we convert "t (^)(...)" to "t (*)(...)". 3866 if (!convertBlockPointerToFunctionPointer(t)) 3867 convertToUnqualifiedObjCType(t); 3868 ArgTypes.push_back(t); 3869 } 3870 } 3871 // Now do the pointer to function cast. 3872 QualType PtrToFuncCastType 3873 = getSimpleFunctionType(Exp->getType(), &ArgTypes[0], ArgTypes.size()); 3874 3875 PtrToFuncCastType = Context->getPointerType(PtrToFuncCastType); 3876 3877 CastExpr *BlkCast = NoTypeInfoCStyleCastExpr(Context, PtrBlock, 3878 CK_BitCast, 3879 const_cast<Expr*>(BlockExp)); 3880 // Don't forget the parens to enforce the proper binding. 3881 ParenExpr *PE = new (Context) ParenExpr(SourceLocation(), SourceLocation(), 3882 BlkCast); 3883 //PE->dump(); 3884 3885 FieldDecl *FD = FieldDecl::Create(*Context, 0, SourceLocation(), 3886 SourceLocation(), 3887 &Context->Idents.get("FuncPtr"), 3888 Context->VoidPtrTy, 0, 3889 /*BitWidth=*/0, /*Mutable=*/true, 3890 /*HasInit=*/false); 3891 MemberExpr *ME = new (Context) MemberExpr(PE, true, FD, SourceLocation(), 3892 FD->getType(), VK_LValue, 3893 OK_Ordinary); 3894 3895 3896 CastExpr *FunkCast = NoTypeInfoCStyleCastExpr(Context, PtrToFuncCastType, 3897 CK_BitCast, ME); 3898 PE = new (Context) ParenExpr(SourceLocation(), SourceLocation(), FunkCast); 3899 3900 SmallVector<Expr*, 8> BlkExprs; 3901 // Add the implicit argument. 3902 BlkExprs.push_back(BlkCast); 3903 // Add the user arguments. 3904 for (CallExpr::arg_iterator I = Exp->arg_begin(), 3905 E = Exp->arg_end(); I != E; ++I) { 3906 BlkExprs.push_back(*I); 3907 } 3908 CallExpr *CE = new (Context) CallExpr(*Context, PE, &BlkExprs[0], 3909 BlkExprs.size(), 3910 Exp->getType(), VK_RValue, 3911 SourceLocation()); 3912 return CE; 3913 } 3914 3915 // We need to return the rewritten expression to handle cases where the 3916 // BlockDeclRefExpr is embedded in another expression being rewritten. 3917 // For example: 3918 // 3919 // int main() { 3920 // __block Foo *f; 3921 // __block int i; 3922 // 3923 // void (^myblock)() = ^() { 3924 // [f test]; // f is a BlockDeclRefExpr embedded in a message (which is being rewritten). 3925 // i = 77; 3926 // }; 3927 //} 3928 Stmt *RewriteObjC::RewriteBlockDeclRefExpr(DeclRefExpr *DeclRefExp) { 3929 // Rewrite the byref variable into BYREFVAR->__forwarding->BYREFVAR 3930 // for each DeclRefExp where BYREFVAR is name of the variable. 3931 ValueDecl *VD = DeclRefExp->getDecl(); 3932 bool isArrow = DeclRefExp->refersToEnclosingLocal(); 3933 3934 FieldDecl *FD = FieldDecl::Create(*Context, 0, SourceLocation(), 3935 SourceLocation(), 3936 &Context->Idents.get("__forwarding"), 3937 Context->VoidPtrTy, 0, 3938 /*BitWidth=*/0, /*Mutable=*/true, 3939 /*HasInit=*/false); 3940 MemberExpr *ME = new (Context) MemberExpr(DeclRefExp, isArrow, 3941 FD, SourceLocation(), 3942 FD->getType(), VK_LValue, 3943 OK_Ordinary); 3944 3945 StringRef Name = VD->getName(); 3946 FD = FieldDecl::Create(*Context, 0, SourceLocation(), SourceLocation(), 3947 &Context->Idents.get(Name), 3948 Context->VoidPtrTy, 0, 3949 /*BitWidth=*/0, /*Mutable=*/true, 3950 /*HasInit=*/false); 3951 ME = new (Context) MemberExpr(ME, true, FD, SourceLocation(), 3952 DeclRefExp->getType(), VK_LValue, OK_Ordinary); 3953 3954 3955 3956 // Need parens to enforce precedence. 3957 ParenExpr *PE = new (Context) ParenExpr(DeclRefExp->getExprLoc(), 3958 DeclRefExp->getExprLoc(), 3959 ME); 3960 ReplaceStmt(DeclRefExp, PE); 3961 return PE; 3962 } 3963 3964 // Rewrites the imported local variable V with external storage 3965 // (static, extern, etc.) as *V 3966 // 3967 Stmt *RewriteObjC::RewriteLocalVariableExternalStorage(DeclRefExpr *DRE) { 3968 ValueDecl *VD = DRE->getDecl(); 3969 if (VarDecl *Var = dyn_cast<VarDecl>(VD)) 3970 if (!ImportedLocalExternalDecls.count(Var)) 3971 return DRE; 3972 Expr *Exp = new (Context) UnaryOperator(DRE, UO_Deref, DRE->getType(), 3973 VK_LValue, OK_Ordinary, 3974 DRE->getLocation()); 3975 // Need parens to enforce precedence. 3976 ParenExpr *PE = new (Context) ParenExpr(SourceLocation(), SourceLocation(), 3977 Exp); 3978 ReplaceStmt(DRE, PE); 3979 return PE; 3980 } 3981 3982 void RewriteObjC::RewriteCastExpr(CStyleCastExpr *CE) { 3983 SourceLocation LocStart = CE->getLParenLoc(); 3984 SourceLocation LocEnd = CE->getRParenLoc(); 3985 3986 // Need to avoid trying to rewrite synthesized casts. 3987 if (LocStart.isInvalid()) 3988 return; 3989 // Need to avoid trying to rewrite casts contained in macros. 3990 if (!Rewriter::isRewritable(LocStart) || !Rewriter::isRewritable(LocEnd)) 3991 return; 3992 3993 const char *startBuf = SM->getCharacterData(LocStart); 3994 const char *endBuf = SM->getCharacterData(LocEnd); 3995 QualType QT = CE->getType(); 3996 const Type* TypePtr = QT->getAs<Type>(); 3997 if (isa<TypeOfExprType>(TypePtr)) { 3998 const TypeOfExprType *TypeOfExprTypePtr = cast<TypeOfExprType>(TypePtr); 3999 QT = TypeOfExprTypePtr->getUnderlyingExpr()->getType(); 4000 std::string TypeAsString = "("; 4001 RewriteBlockPointerType(TypeAsString, QT); 4002 TypeAsString += ")"; 4003 ReplaceText(LocStart, endBuf-startBuf+1, TypeAsString); 4004 return; 4005 } 4006 // advance the location to startArgList. 4007 const char *argPtr = startBuf; 4008 4009 while (*argPtr++ && (argPtr < endBuf)) { 4010 switch (*argPtr) { 4011 case '^': 4012 // Replace the '^' with '*'. 4013 LocStart = LocStart.getLocWithOffset(argPtr-startBuf); 4014 ReplaceText(LocStart, 1, "*"); 4015 break; 4016 } 4017 } 4018 return; 4019 } 4020 4021 void RewriteObjC::RewriteBlockPointerFunctionArgs(FunctionDecl *FD) { 4022 SourceLocation DeclLoc = FD->getLocation(); 4023 unsigned parenCount = 0; 4024 4025 // We have 1 or more arguments that have closure pointers. 4026 const char *startBuf = SM->getCharacterData(DeclLoc); 4027 const char *startArgList = strchr(startBuf, '('); 4028 4029 assert((*startArgList == '(') && "Rewriter fuzzy parser confused"); 4030 4031 parenCount++; 4032 // advance the location to startArgList. 4033 DeclLoc = DeclLoc.getLocWithOffset(startArgList-startBuf); 4034 assert((DeclLoc.isValid()) && "Invalid DeclLoc"); 4035 4036 const char *argPtr = startArgList; 4037 4038 while (*argPtr++ && parenCount) { 4039 switch (*argPtr) { 4040 case '^': 4041 // Replace the '^' with '*'. 4042 DeclLoc = DeclLoc.getLocWithOffset(argPtr-startArgList); 4043 ReplaceText(DeclLoc, 1, "*"); 4044 break; 4045 case '(': 4046 parenCount++; 4047 break; 4048 case ')': 4049 parenCount--; 4050 break; 4051 } 4052 } 4053 return; 4054 } 4055 4056 bool RewriteObjC::PointerTypeTakesAnyBlockArguments(QualType QT) { 4057 const FunctionProtoType *FTP; 4058 const PointerType *PT = QT->getAs<PointerType>(); 4059 if (PT) { 4060 FTP = PT->getPointeeType()->getAs<FunctionProtoType>(); 4061 } else { 4062 const BlockPointerType *BPT = QT->getAs<BlockPointerType>(); 4063 assert(BPT && "BlockPointerTypeTakeAnyBlockArguments(): not a block pointer type"); 4064 FTP = BPT->getPointeeType()->getAs<FunctionProtoType>(); 4065 } 4066 if (FTP) { 4067 for (FunctionProtoType::arg_type_iterator I = FTP->arg_type_begin(), 4068 E = FTP->arg_type_end(); I != E; ++I) 4069 if (isTopLevelBlockPointerType(*I)) 4070 return true; 4071 } 4072 return false; 4073 } 4074 4075 bool RewriteObjC::PointerTypeTakesAnyObjCQualifiedType(QualType QT) { 4076 const FunctionProtoType *FTP; 4077 const PointerType *PT = QT->getAs<PointerType>(); 4078 if (PT) { 4079 FTP = PT->getPointeeType()->getAs<FunctionProtoType>(); 4080 } else { 4081 const BlockPointerType *BPT = QT->getAs<BlockPointerType>(); 4082 assert(BPT && "BlockPointerTypeTakeAnyBlockArguments(): not a block pointer type"); 4083 FTP = BPT->getPointeeType()->getAs<FunctionProtoType>(); 4084 } 4085 if (FTP) { 4086 for (FunctionProtoType::arg_type_iterator I = FTP->arg_type_begin(), 4087 E = FTP->arg_type_end(); I != E; ++I) { 4088 if ((*I)->isObjCQualifiedIdType()) 4089 return true; 4090 if ((*I)->isObjCObjectPointerType() && 4091 (*I)->getPointeeType()->isObjCQualifiedInterfaceType()) 4092 return true; 4093 } 4094 4095 } 4096 return false; 4097 } 4098 4099 void RewriteObjC::GetExtentOfArgList(const char *Name, const char *&LParen, 4100 const char *&RParen) { 4101 const char *argPtr = strchr(Name, '('); 4102 assert((*argPtr == '(') && "Rewriter fuzzy parser confused"); 4103 4104 LParen = argPtr; // output the start. 4105 argPtr++; // skip past the left paren. 4106 unsigned parenCount = 1; 4107 4108 while (*argPtr && parenCount) { 4109 switch (*argPtr) { 4110 case '(': parenCount++; break; 4111 case ')': parenCount--; break; 4112 default: break; 4113 } 4114 if (parenCount) argPtr++; 4115 } 4116 assert((*argPtr == ')') && "Rewriter fuzzy parser confused"); 4117 RParen = argPtr; // output the end 4118 } 4119 4120 void RewriteObjC::RewriteBlockPointerDecl(NamedDecl *ND) { 4121 if (FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) { 4122 RewriteBlockPointerFunctionArgs(FD); 4123 return; 4124 } 4125 // Handle Variables and Typedefs. 4126 SourceLocation DeclLoc = ND->getLocation(); 4127 QualType DeclT; 4128 if (VarDecl *VD = dyn_cast<VarDecl>(ND)) 4129 DeclT = VD->getType(); 4130 else if (TypedefNameDecl *TDD = dyn_cast<TypedefNameDecl>(ND)) 4131 DeclT = TDD->getUnderlyingType(); 4132 else if (FieldDecl *FD = dyn_cast<FieldDecl>(ND)) 4133 DeclT = FD->getType(); 4134 else 4135 llvm_unreachable("RewriteBlockPointerDecl(): Decl type not yet handled"); 4136 4137 const char *startBuf = SM->getCharacterData(DeclLoc); 4138 const char *endBuf = startBuf; 4139 // scan backward (from the decl location) for the end of the previous decl. 4140 while (*startBuf != '^' && *startBuf != ';' && startBuf != MainFileStart) 4141 startBuf--; 4142 SourceLocation Start = DeclLoc.getLocWithOffset(startBuf-endBuf); 4143 std::string buf; 4144 unsigned OrigLength=0; 4145 // *startBuf != '^' if we are dealing with a pointer to function that 4146 // may take block argument types (which will be handled below). 4147 if (*startBuf == '^') { 4148 // Replace the '^' with '*', computing a negative offset. 4149 buf = '*'; 4150 startBuf++; 4151 OrigLength++; 4152 } 4153 while (*startBuf != ')') { 4154 buf += *startBuf; 4155 startBuf++; 4156 OrigLength++; 4157 } 4158 buf += ')'; 4159 OrigLength++; 4160 4161 if (PointerTypeTakesAnyBlockArguments(DeclT) || 4162 PointerTypeTakesAnyObjCQualifiedType(DeclT)) { 4163 // Replace the '^' with '*' for arguments. 4164 // Replace id<P> with id/*<>*/ 4165 DeclLoc = ND->getLocation(); 4166 startBuf = SM->getCharacterData(DeclLoc); 4167 const char *argListBegin, *argListEnd; 4168 GetExtentOfArgList(startBuf, argListBegin, argListEnd); 4169 while (argListBegin < argListEnd) { 4170 if (*argListBegin == '^') 4171 buf += '*'; 4172 else if (*argListBegin == '<') { 4173 buf += "/*"; 4174 buf += *argListBegin++; 4175 OrigLength++;; 4176 while (*argListBegin != '>') { 4177 buf += *argListBegin++; 4178 OrigLength++; 4179 } 4180 buf += *argListBegin; 4181 buf += "*/"; 4182 } 4183 else 4184 buf += *argListBegin; 4185 argListBegin++; 4186 OrigLength++; 4187 } 4188 buf += ')'; 4189 OrigLength++; 4190 } 4191 ReplaceText(Start, OrigLength, buf); 4192 4193 return; 4194 } 4195 4196 4197 /// SynthesizeByrefCopyDestroyHelper - This routine synthesizes: 4198 /// void __Block_byref_id_object_copy(struct Block_byref_id_object *dst, 4199 /// struct Block_byref_id_object *src) { 4200 /// _Block_object_assign (&_dest->object, _src->object, 4201 /// BLOCK_BYREF_CALLER | BLOCK_FIELD_IS_OBJECT 4202 /// [|BLOCK_FIELD_IS_WEAK]) // object 4203 /// _Block_object_assign(&_dest->object, _src->object, 4204 /// BLOCK_BYREF_CALLER | BLOCK_FIELD_IS_BLOCK 4205 /// [|BLOCK_FIELD_IS_WEAK]) // block 4206 /// } 4207 /// And: 4208 /// void __Block_byref_id_object_dispose(struct Block_byref_id_object *_src) { 4209 /// _Block_object_dispose(_src->object, 4210 /// BLOCK_BYREF_CALLER | BLOCK_FIELD_IS_OBJECT 4211 /// [|BLOCK_FIELD_IS_WEAK]) // object 4212 /// _Block_object_dispose(_src->object, 4213 /// BLOCK_BYREF_CALLER | BLOCK_FIELD_IS_BLOCK 4214 /// [|BLOCK_FIELD_IS_WEAK]) // block 4215 /// } 4216 4217 std::string RewriteObjC::SynthesizeByrefCopyDestroyHelper(VarDecl *VD, 4218 int flag) { 4219 std::string S; 4220 if (CopyDestroyCache.count(flag)) 4221 return S; 4222 CopyDestroyCache.insert(flag); 4223 S = "static void __Block_byref_id_object_copy_"; 4224 S += utostr(flag); 4225 S += "(void *dst, void *src) {\n"; 4226 4227 // offset into the object pointer is computed as: 4228 // void * + void* + int + int + void* + void * 4229 unsigned IntSize = 4230 static_cast<unsigned>(Context->getTypeSize(Context->IntTy)); 4231 unsigned VoidPtrSize = 4232 static_cast<unsigned>(Context->getTypeSize(Context->VoidPtrTy)); 4233 4234 unsigned offset = (VoidPtrSize*4 + IntSize + IntSize)/Context->getCharWidth(); 4235 S += " _Block_object_assign((char*)dst + "; 4236 S += utostr(offset); 4237 S += ", *(void * *) ((char*)src + "; 4238 S += utostr(offset); 4239 S += "), "; 4240 S += utostr(flag); 4241 S += ");\n}\n"; 4242 4243 S += "static void __Block_byref_id_object_dispose_"; 4244 S += utostr(flag); 4245 S += "(void *src) {\n"; 4246 S += " _Block_object_dispose(*(void * *) ((char*)src + "; 4247 S += utostr(offset); 4248 S += "), "; 4249 S += utostr(flag); 4250 S += ");\n}\n"; 4251 return S; 4252 } 4253 4254 /// RewriteByRefVar - For each __block typex ND variable this routine transforms 4255 /// the declaration into: 4256 /// struct __Block_byref_ND { 4257 /// void *__isa; // NULL for everything except __weak pointers 4258 /// struct __Block_byref_ND *__forwarding; 4259 /// int32_t __flags; 4260 /// int32_t __size; 4261 /// void *__Block_byref_id_object_copy; // If variable is __block ObjC object 4262 /// void *__Block_byref_id_object_dispose; // If variable is __block ObjC object 4263 /// typex ND; 4264 /// }; 4265 /// 4266 /// It then replaces declaration of ND variable with: 4267 /// struct __Block_byref_ND ND = {__isa=0B, __forwarding=&ND, __flags=some_flag, 4268 /// __size=sizeof(struct __Block_byref_ND), 4269 /// ND=initializer-if-any}; 4270 /// 4271 /// 4272 void RewriteObjC::RewriteByRefVar(VarDecl *ND) { 4273 // Insert declaration for the function in which block literal is 4274 // used. 4275 if (CurFunctionDeclToDeclareForBlock) 4276 RewriteBlockLiteralFunctionDecl(CurFunctionDeclToDeclareForBlock); 4277 int flag = 0; 4278 int isa = 0; 4279 SourceLocation DeclLoc = ND->getTypeSpecStartLoc(); 4280 if (DeclLoc.isInvalid()) 4281 // If type location is missing, it is because of missing type (a warning). 4282 // Use variable's location which is good for this case. 4283 DeclLoc = ND->getLocation(); 4284 const char *startBuf = SM->getCharacterData(DeclLoc); 4285 SourceLocation X = ND->getLocEnd(); 4286 X = SM->getExpansionLoc(X); 4287 const char *endBuf = SM->getCharacterData(X); 4288 std::string Name(ND->getNameAsString()); 4289 std::string ByrefType; 4290 RewriteByRefString(ByrefType, Name, ND, true); 4291 ByrefType += " {\n"; 4292 ByrefType += " void *__isa;\n"; 4293 RewriteByRefString(ByrefType, Name, ND); 4294 ByrefType += " *__forwarding;\n"; 4295 ByrefType += " int __flags;\n"; 4296 ByrefType += " int __size;\n"; 4297 // Add void *__Block_byref_id_object_copy; 4298 // void *__Block_byref_id_object_dispose; if needed. 4299 QualType Ty = ND->getType(); 4300 bool HasCopyAndDispose = Context->BlockRequiresCopying(Ty); 4301 if (HasCopyAndDispose) { 4302 ByrefType += " void (*__Block_byref_id_object_copy)(void*, void*);\n"; 4303 ByrefType += " void (*__Block_byref_id_object_dispose)(void*);\n"; 4304 } 4305 4306 QualType T = Ty; 4307 (void)convertBlockPointerToFunctionPointer(T); 4308 T.getAsStringInternal(Name, Context->getPrintingPolicy()); 4309 4310 ByrefType += " " + Name + ";\n"; 4311 ByrefType += "};\n"; 4312 // Insert this type in global scope. It is needed by helper function. 4313 SourceLocation FunLocStart; 4314 if (CurFunctionDef) 4315 FunLocStart = CurFunctionDef->getTypeSpecStartLoc(); 4316 else { 4317 assert(CurMethodDef && "RewriteByRefVar - CurMethodDef is null"); 4318 FunLocStart = CurMethodDef->getLocStart(); 4319 } 4320 InsertText(FunLocStart, ByrefType); 4321 if (Ty.isObjCGCWeak()) { 4322 flag |= BLOCK_FIELD_IS_WEAK; 4323 isa = 1; 4324 } 4325 4326 if (HasCopyAndDispose) { 4327 flag = BLOCK_BYREF_CALLER; 4328 QualType Ty = ND->getType(); 4329 // FIXME. Handle __weak variable (BLOCK_FIELD_IS_WEAK) as well. 4330 if (Ty->isBlockPointerType()) 4331 flag |= BLOCK_FIELD_IS_BLOCK; 4332 else 4333 flag |= BLOCK_FIELD_IS_OBJECT; 4334 std::string HF = SynthesizeByrefCopyDestroyHelper(ND, flag); 4335 if (!HF.empty()) 4336 InsertText(FunLocStart, HF); 4337 } 4338 4339 // struct __Block_byref_ND ND = 4340 // {0, &ND, some_flag, __size=sizeof(struct __Block_byref_ND), 4341 // initializer-if-any}; 4342 bool hasInit = (ND->getInit() != 0); 4343 unsigned flags = 0; 4344 if (HasCopyAndDispose) 4345 flags |= BLOCK_HAS_COPY_DISPOSE; 4346 Name = ND->getNameAsString(); 4347 ByrefType.clear(); 4348 RewriteByRefString(ByrefType, Name, ND); 4349 std::string ForwardingCastType("("); 4350 ForwardingCastType += ByrefType + " *)"; 4351 if (!hasInit) { 4352 ByrefType += " " + Name + " = {(void*)"; 4353 ByrefType += utostr(isa); 4354 ByrefType += "," + ForwardingCastType + "&" + Name + ", "; 4355 ByrefType += utostr(flags); 4356 ByrefType += ", "; 4357 ByrefType += "sizeof("; 4358 RewriteByRefString(ByrefType, Name, ND); 4359 ByrefType += ")"; 4360 if (HasCopyAndDispose) { 4361 ByrefType += ", __Block_byref_id_object_copy_"; 4362 ByrefType += utostr(flag); 4363 ByrefType += ", __Block_byref_id_object_dispose_"; 4364 ByrefType += utostr(flag); 4365 } 4366 ByrefType += "};\n"; 4367 unsigned nameSize = Name.size(); 4368 // for block or function pointer declaration. Name is aleady 4369 // part of the declaration. 4370 if (Ty->isBlockPointerType() || Ty->isFunctionPointerType()) 4371 nameSize = 1; 4372 ReplaceText(DeclLoc, endBuf-startBuf+nameSize, ByrefType); 4373 } 4374 else { 4375 SourceLocation startLoc; 4376 Expr *E = ND->getInit(); 4377 if (const CStyleCastExpr *ECE = dyn_cast<CStyleCastExpr>(E)) 4378 startLoc = ECE->getLParenLoc(); 4379 else 4380 startLoc = E->getLocStart(); 4381 startLoc = SM->getExpansionLoc(startLoc); 4382 endBuf = SM->getCharacterData(startLoc); 4383 ByrefType += " " + Name; 4384 ByrefType += " = {(void*)"; 4385 ByrefType += utostr(isa); 4386 ByrefType += "," + ForwardingCastType + "&" + Name + ", "; 4387 ByrefType += utostr(flags); 4388 ByrefType += ", "; 4389 ByrefType += "sizeof("; 4390 RewriteByRefString(ByrefType, Name, ND); 4391 ByrefType += "), "; 4392 if (HasCopyAndDispose) { 4393 ByrefType += "__Block_byref_id_object_copy_"; 4394 ByrefType += utostr(flag); 4395 ByrefType += ", __Block_byref_id_object_dispose_"; 4396 ByrefType += utostr(flag); 4397 ByrefType += ", "; 4398 } 4399 ReplaceText(DeclLoc, endBuf-startBuf, ByrefType); 4400 4401 // Complete the newly synthesized compound expression by inserting a right 4402 // curly brace before the end of the declaration. 4403 // FIXME: This approach avoids rewriting the initializer expression. It 4404 // also assumes there is only one declarator. For example, the following 4405 // isn't currently supported by this routine (in general): 4406 // 4407 // double __block BYREFVAR = 1.34, BYREFVAR2 = 1.37; 4408 // 4409 const char *startInitializerBuf = SM->getCharacterData(startLoc); 4410 const char *semiBuf = strchr(startInitializerBuf, ';'); 4411 assert((*semiBuf == ';') && "RewriteByRefVar: can't find ';'"); 4412 SourceLocation semiLoc = 4413 startLoc.getLocWithOffset(semiBuf-startInitializerBuf); 4414 4415 InsertText(semiLoc, "}"); 4416 } 4417 return; 4418 } 4419 4420 void RewriteObjC::CollectBlockDeclRefInfo(BlockExpr *Exp) { 4421 // Add initializers for any closure decl refs. 4422 GetBlockDeclRefExprs(Exp->getBody()); 4423 if (BlockDeclRefs.size()) { 4424 // Unique all "by copy" declarations. 4425 for (unsigned i = 0; i < BlockDeclRefs.size(); i++) 4426 if (!BlockDeclRefs[i]->getDecl()->hasAttr<BlocksAttr>()) { 4427 if (!BlockByCopyDeclsPtrSet.count(BlockDeclRefs[i]->getDecl())) { 4428 BlockByCopyDeclsPtrSet.insert(BlockDeclRefs[i]->getDecl()); 4429 BlockByCopyDecls.push_back(BlockDeclRefs[i]->getDecl()); 4430 } 4431 } 4432 // Unique all "by ref" declarations. 4433 for (unsigned i = 0; i < BlockDeclRefs.size(); i++) 4434 if (BlockDeclRefs[i]->getDecl()->hasAttr<BlocksAttr>()) { 4435 if (!BlockByRefDeclsPtrSet.count(BlockDeclRefs[i]->getDecl())) { 4436 BlockByRefDeclsPtrSet.insert(BlockDeclRefs[i]->getDecl()); 4437 BlockByRefDecls.push_back(BlockDeclRefs[i]->getDecl()); 4438 } 4439 } 4440 // Find any imported blocks...they will need special attention. 4441 for (unsigned i = 0; i < BlockDeclRefs.size(); i++) 4442 if (BlockDeclRefs[i]->getDecl()->hasAttr<BlocksAttr>() || 4443 BlockDeclRefs[i]->getType()->isObjCObjectPointerType() || 4444 BlockDeclRefs[i]->getType()->isBlockPointerType()) 4445 ImportedBlockDecls.insert(BlockDeclRefs[i]->getDecl()); 4446 } 4447 } 4448 4449 FunctionDecl *RewriteObjC::SynthBlockInitFunctionDecl(StringRef name) { 4450 IdentifierInfo *ID = &Context->Idents.get(name); 4451 QualType FType = Context->getFunctionNoProtoType(Context->VoidPtrTy); 4452 return FunctionDecl::Create(*Context, TUDecl, SourceLocation(), 4453 SourceLocation(), ID, FType, 0, SC_Extern, 4454 SC_None, false, false); 4455 } 4456 4457 Stmt *RewriteObjC::SynthBlockInitExpr(BlockExpr *Exp, 4458 const SmallVector<DeclRefExpr *, 8> &InnerBlockDeclRefs) { 4459 const BlockDecl *block = Exp->getBlockDecl(); 4460 Blocks.push_back(Exp); 4461 4462 CollectBlockDeclRefInfo(Exp); 4463 4464 // Add inner imported variables now used in current block. 4465 int countOfInnerDecls = 0; 4466 if (!InnerBlockDeclRefs.empty()) { 4467 for (unsigned i = 0; i < InnerBlockDeclRefs.size(); i++) { 4468 DeclRefExpr *Exp = InnerBlockDeclRefs[i]; 4469 ValueDecl *VD = Exp->getDecl(); 4470 if (!VD->hasAttr<BlocksAttr>() && !BlockByCopyDeclsPtrSet.count(VD)) { 4471 // We need to save the copied-in variables in nested 4472 // blocks because it is needed at the end for some of the API generations. 4473 // See SynthesizeBlockLiterals routine. 4474 InnerDeclRefs.push_back(Exp); countOfInnerDecls++; 4475 BlockDeclRefs.push_back(Exp); 4476 BlockByCopyDeclsPtrSet.insert(VD); 4477 BlockByCopyDecls.push_back(VD); 4478 } 4479 if (VD->hasAttr<BlocksAttr>() && !BlockByRefDeclsPtrSet.count(VD)) { 4480 InnerDeclRefs.push_back(Exp); countOfInnerDecls++; 4481 BlockDeclRefs.push_back(Exp); 4482 BlockByRefDeclsPtrSet.insert(VD); 4483 BlockByRefDecls.push_back(VD); 4484 } 4485 } 4486 // Find any imported blocks...they will need special attention. 4487 for (unsigned i = 0; i < InnerBlockDeclRefs.size(); i++) 4488 if (InnerBlockDeclRefs[i]->getDecl()->hasAttr<BlocksAttr>() || 4489 InnerBlockDeclRefs[i]->getType()->isObjCObjectPointerType() || 4490 InnerBlockDeclRefs[i]->getType()->isBlockPointerType()) 4491 ImportedBlockDecls.insert(InnerBlockDeclRefs[i]->getDecl()); 4492 } 4493 InnerDeclRefsCount.push_back(countOfInnerDecls); 4494 4495 std::string FuncName; 4496 4497 if (CurFunctionDef) 4498 FuncName = CurFunctionDef->getNameAsString(); 4499 else if (CurMethodDef) 4500 BuildUniqueMethodName(FuncName, CurMethodDef); 4501 else if (GlobalVarDecl) 4502 FuncName = std::string(GlobalVarDecl->getNameAsString()); 4503 4504 std::string BlockNumber = utostr(Blocks.size()-1); 4505 4506 std::string Tag = "__" + FuncName + "_block_impl_" + BlockNumber; 4507 std::string Func = "__" + FuncName + "_block_func_" + BlockNumber; 4508 4509 // Get a pointer to the function type so we can cast appropriately. 4510 QualType BFT = convertFunctionTypeOfBlocks(Exp->getFunctionType()); 4511 QualType FType = Context->getPointerType(BFT); 4512 4513 FunctionDecl *FD; 4514 Expr *NewRep; 4515 4516 // Simulate a contructor call... 4517 FD = SynthBlockInitFunctionDecl(Tag); 4518 DeclRefExpr *DRE = new (Context) DeclRefExpr(FD, false, FType, VK_RValue, 4519 SourceLocation()); 4520 4521 SmallVector<Expr*, 4> InitExprs; 4522 4523 // Initialize the block function. 4524 FD = SynthBlockInitFunctionDecl(Func); 4525 DeclRefExpr *Arg = new (Context) DeclRefExpr(FD, false, FD->getType(), 4526 VK_LValue, SourceLocation()); 4527 CastExpr *castExpr = NoTypeInfoCStyleCastExpr(Context, Context->VoidPtrTy, 4528 CK_BitCast, Arg); 4529 InitExprs.push_back(castExpr); 4530 4531 // Initialize the block descriptor. 4532 std::string DescData = "__" + FuncName + "_block_desc_" + BlockNumber + "_DATA"; 4533 4534 VarDecl *NewVD = VarDecl::Create(*Context, TUDecl, 4535 SourceLocation(), SourceLocation(), 4536 &Context->Idents.get(DescData.c_str()), 4537 Context->VoidPtrTy, 0, 4538 SC_Static, SC_None); 4539 UnaryOperator *DescRefExpr = 4540 new (Context) UnaryOperator(new (Context) DeclRefExpr(NewVD, false, 4541 Context->VoidPtrTy, 4542 VK_LValue, 4543 SourceLocation()), 4544 UO_AddrOf, 4545 Context->getPointerType(Context->VoidPtrTy), 4546 VK_RValue, OK_Ordinary, 4547 SourceLocation()); 4548 InitExprs.push_back(DescRefExpr); 4549 4550 // Add initializers for any closure decl refs. 4551 if (BlockDeclRefs.size()) { 4552 Expr *Exp; 4553 // Output all "by copy" declarations. 4554 for (SmallVector<ValueDecl*,8>::iterator I = BlockByCopyDecls.begin(), 4555 E = BlockByCopyDecls.end(); I != E; ++I) { 4556 if (isObjCType((*I)->getType())) { 4557 // FIXME: Conform to ABI ([[obj retain] autorelease]). 4558 FD = SynthBlockInitFunctionDecl((*I)->getName()); 4559 Exp = new (Context) DeclRefExpr(FD, false, FD->getType(), VK_LValue, 4560 SourceLocation()); 4561 if (HasLocalVariableExternalStorage(*I)) { 4562 QualType QT = (*I)->getType(); 4563 QT = Context->getPointerType(QT); 4564 Exp = new (Context) UnaryOperator(Exp, UO_AddrOf, QT, VK_RValue, 4565 OK_Ordinary, SourceLocation()); 4566 } 4567 } else if (isTopLevelBlockPointerType((*I)->getType())) { 4568 FD = SynthBlockInitFunctionDecl((*I)->getName()); 4569 Arg = new (Context) DeclRefExpr(FD, false, FD->getType(), VK_LValue, 4570 SourceLocation()); 4571 Exp = NoTypeInfoCStyleCastExpr(Context, Context->VoidPtrTy, 4572 CK_BitCast, Arg); 4573 } else { 4574 FD = SynthBlockInitFunctionDecl((*I)->getName()); 4575 Exp = new (Context) DeclRefExpr(FD, false, FD->getType(), VK_LValue, 4576 SourceLocation()); 4577 if (HasLocalVariableExternalStorage(*I)) { 4578 QualType QT = (*I)->getType(); 4579 QT = Context->getPointerType(QT); 4580 Exp = new (Context) UnaryOperator(Exp, UO_AddrOf, QT, VK_RValue, 4581 OK_Ordinary, SourceLocation()); 4582 } 4583 4584 } 4585 InitExprs.push_back(Exp); 4586 } 4587 // Output all "by ref" declarations. 4588 for (SmallVector<ValueDecl*,8>::iterator I = BlockByRefDecls.begin(), 4589 E = BlockByRefDecls.end(); I != E; ++I) { 4590 ValueDecl *ND = (*I); 4591 std::string Name(ND->getNameAsString()); 4592 std::string RecName; 4593 RewriteByRefString(RecName, Name, ND, true); 4594 IdentifierInfo *II = &Context->Idents.get(RecName.c_str() 4595 + sizeof("struct")); 4596 RecordDecl *RD = RecordDecl::Create(*Context, TTK_Struct, TUDecl, 4597 SourceLocation(), SourceLocation(), 4598 II); 4599 assert(RD && "SynthBlockInitExpr(): Can't find RecordDecl"); 4600 QualType castT = Context->getPointerType(Context->getTagDeclType(RD)); 4601 4602 FD = SynthBlockInitFunctionDecl((*I)->getName()); 4603 Exp = new (Context) DeclRefExpr(FD, false, FD->getType(), VK_LValue, 4604 SourceLocation()); 4605 bool isNestedCapturedVar = false; 4606 if (block) 4607 for (BlockDecl::capture_const_iterator ci = block->capture_begin(), 4608 ce = block->capture_end(); ci != ce; ++ci) { 4609 const VarDecl *variable = ci->getVariable(); 4610 if (variable == ND && ci->isNested()) { 4611 assert (ci->isByRef() && 4612 "SynthBlockInitExpr - captured block variable is not byref"); 4613 isNestedCapturedVar = true; 4614 break; 4615 } 4616 } 4617 // captured nested byref variable has its address passed. Do not take 4618 // its address again. 4619 if (!isNestedCapturedVar) 4620 Exp = new (Context) UnaryOperator(Exp, UO_AddrOf, 4621 Context->getPointerType(Exp->getType()), 4622 VK_RValue, OK_Ordinary, SourceLocation()); 4623 Exp = NoTypeInfoCStyleCastExpr(Context, castT, CK_BitCast, Exp); 4624 InitExprs.push_back(Exp); 4625 } 4626 } 4627 if (ImportedBlockDecls.size()) { 4628 // generate BLOCK_HAS_COPY_DISPOSE(have helper funcs) | BLOCK_HAS_DESCRIPTOR 4629 int flag = (BLOCK_HAS_COPY_DISPOSE | BLOCK_HAS_DESCRIPTOR); 4630 unsigned IntSize = 4631 static_cast<unsigned>(Context->getTypeSize(Context->IntTy)); 4632 Expr *FlagExp = IntegerLiteral::Create(*Context, llvm::APInt(IntSize, flag), 4633 Context->IntTy, SourceLocation()); 4634 InitExprs.push_back(FlagExp); 4635 } 4636 NewRep = new (Context) CallExpr(*Context, DRE, &InitExprs[0], InitExprs.size(), 4637 FType, VK_LValue, SourceLocation()); 4638 NewRep = new (Context) UnaryOperator(NewRep, UO_AddrOf, 4639 Context->getPointerType(NewRep->getType()), 4640 VK_RValue, OK_Ordinary, SourceLocation()); 4641 NewRep = NoTypeInfoCStyleCastExpr(Context, FType, CK_BitCast, 4642 NewRep); 4643 BlockDeclRefs.clear(); 4644 BlockByRefDecls.clear(); 4645 BlockByRefDeclsPtrSet.clear(); 4646 BlockByCopyDecls.clear(); 4647 BlockByCopyDeclsPtrSet.clear(); 4648 ImportedBlockDecls.clear(); 4649 return NewRep; 4650 } 4651 4652 bool RewriteObjC::IsDeclStmtInForeachHeader(DeclStmt *DS) { 4653 if (const ObjCForCollectionStmt * CS = 4654 dyn_cast<ObjCForCollectionStmt>(Stmts.back())) 4655 return CS->getElement() == DS; 4656 return false; 4657 } 4658 4659 //===----------------------------------------------------------------------===// 4660 // Function Body / Expression rewriting 4661 //===----------------------------------------------------------------------===// 4662 4663 Stmt *RewriteObjC::RewriteFunctionBodyOrGlobalInitializer(Stmt *S) { 4664 if (isa<SwitchStmt>(S) || isa<WhileStmt>(S) || 4665 isa<DoStmt>(S) || isa<ForStmt>(S)) 4666 Stmts.push_back(S); 4667 else if (isa<ObjCForCollectionStmt>(S)) { 4668 Stmts.push_back(S); 4669 ObjCBcLabelNo.push_back(++BcLabelCount); 4670 } 4671 4672 // Pseudo-object operations and ivar references need special 4673 // treatment because we're going to recursively rewrite them. 4674 if (PseudoObjectExpr *PseudoOp = dyn_cast<PseudoObjectExpr>(S)) { 4675 if (isa<BinaryOperator>(PseudoOp->getSyntacticForm())) { 4676 return RewritePropertyOrImplicitSetter(PseudoOp); 4677 } else { 4678 return RewritePropertyOrImplicitGetter(PseudoOp); 4679 } 4680 } else if (ObjCIvarRefExpr *IvarRefExpr = dyn_cast<ObjCIvarRefExpr>(S)) { 4681 return RewriteObjCIvarRefExpr(IvarRefExpr); 4682 } 4683 4684 SourceRange OrigStmtRange = S->getSourceRange(); 4685 4686 // Perform a bottom up rewrite of all children. 4687 for (Stmt::child_range CI = S->children(); CI; ++CI) 4688 if (*CI) { 4689 Stmt *childStmt = (*CI); 4690 Stmt *newStmt = RewriteFunctionBodyOrGlobalInitializer(childStmt); 4691 if (newStmt) { 4692 *CI = newStmt; 4693 } 4694 } 4695 4696 if (BlockExpr *BE = dyn_cast<BlockExpr>(S)) { 4697 SmallVector<DeclRefExpr *, 8> InnerBlockDeclRefs; 4698 llvm::SmallPtrSet<const DeclContext *, 8> InnerContexts; 4699 InnerContexts.insert(BE->getBlockDecl()); 4700 ImportedLocalExternalDecls.clear(); 4701 GetInnerBlockDeclRefExprs(BE->getBody(), 4702 InnerBlockDeclRefs, InnerContexts); 4703 // Rewrite the block body in place. 4704 Stmt *SaveCurrentBody = CurrentBody; 4705 CurrentBody = BE->getBody(); 4706 PropParentMap = 0; 4707 // block literal on rhs of a property-dot-sytax assignment 4708 // must be replaced by its synthesize ast so getRewrittenText 4709 // works as expected. In this case, what actually ends up on RHS 4710 // is the blockTranscribed which is the helper function for the 4711 // block literal; as in: self.c = ^() {[ace ARR];}; 4712 bool saveDisableReplaceStmt = DisableReplaceStmt; 4713 DisableReplaceStmt = false; 4714 RewriteFunctionBodyOrGlobalInitializer(BE->getBody()); 4715 DisableReplaceStmt = saveDisableReplaceStmt; 4716 CurrentBody = SaveCurrentBody; 4717 PropParentMap = 0; 4718 ImportedLocalExternalDecls.clear(); 4719 // Now we snarf the rewritten text and stash it away for later use. 4720 std::string Str = Rewrite.getRewrittenText(BE->getSourceRange()); 4721 RewrittenBlockExprs[BE] = Str; 4722 4723 Stmt *blockTranscribed = SynthBlockInitExpr(BE, InnerBlockDeclRefs); 4724 4725 //blockTranscribed->dump(); 4726 ReplaceStmt(S, blockTranscribed); 4727 return blockTranscribed; 4728 } 4729 // Handle specific things. 4730 if (ObjCEncodeExpr *AtEncode = dyn_cast<ObjCEncodeExpr>(S)) 4731 return RewriteAtEncode(AtEncode); 4732 4733 if (ObjCSelectorExpr *AtSelector = dyn_cast<ObjCSelectorExpr>(S)) 4734 return RewriteAtSelector(AtSelector); 4735 4736 if (ObjCStringLiteral *AtString = dyn_cast<ObjCStringLiteral>(S)) 4737 return RewriteObjCStringLiteral(AtString); 4738 4739 if (ObjCMessageExpr *MessExpr = dyn_cast<ObjCMessageExpr>(S)) { 4740 #if 0 4741 // Before we rewrite it, put the original message expression in a comment. 4742 SourceLocation startLoc = MessExpr->getLocStart(); 4743 SourceLocation endLoc = MessExpr->getLocEnd(); 4744 4745 const char *startBuf = SM->getCharacterData(startLoc); 4746 const char *endBuf = SM->getCharacterData(endLoc); 4747 4748 std::string messString; 4749 messString += "// "; 4750 messString.append(startBuf, endBuf-startBuf+1); 4751 messString += "\n"; 4752 4753 // FIXME: Missing definition of 4754 // InsertText(clang::SourceLocation, char const*, unsigned int). 4755 // InsertText(startLoc, messString.c_str(), messString.size()); 4756 // Tried this, but it didn't work either... 4757 // ReplaceText(startLoc, 0, messString.c_str(), messString.size()); 4758 #endif 4759 return RewriteMessageExpr(MessExpr); 4760 } 4761 4762 if (ObjCAtTryStmt *StmtTry = dyn_cast<ObjCAtTryStmt>(S)) 4763 return RewriteObjCTryStmt(StmtTry); 4764 4765 if (ObjCAtSynchronizedStmt *StmtTry = dyn_cast<ObjCAtSynchronizedStmt>(S)) 4766 return RewriteObjCSynchronizedStmt(StmtTry); 4767 4768 if (ObjCAtThrowStmt *StmtThrow = dyn_cast<ObjCAtThrowStmt>(S)) 4769 return RewriteObjCThrowStmt(StmtThrow); 4770 4771 if (ObjCProtocolExpr *ProtocolExp = dyn_cast<ObjCProtocolExpr>(S)) 4772 return RewriteObjCProtocolExpr(ProtocolExp); 4773 4774 if (ObjCForCollectionStmt *StmtForCollection = 4775 dyn_cast<ObjCForCollectionStmt>(S)) 4776 return RewriteObjCForCollectionStmt(StmtForCollection, 4777 OrigStmtRange.getEnd()); 4778 if (BreakStmt *StmtBreakStmt = 4779 dyn_cast<BreakStmt>(S)) 4780 return RewriteBreakStmt(StmtBreakStmt); 4781 if (ContinueStmt *StmtContinueStmt = 4782 dyn_cast<ContinueStmt>(S)) 4783 return RewriteContinueStmt(StmtContinueStmt); 4784 4785 // Need to check for protocol refs (id <P>, Foo <P> *) in variable decls 4786 // and cast exprs. 4787 if (DeclStmt *DS = dyn_cast<DeclStmt>(S)) { 4788 // FIXME: What we're doing here is modifying the type-specifier that 4789 // precedes the first Decl. In the future the DeclGroup should have 4790 // a separate type-specifier that we can rewrite. 4791 // NOTE: We need to avoid rewriting the DeclStmt if it is within 4792 // the context of an ObjCForCollectionStmt. For example: 4793 // NSArray *someArray; 4794 // for (id <FooProtocol> index in someArray) ; 4795 // This is because RewriteObjCForCollectionStmt() does textual rewriting 4796 // and it depends on the original text locations/positions. 4797 if (Stmts.empty() || !IsDeclStmtInForeachHeader(DS)) 4798 RewriteObjCQualifiedInterfaceTypes(*DS->decl_begin()); 4799 4800 // Blocks rewrite rules. 4801 for (DeclStmt::decl_iterator DI = DS->decl_begin(), DE = DS->decl_end(); 4802 DI != DE; ++DI) { 4803 Decl *SD = *DI; 4804 if (ValueDecl *ND = dyn_cast<ValueDecl>(SD)) { 4805 if (isTopLevelBlockPointerType(ND->getType())) 4806 RewriteBlockPointerDecl(ND); 4807 else if (ND->getType()->isFunctionPointerType()) 4808 CheckFunctionPointerDecl(ND->getType(), ND); 4809 if (VarDecl *VD = dyn_cast<VarDecl>(SD)) { 4810 if (VD->hasAttr<BlocksAttr>()) { 4811 static unsigned uniqueByrefDeclCount = 0; 4812 assert(!BlockByRefDeclNo.count(ND) && 4813 "RewriteFunctionBodyOrGlobalInitializer: Duplicate byref decl"); 4814 BlockByRefDeclNo[ND] = uniqueByrefDeclCount++; 4815 RewriteByRefVar(VD); 4816 } 4817 else 4818 RewriteTypeOfDecl(VD); 4819 } 4820 } 4821 if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(SD)) { 4822 if (isTopLevelBlockPointerType(TD->getUnderlyingType())) 4823 RewriteBlockPointerDecl(TD); 4824 else if (TD->getUnderlyingType()->isFunctionPointerType()) 4825 CheckFunctionPointerDecl(TD->getUnderlyingType(), TD); 4826 } 4827 } 4828 } 4829 4830 if (CStyleCastExpr *CE = dyn_cast<CStyleCastExpr>(S)) 4831 RewriteObjCQualifiedInterfaceTypes(CE); 4832 4833 if (isa<SwitchStmt>(S) || isa<WhileStmt>(S) || 4834 isa<DoStmt>(S) || isa<ForStmt>(S)) { 4835 assert(!Stmts.empty() && "Statement stack is empty"); 4836 assert ((isa<SwitchStmt>(Stmts.back()) || isa<WhileStmt>(Stmts.back()) || 4837 isa<DoStmt>(Stmts.back()) || isa<ForStmt>(Stmts.back())) 4838 && "Statement stack mismatch"); 4839 Stmts.pop_back(); 4840 } 4841 // Handle blocks rewriting. 4842 if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(S)) { 4843 ValueDecl *VD = DRE->getDecl(); 4844 if (VD->hasAttr<BlocksAttr>()) 4845 return RewriteBlockDeclRefExpr(DRE); 4846 if (HasLocalVariableExternalStorage(VD)) 4847 return RewriteLocalVariableExternalStorage(DRE); 4848 } 4849 4850 if (CallExpr *CE = dyn_cast<CallExpr>(S)) { 4851 if (CE->getCallee()->getType()->isBlockPointerType()) { 4852 Stmt *BlockCall = SynthesizeBlockCall(CE, CE->getCallee()); 4853 ReplaceStmt(S, BlockCall); 4854 return BlockCall; 4855 } 4856 } 4857 if (CStyleCastExpr *CE = dyn_cast<CStyleCastExpr>(S)) { 4858 RewriteCastExpr(CE); 4859 } 4860 #if 0 4861 if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(S)) { 4862 CastExpr *Replacement = new (Context) CastExpr(ICE->getType(), 4863 ICE->getSubExpr(), 4864 SourceLocation()); 4865 // Get the new text. 4866 std::string SStr; 4867 llvm::raw_string_ostream Buf(SStr); 4868 Replacement->printPretty(Buf, *Context); 4869 const std::string &Str = Buf.str(); 4870 4871 printf("CAST = %s\n", &Str[0]); 4872 InsertText(ICE->getSubExpr()->getLocStart(), &Str[0], Str.size()); 4873 delete S; 4874 return Replacement; 4875 } 4876 #endif 4877 // Return this stmt unmodified. 4878 return S; 4879 } 4880 4881 void RewriteObjC::RewriteRecordBody(RecordDecl *RD) { 4882 for (RecordDecl::field_iterator i = RD->field_begin(), 4883 e = RD->field_end(); i != e; ++i) { 4884 FieldDecl *FD = *i; 4885 if (isTopLevelBlockPointerType(FD->getType())) 4886 RewriteBlockPointerDecl(FD); 4887 if (FD->getType()->isObjCQualifiedIdType() || 4888 FD->getType()->isObjCQualifiedInterfaceType()) 4889 RewriteObjCQualifiedInterfaceTypes(FD); 4890 } 4891 } 4892 4893 /// HandleDeclInMainFile - This is called for each top-level decl defined in the 4894 /// main file of the input. 4895 void RewriteObjC::HandleDeclInMainFile(Decl *D) { 4896 switch (D->getKind()) { 4897 case Decl::Function: { 4898 FunctionDecl *FD = cast<FunctionDecl>(D); 4899 if (FD->isOverloadedOperator()) 4900 return; 4901 4902 // Since function prototypes don't have ParmDecl's, we check the function 4903 // prototype. This enables us to rewrite function declarations and 4904 // definitions using the same code. 4905 RewriteBlocksInFunctionProtoType(FD->getType(), FD); 4906 4907 if (!FD->isThisDeclarationADefinition()) 4908 break; 4909 4910 // FIXME: If this should support Obj-C++, support CXXTryStmt 4911 if (CompoundStmt *Body = dyn_cast_or_null<CompoundStmt>(FD->getBody())) { 4912 CurFunctionDef = FD; 4913 CurFunctionDeclToDeclareForBlock = FD; 4914 CurrentBody = Body; 4915 Body = 4916 cast_or_null<CompoundStmt>(RewriteFunctionBodyOrGlobalInitializer(Body)); 4917 FD->setBody(Body); 4918 CurrentBody = 0; 4919 if (PropParentMap) { 4920 delete PropParentMap; 4921 PropParentMap = 0; 4922 } 4923 // This synthesizes and inserts the block "impl" struct, invoke function, 4924 // and any copy/dispose helper functions. 4925 InsertBlockLiteralsWithinFunction(FD); 4926 CurFunctionDef = 0; 4927 CurFunctionDeclToDeclareForBlock = 0; 4928 } 4929 break; 4930 } 4931 case Decl::ObjCMethod: { 4932 ObjCMethodDecl *MD = cast<ObjCMethodDecl>(D); 4933 if (CompoundStmt *Body = MD->getCompoundBody()) { 4934 CurMethodDef = MD; 4935 CurrentBody = Body; 4936 Body = 4937 cast_or_null<CompoundStmt>(RewriteFunctionBodyOrGlobalInitializer(Body)); 4938 MD->setBody(Body); 4939 CurrentBody = 0; 4940 if (PropParentMap) { 4941 delete PropParentMap; 4942 PropParentMap = 0; 4943 } 4944 InsertBlockLiteralsWithinMethod(MD); 4945 CurMethodDef = 0; 4946 } 4947 break; 4948 } 4949 case Decl::ObjCImplementation: { 4950 ObjCImplementationDecl *CI = cast<ObjCImplementationDecl>(D); 4951 ClassImplementation.push_back(CI); 4952 break; 4953 } 4954 case Decl::ObjCCategoryImpl: { 4955 ObjCCategoryImplDecl *CI = cast<ObjCCategoryImplDecl>(D); 4956 CategoryImplementation.push_back(CI); 4957 break; 4958 } 4959 case Decl::Var: { 4960 VarDecl *VD = cast<VarDecl>(D); 4961 RewriteObjCQualifiedInterfaceTypes(VD); 4962 if (isTopLevelBlockPointerType(VD->getType())) 4963 RewriteBlockPointerDecl(VD); 4964 else if (VD->getType()->isFunctionPointerType()) { 4965 CheckFunctionPointerDecl(VD->getType(), VD); 4966 if (VD->getInit()) { 4967 if (CStyleCastExpr *CE = dyn_cast<CStyleCastExpr>(VD->getInit())) { 4968 RewriteCastExpr(CE); 4969 } 4970 } 4971 } else if (VD->getType()->isRecordType()) { 4972 RecordDecl *RD = VD->getType()->getAs<RecordType>()->getDecl(); 4973 if (RD->isCompleteDefinition()) 4974 RewriteRecordBody(RD); 4975 } 4976 if (VD->getInit()) { 4977 GlobalVarDecl = VD; 4978 CurrentBody = VD->getInit(); 4979 RewriteFunctionBodyOrGlobalInitializer(VD->getInit()); 4980 CurrentBody = 0; 4981 if (PropParentMap) { 4982 delete PropParentMap; 4983 PropParentMap = 0; 4984 } 4985 SynthesizeBlockLiterals(VD->getTypeSpecStartLoc(), VD->getName()); 4986 GlobalVarDecl = 0; 4987 4988 // This is needed for blocks. 4989 if (CStyleCastExpr *CE = dyn_cast<CStyleCastExpr>(VD->getInit())) { 4990 RewriteCastExpr(CE); 4991 } 4992 } 4993 break; 4994 } 4995 case Decl::TypeAlias: 4996 case Decl::Typedef: { 4997 if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D)) { 4998 if (isTopLevelBlockPointerType(TD->getUnderlyingType())) 4999 RewriteBlockPointerDecl(TD); 5000 else if (TD->getUnderlyingType()->isFunctionPointerType()) 5001 CheckFunctionPointerDecl(TD->getUnderlyingType(), TD); 5002 } 5003 break; 5004 } 5005 case Decl::CXXRecord: 5006 case Decl::Record: { 5007 RecordDecl *RD = cast<RecordDecl>(D); 5008 if (RD->isCompleteDefinition()) 5009 RewriteRecordBody(RD); 5010 break; 5011 } 5012 default: 5013 break; 5014 } 5015 // Nothing yet. 5016 } 5017 5018 void RewriteObjC::HandleTranslationUnit(ASTContext &C) { 5019 if (Diags.hasErrorOccurred()) 5020 return; 5021 5022 RewriteInclude(); 5023 5024 // Here's a great place to add any extra declarations that may be needed. 5025 // Write out meta data for each @protocol(<expr>). 5026 for (llvm::SmallPtrSet<ObjCProtocolDecl *,8>::iterator I = ProtocolExprDecls.begin(), 5027 E = ProtocolExprDecls.end(); I != E; ++I) 5028 RewriteObjCProtocolMetaData(*I, "", "", Preamble); 5029 5030 InsertText(SM->getLocForStartOfFile(MainFileID), Preamble, false); 5031 if (ClassImplementation.size() || CategoryImplementation.size()) 5032 RewriteImplementations(); 5033 5034 // Get the buffer corresponding to MainFileID. If we haven't changed it, then 5035 // we are done. 5036 if (const RewriteBuffer *RewriteBuf = 5037 Rewrite.getRewriteBufferFor(MainFileID)) { 5038 //printf("Changed:\n"); 5039 *OutFile << std::string(RewriteBuf->begin(), RewriteBuf->end()); 5040 } else { 5041 llvm::errs() << "No changes\n"; 5042 } 5043 5044 if (ClassImplementation.size() || CategoryImplementation.size() || 5045 ProtocolExprDecls.size()) { 5046 // Rewrite Objective-c meta data* 5047 std::string ResultStr; 5048 RewriteMetaDataIntoBuffer(ResultStr); 5049 // Emit metadata. 5050 *OutFile << ResultStr; 5051 } 5052 OutFile->flush(); 5053 } 5054 5055 void RewriteObjCFragileABI::Initialize(ASTContext &context) { 5056 InitializeCommon(context); 5057 5058 // declaring objc_selector outside the parameter list removes a silly 5059 // scope related warning... 5060 if (IsHeader) 5061 Preamble = "#pragma once\n"; 5062 Preamble += "struct objc_selector; struct objc_class;\n"; 5063 Preamble += "struct __rw_objc_super { struct objc_object *object; "; 5064 Preamble += "struct objc_object *superClass; "; 5065 if (LangOpts.MicrosoftExt) { 5066 // Add a constructor for creating temporary objects. 5067 Preamble += "__rw_objc_super(struct objc_object *o, struct objc_object *s) " 5068 ": "; 5069 Preamble += "object(o), superClass(s) {} "; 5070 } 5071 Preamble += "};\n"; 5072 Preamble += "#ifndef _REWRITER_typedef_Protocol\n"; 5073 Preamble += "typedef struct objc_object Protocol;\n"; 5074 Preamble += "#define _REWRITER_typedef_Protocol\n"; 5075 Preamble += "#endif\n"; 5076 if (LangOpts.MicrosoftExt) { 5077 Preamble += "#define __OBJC_RW_DLLIMPORT extern \"C\" __declspec(dllimport)\n"; 5078 Preamble += "#define __OBJC_RW_STATICIMPORT extern \"C\"\n"; 5079 } else 5080 Preamble += "#define __OBJC_RW_DLLIMPORT extern\n"; 5081 Preamble += "__OBJC_RW_DLLIMPORT struct objc_object *objc_msgSend"; 5082 Preamble += "(struct objc_object *, struct objc_selector *, ...);\n"; 5083 Preamble += "__OBJC_RW_DLLIMPORT struct objc_object *objc_msgSendSuper"; 5084 Preamble += "(struct objc_super *, struct objc_selector *, ...);\n"; 5085 Preamble += "__OBJC_RW_DLLIMPORT struct objc_object* objc_msgSend_stret"; 5086 Preamble += "(struct objc_object *, struct objc_selector *, ...);\n"; 5087 Preamble += "__OBJC_RW_DLLIMPORT struct objc_object* objc_msgSendSuper_stret"; 5088 Preamble += "(struct objc_super *, struct objc_selector *, ...);\n"; 5089 Preamble += "__OBJC_RW_DLLIMPORT double objc_msgSend_fpret"; 5090 Preamble += "(struct objc_object *, struct objc_selector *, ...);\n"; 5091 Preamble += "__OBJC_RW_DLLIMPORT struct objc_object *objc_getClass"; 5092 Preamble += "(const char *);\n"; 5093 Preamble += "__OBJC_RW_DLLIMPORT struct objc_class *class_getSuperclass"; 5094 Preamble += "(struct objc_class *);\n"; 5095 Preamble += "__OBJC_RW_DLLIMPORT struct objc_object *objc_getMetaClass"; 5096 Preamble += "(const char *);\n"; 5097 Preamble += "__OBJC_RW_DLLIMPORT void objc_exception_throw(struct objc_object *);\n"; 5098 Preamble += "__OBJC_RW_DLLIMPORT void objc_exception_try_enter(void *);\n"; 5099 Preamble += "__OBJC_RW_DLLIMPORT void objc_exception_try_exit(void *);\n"; 5100 Preamble += "__OBJC_RW_DLLIMPORT struct objc_object *objc_exception_extract(void *);\n"; 5101 Preamble += "__OBJC_RW_DLLIMPORT int objc_exception_match"; 5102 Preamble += "(struct objc_class *, struct objc_object *);\n"; 5103 // @synchronized hooks. 5104 Preamble += "__OBJC_RW_DLLIMPORT void objc_sync_enter(struct objc_object *);\n"; 5105 Preamble += "__OBJC_RW_DLLIMPORT void objc_sync_exit(struct objc_object *);\n"; 5106 Preamble += "__OBJC_RW_DLLIMPORT Protocol *objc_getProtocol(const char *);\n"; 5107 Preamble += "#ifndef __FASTENUMERATIONSTATE\n"; 5108 Preamble += "struct __objcFastEnumerationState {\n\t"; 5109 Preamble += "unsigned long state;\n\t"; 5110 Preamble += "void **itemsPtr;\n\t"; 5111 Preamble += "unsigned long *mutationsPtr;\n\t"; 5112 Preamble += "unsigned long extra[5];\n};\n"; 5113 Preamble += "__OBJC_RW_DLLIMPORT void objc_enumerationMutation(struct objc_object *);\n"; 5114 Preamble += "#define __FASTENUMERATIONSTATE\n"; 5115 Preamble += "#endif\n"; 5116 Preamble += "#ifndef __NSCONSTANTSTRINGIMPL\n"; 5117 Preamble += "struct __NSConstantStringImpl {\n"; 5118 Preamble += " int *isa;\n"; 5119 Preamble += " int flags;\n"; 5120 Preamble += " char *str;\n"; 5121 Preamble += " long length;\n"; 5122 Preamble += "};\n"; 5123 Preamble += "#ifdef CF_EXPORT_CONSTANT_STRING\n"; 5124 Preamble += "extern \"C\" __declspec(dllexport) int __CFConstantStringClassReference[];\n"; 5125 Preamble += "#else\n"; 5126 Preamble += "__OBJC_RW_DLLIMPORT int __CFConstantStringClassReference[];\n"; 5127 Preamble += "#endif\n"; 5128 Preamble += "#define __NSCONSTANTSTRINGIMPL\n"; 5129 Preamble += "#endif\n"; 5130 // Blocks preamble. 5131 Preamble += "#ifndef BLOCK_IMPL\n"; 5132 Preamble += "#define BLOCK_IMPL\n"; 5133 Preamble += "struct __block_impl {\n"; 5134 Preamble += " void *isa;\n"; 5135 Preamble += " int Flags;\n"; 5136 Preamble += " int Reserved;\n"; 5137 Preamble += " void *FuncPtr;\n"; 5138 Preamble += "};\n"; 5139 Preamble += "// Runtime copy/destroy helper functions (from Block_private.h)\n"; 5140 Preamble += "#ifdef __OBJC_EXPORT_BLOCKS\n"; 5141 Preamble += "extern \"C\" __declspec(dllexport) " 5142 "void _Block_object_assign(void *, const void *, const int);\n"; 5143 Preamble += "extern \"C\" __declspec(dllexport) void _Block_object_dispose(const void *, const int);\n"; 5144 Preamble += "extern \"C\" __declspec(dllexport) void *_NSConcreteGlobalBlock[32];\n"; 5145 Preamble += "extern \"C\" __declspec(dllexport) void *_NSConcreteStackBlock[32];\n"; 5146 Preamble += "#else\n"; 5147 Preamble += "__OBJC_RW_DLLIMPORT void _Block_object_assign(void *, const void *, const int);\n"; 5148 Preamble += "__OBJC_RW_DLLIMPORT void _Block_object_dispose(const void *, const int);\n"; 5149 Preamble += "__OBJC_RW_DLLIMPORT void *_NSConcreteGlobalBlock[32];\n"; 5150 Preamble += "__OBJC_RW_DLLIMPORT void *_NSConcreteStackBlock[32];\n"; 5151 Preamble += "#endif\n"; 5152 Preamble += "#endif\n"; 5153 if (LangOpts.MicrosoftExt) { 5154 Preamble += "#undef __OBJC_RW_DLLIMPORT\n"; 5155 Preamble += "#undef __OBJC_RW_STATICIMPORT\n"; 5156 Preamble += "#ifndef KEEP_ATTRIBUTES\n"; // We use this for clang tests. 5157 Preamble += "#define __attribute__(X)\n"; 5158 Preamble += "#endif\n"; 5159 Preamble += "#define __weak\n"; 5160 } 5161 else { 5162 Preamble += "#define __block\n"; 5163 Preamble += "#define __weak\n"; 5164 } 5165 // NOTE! Windows uses LLP64 for 64bit mode. So, cast pointer to long long 5166 // as this avoids warning in any 64bit/32bit compilation model. 5167 Preamble += "\n#define __OFFSETOFIVAR__(TYPE, MEMBER) ((long long) &((TYPE *)0)->MEMBER)\n"; 5168 } 5169 5170 /// RewriteIvarOffsetComputation - This rutine synthesizes computation of 5171 /// ivar offset. 5172 void RewriteObjCFragileABI::RewriteIvarOffsetComputation(ObjCIvarDecl *ivar, 5173 std::string &Result) { 5174 if (ivar->isBitField()) { 5175 // FIXME: The hack below doesn't work for bitfields. For now, we simply 5176 // place all bitfields at offset 0. 5177 Result += "0"; 5178 } else { 5179 Result += "__OFFSETOFIVAR__(struct "; 5180 Result += ivar->getContainingInterface()->getNameAsString(); 5181 if (LangOpts.MicrosoftExt) 5182 Result += "_IMPL"; 5183 Result += ", "; 5184 Result += ivar->getNameAsString(); 5185 Result += ")"; 5186 } 5187 } 5188 5189 /// RewriteObjCProtocolMetaData - Rewrite protocols meta-data. 5190 void RewriteObjCFragileABI::RewriteObjCProtocolMetaData( 5191 ObjCProtocolDecl *PDecl, StringRef prefix, 5192 StringRef ClassName, std::string &Result) { 5193 static bool objc_protocol_methods = false; 5194 5195 // Output struct protocol_methods holder of method selector and type. 5196 if (!objc_protocol_methods && PDecl->hasDefinition()) { 5197 /* struct protocol_methods { 5198 SEL _cmd; 5199 char *method_types; 5200 } 5201 */ 5202 Result += "\nstruct _protocol_methods {\n"; 5203 Result += "\tstruct objc_selector *_cmd;\n"; 5204 Result += "\tchar *method_types;\n"; 5205 Result += "};\n"; 5206 5207 objc_protocol_methods = true; 5208 } 5209 // Do not synthesize the protocol more than once. 5210 if (ObjCSynthesizedProtocols.count(PDecl->getCanonicalDecl())) 5211 return; 5212 5213 if (ObjCProtocolDecl *Def = PDecl->getDefinition()) 5214 PDecl = Def; 5215 5216 if (PDecl->instmeth_begin() != PDecl->instmeth_end()) { 5217 unsigned NumMethods = std::distance(PDecl->instmeth_begin(), 5218 PDecl->instmeth_end()); 5219 /* struct _objc_protocol_method_list { 5220 int protocol_method_count; 5221 struct protocol_methods protocols[]; 5222 } 5223 */ 5224 Result += "\nstatic struct {\n"; 5225 Result += "\tint protocol_method_count;\n"; 5226 Result += "\tstruct _protocol_methods protocol_methods["; 5227 Result += utostr(NumMethods); 5228 Result += "];\n} _OBJC_PROTOCOL_INSTANCE_METHODS_"; 5229 Result += PDecl->getNameAsString(); 5230 Result += " __attribute__ ((used, section (\"__OBJC, __cat_inst_meth\")))= " 5231 "{\n\t" + utostr(NumMethods) + "\n"; 5232 5233 // Output instance methods declared in this protocol. 5234 for (ObjCProtocolDecl::instmeth_iterator 5235 I = PDecl->instmeth_begin(), E = PDecl->instmeth_end(); 5236 I != E; ++I) { 5237 if (I == PDecl->instmeth_begin()) 5238 Result += "\t ,{{(struct objc_selector *)\""; 5239 else 5240 Result += "\t ,{(struct objc_selector *)\""; 5241 Result += (*I)->getSelector().getAsString(); 5242 std::string MethodTypeString; 5243 Context->getObjCEncodingForMethodDecl((*I), MethodTypeString); 5244 Result += "\", \""; 5245 Result += MethodTypeString; 5246 Result += "\"}\n"; 5247 } 5248 Result += "\t }\n};\n"; 5249 } 5250 5251 // Output class methods declared in this protocol. 5252 unsigned NumMethods = std::distance(PDecl->classmeth_begin(), 5253 PDecl->classmeth_end()); 5254 if (NumMethods > 0) { 5255 /* struct _objc_protocol_method_list { 5256 int protocol_method_count; 5257 struct protocol_methods protocols[]; 5258 } 5259 */ 5260 Result += "\nstatic struct {\n"; 5261 Result += "\tint protocol_method_count;\n"; 5262 Result += "\tstruct _protocol_methods protocol_methods["; 5263 Result += utostr(NumMethods); 5264 Result += "];\n} _OBJC_PROTOCOL_CLASS_METHODS_"; 5265 Result += PDecl->getNameAsString(); 5266 Result += " __attribute__ ((used, section (\"__OBJC, __cat_cls_meth\")))= " 5267 "{\n\t"; 5268 Result += utostr(NumMethods); 5269 Result += "\n"; 5270 5271 // Output instance methods declared in this protocol. 5272 for (ObjCProtocolDecl::classmeth_iterator 5273 I = PDecl->classmeth_begin(), E = PDecl->classmeth_end(); 5274 I != E; ++I) { 5275 if (I == PDecl->classmeth_begin()) 5276 Result += "\t ,{{(struct objc_selector *)\""; 5277 else 5278 Result += "\t ,{(struct objc_selector *)\""; 5279 Result += (*I)->getSelector().getAsString(); 5280 std::string MethodTypeString; 5281 Context->getObjCEncodingForMethodDecl((*I), MethodTypeString); 5282 Result += "\", \""; 5283 Result += MethodTypeString; 5284 Result += "\"}\n"; 5285 } 5286 Result += "\t }\n};\n"; 5287 } 5288 5289 // Output: 5290 /* struct _objc_protocol { 5291 // Objective-C 1.0 extensions 5292 struct _objc_protocol_extension *isa; 5293 char *protocol_name; 5294 struct _objc_protocol **protocol_list; 5295 struct _objc_protocol_method_list *instance_methods; 5296 struct _objc_protocol_method_list *class_methods; 5297 }; 5298 */ 5299 static bool objc_protocol = false; 5300 if (!objc_protocol) { 5301 Result += "\nstruct _objc_protocol {\n"; 5302 Result += "\tstruct _objc_protocol_extension *isa;\n"; 5303 Result += "\tchar *protocol_name;\n"; 5304 Result += "\tstruct _objc_protocol **protocol_list;\n"; 5305 Result += "\tstruct _objc_protocol_method_list *instance_methods;\n"; 5306 Result += "\tstruct _objc_protocol_method_list *class_methods;\n"; 5307 Result += "};\n"; 5308 5309 objc_protocol = true; 5310 } 5311 5312 Result += "\nstatic struct _objc_protocol _OBJC_PROTOCOL_"; 5313 Result += PDecl->getNameAsString(); 5314 Result += " __attribute__ ((used, section (\"__OBJC, __protocol\")))= " 5315 "{\n\t0, \""; 5316 Result += PDecl->getNameAsString(); 5317 Result += "\", 0, "; 5318 if (PDecl->instmeth_begin() != PDecl->instmeth_end()) { 5319 Result += "(struct _objc_protocol_method_list *)&_OBJC_PROTOCOL_INSTANCE_METHODS_"; 5320 Result += PDecl->getNameAsString(); 5321 Result += ", "; 5322 } 5323 else 5324 Result += "0, "; 5325 if (PDecl->classmeth_begin() != PDecl->classmeth_end()) { 5326 Result += "(struct _objc_protocol_method_list *)&_OBJC_PROTOCOL_CLASS_METHODS_"; 5327 Result += PDecl->getNameAsString(); 5328 Result += "\n"; 5329 } 5330 else 5331 Result += "0\n"; 5332 Result += "};\n"; 5333 5334 // Mark this protocol as having been generated. 5335 if (!ObjCSynthesizedProtocols.insert(PDecl->getCanonicalDecl())) 5336 llvm_unreachable("protocol already synthesized"); 5337 5338 } 5339 5340 void RewriteObjCFragileABI::RewriteObjCProtocolListMetaData( 5341 const ObjCList<ObjCProtocolDecl> &Protocols, 5342 StringRef prefix, StringRef ClassName, 5343 std::string &Result) { 5344 if (Protocols.empty()) return; 5345 5346 for (unsigned i = 0; i != Protocols.size(); i++) 5347 RewriteObjCProtocolMetaData(Protocols[i], prefix, ClassName, Result); 5348 5349 // Output the top lovel protocol meta-data for the class. 5350 /* struct _objc_protocol_list { 5351 struct _objc_protocol_list *next; 5352 int protocol_count; 5353 struct _objc_protocol *class_protocols[]; 5354 } 5355 */ 5356 Result += "\nstatic struct {\n"; 5357 Result += "\tstruct _objc_protocol_list *next;\n"; 5358 Result += "\tint protocol_count;\n"; 5359 Result += "\tstruct _objc_protocol *class_protocols["; 5360 Result += utostr(Protocols.size()); 5361 Result += "];\n} _OBJC_"; 5362 Result += prefix; 5363 Result += "_PROTOCOLS_"; 5364 Result += ClassName; 5365 Result += " __attribute__ ((used, section (\"__OBJC, __cat_cls_meth\")))= " 5366 "{\n\t0, "; 5367 Result += utostr(Protocols.size()); 5368 Result += "\n"; 5369 5370 Result += "\t,{&_OBJC_PROTOCOL_"; 5371 Result += Protocols[0]->getNameAsString(); 5372 Result += " \n"; 5373 5374 for (unsigned i = 1; i != Protocols.size(); i++) { 5375 Result += "\t ,&_OBJC_PROTOCOL_"; 5376 Result += Protocols[i]->getNameAsString(); 5377 Result += "\n"; 5378 } 5379 Result += "\t }\n};\n"; 5380 } 5381 5382 void RewriteObjCFragileABI::RewriteObjCClassMetaData(ObjCImplementationDecl *IDecl, 5383 std::string &Result) { 5384 ObjCInterfaceDecl *CDecl = IDecl->getClassInterface(); 5385 5386 // Explicitly declared @interface's are already synthesized. 5387 if (CDecl->isImplicitInterfaceDecl()) { 5388 // FIXME: Implementation of a class with no @interface (legacy) does not 5389 // produce correct synthesis as yet. 5390 RewriteObjCInternalStruct(CDecl, Result); 5391 } 5392 5393 // Build _objc_ivar_list metadata for classes ivars if needed 5394 unsigned NumIvars = !IDecl->ivar_empty() 5395 ? IDecl->ivar_size() 5396 : (CDecl ? CDecl->ivar_size() : 0); 5397 if (NumIvars > 0) { 5398 static bool objc_ivar = false; 5399 if (!objc_ivar) { 5400 /* struct _objc_ivar { 5401 char *ivar_name; 5402 char *ivar_type; 5403 int ivar_offset; 5404 }; 5405 */ 5406 Result += "\nstruct _objc_ivar {\n"; 5407 Result += "\tchar *ivar_name;\n"; 5408 Result += "\tchar *ivar_type;\n"; 5409 Result += "\tint ivar_offset;\n"; 5410 Result += "};\n"; 5411 5412 objc_ivar = true; 5413 } 5414 5415 /* struct { 5416 int ivar_count; 5417 struct _objc_ivar ivar_list[nIvars]; 5418 }; 5419 */ 5420 Result += "\nstatic struct {\n"; 5421 Result += "\tint ivar_count;\n"; 5422 Result += "\tstruct _objc_ivar ivar_list["; 5423 Result += utostr(NumIvars); 5424 Result += "];\n} _OBJC_INSTANCE_VARIABLES_"; 5425 Result += IDecl->getNameAsString(); 5426 Result += " __attribute__ ((used, section (\"__OBJC, __instance_vars\")))= " 5427 "{\n\t"; 5428 Result += utostr(NumIvars); 5429 Result += "\n"; 5430 5431 ObjCInterfaceDecl::ivar_iterator IVI, IVE; 5432 SmallVector<ObjCIvarDecl *, 8> IVars; 5433 if (!IDecl->ivar_empty()) { 5434 for (ObjCInterfaceDecl::ivar_iterator 5435 IV = IDecl->ivar_begin(), IVEnd = IDecl->ivar_end(); 5436 IV != IVEnd; ++IV) 5437 IVars.push_back(*IV); 5438 IVI = IDecl->ivar_begin(); 5439 IVE = IDecl->ivar_end(); 5440 } else { 5441 IVI = CDecl->ivar_begin(); 5442 IVE = CDecl->ivar_end(); 5443 } 5444 Result += "\t,{{\""; 5445 Result += (*IVI)->getNameAsString(); 5446 Result += "\", \""; 5447 std::string TmpString, StrEncoding; 5448 Context->getObjCEncodingForType((*IVI)->getType(), TmpString, *IVI); 5449 QuoteDoublequotes(TmpString, StrEncoding); 5450 Result += StrEncoding; 5451 Result += "\", "; 5452 RewriteIvarOffsetComputation(*IVI, Result); 5453 Result += "}\n"; 5454 for (++IVI; IVI != IVE; ++IVI) { 5455 Result += "\t ,{\""; 5456 Result += (*IVI)->getNameAsString(); 5457 Result += "\", \""; 5458 std::string TmpString, StrEncoding; 5459 Context->getObjCEncodingForType((*IVI)->getType(), TmpString, *IVI); 5460 QuoteDoublequotes(TmpString, StrEncoding); 5461 Result += StrEncoding; 5462 Result += "\", "; 5463 RewriteIvarOffsetComputation((*IVI), Result); 5464 Result += "}\n"; 5465 } 5466 5467 Result += "\t }\n};\n"; 5468 } 5469 5470 // Build _objc_method_list for class's instance methods if needed 5471 SmallVector<ObjCMethodDecl *, 32> 5472 InstanceMethods(IDecl->instmeth_begin(), IDecl->instmeth_end()); 5473 5474 // If any of our property implementations have associated getters or 5475 // setters, produce metadata for them as well. 5476 for (ObjCImplDecl::propimpl_iterator Prop = IDecl->propimpl_begin(), 5477 PropEnd = IDecl->propimpl_end(); 5478 Prop != PropEnd; ++Prop) { 5479 if ((*Prop)->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic) 5480 continue; 5481 if (!(*Prop)->getPropertyIvarDecl()) 5482 continue; 5483 ObjCPropertyDecl *PD = (*Prop)->getPropertyDecl(); 5484 if (!PD) 5485 continue; 5486 if (ObjCMethodDecl *Getter = PD->getGetterMethodDecl()) 5487 if (!Getter->isDefined()) 5488 InstanceMethods.push_back(Getter); 5489 if (PD->isReadOnly()) 5490 continue; 5491 if (ObjCMethodDecl *Setter = PD->getSetterMethodDecl()) 5492 if (!Setter->isDefined()) 5493 InstanceMethods.push_back(Setter); 5494 } 5495 RewriteObjCMethodsMetaData(InstanceMethods.begin(), InstanceMethods.end(), 5496 true, "", IDecl->getName(), Result); 5497 5498 // Build _objc_method_list for class's class methods if needed 5499 RewriteObjCMethodsMetaData(IDecl->classmeth_begin(), IDecl->classmeth_end(), 5500 false, "", IDecl->getName(), Result); 5501 5502 // Protocols referenced in class declaration? 5503 RewriteObjCProtocolListMetaData(CDecl->getReferencedProtocols(), 5504 "CLASS", CDecl->getName(), Result); 5505 5506 // Declaration of class/meta-class metadata 5507 /* struct _objc_class { 5508 struct _objc_class *isa; // or const char *root_class_name when metadata 5509 const char *super_class_name; 5510 char *name; 5511 long version; 5512 long info; 5513 long instance_size; 5514 struct _objc_ivar_list *ivars; 5515 struct _objc_method_list *methods; 5516 struct objc_cache *cache; 5517 struct objc_protocol_list *protocols; 5518 const char *ivar_layout; 5519 struct _objc_class_ext *ext; 5520 }; 5521 */ 5522 static bool objc_class = false; 5523 if (!objc_class) { 5524 Result += "\nstruct _objc_class {\n"; 5525 Result += "\tstruct _objc_class *isa;\n"; 5526 Result += "\tconst char *super_class_name;\n"; 5527 Result += "\tchar *name;\n"; 5528 Result += "\tlong version;\n"; 5529 Result += "\tlong info;\n"; 5530 Result += "\tlong instance_size;\n"; 5531 Result += "\tstruct _objc_ivar_list *ivars;\n"; 5532 Result += "\tstruct _objc_method_list *methods;\n"; 5533 Result += "\tstruct objc_cache *cache;\n"; 5534 Result += "\tstruct _objc_protocol_list *protocols;\n"; 5535 Result += "\tconst char *ivar_layout;\n"; 5536 Result += "\tstruct _objc_class_ext *ext;\n"; 5537 Result += "};\n"; 5538 objc_class = true; 5539 } 5540 5541 // Meta-class metadata generation. 5542 ObjCInterfaceDecl *RootClass = 0; 5543 ObjCInterfaceDecl *SuperClass = CDecl->getSuperClass(); 5544 while (SuperClass) { 5545 RootClass = SuperClass; 5546 SuperClass = SuperClass->getSuperClass(); 5547 } 5548 SuperClass = CDecl->getSuperClass(); 5549 5550 Result += "\nstatic struct _objc_class _OBJC_METACLASS_"; 5551 Result += CDecl->getNameAsString(); 5552 Result += " __attribute__ ((used, section (\"__OBJC, __meta_class\")))= " 5553 "{\n\t(struct _objc_class *)\""; 5554 Result += (RootClass ? RootClass->getNameAsString() : CDecl->getNameAsString()); 5555 Result += "\""; 5556 5557 if (SuperClass) { 5558 Result += ", \""; 5559 Result += SuperClass->getNameAsString(); 5560 Result += "\", \""; 5561 Result += CDecl->getNameAsString(); 5562 Result += "\""; 5563 } 5564 else { 5565 Result += ", 0, \""; 5566 Result += CDecl->getNameAsString(); 5567 Result += "\""; 5568 } 5569 // Set 'ivars' field for root class to 0. ObjC1 runtime does not use it. 5570 // 'info' field is initialized to CLS_META(2) for metaclass 5571 Result += ", 0,2, sizeof(struct _objc_class), 0"; 5572 if (IDecl->classmeth_begin() != IDecl->classmeth_end()) { 5573 Result += "\n\t, (struct _objc_method_list *)&_OBJC_CLASS_METHODS_"; 5574 Result += IDecl->getNameAsString(); 5575 Result += "\n"; 5576 } 5577 else 5578 Result += ", 0\n"; 5579 if (CDecl->protocol_begin() != CDecl->protocol_end()) { 5580 Result += "\t,0, (struct _objc_protocol_list *)&_OBJC_CLASS_PROTOCOLS_"; 5581 Result += CDecl->getNameAsString(); 5582 Result += ",0,0\n"; 5583 } 5584 else 5585 Result += "\t,0,0,0,0\n"; 5586 Result += "};\n"; 5587 5588 // class metadata generation. 5589 Result += "\nstatic struct _objc_class _OBJC_CLASS_"; 5590 Result += CDecl->getNameAsString(); 5591 Result += " __attribute__ ((used, section (\"__OBJC, __class\")))= " 5592 "{\n\t&_OBJC_METACLASS_"; 5593 Result += CDecl->getNameAsString(); 5594 if (SuperClass) { 5595 Result += ", \""; 5596 Result += SuperClass->getNameAsString(); 5597 Result += "\", \""; 5598 Result += CDecl->getNameAsString(); 5599 Result += "\""; 5600 } 5601 else { 5602 Result += ", 0, \""; 5603 Result += CDecl->getNameAsString(); 5604 Result += "\""; 5605 } 5606 // 'info' field is initialized to CLS_CLASS(1) for class 5607 Result += ", 0,1"; 5608 if (!ObjCSynthesizedStructs.count(CDecl)) 5609 Result += ",0"; 5610 else { 5611 // class has size. Must synthesize its size. 5612 Result += ",sizeof(struct "; 5613 Result += CDecl->getNameAsString(); 5614 if (LangOpts.MicrosoftExt) 5615 Result += "_IMPL"; 5616 Result += ")"; 5617 } 5618 if (NumIvars > 0) { 5619 Result += ", (struct _objc_ivar_list *)&_OBJC_INSTANCE_VARIABLES_"; 5620 Result += CDecl->getNameAsString(); 5621 Result += "\n\t"; 5622 } 5623 else 5624 Result += ",0"; 5625 if (IDecl->instmeth_begin() != IDecl->instmeth_end()) { 5626 Result += ", (struct _objc_method_list *)&_OBJC_INSTANCE_METHODS_"; 5627 Result += CDecl->getNameAsString(); 5628 Result += ", 0\n\t"; 5629 } 5630 else 5631 Result += ",0,0"; 5632 if (CDecl->protocol_begin() != CDecl->protocol_end()) { 5633 Result += ", (struct _objc_protocol_list*)&_OBJC_CLASS_PROTOCOLS_"; 5634 Result += CDecl->getNameAsString(); 5635 Result += ", 0,0\n"; 5636 } 5637 else 5638 Result += ",0,0,0\n"; 5639 Result += "};\n"; 5640 } 5641 5642 void RewriteObjCFragileABI::RewriteMetaDataIntoBuffer(std::string &Result) { 5643 int ClsDefCount = ClassImplementation.size(); 5644 int CatDefCount = CategoryImplementation.size(); 5645 5646 // For each implemented class, write out all its meta data. 5647 for (int i = 0; i < ClsDefCount; i++) 5648 RewriteObjCClassMetaData(ClassImplementation[i], Result); 5649 5650 // For each implemented category, write out all its meta data. 5651 for (int i = 0; i < CatDefCount; i++) 5652 RewriteObjCCategoryImplDecl(CategoryImplementation[i], Result); 5653 5654 // Write objc_symtab metadata 5655 /* 5656 struct _objc_symtab 5657 { 5658 long sel_ref_cnt; 5659 SEL *refs; 5660 short cls_def_cnt; 5661 short cat_def_cnt; 5662 void *defs[cls_def_cnt + cat_def_cnt]; 5663 }; 5664 */ 5665 5666 Result += "\nstruct _objc_symtab {\n"; 5667 Result += "\tlong sel_ref_cnt;\n"; 5668 Result += "\tSEL *refs;\n"; 5669 Result += "\tshort cls_def_cnt;\n"; 5670 Result += "\tshort cat_def_cnt;\n"; 5671 Result += "\tvoid *defs[" + utostr(ClsDefCount + CatDefCount)+ "];\n"; 5672 Result += "};\n\n"; 5673 5674 Result += "static struct _objc_symtab " 5675 "_OBJC_SYMBOLS __attribute__((used, section (\"__OBJC, __symbols\")))= {\n"; 5676 Result += "\t0, 0, " + utostr(ClsDefCount) 5677 + ", " + utostr(CatDefCount) + "\n"; 5678 for (int i = 0; i < ClsDefCount; i++) { 5679 Result += "\t,&_OBJC_CLASS_"; 5680 Result += ClassImplementation[i]->getNameAsString(); 5681 Result += "\n"; 5682 } 5683 5684 for (int i = 0; i < CatDefCount; i++) { 5685 Result += "\t,&_OBJC_CATEGORY_"; 5686 Result += CategoryImplementation[i]->getClassInterface()->getNameAsString(); 5687 Result += "_"; 5688 Result += CategoryImplementation[i]->getNameAsString(); 5689 Result += "\n"; 5690 } 5691 5692 Result += "};\n\n"; 5693 5694 // Write objc_module metadata 5695 5696 /* 5697 struct _objc_module { 5698 long version; 5699 long size; 5700 const char *name; 5701 struct _objc_symtab *symtab; 5702 } 5703 */ 5704 5705 Result += "\nstruct _objc_module {\n"; 5706 Result += "\tlong version;\n"; 5707 Result += "\tlong size;\n"; 5708 Result += "\tconst char *name;\n"; 5709 Result += "\tstruct _objc_symtab *symtab;\n"; 5710 Result += "};\n\n"; 5711 Result += "static struct _objc_module " 5712 "_OBJC_MODULES __attribute__ ((used, section (\"__OBJC, __module_info\")))= {\n"; 5713 Result += "\t" + utostr(OBJC_ABI_VERSION) + 5714 ", sizeof(struct _objc_module), \"\", &_OBJC_SYMBOLS\n"; 5715 Result += "};\n\n"; 5716 5717 if (LangOpts.MicrosoftExt) { 5718 if (ProtocolExprDecls.size()) { 5719 Result += "#pragma section(\".objc_protocol$B\",long,read,write)\n"; 5720 Result += "#pragma data_seg(push, \".objc_protocol$B\")\n"; 5721 for (llvm::SmallPtrSet<ObjCProtocolDecl *,8>::iterator I = ProtocolExprDecls.begin(), 5722 E = ProtocolExprDecls.end(); I != E; ++I) { 5723 Result += "static struct _objc_protocol *_POINTER_OBJC_PROTOCOL_"; 5724 Result += (*I)->getNameAsString(); 5725 Result += " = &_OBJC_PROTOCOL_"; 5726 Result += (*I)->getNameAsString(); 5727 Result += ";\n"; 5728 } 5729 Result += "#pragma data_seg(pop)\n\n"; 5730 } 5731 Result += "#pragma section(\".objc_module_info$B\",long,read,write)\n"; 5732 Result += "#pragma data_seg(push, \".objc_module_info$B\")\n"; 5733 Result += "static struct _objc_module *_POINTER_OBJC_MODULES = "; 5734 Result += "&_OBJC_MODULES;\n"; 5735 Result += "#pragma data_seg(pop)\n\n"; 5736 } 5737 } 5738 5739 /// RewriteObjCCategoryImplDecl - Rewrite metadata for each category 5740 /// implementation. 5741 void RewriteObjCFragileABI::RewriteObjCCategoryImplDecl(ObjCCategoryImplDecl *IDecl, 5742 std::string &Result) { 5743 ObjCInterfaceDecl *ClassDecl = IDecl->getClassInterface(); 5744 // Find category declaration for this implementation. 5745 ObjCCategoryDecl *CDecl; 5746 for (CDecl = ClassDecl->getCategoryList(); CDecl; 5747 CDecl = CDecl->getNextClassCategory()) 5748 if (CDecl->getIdentifier() == IDecl->getIdentifier()) 5749 break; 5750 5751 std::string FullCategoryName = ClassDecl->getNameAsString(); 5752 FullCategoryName += '_'; 5753 FullCategoryName += IDecl->getNameAsString(); 5754 5755 // Build _objc_method_list for class's instance methods if needed 5756 SmallVector<ObjCMethodDecl *, 32> 5757 InstanceMethods(IDecl->instmeth_begin(), IDecl->instmeth_end()); 5758 5759 // If any of our property implementations have associated getters or 5760 // setters, produce metadata for them as well. 5761 for (ObjCImplDecl::propimpl_iterator Prop = IDecl->propimpl_begin(), 5762 PropEnd = IDecl->propimpl_end(); 5763 Prop != PropEnd; ++Prop) { 5764 if ((*Prop)->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic) 5765 continue; 5766 if (!(*Prop)->getPropertyIvarDecl()) 5767 continue; 5768 ObjCPropertyDecl *PD = (*Prop)->getPropertyDecl(); 5769 if (!PD) 5770 continue; 5771 if (ObjCMethodDecl *Getter = PD->getGetterMethodDecl()) 5772 InstanceMethods.push_back(Getter); 5773 if (PD->isReadOnly()) 5774 continue; 5775 if (ObjCMethodDecl *Setter = PD->getSetterMethodDecl()) 5776 InstanceMethods.push_back(Setter); 5777 } 5778 RewriteObjCMethodsMetaData(InstanceMethods.begin(), InstanceMethods.end(), 5779 true, "CATEGORY_", FullCategoryName.c_str(), 5780 Result); 5781 5782 // Build _objc_method_list for class's class methods if needed 5783 RewriteObjCMethodsMetaData(IDecl->classmeth_begin(), IDecl->classmeth_end(), 5784 false, "CATEGORY_", FullCategoryName.c_str(), 5785 Result); 5786 5787 // Protocols referenced in class declaration? 5788 // Null CDecl is case of a category implementation with no category interface 5789 if (CDecl) 5790 RewriteObjCProtocolListMetaData(CDecl->getReferencedProtocols(), "CATEGORY", 5791 FullCategoryName, Result); 5792 /* struct _objc_category { 5793 char *category_name; 5794 char *class_name; 5795 struct _objc_method_list *instance_methods; 5796 struct _objc_method_list *class_methods; 5797 struct _objc_protocol_list *protocols; 5798 // Objective-C 1.0 extensions 5799 uint32_t size; // sizeof (struct _objc_category) 5800 struct _objc_property_list *instance_properties; // category's own 5801 // @property decl. 5802 }; 5803 */ 5804 5805 static bool objc_category = false; 5806 if (!objc_category) { 5807 Result += "\nstruct _objc_category {\n"; 5808 Result += "\tchar *category_name;\n"; 5809 Result += "\tchar *class_name;\n"; 5810 Result += "\tstruct _objc_method_list *instance_methods;\n"; 5811 Result += "\tstruct _objc_method_list *class_methods;\n"; 5812 Result += "\tstruct _objc_protocol_list *protocols;\n"; 5813 Result += "\tunsigned int size;\n"; 5814 Result += "\tstruct _objc_property_list *instance_properties;\n"; 5815 Result += "};\n"; 5816 objc_category = true; 5817 } 5818 Result += "\nstatic struct _objc_category _OBJC_CATEGORY_"; 5819 Result += FullCategoryName; 5820 Result += " __attribute__ ((used, section (\"__OBJC, __category\")))= {\n\t\""; 5821 Result += IDecl->getNameAsString(); 5822 Result += "\"\n\t, \""; 5823 Result += ClassDecl->getNameAsString(); 5824 Result += "\"\n"; 5825 5826 if (IDecl->instmeth_begin() != IDecl->instmeth_end()) { 5827 Result += "\t, (struct _objc_method_list *)" 5828 "&_OBJC_CATEGORY_INSTANCE_METHODS_"; 5829 Result += FullCategoryName; 5830 Result += "\n"; 5831 } 5832 else 5833 Result += "\t, 0\n"; 5834 if (IDecl->classmeth_begin() != IDecl->classmeth_end()) { 5835 Result += "\t, (struct _objc_method_list *)" 5836 "&_OBJC_CATEGORY_CLASS_METHODS_"; 5837 Result += FullCategoryName; 5838 Result += "\n"; 5839 } 5840 else 5841 Result += "\t, 0\n"; 5842 5843 if (CDecl && CDecl->protocol_begin() != CDecl->protocol_end()) { 5844 Result += "\t, (struct _objc_protocol_list *)&_OBJC_CATEGORY_PROTOCOLS_"; 5845 Result += FullCategoryName; 5846 Result += "\n"; 5847 } 5848 else 5849 Result += "\t, 0\n"; 5850 Result += "\t, sizeof(struct _objc_category), 0\n};\n"; 5851 } 5852 5853 // RewriteObjCMethodsMetaData - Rewrite methods metadata for instance or 5854 /// class methods. 5855 template<typename MethodIterator> 5856 void RewriteObjCFragileABI::RewriteObjCMethodsMetaData(MethodIterator MethodBegin, 5857 MethodIterator MethodEnd, 5858 bool IsInstanceMethod, 5859 StringRef prefix, 5860 StringRef ClassName, 5861 std::string &Result) { 5862 if (MethodBegin == MethodEnd) return; 5863 5864 if (!objc_impl_method) { 5865 /* struct _objc_method { 5866 SEL _cmd; 5867 char *method_types; 5868 void *_imp; 5869 } 5870 */ 5871 Result += "\nstruct _objc_method {\n"; 5872 Result += "\tSEL _cmd;\n"; 5873 Result += "\tchar *method_types;\n"; 5874 Result += "\tvoid *_imp;\n"; 5875 Result += "};\n"; 5876 5877 objc_impl_method = true; 5878 } 5879 5880 // Build _objc_method_list for class's methods if needed 5881 5882 /* struct { 5883 struct _objc_method_list *next_method; 5884 int method_count; 5885 struct _objc_method method_list[]; 5886 } 5887 */ 5888 unsigned NumMethods = std::distance(MethodBegin, MethodEnd); 5889 Result += "\nstatic struct {\n"; 5890 Result += "\tstruct _objc_method_list *next_method;\n"; 5891 Result += "\tint method_count;\n"; 5892 Result += "\tstruct _objc_method method_list["; 5893 Result += utostr(NumMethods); 5894 Result += "];\n} _OBJC_"; 5895 Result += prefix; 5896 Result += IsInstanceMethod ? "INSTANCE" : "CLASS"; 5897 Result += "_METHODS_"; 5898 Result += ClassName; 5899 Result += " __attribute__ ((used, section (\"__OBJC, __"; 5900 Result += IsInstanceMethod ? "inst" : "cls"; 5901 Result += "_meth\")))= "; 5902 Result += "{\n\t0, " + utostr(NumMethods) + "\n"; 5903 5904 Result += "\t,{{(SEL)\""; 5905 Result += (*MethodBegin)->getSelector().getAsString().c_str(); 5906 std::string MethodTypeString; 5907 Context->getObjCEncodingForMethodDecl(*MethodBegin, MethodTypeString); 5908 Result += "\", \""; 5909 Result += MethodTypeString; 5910 Result += "\", (void *)"; 5911 Result += MethodInternalNames[*MethodBegin]; 5912 Result += "}\n"; 5913 for (++MethodBegin; MethodBegin != MethodEnd; ++MethodBegin) { 5914 Result += "\t ,{(SEL)\""; 5915 Result += (*MethodBegin)->getSelector().getAsString().c_str(); 5916 std::string MethodTypeString; 5917 Context->getObjCEncodingForMethodDecl(*MethodBegin, MethodTypeString); 5918 Result += "\", \""; 5919 Result += MethodTypeString; 5920 Result += "\", (void *)"; 5921 Result += MethodInternalNames[*MethodBegin]; 5922 Result += "}\n"; 5923 } 5924 Result += "\t }\n};\n"; 5925 } 5926 5927 Stmt *RewriteObjCFragileABI::RewriteObjCIvarRefExpr(ObjCIvarRefExpr *IV) { 5928 SourceRange OldRange = IV->getSourceRange(); 5929 Expr *BaseExpr = IV->getBase(); 5930 5931 // Rewrite the base, but without actually doing replaces. 5932 { 5933 DisableReplaceStmtScope S(*this); 5934 BaseExpr = cast<Expr>(RewriteFunctionBodyOrGlobalInitializer(BaseExpr)); 5935 IV->setBase(BaseExpr); 5936 } 5937 5938 ObjCIvarDecl *D = IV->getDecl(); 5939 5940 Expr *Replacement = IV; 5941 if (CurMethodDef) { 5942 if (BaseExpr->getType()->isObjCObjectPointerType()) { 5943 const ObjCInterfaceType *iFaceDecl = 5944 dyn_cast<ObjCInterfaceType>(BaseExpr->getType()->getPointeeType()); 5945 assert(iFaceDecl && "RewriteObjCIvarRefExpr - iFaceDecl is null"); 5946 // lookup which class implements the instance variable. 5947 ObjCInterfaceDecl *clsDeclared = 0; 5948 iFaceDecl->getDecl()->lookupInstanceVariable(D->getIdentifier(), 5949 clsDeclared); 5950 assert(clsDeclared && "RewriteObjCIvarRefExpr(): Can't find class"); 5951 5952 // Synthesize an explicit cast to gain access to the ivar. 5953 std::string RecName = clsDeclared->getIdentifier()->getName(); 5954 RecName += "_IMPL"; 5955 IdentifierInfo *II = &Context->Idents.get(RecName); 5956 RecordDecl *RD = RecordDecl::Create(*Context, TTK_Struct, TUDecl, 5957 SourceLocation(), SourceLocation(), 5958 II); 5959 assert(RD && "RewriteObjCIvarRefExpr(): Can't find RecordDecl"); 5960 QualType castT = Context->getPointerType(Context->getTagDeclType(RD)); 5961 CastExpr *castExpr = NoTypeInfoCStyleCastExpr(Context, castT, 5962 CK_BitCast, 5963 IV->getBase()); 5964 // Don't forget the parens to enforce the proper binding. 5965 ParenExpr *PE = new (Context) ParenExpr(OldRange.getBegin(), 5966 OldRange.getEnd(), 5967 castExpr); 5968 if (IV->isFreeIvar() && 5969 declaresSameEntity(CurMethodDef->getClassInterface(), iFaceDecl->getDecl())) { 5970 MemberExpr *ME = new (Context) MemberExpr(PE, true, D, 5971 IV->getLocation(), 5972 D->getType(), 5973 VK_LValue, OK_Ordinary); 5974 Replacement = ME; 5975 } else { 5976 IV->setBase(PE); 5977 } 5978 } 5979 } else { // we are outside a method. 5980 assert(!IV->isFreeIvar() && "Cannot have a free standing ivar outside a method"); 5981 5982 // Explicit ivar refs need to have a cast inserted. 5983 // FIXME: consider sharing some of this code with the code above. 5984 if (BaseExpr->getType()->isObjCObjectPointerType()) { 5985 const ObjCInterfaceType *iFaceDecl = 5986 dyn_cast<ObjCInterfaceType>(BaseExpr->getType()->getPointeeType()); 5987 // lookup which class implements the instance variable. 5988 ObjCInterfaceDecl *clsDeclared = 0; 5989 iFaceDecl->getDecl()->lookupInstanceVariable(D->getIdentifier(), 5990 clsDeclared); 5991 assert(clsDeclared && "RewriteObjCIvarRefExpr(): Can't find class"); 5992 5993 // Synthesize an explicit cast to gain access to the ivar. 5994 std::string RecName = clsDeclared->getIdentifier()->getName(); 5995 RecName += "_IMPL"; 5996 IdentifierInfo *II = &Context->Idents.get(RecName); 5997 RecordDecl *RD = RecordDecl::Create(*Context, TTK_Struct, TUDecl, 5998 SourceLocation(), SourceLocation(), 5999 II); 6000 assert(RD && "RewriteObjCIvarRefExpr(): Can't find RecordDecl"); 6001 QualType castT = Context->getPointerType(Context->getTagDeclType(RD)); 6002 CastExpr *castExpr = NoTypeInfoCStyleCastExpr(Context, castT, 6003 CK_BitCast, 6004 IV->getBase()); 6005 // Don't forget the parens to enforce the proper binding. 6006 ParenExpr *PE = new (Context) ParenExpr(IV->getBase()->getLocStart(), 6007 IV->getBase()->getLocEnd(), castExpr); 6008 // Cannot delete IV->getBase(), since PE points to it. 6009 // Replace the old base with the cast. This is important when doing 6010 // embedded rewrites. For example, [newInv->_container addObject:0]. 6011 IV->setBase(PE); 6012 } 6013 } 6014 6015 ReplaceStmtWithRange(IV, Replacement, OldRange); 6016 return Replacement; 6017 } 6018 6019