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