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