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