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::SmallPtrSetImpl<const DeclContext *> &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 std::unique_ptr<ASTConsumer> 604 clang::CreateObjCRewriter(const std::string &InFile, raw_ostream *OS, 605 DiagnosticsEngine &Diags, const LangOptions &LOpts, 606 bool SilenceRewriteMacroWarning) { 607 return llvm::make_unique<RewriteObjCFragileABI>(InFile, OS, Diags, LOpts, 608 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 (ValueDecl *VD : ImportedBlockDecls) { 3386 S += "_Block_object_assign((void*)&dst->"; 3387 S += VD->getNameAsString(); 3388 S += ", (void*)src->"; 3389 S += VD->getNameAsString(); 3390 if (BlockByRefDeclsPtrSet.count(VD)) 3391 S += ", " + utostr(BLOCK_FIELD_IS_BYREF) + "/*BLOCK_FIELD_IS_BYREF*/);"; 3392 else if (VD->getType()->isBlockPointerType()) 3393 S += ", " + utostr(BLOCK_FIELD_IS_BLOCK) + "/*BLOCK_FIELD_IS_BLOCK*/);"; 3394 else 3395 S += ", " + utostr(BLOCK_FIELD_IS_OBJECT) + "/*BLOCK_FIELD_IS_OBJECT*/);"; 3396 } 3397 S += "}\n"; 3398 3399 S += "\nstatic void __"; 3400 S += funcName; 3401 S += "_block_dispose_" + utostr(i); 3402 S += "(" + StructRef; 3403 S += "*src) {"; 3404 for (ValueDecl *VD : ImportedBlockDecls) { 3405 S += "_Block_object_dispose((void*)src->"; 3406 S += VD->getNameAsString(); 3407 if (BlockByRefDeclsPtrSet.count(VD)) 3408 S += ", " + utostr(BLOCK_FIELD_IS_BYREF) + "/*BLOCK_FIELD_IS_BYREF*/);"; 3409 else if (VD->getType()->isBlockPointerType()) 3410 S += ", " + utostr(BLOCK_FIELD_IS_BLOCK) + "/*BLOCK_FIELD_IS_BLOCK*/);"; 3411 else 3412 S += ", " + utostr(BLOCK_FIELD_IS_OBJECT) + "/*BLOCK_FIELD_IS_OBJECT*/);"; 3413 } 3414 S += "}\n"; 3415 return S; 3416 } 3417 3418 std::string RewriteObjC::SynthesizeBlockImpl(BlockExpr *CE, std::string Tag, 3419 std::string Desc) { 3420 std::string S = "\nstruct " + Tag; 3421 std::string Constructor = " " + Tag; 3422 3423 S += " {\n struct __block_impl impl;\n"; 3424 S += " struct " + Desc; 3425 S += "* Desc;\n"; 3426 3427 Constructor += "(void *fp, "; // Invoke function pointer. 3428 Constructor += "struct " + Desc; // Descriptor pointer. 3429 Constructor += " *desc"; 3430 3431 if (BlockDeclRefs.size()) { 3432 // Output all "by copy" declarations. 3433 for (SmallVectorImpl<ValueDecl *>::iterator I = BlockByCopyDecls.begin(), 3434 E = BlockByCopyDecls.end(); I != E; ++I) { 3435 S += " "; 3436 std::string FieldName = (*I)->getNameAsString(); 3437 std::string ArgName = "_" + FieldName; 3438 // Handle nested closure invocation. For example: 3439 // 3440 // void (^myImportedBlock)(void); 3441 // myImportedBlock = ^(void) { setGlobalInt(x + y); }; 3442 // 3443 // void (^anotherBlock)(void); 3444 // anotherBlock = ^(void) { 3445 // myImportedBlock(); // import and invoke the closure 3446 // }; 3447 // 3448 if (isTopLevelBlockPointerType((*I)->getType())) { 3449 S += "struct __block_impl *"; 3450 Constructor += ", void *" + ArgName; 3451 } else { 3452 QualType QT = (*I)->getType(); 3453 if (HasLocalVariableExternalStorage(*I)) 3454 QT = Context->getPointerType(QT); 3455 QT.getAsStringInternal(FieldName, Context->getPrintingPolicy()); 3456 QT.getAsStringInternal(ArgName, Context->getPrintingPolicy()); 3457 Constructor += ", " + ArgName; 3458 } 3459 S += FieldName + ";\n"; 3460 } 3461 // Output all "by ref" declarations. 3462 for (SmallVectorImpl<ValueDecl *>::iterator I = BlockByRefDecls.begin(), 3463 E = BlockByRefDecls.end(); I != E; ++I) { 3464 S += " "; 3465 std::string FieldName = (*I)->getNameAsString(); 3466 std::string ArgName = "_" + FieldName; 3467 { 3468 std::string TypeString; 3469 RewriteByRefString(TypeString, FieldName, (*I)); 3470 TypeString += " *"; 3471 FieldName = TypeString + FieldName; 3472 ArgName = TypeString + ArgName; 3473 Constructor += ", " + ArgName; 3474 } 3475 S += FieldName + "; // by ref\n"; 3476 } 3477 // Finish writing the constructor. 3478 Constructor += ", int flags=0)"; 3479 // Initialize all "by copy" arguments. 3480 bool firsTime = true; 3481 for (SmallVectorImpl<ValueDecl *>::iterator I = BlockByCopyDecls.begin(), 3482 E = BlockByCopyDecls.end(); I != E; ++I) { 3483 std::string Name = (*I)->getNameAsString(); 3484 if (firsTime) { 3485 Constructor += " : "; 3486 firsTime = false; 3487 } 3488 else 3489 Constructor += ", "; 3490 if (isTopLevelBlockPointerType((*I)->getType())) 3491 Constructor += Name + "((struct __block_impl *)_" + Name + ")"; 3492 else 3493 Constructor += Name + "(_" + Name + ")"; 3494 } 3495 // Initialize all "by ref" arguments. 3496 for (SmallVectorImpl<ValueDecl *>::iterator I = BlockByRefDecls.begin(), 3497 E = BlockByRefDecls.end(); I != E; ++I) { 3498 std::string Name = (*I)->getNameAsString(); 3499 if (firsTime) { 3500 Constructor += " : "; 3501 firsTime = false; 3502 } 3503 else 3504 Constructor += ", "; 3505 Constructor += Name + "(_" + Name + "->__forwarding)"; 3506 } 3507 3508 Constructor += " {\n"; 3509 if (GlobalVarDecl) 3510 Constructor += " impl.isa = &_NSConcreteGlobalBlock;\n"; 3511 else 3512 Constructor += " impl.isa = &_NSConcreteStackBlock;\n"; 3513 Constructor += " impl.Flags = flags;\n impl.FuncPtr = fp;\n"; 3514 3515 Constructor += " Desc = desc;\n"; 3516 } else { 3517 // Finish writing the constructor. 3518 Constructor += ", int flags=0) {\n"; 3519 if (GlobalVarDecl) 3520 Constructor += " impl.isa = &_NSConcreteGlobalBlock;\n"; 3521 else 3522 Constructor += " impl.isa = &_NSConcreteStackBlock;\n"; 3523 Constructor += " impl.Flags = flags;\n impl.FuncPtr = fp;\n"; 3524 Constructor += " Desc = desc;\n"; 3525 } 3526 Constructor += " "; 3527 Constructor += "}\n"; 3528 S += Constructor; 3529 S += "};\n"; 3530 return S; 3531 } 3532 3533 std::string RewriteObjC::SynthesizeBlockDescriptor(std::string DescTag, 3534 std::string ImplTag, int i, 3535 StringRef FunName, 3536 unsigned hasCopy) { 3537 std::string S = "\nstatic struct " + DescTag; 3538 3539 S += " {\n unsigned long reserved;\n"; 3540 S += " unsigned long Block_size;\n"; 3541 if (hasCopy) { 3542 S += " void (*copy)(struct "; 3543 S += ImplTag; S += "*, struct "; 3544 S += ImplTag; S += "*);\n"; 3545 3546 S += " void (*dispose)(struct "; 3547 S += ImplTag; S += "*);\n"; 3548 } 3549 S += "} "; 3550 3551 S += DescTag + "_DATA = { 0, sizeof(struct "; 3552 S += ImplTag + ")"; 3553 if (hasCopy) { 3554 S += ", __" + FunName.str() + "_block_copy_" + utostr(i); 3555 S += ", __" + FunName.str() + "_block_dispose_" + utostr(i); 3556 } 3557 S += "};\n"; 3558 return S; 3559 } 3560 3561 void RewriteObjC::SynthesizeBlockLiterals(SourceLocation FunLocStart, 3562 StringRef FunName) { 3563 // Insert declaration for the function in which block literal is used. 3564 if (CurFunctionDeclToDeclareForBlock && !Blocks.empty()) 3565 RewriteBlockLiteralFunctionDecl(CurFunctionDeclToDeclareForBlock); 3566 bool RewriteSC = (GlobalVarDecl && 3567 !Blocks.empty() && 3568 GlobalVarDecl->getStorageClass() == SC_Static && 3569 GlobalVarDecl->getType().getCVRQualifiers()); 3570 if (RewriteSC) { 3571 std::string SC(" void __"); 3572 SC += GlobalVarDecl->getNameAsString(); 3573 SC += "() {}"; 3574 InsertText(FunLocStart, SC); 3575 } 3576 3577 // Insert closures that were part of the function. 3578 for (unsigned i = 0, count=0; i < Blocks.size(); i++) { 3579 CollectBlockDeclRefInfo(Blocks[i]); 3580 // Need to copy-in the inner copied-in variables not actually used in this 3581 // block. 3582 for (int j = 0; j < InnerDeclRefsCount[i]; j++) { 3583 DeclRefExpr *Exp = InnerDeclRefs[count++]; 3584 ValueDecl *VD = Exp->getDecl(); 3585 BlockDeclRefs.push_back(Exp); 3586 if (!VD->hasAttr<BlocksAttr>() && !BlockByCopyDeclsPtrSet.count(VD)) { 3587 BlockByCopyDeclsPtrSet.insert(VD); 3588 BlockByCopyDecls.push_back(VD); 3589 } 3590 if (VD->hasAttr<BlocksAttr>() && !BlockByRefDeclsPtrSet.count(VD)) { 3591 BlockByRefDeclsPtrSet.insert(VD); 3592 BlockByRefDecls.push_back(VD); 3593 } 3594 // imported objects in the inner blocks not used in the outer 3595 // blocks must be copied/disposed in the outer block as well. 3596 if (VD->hasAttr<BlocksAttr>() || 3597 VD->getType()->isObjCObjectPointerType() || 3598 VD->getType()->isBlockPointerType()) 3599 ImportedBlockDecls.insert(VD); 3600 } 3601 3602 std::string ImplTag = "__" + FunName.str() + "_block_impl_" + utostr(i); 3603 std::string DescTag = "__" + FunName.str() + "_block_desc_" + utostr(i); 3604 3605 std::string CI = SynthesizeBlockImpl(Blocks[i], ImplTag, DescTag); 3606 3607 InsertText(FunLocStart, CI); 3608 3609 std::string CF = SynthesizeBlockFunc(Blocks[i], i, FunName, ImplTag); 3610 3611 InsertText(FunLocStart, CF); 3612 3613 if (ImportedBlockDecls.size()) { 3614 std::string HF = SynthesizeBlockHelperFuncs(Blocks[i], i, FunName, ImplTag); 3615 InsertText(FunLocStart, HF); 3616 } 3617 std::string BD = SynthesizeBlockDescriptor(DescTag, ImplTag, i, FunName, 3618 ImportedBlockDecls.size() > 0); 3619 InsertText(FunLocStart, BD); 3620 3621 BlockDeclRefs.clear(); 3622 BlockByRefDecls.clear(); 3623 BlockByRefDeclsPtrSet.clear(); 3624 BlockByCopyDecls.clear(); 3625 BlockByCopyDeclsPtrSet.clear(); 3626 ImportedBlockDecls.clear(); 3627 } 3628 if (RewriteSC) { 3629 // Must insert any 'const/volatile/static here. Since it has been 3630 // removed as result of rewriting of block literals. 3631 std::string SC; 3632 if (GlobalVarDecl->getStorageClass() == SC_Static) 3633 SC = "static "; 3634 if (GlobalVarDecl->getType().isConstQualified()) 3635 SC += "const "; 3636 if (GlobalVarDecl->getType().isVolatileQualified()) 3637 SC += "volatile "; 3638 if (GlobalVarDecl->getType().isRestrictQualified()) 3639 SC += "restrict "; 3640 InsertText(FunLocStart, SC); 3641 } 3642 3643 Blocks.clear(); 3644 InnerDeclRefsCount.clear(); 3645 InnerDeclRefs.clear(); 3646 RewrittenBlockExprs.clear(); 3647 } 3648 3649 void RewriteObjC::InsertBlockLiteralsWithinFunction(FunctionDecl *FD) { 3650 SourceLocation FunLocStart = FD->getTypeSpecStartLoc(); 3651 StringRef FuncName = FD->getName(); 3652 3653 SynthesizeBlockLiterals(FunLocStart, FuncName); 3654 } 3655 3656 static void BuildUniqueMethodName(std::string &Name, 3657 ObjCMethodDecl *MD) { 3658 ObjCInterfaceDecl *IFace = MD->getClassInterface(); 3659 Name = IFace->getName(); 3660 Name += "__" + MD->getSelector().getAsString(); 3661 // Convert colons to underscores. 3662 std::string::size_type loc = 0; 3663 while ((loc = Name.find(":", loc)) != std::string::npos) 3664 Name.replace(loc, 1, "_"); 3665 } 3666 3667 void RewriteObjC::InsertBlockLiteralsWithinMethod(ObjCMethodDecl *MD) { 3668 //fprintf(stderr,"In InsertBlockLiteralsWitinMethod\n"); 3669 //SourceLocation FunLocStart = MD->getLocStart(); 3670 SourceLocation FunLocStart = MD->getLocStart(); 3671 std::string FuncName; 3672 BuildUniqueMethodName(FuncName, MD); 3673 SynthesizeBlockLiterals(FunLocStart, FuncName); 3674 } 3675 3676 void RewriteObjC::GetBlockDeclRefExprs(Stmt *S) { 3677 for (Stmt::child_range CI = S->children(); CI; ++CI) 3678 if (*CI) { 3679 if (BlockExpr *CBE = dyn_cast<BlockExpr>(*CI)) 3680 GetBlockDeclRefExprs(CBE->getBody()); 3681 else 3682 GetBlockDeclRefExprs(*CI); 3683 } 3684 // Handle specific things. 3685 if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(S)) { 3686 if (DRE->refersToEnclosingLocal()) { 3687 // FIXME: Handle enums. 3688 if (!isa<FunctionDecl>(DRE->getDecl())) 3689 BlockDeclRefs.push_back(DRE); 3690 if (HasLocalVariableExternalStorage(DRE->getDecl())) 3691 BlockDeclRefs.push_back(DRE); 3692 } 3693 } 3694 3695 return; 3696 } 3697 3698 void RewriteObjC::GetInnerBlockDeclRefExprs(Stmt *S, 3699 SmallVectorImpl<DeclRefExpr *> &InnerBlockDeclRefs, 3700 llvm::SmallPtrSetImpl<const DeclContext *> &InnerContexts) { 3701 for (Stmt::child_range CI = S->children(); CI; ++CI) 3702 if (*CI) { 3703 if (BlockExpr *CBE = dyn_cast<BlockExpr>(*CI)) { 3704 InnerContexts.insert(cast<DeclContext>(CBE->getBlockDecl())); 3705 GetInnerBlockDeclRefExprs(CBE->getBody(), 3706 InnerBlockDeclRefs, 3707 InnerContexts); 3708 } 3709 else 3710 GetInnerBlockDeclRefExprs(*CI, 3711 InnerBlockDeclRefs, 3712 InnerContexts); 3713 3714 } 3715 // Handle specific things. 3716 if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(S)) { 3717 if (DRE->refersToEnclosingLocal()) { 3718 if (!isa<FunctionDecl>(DRE->getDecl()) && 3719 !InnerContexts.count(DRE->getDecl()->getDeclContext())) 3720 InnerBlockDeclRefs.push_back(DRE); 3721 if (VarDecl *Var = dyn_cast<VarDecl>(DRE->getDecl())) 3722 if (Var->isFunctionOrMethodVarDecl()) 3723 ImportedLocalExternalDecls.insert(Var); 3724 } 3725 } 3726 3727 return; 3728 } 3729 3730 /// convertFunctionTypeOfBlocks - This routine converts a function type 3731 /// whose result type may be a block pointer or whose argument type(s) 3732 /// might be block pointers to an equivalent function type replacing 3733 /// all block pointers to function pointers. 3734 QualType RewriteObjC::convertFunctionTypeOfBlocks(const FunctionType *FT) { 3735 const FunctionProtoType *FTP = dyn_cast<FunctionProtoType>(FT); 3736 // FTP will be null for closures that don't take arguments. 3737 // Generate a funky cast. 3738 SmallVector<QualType, 8> ArgTypes; 3739 QualType Res = FT->getReturnType(); 3740 bool HasBlockType = convertBlockPointerToFunctionPointer(Res); 3741 3742 if (FTP) { 3743 for (auto &I : FTP->param_types()) { 3744 QualType t = I; 3745 // Make sure we convert "t (^)(...)" to "t (*)(...)". 3746 if (convertBlockPointerToFunctionPointer(t)) 3747 HasBlockType = true; 3748 ArgTypes.push_back(t); 3749 } 3750 } 3751 QualType FuncType; 3752 // FIXME. Does this work if block takes no argument but has a return type 3753 // which is of block type? 3754 if (HasBlockType) 3755 FuncType = getSimpleFunctionType(Res, ArgTypes); 3756 else FuncType = QualType(FT, 0); 3757 return FuncType; 3758 } 3759 3760 Stmt *RewriteObjC::SynthesizeBlockCall(CallExpr *Exp, const Expr *BlockExp) { 3761 // Navigate to relevant type information. 3762 const BlockPointerType *CPT = nullptr; 3763 3764 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(BlockExp)) { 3765 CPT = DRE->getType()->getAs<BlockPointerType>(); 3766 } else if (const MemberExpr *MExpr = dyn_cast<MemberExpr>(BlockExp)) { 3767 CPT = MExpr->getType()->getAs<BlockPointerType>(); 3768 } 3769 else if (const ParenExpr *PRE = dyn_cast<ParenExpr>(BlockExp)) { 3770 return SynthesizeBlockCall(Exp, PRE->getSubExpr()); 3771 } 3772 else if (const ImplicitCastExpr *IEXPR = dyn_cast<ImplicitCastExpr>(BlockExp)) 3773 CPT = IEXPR->getType()->getAs<BlockPointerType>(); 3774 else if (const ConditionalOperator *CEXPR = 3775 dyn_cast<ConditionalOperator>(BlockExp)) { 3776 Expr *LHSExp = CEXPR->getLHS(); 3777 Stmt *LHSStmt = SynthesizeBlockCall(Exp, LHSExp); 3778 Expr *RHSExp = CEXPR->getRHS(); 3779 Stmt *RHSStmt = SynthesizeBlockCall(Exp, RHSExp); 3780 Expr *CONDExp = CEXPR->getCond(); 3781 ConditionalOperator *CondExpr = 3782 new (Context) ConditionalOperator(CONDExp, 3783 SourceLocation(), cast<Expr>(LHSStmt), 3784 SourceLocation(), cast<Expr>(RHSStmt), 3785 Exp->getType(), VK_RValue, OK_Ordinary); 3786 return CondExpr; 3787 } else if (const ObjCIvarRefExpr *IRE = dyn_cast<ObjCIvarRefExpr>(BlockExp)) { 3788 CPT = IRE->getType()->getAs<BlockPointerType>(); 3789 } else if (const PseudoObjectExpr *POE 3790 = dyn_cast<PseudoObjectExpr>(BlockExp)) { 3791 CPT = POE->getType()->castAs<BlockPointerType>(); 3792 } else { 3793 assert(1 && "RewriteBlockClass: Bad type"); 3794 } 3795 assert(CPT && "RewriteBlockClass: Bad type"); 3796 const FunctionType *FT = CPT->getPointeeType()->getAs<FunctionType>(); 3797 assert(FT && "RewriteBlockClass: Bad type"); 3798 const FunctionProtoType *FTP = dyn_cast<FunctionProtoType>(FT); 3799 // FTP will be null for closures that don't take arguments. 3800 3801 RecordDecl *RD = RecordDecl::Create(*Context, TTK_Struct, TUDecl, 3802 SourceLocation(), SourceLocation(), 3803 &Context->Idents.get("__block_impl")); 3804 QualType PtrBlock = Context->getPointerType(Context->getTagDeclType(RD)); 3805 3806 // Generate a funky cast. 3807 SmallVector<QualType, 8> ArgTypes; 3808 3809 // Push the block argument type. 3810 ArgTypes.push_back(PtrBlock); 3811 if (FTP) { 3812 for (auto &I : FTP->param_types()) { 3813 QualType t = I; 3814 // Make sure we convert "t (^)(...)" to "t (*)(...)". 3815 if (!convertBlockPointerToFunctionPointer(t)) 3816 convertToUnqualifiedObjCType(t); 3817 ArgTypes.push_back(t); 3818 } 3819 } 3820 // Now do the pointer to function cast. 3821 QualType PtrToFuncCastType = getSimpleFunctionType(Exp->getType(), ArgTypes); 3822 3823 PtrToFuncCastType = Context->getPointerType(PtrToFuncCastType); 3824 3825 CastExpr *BlkCast = NoTypeInfoCStyleCastExpr(Context, PtrBlock, 3826 CK_BitCast, 3827 const_cast<Expr*>(BlockExp)); 3828 // Don't forget the parens to enforce the proper binding. 3829 ParenExpr *PE = new (Context) ParenExpr(SourceLocation(), SourceLocation(), 3830 BlkCast); 3831 //PE->dump(); 3832 3833 FieldDecl *FD = FieldDecl::Create(*Context, nullptr, SourceLocation(), 3834 SourceLocation(), 3835 &Context->Idents.get("FuncPtr"), 3836 Context->VoidPtrTy, nullptr, 3837 /*BitWidth=*/nullptr, /*Mutable=*/true, 3838 ICIS_NoInit); 3839 MemberExpr *ME = new (Context) MemberExpr(PE, true, FD, SourceLocation(), 3840 FD->getType(), VK_LValue, 3841 OK_Ordinary); 3842 3843 3844 CastExpr *FunkCast = NoTypeInfoCStyleCastExpr(Context, PtrToFuncCastType, 3845 CK_BitCast, ME); 3846 PE = new (Context) ParenExpr(SourceLocation(), SourceLocation(), FunkCast); 3847 3848 SmallVector<Expr*, 8> BlkExprs; 3849 // Add the implicit argument. 3850 BlkExprs.push_back(BlkCast); 3851 // Add the user arguments. 3852 for (CallExpr::arg_iterator I = Exp->arg_begin(), 3853 E = Exp->arg_end(); I != E; ++I) { 3854 BlkExprs.push_back(*I); 3855 } 3856 CallExpr *CE = new (Context) CallExpr(*Context, PE, BlkExprs, 3857 Exp->getType(), VK_RValue, 3858 SourceLocation()); 3859 return CE; 3860 } 3861 3862 // We need to return the rewritten expression to handle cases where the 3863 // BlockDeclRefExpr is embedded in another expression being rewritten. 3864 // For example: 3865 // 3866 // int main() { 3867 // __block Foo *f; 3868 // __block int i; 3869 // 3870 // void (^myblock)() = ^() { 3871 // [f test]; // f is a BlockDeclRefExpr embedded in a message (which is being rewritten). 3872 // i = 77; 3873 // }; 3874 //} 3875 Stmt *RewriteObjC::RewriteBlockDeclRefExpr(DeclRefExpr *DeclRefExp) { 3876 // Rewrite the byref variable into BYREFVAR->__forwarding->BYREFVAR 3877 // for each DeclRefExp where BYREFVAR is name of the variable. 3878 ValueDecl *VD = DeclRefExp->getDecl(); 3879 bool isArrow = DeclRefExp->refersToEnclosingLocal(); 3880 3881 FieldDecl *FD = FieldDecl::Create(*Context, nullptr, SourceLocation(), 3882 SourceLocation(), 3883 &Context->Idents.get("__forwarding"), 3884 Context->VoidPtrTy, nullptr, 3885 /*BitWidth=*/nullptr, /*Mutable=*/true, 3886 ICIS_NoInit); 3887 MemberExpr *ME = new (Context) MemberExpr(DeclRefExp, isArrow, 3888 FD, SourceLocation(), 3889 FD->getType(), VK_LValue, 3890 OK_Ordinary); 3891 3892 StringRef Name = VD->getName(); 3893 FD = FieldDecl::Create(*Context, nullptr, SourceLocation(), SourceLocation(), 3894 &Context->Idents.get(Name), 3895 Context->VoidPtrTy, nullptr, 3896 /*BitWidth=*/nullptr, /*Mutable=*/true, 3897 ICIS_NoInit); 3898 ME = new (Context) MemberExpr(ME, true, FD, SourceLocation(), 3899 DeclRefExp->getType(), VK_LValue, OK_Ordinary); 3900 3901 3902 3903 // Need parens to enforce precedence. 3904 ParenExpr *PE = new (Context) ParenExpr(DeclRefExp->getExprLoc(), 3905 DeclRefExp->getExprLoc(), 3906 ME); 3907 ReplaceStmt(DeclRefExp, PE); 3908 return PE; 3909 } 3910 3911 // Rewrites the imported local variable V with external storage 3912 // (static, extern, etc.) as *V 3913 // 3914 Stmt *RewriteObjC::RewriteLocalVariableExternalStorage(DeclRefExpr *DRE) { 3915 ValueDecl *VD = DRE->getDecl(); 3916 if (VarDecl *Var = dyn_cast<VarDecl>(VD)) 3917 if (!ImportedLocalExternalDecls.count(Var)) 3918 return DRE; 3919 Expr *Exp = new (Context) UnaryOperator(DRE, UO_Deref, DRE->getType(), 3920 VK_LValue, OK_Ordinary, 3921 DRE->getLocation()); 3922 // Need parens to enforce precedence. 3923 ParenExpr *PE = new (Context) ParenExpr(SourceLocation(), SourceLocation(), 3924 Exp); 3925 ReplaceStmt(DRE, PE); 3926 return PE; 3927 } 3928 3929 void RewriteObjC::RewriteCastExpr(CStyleCastExpr *CE) { 3930 SourceLocation LocStart = CE->getLParenLoc(); 3931 SourceLocation LocEnd = CE->getRParenLoc(); 3932 3933 // Need to avoid trying to rewrite synthesized casts. 3934 if (LocStart.isInvalid()) 3935 return; 3936 // Need to avoid trying to rewrite casts contained in macros. 3937 if (!Rewriter::isRewritable(LocStart) || !Rewriter::isRewritable(LocEnd)) 3938 return; 3939 3940 const char *startBuf = SM->getCharacterData(LocStart); 3941 const char *endBuf = SM->getCharacterData(LocEnd); 3942 QualType QT = CE->getType(); 3943 const Type* TypePtr = QT->getAs<Type>(); 3944 if (isa<TypeOfExprType>(TypePtr)) { 3945 const TypeOfExprType *TypeOfExprTypePtr = cast<TypeOfExprType>(TypePtr); 3946 QT = TypeOfExprTypePtr->getUnderlyingExpr()->getType(); 3947 std::string TypeAsString = "("; 3948 RewriteBlockPointerType(TypeAsString, QT); 3949 TypeAsString += ")"; 3950 ReplaceText(LocStart, endBuf-startBuf+1, TypeAsString); 3951 return; 3952 } 3953 // advance the location to startArgList. 3954 const char *argPtr = startBuf; 3955 3956 while (*argPtr++ && (argPtr < endBuf)) { 3957 switch (*argPtr) { 3958 case '^': 3959 // Replace the '^' with '*'. 3960 LocStart = LocStart.getLocWithOffset(argPtr-startBuf); 3961 ReplaceText(LocStart, 1, "*"); 3962 break; 3963 } 3964 } 3965 return; 3966 } 3967 3968 void RewriteObjC::RewriteBlockPointerFunctionArgs(FunctionDecl *FD) { 3969 SourceLocation DeclLoc = FD->getLocation(); 3970 unsigned parenCount = 0; 3971 3972 // We have 1 or more arguments that have closure pointers. 3973 const char *startBuf = SM->getCharacterData(DeclLoc); 3974 const char *startArgList = strchr(startBuf, '('); 3975 3976 assert((*startArgList == '(') && "Rewriter fuzzy parser confused"); 3977 3978 parenCount++; 3979 // advance the location to startArgList. 3980 DeclLoc = DeclLoc.getLocWithOffset(startArgList-startBuf); 3981 assert((DeclLoc.isValid()) && "Invalid DeclLoc"); 3982 3983 const char *argPtr = startArgList; 3984 3985 while (*argPtr++ && parenCount) { 3986 switch (*argPtr) { 3987 case '^': 3988 // Replace the '^' with '*'. 3989 DeclLoc = DeclLoc.getLocWithOffset(argPtr-startArgList); 3990 ReplaceText(DeclLoc, 1, "*"); 3991 break; 3992 case '(': 3993 parenCount++; 3994 break; 3995 case ')': 3996 parenCount--; 3997 break; 3998 } 3999 } 4000 return; 4001 } 4002 4003 bool RewriteObjC::PointerTypeTakesAnyBlockArguments(QualType QT) { 4004 const FunctionProtoType *FTP; 4005 const PointerType *PT = QT->getAs<PointerType>(); 4006 if (PT) { 4007 FTP = PT->getPointeeType()->getAs<FunctionProtoType>(); 4008 } else { 4009 const BlockPointerType *BPT = QT->getAs<BlockPointerType>(); 4010 assert(BPT && "BlockPointerTypeTakeAnyBlockArguments(): not a block pointer type"); 4011 FTP = BPT->getPointeeType()->getAs<FunctionProtoType>(); 4012 } 4013 if (FTP) { 4014 for (const auto &I : FTP->param_types()) 4015 if (isTopLevelBlockPointerType(I)) 4016 return true; 4017 } 4018 return false; 4019 } 4020 4021 bool RewriteObjC::PointerTypeTakesAnyObjCQualifiedType(QualType QT) { 4022 const FunctionProtoType *FTP; 4023 const PointerType *PT = QT->getAs<PointerType>(); 4024 if (PT) { 4025 FTP = PT->getPointeeType()->getAs<FunctionProtoType>(); 4026 } else { 4027 const BlockPointerType *BPT = QT->getAs<BlockPointerType>(); 4028 assert(BPT && "BlockPointerTypeTakeAnyBlockArguments(): not a block pointer type"); 4029 FTP = BPT->getPointeeType()->getAs<FunctionProtoType>(); 4030 } 4031 if (FTP) { 4032 for (const auto &I : FTP->param_types()) { 4033 if (I->isObjCQualifiedIdType()) 4034 return true; 4035 if (I->isObjCObjectPointerType() && 4036 I->getPointeeType()->isObjCQualifiedInterfaceType()) 4037 return true; 4038 } 4039 4040 } 4041 return false; 4042 } 4043 4044 void RewriteObjC::GetExtentOfArgList(const char *Name, const char *&LParen, 4045 const char *&RParen) { 4046 const char *argPtr = strchr(Name, '('); 4047 assert((*argPtr == '(') && "Rewriter fuzzy parser confused"); 4048 4049 LParen = argPtr; // output the start. 4050 argPtr++; // skip past the left paren. 4051 unsigned parenCount = 1; 4052 4053 while (*argPtr && parenCount) { 4054 switch (*argPtr) { 4055 case '(': parenCount++; break; 4056 case ')': parenCount--; break; 4057 default: break; 4058 } 4059 if (parenCount) argPtr++; 4060 } 4061 assert((*argPtr == ')') && "Rewriter fuzzy parser confused"); 4062 RParen = argPtr; // output the end 4063 } 4064 4065 void RewriteObjC::RewriteBlockPointerDecl(NamedDecl *ND) { 4066 if (FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) { 4067 RewriteBlockPointerFunctionArgs(FD); 4068 return; 4069 } 4070 // Handle Variables and Typedefs. 4071 SourceLocation DeclLoc = ND->getLocation(); 4072 QualType DeclT; 4073 if (VarDecl *VD = dyn_cast<VarDecl>(ND)) 4074 DeclT = VD->getType(); 4075 else if (TypedefNameDecl *TDD = dyn_cast<TypedefNameDecl>(ND)) 4076 DeclT = TDD->getUnderlyingType(); 4077 else if (FieldDecl *FD = dyn_cast<FieldDecl>(ND)) 4078 DeclT = FD->getType(); 4079 else 4080 llvm_unreachable("RewriteBlockPointerDecl(): Decl type not yet handled"); 4081 4082 const char *startBuf = SM->getCharacterData(DeclLoc); 4083 const char *endBuf = startBuf; 4084 // scan backward (from the decl location) for the end of the previous decl. 4085 while (*startBuf != '^' && *startBuf != ';' && startBuf != MainFileStart) 4086 startBuf--; 4087 SourceLocation Start = DeclLoc.getLocWithOffset(startBuf-endBuf); 4088 std::string buf; 4089 unsigned OrigLength=0; 4090 // *startBuf != '^' if we are dealing with a pointer to function that 4091 // may take block argument types (which will be handled below). 4092 if (*startBuf == '^') { 4093 // Replace the '^' with '*', computing a negative offset. 4094 buf = '*'; 4095 startBuf++; 4096 OrigLength++; 4097 } 4098 while (*startBuf != ')') { 4099 buf += *startBuf; 4100 startBuf++; 4101 OrigLength++; 4102 } 4103 buf += ')'; 4104 OrigLength++; 4105 4106 if (PointerTypeTakesAnyBlockArguments(DeclT) || 4107 PointerTypeTakesAnyObjCQualifiedType(DeclT)) { 4108 // Replace the '^' with '*' for arguments. 4109 // Replace id<P> with id/*<>*/ 4110 DeclLoc = ND->getLocation(); 4111 startBuf = SM->getCharacterData(DeclLoc); 4112 const char *argListBegin, *argListEnd; 4113 GetExtentOfArgList(startBuf, argListBegin, argListEnd); 4114 while (argListBegin < argListEnd) { 4115 if (*argListBegin == '^') 4116 buf += '*'; 4117 else if (*argListBegin == '<') { 4118 buf += "/*"; 4119 buf += *argListBegin++; 4120 OrigLength++; 4121 while (*argListBegin != '>') { 4122 buf += *argListBegin++; 4123 OrigLength++; 4124 } 4125 buf += *argListBegin; 4126 buf += "*/"; 4127 } 4128 else 4129 buf += *argListBegin; 4130 argListBegin++; 4131 OrigLength++; 4132 } 4133 buf += ')'; 4134 OrigLength++; 4135 } 4136 ReplaceText(Start, OrigLength, buf); 4137 4138 return; 4139 } 4140 4141 4142 /// SynthesizeByrefCopyDestroyHelper - This routine synthesizes: 4143 /// void __Block_byref_id_object_copy(struct Block_byref_id_object *dst, 4144 /// struct Block_byref_id_object *src) { 4145 /// _Block_object_assign (&_dest->object, _src->object, 4146 /// BLOCK_BYREF_CALLER | BLOCK_FIELD_IS_OBJECT 4147 /// [|BLOCK_FIELD_IS_WEAK]) // object 4148 /// _Block_object_assign(&_dest->object, _src->object, 4149 /// BLOCK_BYREF_CALLER | BLOCK_FIELD_IS_BLOCK 4150 /// [|BLOCK_FIELD_IS_WEAK]) // block 4151 /// } 4152 /// And: 4153 /// void __Block_byref_id_object_dispose(struct Block_byref_id_object *_src) { 4154 /// _Block_object_dispose(_src->object, 4155 /// BLOCK_BYREF_CALLER | BLOCK_FIELD_IS_OBJECT 4156 /// [|BLOCK_FIELD_IS_WEAK]) // object 4157 /// _Block_object_dispose(_src->object, 4158 /// BLOCK_BYREF_CALLER | BLOCK_FIELD_IS_BLOCK 4159 /// [|BLOCK_FIELD_IS_WEAK]) // block 4160 /// } 4161 4162 std::string RewriteObjC::SynthesizeByrefCopyDestroyHelper(VarDecl *VD, 4163 int flag) { 4164 std::string S; 4165 if (CopyDestroyCache.count(flag)) 4166 return S; 4167 CopyDestroyCache.insert(flag); 4168 S = "static void __Block_byref_id_object_copy_"; 4169 S += utostr(flag); 4170 S += "(void *dst, void *src) {\n"; 4171 4172 // offset into the object pointer is computed as: 4173 // void * + void* + int + int + void* + void * 4174 unsigned IntSize = 4175 static_cast<unsigned>(Context->getTypeSize(Context->IntTy)); 4176 unsigned VoidPtrSize = 4177 static_cast<unsigned>(Context->getTypeSize(Context->VoidPtrTy)); 4178 4179 unsigned offset = (VoidPtrSize*4 + IntSize + IntSize)/Context->getCharWidth(); 4180 S += " _Block_object_assign((char*)dst + "; 4181 S += utostr(offset); 4182 S += ", *(void * *) ((char*)src + "; 4183 S += utostr(offset); 4184 S += "), "; 4185 S += utostr(flag); 4186 S += ");\n}\n"; 4187 4188 S += "static void __Block_byref_id_object_dispose_"; 4189 S += utostr(flag); 4190 S += "(void *src) {\n"; 4191 S += " _Block_object_dispose(*(void * *) ((char*)src + "; 4192 S += utostr(offset); 4193 S += "), "; 4194 S += utostr(flag); 4195 S += ");\n}\n"; 4196 return S; 4197 } 4198 4199 /// RewriteByRefVar - For each __block typex ND variable this routine transforms 4200 /// the declaration into: 4201 /// struct __Block_byref_ND { 4202 /// void *__isa; // NULL for everything except __weak pointers 4203 /// struct __Block_byref_ND *__forwarding; 4204 /// int32_t __flags; 4205 /// int32_t __size; 4206 /// void *__Block_byref_id_object_copy; // If variable is __block ObjC object 4207 /// void *__Block_byref_id_object_dispose; // If variable is __block ObjC object 4208 /// typex ND; 4209 /// }; 4210 /// 4211 /// It then replaces declaration of ND variable with: 4212 /// struct __Block_byref_ND ND = {__isa=0B, __forwarding=&ND, __flags=some_flag, 4213 /// __size=sizeof(struct __Block_byref_ND), 4214 /// ND=initializer-if-any}; 4215 /// 4216 /// 4217 void RewriteObjC::RewriteByRefVar(VarDecl *ND) { 4218 // Insert declaration for the function in which block literal is 4219 // used. 4220 if (CurFunctionDeclToDeclareForBlock) 4221 RewriteBlockLiteralFunctionDecl(CurFunctionDeclToDeclareForBlock); 4222 int flag = 0; 4223 int isa = 0; 4224 SourceLocation DeclLoc = ND->getTypeSpecStartLoc(); 4225 if (DeclLoc.isInvalid()) 4226 // If type location is missing, it is because of missing type (a warning). 4227 // Use variable's location which is good for this case. 4228 DeclLoc = ND->getLocation(); 4229 const char *startBuf = SM->getCharacterData(DeclLoc); 4230 SourceLocation X = ND->getLocEnd(); 4231 X = SM->getExpansionLoc(X); 4232 const char *endBuf = SM->getCharacterData(X); 4233 std::string Name(ND->getNameAsString()); 4234 std::string ByrefType; 4235 RewriteByRefString(ByrefType, Name, ND, true); 4236 ByrefType += " {\n"; 4237 ByrefType += " void *__isa;\n"; 4238 RewriteByRefString(ByrefType, Name, ND); 4239 ByrefType += " *__forwarding;\n"; 4240 ByrefType += " int __flags;\n"; 4241 ByrefType += " int __size;\n"; 4242 // Add void *__Block_byref_id_object_copy; 4243 // void *__Block_byref_id_object_dispose; if needed. 4244 QualType Ty = ND->getType(); 4245 bool HasCopyAndDispose = Context->BlockRequiresCopying(Ty, ND); 4246 if (HasCopyAndDispose) { 4247 ByrefType += " void (*__Block_byref_id_object_copy)(void*, void*);\n"; 4248 ByrefType += " void (*__Block_byref_id_object_dispose)(void*);\n"; 4249 } 4250 4251 QualType T = Ty; 4252 (void)convertBlockPointerToFunctionPointer(T); 4253 T.getAsStringInternal(Name, Context->getPrintingPolicy()); 4254 4255 ByrefType += " " + Name + ";\n"; 4256 ByrefType += "};\n"; 4257 // Insert this type in global scope. It is needed by helper function. 4258 SourceLocation FunLocStart; 4259 if (CurFunctionDef) 4260 FunLocStart = CurFunctionDef->getTypeSpecStartLoc(); 4261 else { 4262 assert(CurMethodDef && "RewriteByRefVar - CurMethodDef is null"); 4263 FunLocStart = CurMethodDef->getLocStart(); 4264 } 4265 InsertText(FunLocStart, ByrefType); 4266 if (Ty.isObjCGCWeak()) { 4267 flag |= BLOCK_FIELD_IS_WEAK; 4268 isa = 1; 4269 } 4270 4271 if (HasCopyAndDispose) { 4272 flag = BLOCK_BYREF_CALLER; 4273 QualType Ty = ND->getType(); 4274 // FIXME. Handle __weak variable (BLOCK_FIELD_IS_WEAK) as well. 4275 if (Ty->isBlockPointerType()) 4276 flag |= BLOCK_FIELD_IS_BLOCK; 4277 else 4278 flag |= BLOCK_FIELD_IS_OBJECT; 4279 std::string HF = SynthesizeByrefCopyDestroyHelper(ND, flag); 4280 if (!HF.empty()) 4281 InsertText(FunLocStart, HF); 4282 } 4283 4284 // struct __Block_byref_ND ND = 4285 // {0, &ND, some_flag, __size=sizeof(struct __Block_byref_ND), 4286 // initializer-if-any}; 4287 bool hasInit = (ND->getInit() != nullptr); 4288 unsigned flags = 0; 4289 if (HasCopyAndDispose) 4290 flags |= BLOCK_HAS_COPY_DISPOSE; 4291 Name = ND->getNameAsString(); 4292 ByrefType.clear(); 4293 RewriteByRefString(ByrefType, Name, ND); 4294 std::string ForwardingCastType("("); 4295 ForwardingCastType += ByrefType + " *)"; 4296 if (!hasInit) { 4297 ByrefType += " " + Name + " = {(void*)"; 4298 ByrefType += utostr(isa); 4299 ByrefType += "," + ForwardingCastType + "&" + Name + ", "; 4300 ByrefType += utostr(flags); 4301 ByrefType += ", "; 4302 ByrefType += "sizeof("; 4303 RewriteByRefString(ByrefType, Name, ND); 4304 ByrefType += ")"; 4305 if (HasCopyAndDispose) { 4306 ByrefType += ", __Block_byref_id_object_copy_"; 4307 ByrefType += utostr(flag); 4308 ByrefType += ", __Block_byref_id_object_dispose_"; 4309 ByrefType += utostr(flag); 4310 } 4311 ByrefType += "};\n"; 4312 unsigned nameSize = Name.size(); 4313 // for block or function pointer declaration. Name is aleady 4314 // part of the declaration. 4315 if (Ty->isBlockPointerType() || Ty->isFunctionPointerType()) 4316 nameSize = 1; 4317 ReplaceText(DeclLoc, endBuf-startBuf+nameSize, ByrefType); 4318 } 4319 else { 4320 SourceLocation startLoc; 4321 Expr *E = ND->getInit(); 4322 if (const CStyleCastExpr *ECE = dyn_cast<CStyleCastExpr>(E)) 4323 startLoc = ECE->getLParenLoc(); 4324 else 4325 startLoc = E->getLocStart(); 4326 startLoc = SM->getExpansionLoc(startLoc); 4327 endBuf = SM->getCharacterData(startLoc); 4328 ByrefType += " " + Name; 4329 ByrefType += " = {(void*)"; 4330 ByrefType += utostr(isa); 4331 ByrefType += "," + ForwardingCastType + "&" + Name + ", "; 4332 ByrefType += utostr(flags); 4333 ByrefType += ", "; 4334 ByrefType += "sizeof("; 4335 RewriteByRefString(ByrefType, Name, ND); 4336 ByrefType += "), "; 4337 if (HasCopyAndDispose) { 4338 ByrefType += "__Block_byref_id_object_copy_"; 4339 ByrefType += utostr(flag); 4340 ByrefType += ", __Block_byref_id_object_dispose_"; 4341 ByrefType += utostr(flag); 4342 ByrefType += ", "; 4343 } 4344 ReplaceText(DeclLoc, endBuf-startBuf, ByrefType); 4345 4346 // Complete the newly synthesized compound expression by inserting a right 4347 // curly brace before the end of the declaration. 4348 // FIXME: This approach avoids rewriting the initializer expression. It 4349 // also assumes there is only one declarator. For example, the following 4350 // isn't currently supported by this routine (in general): 4351 // 4352 // double __block BYREFVAR = 1.34, BYREFVAR2 = 1.37; 4353 // 4354 const char *startInitializerBuf = SM->getCharacterData(startLoc); 4355 const char *semiBuf = strchr(startInitializerBuf, ';'); 4356 assert((*semiBuf == ';') && "RewriteByRefVar: can't find ';'"); 4357 SourceLocation semiLoc = 4358 startLoc.getLocWithOffset(semiBuf-startInitializerBuf); 4359 4360 InsertText(semiLoc, "}"); 4361 } 4362 return; 4363 } 4364 4365 void RewriteObjC::CollectBlockDeclRefInfo(BlockExpr *Exp) { 4366 // Add initializers for any closure decl refs. 4367 GetBlockDeclRefExprs(Exp->getBody()); 4368 if (BlockDeclRefs.size()) { 4369 // Unique all "by copy" declarations. 4370 for (unsigned i = 0; i < BlockDeclRefs.size(); i++) 4371 if (!BlockDeclRefs[i]->getDecl()->hasAttr<BlocksAttr>()) { 4372 if (!BlockByCopyDeclsPtrSet.count(BlockDeclRefs[i]->getDecl())) { 4373 BlockByCopyDeclsPtrSet.insert(BlockDeclRefs[i]->getDecl()); 4374 BlockByCopyDecls.push_back(BlockDeclRefs[i]->getDecl()); 4375 } 4376 } 4377 // Unique all "by ref" declarations. 4378 for (unsigned i = 0; i < BlockDeclRefs.size(); i++) 4379 if (BlockDeclRefs[i]->getDecl()->hasAttr<BlocksAttr>()) { 4380 if (!BlockByRefDeclsPtrSet.count(BlockDeclRefs[i]->getDecl())) { 4381 BlockByRefDeclsPtrSet.insert(BlockDeclRefs[i]->getDecl()); 4382 BlockByRefDecls.push_back(BlockDeclRefs[i]->getDecl()); 4383 } 4384 } 4385 // Find any imported blocks...they will need special attention. 4386 for (unsigned i = 0; i < BlockDeclRefs.size(); i++) 4387 if (BlockDeclRefs[i]->getDecl()->hasAttr<BlocksAttr>() || 4388 BlockDeclRefs[i]->getType()->isObjCObjectPointerType() || 4389 BlockDeclRefs[i]->getType()->isBlockPointerType()) 4390 ImportedBlockDecls.insert(BlockDeclRefs[i]->getDecl()); 4391 } 4392 } 4393 4394 FunctionDecl *RewriteObjC::SynthBlockInitFunctionDecl(StringRef name) { 4395 IdentifierInfo *ID = &Context->Idents.get(name); 4396 QualType FType = Context->getFunctionNoProtoType(Context->VoidPtrTy); 4397 return FunctionDecl::Create(*Context, TUDecl, SourceLocation(), 4398 SourceLocation(), ID, FType, nullptr, SC_Extern, 4399 false, false); 4400 } 4401 4402 Stmt *RewriteObjC::SynthBlockInitExpr(BlockExpr *Exp, 4403 const SmallVectorImpl<DeclRefExpr *> &InnerBlockDeclRefs) { 4404 const BlockDecl *block = Exp->getBlockDecl(); 4405 Blocks.push_back(Exp); 4406 4407 CollectBlockDeclRefInfo(Exp); 4408 4409 // Add inner imported variables now used in current block. 4410 int countOfInnerDecls = 0; 4411 if (!InnerBlockDeclRefs.empty()) { 4412 for (unsigned i = 0; i < InnerBlockDeclRefs.size(); i++) { 4413 DeclRefExpr *Exp = InnerBlockDeclRefs[i]; 4414 ValueDecl *VD = Exp->getDecl(); 4415 if (!VD->hasAttr<BlocksAttr>() && !BlockByCopyDeclsPtrSet.count(VD)) { 4416 // We need to save the copied-in variables in nested 4417 // blocks because it is needed at the end for some of the API generations. 4418 // See SynthesizeBlockLiterals routine. 4419 InnerDeclRefs.push_back(Exp); countOfInnerDecls++; 4420 BlockDeclRefs.push_back(Exp); 4421 BlockByCopyDeclsPtrSet.insert(VD); 4422 BlockByCopyDecls.push_back(VD); 4423 } 4424 if (VD->hasAttr<BlocksAttr>() && !BlockByRefDeclsPtrSet.count(VD)) { 4425 InnerDeclRefs.push_back(Exp); countOfInnerDecls++; 4426 BlockDeclRefs.push_back(Exp); 4427 BlockByRefDeclsPtrSet.insert(VD); 4428 BlockByRefDecls.push_back(VD); 4429 } 4430 } 4431 // Find any imported blocks...they will need special attention. 4432 for (unsigned i = 0; i < InnerBlockDeclRefs.size(); i++) 4433 if (InnerBlockDeclRefs[i]->getDecl()->hasAttr<BlocksAttr>() || 4434 InnerBlockDeclRefs[i]->getType()->isObjCObjectPointerType() || 4435 InnerBlockDeclRefs[i]->getType()->isBlockPointerType()) 4436 ImportedBlockDecls.insert(InnerBlockDeclRefs[i]->getDecl()); 4437 } 4438 InnerDeclRefsCount.push_back(countOfInnerDecls); 4439 4440 std::string FuncName; 4441 4442 if (CurFunctionDef) 4443 FuncName = CurFunctionDef->getNameAsString(); 4444 else if (CurMethodDef) 4445 BuildUniqueMethodName(FuncName, CurMethodDef); 4446 else if (GlobalVarDecl) 4447 FuncName = std::string(GlobalVarDecl->getNameAsString()); 4448 4449 std::string BlockNumber = utostr(Blocks.size()-1); 4450 4451 std::string Tag = "__" + FuncName + "_block_impl_" + BlockNumber; 4452 std::string Func = "__" + FuncName + "_block_func_" + BlockNumber; 4453 4454 // Get a pointer to the function type so we can cast appropriately. 4455 QualType BFT = convertFunctionTypeOfBlocks(Exp->getFunctionType()); 4456 QualType FType = Context->getPointerType(BFT); 4457 4458 FunctionDecl *FD; 4459 Expr *NewRep; 4460 4461 // Simulate a constructor call... 4462 FD = SynthBlockInitFunctionDecl(Tag); 4463 DeclRefExpr *DRE = new (Context) DeclRefExpr(FD, false, FType, VK_RValue, 4464 SourceLocation()); 4465 4466 SmallVector<Expr*, 4> InitExprs; 4467 4468 // Initialize the block function. 4469 FD = SynthBlockInitFunctionDecl(Func); 4470 DeclRefExpr *Arg = new (Context) DeclRefExpr(FD, false, FD->getType(), 4471 VK_LValue, SourceLocation()); 4472 CastExpr *castExpr = NoTypeInfoCStyleCastExpr(Context, Context->VoidPtrTy, 4473 CK_BitCast, Arg); 4474 InitExprs.push_back(castExpr); 4475 4476 // Initialize the block descriptor. 4477 std::string DescData = "__" + FuncName + "_block_desc_" + BlockNumber + "_DATA"; 4478 4479 VarDecl *NewVD = VarDecl::Create(*Context, TUDecl, 4480 SourceLocation(), SourceLocation(), 4481 &Context->Idents.get(DescData.c_str()), 4482 Context->VoidPtrTy, nullptr, 4483 SC_Static); 4484 UnaryOperator *DescRefExpr = 4485 new (Context) UnaryOperator(new (Context) DeclRefExpr(NewVD, false, 4486 Context->VoidPtrTy, 4487 VK_LValue, 4488 SourceLocation()), 4489 UO_AddrOf, 4490 Context->getPointerType(Context->VoidPtrTy), 4491 VK_RValue, OK_Ordinary, 4492 SourceLocation()); 4493 InitExprs.push_back(DescRefExpr); 4494 4495 // Add initializers for any closure decl refs. 4496 if (BlockDeclRefs.size()) { 4497 Expr *Exp; 4498 // Output all "by copy" declarations. 4499 for (SmallVectorImpl<ValueDecl *>::iterator I = BlockByCopyDecls.begin(), 4500 E = BlockByCopyDecls.end(); I != E; ++I) { 4501 if (isObjCType((*I)->getType())) { 4502 // FIXME: Conform to ABI ([[obj retain] autorelease]). 4503 FD = SynthBlockInitFunctionDecl((*I)->getName()); 4504 Exp = new (Context) DeclRefExpr(FD, false, FD->getType(), VK_LValue, 4505 SourceLocation()); 4506 if (HasLocalVariableExternalStorage(*I)) { 4507 QualType QT = (*I)->getType(); 4508 QT = Context->getPointerType(QT); 4509 Exp = new (Context) UnaryOperator(Exp, UO_AddrOf, QT, VK_RValue, 4510 OK_Ordinary, SourceLocation()); 4511 } 4512 } else if (isTopLevelBlockPointerType((*I)->getType())) { 4513 FD = SynthBlockInitFunctionDecl((*I)->getName()); 4514 Arg = new (Context) DeclRefExpr(FD, false, FD->getType(), VK_LValue, 4515 SourceLocation()); 4516 Exp = NoTypeInfoCStyleCastExpr(Context, Context->VoidPtrTy, 4517 CK_BitCast, Arg); 4518 } else { 4519 FD = SynthBlockInitFunctionDecl((*I)->getName()); 4520 Exp = new (Context) DeclRefExpr(FD, false, FD->getType(), VK_LValue, 4521 SourceLocation()); 4522 if (HasLocalVariableExternalStorage(*I)) { 4523 QualType QT = (*I)->getType(); 4524 QT = Context->getPointerType(QT); 4525 Exp = new (Context) UnaryOperator(Exp, UO_AddrOf, QT, VK_RValue, 4526 OK_Ordinary, SourceLocation()); 4527 } 4528 4529 } 4530 InitExprs.push_back(Exp); 4531 } 4532 // Output all "by ref" declarations. 4533 for (SmallVectorImpl<ValueDecl *>::iterator I = BlockByRefDecls.begin(), 4534 E = BlockByRefDecls.end(); I != E; ++I) { 4535 ValueDecl *ND = (*I); 4536 std::string Name(ND->getNameAsString()); 4537 std::string RecName; 4538 RewriteByRefString(RecName, Name, ND, true); 4539 IdentifierInfo *II = &Context->Idents.get(RecName.c_str() 4540 + sizeof("struct")); 4541 RecordDecl *RD = RecordDecl::Create(*Context, TTK_Struct, TUDecl, 4542 SourceLocation(), SourceLocation(), 4543 II); 4544 assert(RD && "SynthBlockInitExpr(): Can't find RecordDecl"); 4545 QualType castT = Context->getPointerType(Context->getTagDeclType(RD)); 4546 4547 FD = SynthBlockInitFunctionDecl((*I)->getName()); 4548 Exp = new (Context) DeclRefExpr(FD, false, FD->getType(), VK_LValue, 4549 SourceLocation()); 4550 bool isNestedCapturedVar = false; 4551 if (block) 4552 for (const auto &CI : block->captures()) { 4553 const VarDecl *variable = CI.getVariable(); 4554 if (variable == ND && CI.isNested()) { 4555 assert (CI.isByRef() && 4556 "SynthBlockInitExpr - captured block variable is not byref"); 4557 isNestedCapturedVar = true; 4558 break; 4559 } 4560 } 4561 // captured nested byref variable has its address passed. Do not take 4562 // its address again. 4563 if (!isNestedCapturedVar) 4564 Exp = new (Context) UnaryOperator(Exp, UO_AddrOf, 4565 Context->getPointerType(Exp->getType()), 4566 VK_RValue, OK_Ordinary, SourceLocation()); 4567 Exp = NoTypeInfoCStyleCastExpr(Context, castT, CK_BitCast, Exp); 4568 InitExprs.push_back(Exp); 4569 } 4570 } 4571 if (ImportedBlockDecls.size()) { 4572 // generate BLOCK_HAS_COPY_DISPOSE(have helper funcs) | BLOCK_HAS_DESCRIPTOR 4573 int flag = (BLOCK_HAS_COPY_DISPOSE | BLOCK_HAS_DESCRIPTOR); 4574 unsigned IntSize = 4575 static_cast<unsigned>(Context->getTypeSize(Context->IntTy)); 4576 Expr *FlagExp = IntegerLiteral::Create(*Context, llvm::APInt(IntSize, flag), 4577 Context->IntTy, SourceLocation()); 4578 InitExprs.push_back(FlagExp); 4579 } 4580 NewRep = new (Context) CallExpr(*Context, DRE, InitExprs, 4581 FType, VK_LValue, SourceLocation()); 4582 NewRep = new (Context) UnaryOperator(NewRep, UO_AddrOf, 4583 Context->getPointerType(NewRep->getType()), 4584 VK_RValue, OK_Ordinary, SourceLocation()); 4585 NewRep = NoTypeInfoCStyleCastExpr(Context, FType, CK_BitCast, 4586 NewRep); 4587 BlockDeclRefs.clear(); 4588 BlockByRefDecls.clear(); 4589 BlockByRefDeclsPtrSet.clear(); 4590 BlockByCopyDecls.clear(); 4591 BlockByCopyDeclsPtrSet.clear(); 4592 ImportedBlockDecls.clear(); 4593 return NewRep; 4594 } 4595 4596 bool RewriteObjC::IsDeclStmtInForeachHeader(DeclStmt *DS) { 4597 if (const ObjCForCollectionStmt * CS = 4598 dyn_cast<ObjCForCollectionStmt>(Stmts.back())) 4599 return CS->getElement() == DS; 4600 return false; 4601 } 4602 4603 //===----------------------------------------------------------------------===// 4604 // Function Body / Expression rewriting 4605 //===----------------------------------------------------------------------===// 4606 4607 Stmt *RewriteObjC::RewriteFunctionBodyOrGlobalInitializer(Stmt *S) { 4608 if (isa<SwitchStmt>(S) || isa<WhileStmt>(S) || 4609 isa<DoStmt>(S) || isa<ForStmt>(S)) 4610 Stmts.push_back(S); 4611 else if (isa<ObjCForCollectionStmt>(S)) { 4612 Stmts.push_back(S); 4613 ObjCBcLabelNo.push_back(++BcLabelCount); 4614 } 4615 4616 // Pseudo-object operations and ivar references need special 4617 // treatment because we're going to recursively rewrite them. 4618 if (PseudoObjectExpr *PseudoOp = dyn_cast<PseudoObjectExpr>(S)) { 4619 if (isa<BinaryOperator>(PseudoOp->getSyntacticForm())) { 4620 return RewritePropertyOrImplicitSetter(PseudoOp); 4621 } else { 4622 return RewritePropertyOrImplicitGetter(PseudoOp); 4623 } 4624 } else if (ObjCIvarRefExpr *IvarRefExpr = dyn_cast<ObjCIvarRefExpr>(S)) { 4625 return RewriteObjCIvarRefExpr(IvarRefExpr); 4626 } 4627 4628 SourceRange OrigStmtRange = S->getSourceRange(); 4629 4630 // Perform a bottom up rewrite of all children. 4631 for (Stmt::child_range CI = S->children(); CI; ++CI) 4632 if (*CI) { 4633 Stmt *childStmt = (*CI); 4634 Stmt *newStmt = RewriteFunctionBodyOrGlobalInitializer(childStmt); 4635 if (newStmt) { 4636 *CI = newStmt; 4637 } 4638 } 4639 4640 if (BlockExpr *BE = dyn_cast<BlockExpr>(S)) { 4641 SmallVector<DeclRefExpr *, 8> InnerBlockDeclRefs; 4642 llvm::SmallPtrSet<const DeclContext *, 8> InnerContexts; 4643 InnerContexts.insert(BE->getBlockDecl()); 4644 ImportedLocalExternalDecls.clear(); 4645 GetInnerBlockDeclRefExprs(BE->getBody(), 4646 InnerBlockDeclRefs, InnerContexts); 4647 // Rewrite the block body in place. 4648 Stmt *SaveCurrentBody = CurrentBody; 4649 CurrentBody = BE->getBody(); 4650 PropParentMap = nullptr; 4651 // block literal on rhs of a property-dot-sytax assignment 4652 // must be replaced by its synthesize ast so getRewrittenText 4653 // works as expected. In this case, what actually ends up on RHS 4654 // is the blockTranscribed which is the helper function for the 4655 // block literal; as in: self.c = ^() {[ace ARR];}; 4656 bool saveDisableReplaceStmt = DisableReplaceStmt; 4657 DisableReplaceStmt = false; 4658 RewriteFunctionBodyOrGlobalInitializer(BE->getBody()); 4659 DisableReplaceStmt = saveDisableReplaceStmt; 4660 CurrentBody = SaveCurrentBody; 4661 PropParentMap = nullptr; 4662 ImportedLocalExternalDecls.clear(); 4663 // Now we snarf the rewritten text and stash it away for later use. 4664 std::string Str = Rewrite.getRewrittenText(BE->getSourceRange()); 4665 RewrittenBlockExprs[BE] = Str; 4666 4667 Stmt *blockTranscribed = SynthBlockInitExpr(BE, InnerBlockDeclRefs); 4668 4669 //blockTranscribed->dump(); 4670 ReplaceStmt(S, blockTranscribed); 4671 return blockTranscribed; 4672 } 4673 // Handle specific things. 4674 if (ObjCEncodeExpr *AtEncode = dyn_cast<ObjCEncodeExpr>(S)) 4675 return RewriteAtEncode(AtEncode); 4676 4677 if (ObjCSelectorExpr *AtSelector = dyn_cast<ObjCSelectorExpr>(S)) 4678 return RewriteAtSelector(AtSelector); 4679 4680 if (ObjCStringLiteral *AtString = dyn_cast<ObjCStringLiteral>(S)) 4681 return RewriteObjCStringLiteral(AtString); 4682 4683 if (ObjCMessageExpr *MessExpr = dyn_cast<ObjCMessageExpr>(S)) { 4684 #if 0 4685 // Before we rewrite it, put the original message expression in a comment. 4686 SourceLocation startLoc = MessExpr->getLocStart(); 4687 SourceLocation endLoc = MessExpr->getLocEnd(); 4688 4689 const char *startBuf = SM->getCharacterData(startLoc); 4690 const char *endBuf = SM->getCharacterData(endLoc); 4691 4692 std::string messString; 4693 messString += "// "; 4694 messString.append(startBuf, endBuf-startBuf+1); 4695 messString += "\n"; 4696 4697 // FIXME: Missing definition of 4698 // InsertText(clang::SourceLocation, char const*, unsigned int). 4699 // InsertText(startLoc, messString.c_str(), messString.size()); 4700 // Tried this, but it didn't work either... 4701 // ReplaceText(startLoc, 0, messString.c_str(), messString.size()); 4702 #endif 4703 return RewriteMessageExpr(MessExpr); 4704 } 4705 4706 if (ObjCAtTryStmt *StmtTry = dyn_cast<ObjCAtTryStmt>(S)) 4707 return RewriteObjCTryStmt(StmtTry); 4708 4709 if (ObjCAtSynchronizedStmt *StmtTry = dyn_cast<ObjCAtSynchronizedStmt>(S)) 4710 return RewriteObjCSynchronizedStmt(StmtTry); 4711 4712 if (ObjCAtThrowStmt *StmtThrow = dyn_cast<ObjCAtThrowStmt>(S)) 4713 return RewriteObjCThrowStmt(StmtThrow); 4714 4715 if (ObjCProtocolExpr *ProtocolExp = dyn_cast<ObjCProtocolExpr>(S)) 4716 return RewriteObjCProtocolExpr(ProtocolExp); 4717 4718 if (ObjCForCollectionStmt *StmtForCollection = 4719 dyn_cast<ObjCForCollectionStmt>(S)) 4720 return RewriteObjCForCollectionStmt(StmtForCollection, 4721 OrigStmtRange.getEnd()); 4722 if (BreakStmt *StmtBreakStmt = 4723 dyn_cast<BreakStmt>(S)) 4724 return RewriteBreakStmt(StmtBreakStmt); 4725 if (ContinueStmt *StmtContinueStmt = 4726 dyn_cast<ContinueStmt>(S)) 4727 return RewriteContinueStmt(StmtContinueStmt); 4728 4729 // Need to check for protocol refs (id <P>, Foo <P> *) in variable decls 4730 // and cast exprs. 4731 if (DeclStmt *DS = dyn_cast<DeclStmt>(S)) { 4732 // FIXME: What we're doing here is modifying the type-specifier that 4733 // precedes the first Decl. In the future the DeclGroup should have 4734 // a separate type-specifier that we can rewrite. 4735 // NOTE: We need to avoid rewriting the DeclStmt if it is within 4736 // the context of an ObjCForCollectionStmt. For example: 4737 // NSArray *someArray; 4738 // for (id <FooProtocol> index in someArray) ; 4739 // This is because RewriteObjCForCollectionStmt() does textual rewriting 4740 // and it depends on the original text locations/positions. 4741 if (Stmts.empty() || !IsDeclStmtInForeachHeader(DS)) 4742 RewriteObjCQualifiedInterfaceTypes(*DS->decl_begin()); 4743 4744 // Blocks rewrite rules. 4745 for (auto *SD : DS->decls()) { 4746 if (ValueDecl *ND = dyn_cast<ValueDecl>(SD)) { 4747 if (isTopLevelBlockPointerType(ND->getType())) 4748 RewriteBlockPointerDecl(ND); 4749 else if (ND->getType()->isFunctionPointerType()) 4750 CheckFunctionPointerDecl(ND->getType(), ND); 4751 if (VarDecl *VD = dyn_cast<VarDecl>(SD)) { 4752 if (VD->hasAttr<BlocksAttr>()) { 4753 static unsigned uniqueByrefDeclCount = 0; 4754 assert(!BlockByRefDeclNo.count(ND) && 4755 "RewriteFunctionBodyOrGlobalInitializer: Duplicate byref decl"); 4756 BlockByRefDeclNo[ND] = uniqueByrefDeclCount++; 4757 RewriteByRefVar(VD); 4758 } 4759 else 4760 RewriteTypeOfDecl(VD); 4761 } 4762 } 4763 if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(SD)) { 4764 if (isTopLevelBlockPointerType(TD->getUnderlyingType())) 4765 RewriteBlockPointerDecl(TD); 4766 else if (TD->getUnderlyingType()->isFunctionPointerType()) 4767 CheckFunctionPointerDecl(TD->getUnderlyingType(), TD); 4768 } 4769 } 4770 } 4771 4772 if (CStyleCastExpr *CE = dyn_cast<CStyleCastExpr>(S)) 4773 RewriteObjCQualifiedInterfaceTypes(CE); 4774 4775 if (isa<SwitchStmt>(S) || isa<WhileStmt>(S) || 4776 isa<DoStmt>(S) || isa<ForStmt>(S)) { 4777 assert(!Stmts.empty() && "Statement stack is empty"); 4778 assert ((isa<SwitchStmt>(Stmts.back()) || isa<WhileStmt>(Stmts.back()) || 4779 isa<DoStmt>(Stmts.back()) || isa<ForStmt>(Stmts.back())) 4780 && "Statement stack mismatch"); 4781 Stmts.pop_back(); 4782 } 4783 // Handle blocks rewriting. 4784 if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(S)) { 4785 ValueDecl *VD = DRE->getDecl(); 4786 if (VD->hasAttr<BlocksAttr>()) 4787 return RewriteBlockDeclRefExpr(DRE); 4788 if (HasLocalVariableExternalStorage(VD)) 4789 return RewriteLocalVariableExternalStorage(DRE); 4790 } 4791 4792 if (CallExpr *CE = dyn_cast<CallExpr>(S)) { 4793 if (CE->getCallee()->getType()->isBlockPointerType()) { 4794 Stmt *BlockCall = SynthesizeBlockCall(CE, CE->getCallee()); 4795 ReplaceStmt(S, BlockCall); 4796 return BlockCall; 4797 } 4798 } 4799 if (CStyleCastExpr *CE = dyn_cast<CStyleCastExpr>(S)) { 4800 RewriteCastExpr(CE); 4801 } 4802 #if 0 4803 if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(S)) { 4804 CastExpr *Replacement = new (Context) CastExpr(ICE->getType(), 4805 ICE->getSubExpr(), 4806 SourceLocation()); 4807 // Get the new text. 4808 std::string SStr; 4809 llvm::raw_string_ostream Buf(SStr); 4810 Replacement->printPretty(Buf); 4811 const std::string &Str = Buf.str(); 4812 4813 printf("CAST = %s\n", &Str[0]); 4814 InsertText(ICE->getSubExpr()->getLocStart(), &Str[0], Str.size()); 4815 delete S; 4816 return Replacement; 4817 } 4818 #endif 4819 // Return this stmt unmodified. 4820 return S; 4821 } 4822 4823 void RewriteObjC::RewriteRecordBody(RecordDecl *RD) { 4824 for (auto *FD : RD->fields()) { 4825 if (isTopLevelBlockPointerType(FD->getType())) 4826 RewriteBlockPointerDecl(FD); 4827 if (FD->getType()->isObjCQualifiedIdType() || 4828 FD->getType()->isObjCQualifiedInterfaceType()) 4829 RewriteObjCQualifiedInterfaceTypes(FD); 4830 } 4831 } 4832 4833 /// HandleDeclInMainFile - This is called for each top-level decl defined in the 4834 /// main file of the input. 4835 void RewriteObjC::HandleDeclInMainFile(Decl *D) { 4836 switch (D->getKind()) { 4837 case Decl::Function: { 4838 FunctionDecl *FD = cast<FunctionDecl>(D); 4839 if (FD->isOverloadedOperator()) 4840 return; 4841 4842 // Since function prototypes don't have ParmDecl's, we check the function 4843 // prototype. This enables us to rewrite function declarations and 4844 // definitions using the same code. 4845 RewriteBlocksInFunctionProtoType(FD->getType(), FD); 4846 4847 if (!FD->isThisDeclarationADefinition()) 4848 break; 4849 4850 // FIXME: If this should support Obj-C++, support CXXTryStmt 4851 if (CompoundStmt *Body = dyn_cast_or_null<CompoundStmt>(FD->getBody())) { 4852 CurFunctionDef = FD; 4853 CurFunctionDeclToDeclareForBlock = FD; 4854 CurrentBody = Body; 4855 Body = 4856 cast_or_null<CompoundStmt>(RewriteFunctionBodyOrGlobalInitializer(Body)); 4857 FD->setBody(Body); 4858 CurrentBody = nullptr; 4859 if (PropParentMap) { 4860 delete PropParentMap; 4861 PropParentMap = nullptr; 4862 } 4863 // This synthesizes and inserts the block "impl" struct, invoke function, 4864 // and any copy/dispose helper functions. 4865 InsertBlockLiteralsWithinFunction(FD); 4866 CurFunctionDef = nullptr; 4867 CurFunctionDeclToDeclareForBlock = nullptr; 4868 } 4869 break; 4870 } 4871 case Decl::ObjCMethod: { 4872 ObjCMethodDecl *MD = cast<ObjCMethodDecl>(D); 4873 if (CompoundStmt *Body = MD->getCompoundBody()) { 4874 CurMethodDef = MD; 4875 CurrentBody = Body; 4876 Body = 4877 cast_or_null<CompoundStmt>(RewriteFunctionBodyOrGlobalInitializer(Body)); 4878 MD->setBody(Body); 4879 CurrentBody = nullptr; 4880 if (PropParentMap) { 4881 delete PropParentMap; 4882 PropParentMap = nullptr; 4883 } 4884 InsertBlockLiteralsWithinMethod(MD); 4885 CurMethodDef = nullptr; 4886 } 4887 break; 4888 } 4889 case Decl::ObjCImplementation: { 4890 ObjCImplementationDecl *CI = cast<ObjCImplementationDecl>(D); 4891 ClassImplementation.push_back(CI); 4892 break; 4893 } 4894 case Decl::ObjCCategoryImpl: { 4895 ObjCCategoryImplDecl *CI = cast<ObjCCategoryImplDecl>(D); 4896 CategoryImplementation.push_back(CI); 4897 break; 4898 } 4899 case Decl::Var: { 4900 VarDecl *VD = cast<VarDecl>(D); 4901 RewriteObjCQualifiedInterfaceTypes(VD); 4902 if (isTopLevelBlockPointerType(VD->getType())) 4903 RewriteBlockPointerDecl(VD); 4904 else if (VD->getType()->isFunctionPointerType()) { 4905 CheckFunctionPointerDecl(VD->getType(), VD); 4906 if (VD->getInit()) { 4907 if (CStyleCastExpr *CE = dyn_cast<CStyleCastExpr>(VD->getInit())) { 4908 RewriteCastExpr(CE); 4909 } 4910 } 4911 } else if (VD->getType()->isRecordType()) { 4912 RecordDecl *RD = VD->getType()->getAs<RecordType>()->getDecl(); 4913 if (RD->isCompleteDefinition()) 4914 RewriteRecordBody(RD); 4915 } 4916 if (VD->getInit()) { 4917 GlobalVarDecl = VD; 4918 CurrentBody = VD->getInit(); 4919 RewriteFunctionBodyOrGlobalInitializer(VD->getInit()); 4920 CurrentBody = nullptr; 4921 if (PropParentMap) { 4922 delete PropParentMap; 4923 PropParentMap = nullptr; 4924 } 4925 SynthesizeBlockLiterals(VD->getTypeSpecStartLoc(), VD->getName()); 4926 GlobalVarDecl = nullptr; 4927 4928 // This is needed for blocks. 4929 if (CStyleCastExpr *CE = dyn_cast<CStyleCastExpr>(VD->getInit())) { 4930 RewriteCastExpr(CE); 4931 } 4932 } 4933 break; 4934 } 4935 case Decl::TypeAlias: 4936 case Decl::Typedef: { 4937 if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D)) { 4938 if (isTopLevelBlockPointerType(TD->getUnderlyingType())) 4939 RewriteBlockPointerDecl(TD); 4940 else if (TD->getUnderlyingType()->isFunctionPointerType()) 4941 CheckFunctionPointerDecl(TD->getUnderlyingType(), TD); 4942 } 4943 break; 4944 } 4945 case Decl::CXXRecord: 4946 case Decl::Record: { 4947 RecordDecl *RD = cast<RecordDecl>(D); 4948 if (RD->isCompleteDefinition()) 4949 RewriteRecordBody(RD); 4950 break; 4951 } 4952 default: 4953 break; 4954 } 4955 // Nothing yet. 4956 } 4957 4958 void RewriteObjC::HandleTranslationUnit(ASTContext &C) { 4959 if (Diags.hasErrorOccurred()) 4960 return; 4961 4962 RewriteInclude(); 4963 4964 // Here's a great place to add any extra declarations that may be needed. 4965 // Write out meta data for each @protocol(<expr>). 4966 for (ObjCProtocolDecl *ProtDecl : ProtocolExprDecls) 4967 RewriteObjCProtocolMetaData(ProtDecl, "", "", Preamble); 4968 4969 InsertText(SM->getLocForStartOfFile(MainFileID), Preamble, false); 4970 if (ClassImplementation.size() || CategoryImplementation.size()) 4971 RewriteImplementations(); 4972 4973 // Get the buffer corresponding to MainFileID. If we haven't changed it, then 4974 // we are done. 4975 if (const RewriteBuffer *RewriteBuf = 4976 Rewrite.getRewriteBufferFor(MainFileID)) { 4977 //printf("Changed:\n"); 4978 *OutFile << std::string(RewriteBuf->begin(), RewriteBuf->end()); 4979 } else { 4980 llvm::errs() << "No changes\n"; 4981 } 4982 4983 if (ClassImplementation.size() || CategoryImplementation.size() || 4984 ProtocolExprDecls.size()) { 4985 // Rewrite Objective-c meta data* 4986 std::string ResultStr; 4987 RewriteMetaDataIntoBuffer(ResultStr); 4988 // Emit metadata. 4989 *OutFile << ResultStr; 4990 } 4991 OutFile->flush(); 4992 } 4993 4994 void RewriteObjCFragileABI::Initialize(ASTContext &context) { 4995 InitializeCommon(context); 4996 4997 // declaring objc_selector outside the parameter list removes a silly 4998 // scope related warning... 4999 if (IsHeader) 5000 Preamble = "#pragma once\n"; 5001 Preamble += "struct objc_selector; struct objc_class;\n"; 5002 Preamble += "struct __rw_objc_super { struct objc_object *object; "; 5003 Preamble += "struct objc_object *superClass; "; 5004 if (LangOpts.MicrosoftExt) { 5005 // Add a constructor for creating temporary objects. 5006 Preamble += "__rw_objc_super(struct objc_object *o, struct objc_object *s) " 5007 ": "; 5008 Preamble += "object(o), superClass(s) {} "; 5009 } 5010 Preamble += "};\n"; 5011 Preamble += "#ifndef _REWRITER_typedef_Protocol\n"; 5012 Preamble += "typedef struct objc_object Protocol;\n"; 5013 Preamble += "#define _REWRITER_typedef_Protocol\n"; 5014 Preamble += "#endif\n"; 5015 if (LangOpts.MicrosoftExt) { 5016 Preamble += "#define __OBJC_RW_DLLIMPORT extern \"C\" __declspec(dllimport)\n"; 5017 Preamble += "#define __OBJC_RW_STATICIMPORT extern \"C\"\n"; 5018 } else 5019 Preamble += "#define __OBJC_RW_DLLIMPORT extern\n"; 5020 Preamble += "__OBJC_RW_DLLIMPORT struct objc_object *objc_msgSend"; 5021 Preamble += "(struct objc_object *, struct objc_selector *, ...);\n"; 5022 Preamble += "__OBJC_RW_DLLIMPORT struct objc_object *objc_msgSendSuper"; 5023 Preamble += "(struct objc_super *, struct objc_selector *, ...);\n"; 5024 Preamble += "__OBJC_RW_DLLIMPORT struct objc_object* objc_msgSend_stret"; 5025 Preamble += "(struct objc_object *, struct objc_selector *, ...);\n"; 5026 Preamble += "__OBJC_RW_DLLIMPORT struct objc_object* objc_msgSendSuper_stret"; 5027 Preamble += "(struct objc_super *, struct objc_selector *, ...);\n"; 5028 Preamble += "__OBJC_RW_DLLIMPORT double objc_msgSend_fpret"; 5029 Preamble += "(struct objc_object *, struct objc_selector *, ...);\n"; 5030 Preamble += "__OBJC_RW_DLLIMPORT struct objc_object *objc_getClass"; 5031 Preamble += "(const char *);\n"; 5032 Preamble += "__OBJC_RW_DLLIMPORT struct objc_class *class_getSuperclass"; 5033 Preamble += "(struct objc_class *);\n"; 5034 Preamble += "__OBJC_RW_DLLIMPORT struct objc_object *objc_getMetaClass"; 5035 Preamble += "(const char *);\n"; 5036 Preamble += "__OBJC_RW_DLLIMPORT void objc_exception_throw(struct objc_object *);\n"; 5037 Preamble += "__OBJC_RW_DLLIMPORT void objc_exception_try_enter(void *);\n"; 5038 Preamble += "__OBJC_RW_DLLIMPORT void objc_exception_try_exit(void *);\n"; 5039 Preamble += "__OBJC_RW_DLLIMPORT struct objc_object *objc_exception_extract(void *);\n"; 5040 Preamble += "__OBJC_RW_DLLIMPORT int objc_exception_match"; 5041 Preamble += "(struct objc_class *, struct objc_object *);\n"; 5042 // @synchronized hooks. 5043 Preamble += "__OBJC_RW_DLLIMPORT int objc_sync_enter(struct objc_object *);\n"; 5044 Preamble += "__OBJC_RW_DLLIMPORT int objc_sync_exit(struct objc_object *);\n"; 5045 Preamble += "__OBJC_RW_DLLIMPORT Protocol *objc_getProtocol(const char *);\n"; 5046 Preamble += "#ifndef __FASTENUMERATIONSTATE\n"; 5047 Preamble += "struct __objcFastEnumerationState {\n\t"; 5048 Preamble += "unsigned long state;\n\t"; 5049 Preamble += "void **itemsPtr;\n\t"; 5050 Preamble += "unsigned long *mutationsPtr;\n\t"; 5051 Preamble += "unsigned long extra[5];\n};\n"; 5052 Preamble += "__OBJC_RW_DLLIMPORT void objc_enumerationMutation(struct objc_object *);\n"; 5053 Preamble += "#define __FASTENUMERATIONSTATE\n"; 5054 Preamble += "#endif\n"; 5055 Preamble += "#ifndef __NSCONSTANTSTRINGIMPL\n"; 5056 Preamble += "struct __NSConstantStringImpl {\n"; 5057 Preamble += " int *isa;\n"; 5058 Preamble += " int flags;\n"; 5059 Preamble += " char *str;\n"; 5060 Preamble += " long length;\n"; 5061 Preamble += "};\n"; 5062 Preamble += "#ifdef CF_EXPORT_CONSTANT_STRING\n"; 5063 Preamble += "extern \"C\" __declspec(dllexport) int __CFConstantStringClassReference[];\n"; 5064 Preamble += "#else\n"; 5065 Preamble += "__OBJC_RW_DLLIMPORT int __CFConstantStringClassReference[];\n"; 5066 Preamble += "#endif\n"; 5067 Preamble += "#define __NSCONSTANTSTRINGIMPL\n"; 5068 Preamble += "#endif\n"; 5069 // Blocks preamble. 5070 Preamble += "#ifndef BLOCK_IMPL\n"; 5071 Preamble += "#define BLOCK_IMPL\n"; 5072 Preamble += "struct __block_impl {\n"; 5073 Preamble += " void *isa;\n"; 5074 Preamble += " int Flags;\n"; 5075 Preamble += " int Reserved;\n"; 5076 Preamble += " void *FuncPtr;\n"; 5077 Preamble += "};\n"; 5078 Preamble += "// Runtime copy/destroy helper functions (from Block_private.h)\n"; 5079 Preamble += "#ifdef __OBJC_EXPORT_BLOCKS\n"; 5080 Preamble += "extern \"C\" __declspec(dllexport) " 5081 "void _Block_object_assign(void *, const void *, const int);\n"; 5082 Preamble += "extern \"C\" __declspec(dllexport) void _Block_object_dispose(const void *, const int);\n"; 5083 Preamble += "extern \"C\" __declspec(dllexport) void *_NSConcreteGlobalBlock[32];\n"; 5084 Preamble += "extern \"C\" __declspec(dllexport) void *_NSConcreteStackBlock[32];\n"; 5085 Preamble += "#else\n"; 5086 Preamble += "__OBJC_RW_DLLIMPORT void _Block_object_assign(void *, const void *, const int);\n"; 5087 Preamble += "__OBJC_RW_DLLIMPORT void _Block_object_dispose(const void *, const int);\n"; 5088 Preamble += "__OBJC_RW_DLLIMPORT void *_NSConcreteGlobalBlock[32];\n"; 5089 Preamble += "__OBJC_RW_DLLIMPORT void *_NSConcreteStackBlock[32];\n"; 5090 Preamble += "#endif\n"; 5091 Preamble += "#endif\n"; 5092 if (LangOpts.MicrosoftExt) { 5093 Preamble += "#undef __OBJC_RW_DLLIMPORT\n"; 5094 Preamble += "#undef __OBJC_RW_STATICIMPORT\n"; 5095 Preamble += "#ifndef KEEP_ATTRIBUTES\n"; // We use this for clang tests. 5096 Preamble += "#define __attribute__(X)\n"; 5097 Preamble += "#endif\n"; 5098 Preamble += "#define __weak\n"; 5099 } 5100 else { 5101 Preamble += "#define __block\n"; 5102 Preamble += "#define __weak\n"; 5103 } 5104 // NOTE! Windows uses LLP64 for 64bit mode. So, cast pointer to long long 5105 // as this avoids warning in any 64bit/32bit compilation model. 5106 Preamble += "\n#define __OFFSETOFIVAR__(TYPE, MEMBER) ((long long) &((TYPE *)0)->MEMBER)\n"; 5107 } 5108 5109 /// RewriteIvarOffsetComputation - This rutine synthesizes computation of 5110 /// ivar offset. 5111 void RewriteObjCFragileABI::RewriteIvarOffsetComputation(ObjCIvarDecl *ivar, 5112 std::string &Result) { 5113 if (ivar->isBitField()) { 5114 // FIXME: The hack below doesn't work for bitfields. For now, we simply 5115 // place all bitfields at offset 0. 5116 Result += "0"; 5117 } else { 5118 Result += "__OFFSETOFIVAR__(struct "; 5119 Result += ivar->getContainingInterface()->getNameAsString(); 5120 if (LangOpts.MicrosoftExt) 5121 Result += "_IMPL"; 5122 Result += ", "; 5123 Result += ivar->getNameAsString(); 5124 Result += ")"; 5125 } 5126 } 5127 5128 /// RewriteObjCProtocolMetaData - Rewrite protocols meta-data. 5129 void RewriteObjCFragileABI::RewriteObjCProtocolMetaData( 5130 ObjCProtocolDecl *PDecl, StringRef prefix, 5131 StringRef ClassName, std::string &Result) { 5132 static bool objc_protocol_methods = false; 5133 5134 // Output struct protocol_methods holder of method selector and type. 5135 if (!objc_protocol_methods && PDecl->hasDefinition()) { 5136 /* struct protocol_methods { 5137 SEL _cmd; 5138 char *method_types; 5139 } 5140 */ 5141 Result += "\nstruct _protocol_methods {\n"; 5142 Result += "\tstruct objc_selector *_cmd;\n"; 5143 Result += "\tchar *method_types;\n"; 5144 Result += "};\n"; 5145 5146 objc_protocol_methods = true; 5147 } 5148 // Do not synthesize the protocol more than once. 5149 if (ObjCSynthesizedProtocols.count(PDecl->getCanonicalDecl())) 5150 return; 5151 5152 if (ObjCProtocolDecl *Def = PDecl->getDefinition()) 5153 PDecl = Def; 5154 5155 if (PDecl->instmeth_begin() != PDecl->instmeth_end()) { 5156 unsigned NumMethods = std::distance(PDecl->instmeth_begin(), 5157 PDecl->instmeth_end()); 5158 /* struct _objc_protocol_method_list { 5159 int protocol_method_count; 5160 struct protocol_methods protocols[]; 5161 } 5162 */ 5163 Result += "\nstatic struct {\n"; 5164 Result += "\tint protocol_method_count;\n"; 5165 Result += "\tstruct _protocol_methods protocol_methods["; 5166 Result += utostr(NumMethods); 5167 Result += "];\n} _OBJC_PROTOCOL_INSTANCE_METHODS_"; 5168 Result += PDecl->getNameAsString(); 5169 Result += " __attribute__ ((used, section (\"__OBJC, __cat_inst_meth\")))= " 5170 "{\n\t" + utostr(NumMethods) + "\n"; 5171 5172 // Output instance methods declared in this protocol. 5173 for (ObjCProtocolDecl::instmeth_iterator 5174 I = PDecl->instmeth_begin(), E = PDecl->instmeth_end(); 5175 I != E; ++I) { 5176 if (I == PDecl->instmeth_begin()) 5177 Result += "\t ,{{(struct objc_selector *)\""; 5178 else 5179 Result += "\t ,{(struct objc_selector *)\""; 5180 Result += (*I)->getSelector().getAsString(); 5181 std::string MethodTypeString; 5182 Context->getObjCEncodingForMethodDecl((*I), MethodTypeString); 5183 Result += "\", \""; 5184 Result += MethodTypeString; 5185 Result += "\"}\n"; 5186 } 5187 Result += "\t }\n};\n"; 5188 } 5189 5190 // Output class methods declared in this protocol. 5191 unsigned NumMethods = std::distance(PDecl->classmeth_begin(), 5192 PDecl->classmeth_end()); 5193 if (NumMethods > 0) { 5194 /* struct _objc_protocol_method_list { 5195 int protocol_method_count; 5196 struct protocol_methods protocols[]; 5197 } 5198 */ 5199 Result += "\nstatic struct {\n"; 5200 Result += "\tint protocol_method_count;\n"; 5201 Result += "\tstruct _protocol_methods protocol_methods["; 5202 Result += utostr(NumMethods); 5203 Result += "];\n} _OBJC_PROTOCOL_CLASS_METHODS_"; 5204 Result += PDecl->getNameAsString(); 5205 Result += " __attribute__ ((used, section (\"__OBJC, __cat_cls_meth\")))= " 5206 "{\n\t"; 5207 Result += utostr(NumMethods); 5208 Result += "\n"; 5209 5210 // Output instance methods declared in this protocol. 5211 for (ObjCProtocolDecl::classmeth_iterator 5212 I = PDecl->classmeth_begin(), E = PDecl->classmeth_end(); 5213 I != E; ++I) { 5214 if (I == PDecl->classmeth_begin()) 5215 Result += "\t ,{{(struct objc_selector *)\""; 5216 else 5217 Result += "\t ,{(struct objc_selector *)\""; 5218 Result += (*I)->getSelector().getAsString(); 5219 std::string MethodTypeString; 5220 Context->getObjCEncodingForMethodDecl((*I), MethodTypeString); 5221 Result += "\", \""; 5222 Result += MethodTypeString; 5223 Result += "\"}\n"; 5224 } 5225 Result += "\t }\n};\n"; 5226 } 5227 5228 // Output: 5229 /* struct _objc_protocol { 5230 // Objective-C 1.0 extensions 5231 struct _objc_protocol_extension *isa; 5232 char *protocol_name; 5233 struct _objc_protocol **protocol_list; 5234 struct _objc_protocol_method_list *instance_methods; 5235 struct _objc_protocol_method_list *class_methods; 5236 }; 5237 */ 5238 static bool objc_protocol = false; 5239 if (!objc_protocol) { 5240 Result += "\nstruct _objc_protocol {\n"; 5241 Result += "\tstruct _objc_protocol_extension *isa;\n"; 5242 Result += "\tchar *protocol_name;\n"; 5243 Result += "\tstruct _objc_protocol **protocol_list;\n"; 5244 Result += "\tstruct _objc_protocol_method_list *instance_methods;\n"; 5245 Result += "\tstruct _objc_protocol_method_list *class_methods;\n"; 5246 Result += "};\n"; 5247 5248 objc_protocol = true; 5249 } 5250 5251 Result += "\nstatic struct _objc_protocol _OBJC_PROTOCOL_"; 5252 Result += PDecl->getNameAsString(); 5253 Result += " __attribute__ ((used, section (\"__OBJC, __protocol\")))= " 5254 "{\n\t0, \""; 5255 Result += PDecl->getNameAsString(); 5256 Result += "\", 0, "; 5257 if (PDecl->instmeth_begin() != PDecl->instmeth_end()) { 5258 Result += "(struct _objc_protocol_method_list *)&_OBJC_PROTOCOL_INSTANCE_METHODS_"; 5259 Result += PDecl->getNameAsString(); 5260 Result += ", "; 5261 } 5262 else 5263 Result += "0, "; 5264 if (PDecl->classmeth_begin() != PDecl->classmeth_end()) { 5265 Result += "(struct _objc_protocol_method_list *)&_OBJC_PROTOCOL_CLASS_METHODS_"; 5266 Result += PDecl->getNameAsString(); 5267 Result += "\n"; 5268 } 5269 else 5270 Result += "0\n"; 5271 Result += "};\n"; 5272 5273 // Mark this protocol as having been generated. 5274 if (!ObjCSynthesizedProtocols.insert(PDecl->getCanonicalDecl())) 5275 llvm_unreachable("protocol already synthesized"); 5276 5277 } 5278 5279 void RewriteObjCFragileABI::RewriteObjCProtocolListMetaData( 5280 const ObjCList<ObjCProtocolDecl> &Protocols, 5281 StringRef prefix, StringRef ClassName, 5282 std::string &Result) { 5283 if (Protocols.empty()) return; 5284 5285 for (unsigned i = 0; i != Protocols.size(); i++) 5286 RewriteObjCProtocolMetaData(Protocols[i], prefix, ClassName, Result); 5287 5288 // Output the top lovel protocol meta-data for the class. 5289 /* struct _objc_protocol_list { 5290 struct _objc_protocol_list *next; 5291 int protocol_count; 5292 struct _objc_protocol *class_protocols[]; 5293 } 5294 */ 5295 Result += "\nstatic struct {\n"; 5296 Result += "\tstruct _objc_protocol_list *next;\n"; 5297 Result += "\tint protocol_count;\n"; 5298 Result += "\tstruct _objc_protocol *class_protocols["; 5299 Result += utostr(Protocols.size()); 5300 Result += "];\n} _OBJC_"; 5301 Result += prefix; 5302 Result += "_PROTOCOLS_"; 5303 Result += ClassName; 5304 Result += " __attribute__ ((used, section (\"__OBJC, __cat_cls_meth\")))= " 5305 "{\n\t0, "; 5306 Result += utostr(Protocols.size()); 5307 Result += "\n"; 5308 5309 Result += "\t,{&_OBJC_PROTOCOL_"; 5310 Result += Protocols[0]->getNameAsString(); 5311 Result += " \n"; 5312 5313 for (unsigned i = 1; i != Protocols.size(); i++) { 5314 Result += "\t ,&_OBJC_PROTOCOL_"; 5315 Result += Protocols[i]->getNameAsString(); 5316 Result += "\n"; 5317 } 5318 Result += "\t }\n};\n"; 5319 } 5320 5321 void RewriteObjCFragileABI::RewriteObjCClassMetaData(ObjCImplementationDecl *IDecl, 5322 std::string &Result) { 5323 ObjCInterfaceDecl *CDecl = IDecl->getClassInterface(); 5324 5325 // Explicitly declared @interface's are already synthesized. 5326 if (CDecl->isImplicitInterfaceDecl()) { 5327 // FIXME: Implementation of a class with no @interface (legacy) does not 5328 // produce correct synthesis as yet. 5329 RewriteObjCInternalStruct(CDecl, Result); 5330 } 5331 5332 // Build _objc_ivar_list metadata for classes ivars if needed 5333 unsigned NumIvars = !IDecl->ivar_empty() 5334 ? IDecl->ivar_size() 5335 : (CDecl ? CDecl->ivar_size() : 0); 5336 if (NumIvars > 0) { 5337 static bool objc_ivar = false; 5338 if (!objc_ivar) { 5339 /* struct _objc_ivar { 5340 char *ivar_name; 5341 char *ivar_type; 5342 int ivar_offset; 5343 }; 5344 */ 5345 Result += "\nstruct _objc_ivar {\n"; 5346 Result += "\tchar *ivar_name;\n"; 5347 Result += "\tchar *ivar_type;\n"; 5348 Result += "\tint ivar_offset;\n"; 5349 Result += "};\n"; 5350 5351 objc_ivar = true; 5352 } 5353 5354 /* struct { 5355 int ivar_count; 5356 struct _objc_ivar ivar_list[nIvars]; 5357 }; 5358 */ 5359 Result += "\nstatic struct {\n"; 5360 Result += "\tint ivar_count;\n"; 5361 Result += "\tstruct _objc_ivar ivar_list["; 5362 Result += utostr(NumIvars); 5363 Result += "];\n} _OBJC_INSTANCE_VARIABLES_"; 5364 Result += IDecl->getNameAsString(); 5365 Result += " __attribute__ ((used, section (\"__OBJC, __instance_vars\")))= " 5366 "{\n\t"; 5367 Result += utostr(NumIvars); 5368 Result += "\n"; 5369 5370 ObjCInterfaceDecl::ivar_iterator IVI, IVE; 5371 SmallVector<ObjCIvarDecl *, 8> IVars; 5372 if (!IDecl->ivar_empty()) { 5373 for (auto *IV : IDecl->ivars()) 5374 IVars.push_back(IV); 5375 IVI = IDecl->ivar_begin(); 5376 IVE = IDecl->ivar_end(); 5377 } else { 5378 IVI = CDecl->ivar_begin(); 5379 IVE = CDecl->ivar_end(); 5380 } 5381 Result += "\t,{{\""; 5382 Result += IVI->getNameAsString(); 5383 Result += "\", \""; 5384 std::string TmpString, StrEncoding; 5385 Context->getObjCEncodingForType(IVI->getType(), TmpString, *IVI); 5386 QuoteDoublequotes(TmpString, StrEncoding); 5387 Result += StrEncoding; 5388 Result += "\", "; 5389 RewriteIvarOffsetComputation(*IVI, Result); 5390 Result += "}\n"; 5391 for (++IVI; IVI != IVE; ++IVI) { 5392 Result += "\t ,{\""; 5393 Result += IVI->getNameAsString(); 5394 Result += "\", \""; 5395 std::string TmpString, StrEncoding; 5396 Context->getObjCEncodingForType(IVI->getType(), TmpString, *IVI); 5397 QuoteDoublequotes(TmpString, StrEncoding); 5398 Result += StrEncoding; 5399 Result += "\", "; 5400 RewriteIvarOffsetComputation(*IVI, Result); 5401 Result += "}\n"; 5402 } 5403 5404 Result += "\t }\n};\n"; 5405 } 5406 5407 // Build _objc_method_list for class's instance methods if needed 5408 SmallVector<ObjCMethodDecl *, 32> InstanceMethods(IDecl->instance_methods()); 5409 5410 // If any of our property implementations have associated getters or 5411 // setters, produce metadata for them as well. 5412 for (const auto *Prop : IDecl->property_impls()) { 5413 if (Prop->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic) 5414 continue; 5415 if (!Prop->getPropertyIvarDecl()) 5416 continue; 5417 ObjCPropertyDecl *PD = Prop->getPropertyDecl(); 5418 if (!PD) 5419 continue; 5420 if (ObjCMethodDecl *Getter = PD->getGetterMethodDecl()) 5421 if (!Getter->isDefined()) 5422 InstanceMethods.push_back(Getter); 5423 if (PD->isReadOnly()) 5424 continue; 5425 if (ObjCMethodDecl *Setter = PD->getSetterMethodDecl()) 5426 if (!Setter->isDefined()) 5427 InstanceMethods.push_back(Setter); 5428 } 5429 RewriteObjCMethodsMetaData(InstanceMethods.begin(), InstanceMethods.end(), 5430 true, "", IDecl->getName(), Result); 5431 5432 // Build _objc_method_list for class's class methods if needed 5433 RewriteObjCMethodsMetaData(IDecl->classmeth_begin(), IDecl->classmeth_end(), 5434 false, "", IDecl->getName(), Result); 5435 5436 // Protocols referenced in class declaration? 5437 RewriteObjCProtocolListMetaData(CDecl->getReferencedProtocols(), 5438 "CLASS", CDecl->getName(), Result); 5439 5440 // Declaration of class/meta-class metadata 5441 /* struct _objc_class { 5442 struct _objc_class *isa; // or const char *root_class_name when metadata 5443 const char *super_class_name; 5444 char *name; 5445 long version; 5446 long info; 5447 long instance_size; 5448 struct _objc_ivar_list *ivars; 5449 struct _objc_method_list *methods; 5450 struct objc_cache *cache; 5451 struct objc_protocol_list *protocols; 5452 const char *ivar_layout; 5453 struct _objc_class_ext *ext; 5454 }; 5455 */ 5456 static bool objc_class = false; 5457 if (!objc_class) { 5458 Result += "\nstruct _objc_class {\n"; 5459 Result += "\tstruct _objc_class *isa;\n"; 5460 Result += "\tconst char *super_class_name;\n"; 5461 Result += "\tchar *name;\n"; 5462 Result += "\tlong version;\n"; 5463 Result += "\tlong info;\n"; 5464 Result += "\tlong instance_size;\n"; 5465 Result += "\tstruct _objc_ivar_list *ivars;\n"; 5466 Result += "\tstruct _objc_method_list *methods;\n"; 5467 Result += "\tstruct objc_cache *cache;\n"; 5468 Result += "\tstruct _objc_protocol_list *protocols;\n"; 5469 Result += "\tconst char *ivar_layout;\n"; 5470 Result += "\tstruct _objc_class_ext *ext;\n"; 5471 Result += "};\n"; 5472 objc_class = true; 5473 } 5474 5475 // Meta-class metadata generation. 5476 ObjCInterfaceDecl *RootClass = nullptr; 5477 ObjCInterfaceDecl *SuperClass = CDecl->getSuperClass(); 5478 while (SuperClass) { 5479 RootClass = SuperClass; 5480 SuperClass = SuperClass->getSuperClass(); 5481 } 5482 SuperClass = CDecl->getSuperClass(); 5483 5484 Result += "\nstatic struct _objc_class _OBJC_METACLASS_"; 5485 Result += CDecl->getNameAsString(); 5486 Result += " __attribute__ ((used, section (\"__OBJC, __meta_class\")))= " 5487 "{\n\t(struct _objc_class *)\""; 5488 Result += (RootClass ? RootClass->getNameAsString() : CDecl->getNameAsString()); 5489 Result += "\""; 5490 5491 if (SuperClass) { 5492 Result += ", \""; 5493 Result += SuperClass->getNameAsString(); 5494 Result += "\", \""; 5495 Result += CDecl->getNameAsString(); 5496 Result += "\""; 5497 } 5498 else { 5499 Result += ", 0, \""; 5500 Result += CDecl->getNameAsString(); 5501 Result += "\""; 5502 } 5503 // Set 'ivars' field for root class to 0. ObjC1 runtime does not use it. 5504 // 'info' field is initialized to CLS_META(2) for metaclass 5505 Result += ", 0,2, sizeof(struct _objc_class), 0"; 5506 if (IDecl->classmeth_begin() != IDecl->classmeth_end()) { 5507 Result += "\n\t, (struct _objc_method_list *)&_OBJC_CLASS_METHODS_"; 5508 Result += IDecl->getNameAsString(); 5509 Result += "\n"; 5510 } 5511 else 5512 Result += ", 0\n"; 5513 if (CDecl->protocol_begin() != CDecl->protocol_end()) { 5514 Result += "\t,0, (struct _objc_protocol_list *)&_OBJC_CLASS_PROTOCOLS_"; 5515 Result += CDecl->getNameAsString(); 5516 Result += ",0,0\n"; 5517 } 5518 else 5519 Result += "\t,0,0,0,0\n"; 5520 Result += "};\n"; 5521 5522 // class metadata generation. 5523 Result += "\nstatic struct _objc_class _OBJC_CLASS_"; 5524 Result += CDecl->getNameAsString(); 5525 Result += " __attribute__ ((used, section (\"__OBJC, __class\")))= " 5526 "{\n\t&_OBJC_METACLASS_"; 5527 Result += CDecl->getNameAsString(); 5528 if (SuperClass) { 5529 Result += ", \""; 5530 Result += SuperClass->getNameAsString(); 5531 Result += "\", \""; 5532 Result += CDecl->getNameAsString(); 5533 Result += "\""; 5534 } 5535 else { 5536 Result += ", 0, \""; 5537 Result += CDecl->getNameAsString(); 5538 Result += "\""; 5539 } 5540 // 'info' field is initialized to CLS_CLASS(1) for class 5541 Result += ", 0,1"; 5542 if (!ObjCSynthesizedStructs.count(CDecl)) 5543 Result += ",0"; 5544 else { 5545 // class has size. Must synthesize its size. 5546 Result += ",sizeof(struct "; 5547 Result += CDecl->getNameAsString(); 5548 if (LangOpts.MicrosoftExt) 5549 Result += "_IMPL"; 5550 Result += ")"; 5551 } 5552 if (NumIvars > 0) { 5553 Result += ", (struct _objc_ivar_list *)&_OBJC_INSTANCE_VARIABLES_"; 5554 Result += CDecl->getNameAsString(); 5555 Result += "\n\t"; 5556 } 5557 else 5558 Result += ",0"; 5559 if (IDecl->instmeth_begin() != IDecl->instmeth_end()) { 5560 Result += ", (struct _objc_method_list *)&_OBJC_INSTANCE_METHODS_"; 5561 Result += CDecl->getNameAsString(); 5562 Result += ", 0\n\t"; 5563 } 5564 else 5565 Result += ",0,0"; 5566 if (CDecl->protocol_begin() != CDecl->protocol_end()) { 5567 Result += ", (struct _objc_protocol_list*)&_OBJC_CLASS_PROTOCOLS_"; 5568 Result += CDecl->getNameAsString(); 5569 Result += ", 0,0\n"; 5570 } 5571 else 5572 Result += ",0,0,0\n"; 5573 Result += "};\n"; 5574 } 5575 5576 void RewriteObjCFragileABI::RewriteMetaDataIntoBuffer(std::string &Result) { 5577 int ClsDefCount = ClassImplementation.size(); 5578 int CatDefCount = CategoryImplementation.size(); 5579 5580 // For each implemented class, write out all its meta data. 5581 for (int i = 0; i < ClsDefCount; i++) 5582 RewriteObjCClassMetaData(ClassImplementation[i], Result); 5583 5584 // For each implemented category, write out all its meta data. 5585 for (int i = 0; i < CatDefCount; i++) 5586 RewriteObjCCategoryImplDecl(CategoryImplementation[i], Result); 5587 5588 // Write objc_symtab metadata 5589 /* 5590 struct _objc_symtab 5591 { 5592 long sel_ref_cnt; 5593 SEL *refs; 5594 short cls_def_cnt; 5595 short cat_def_cnt; 5596 void *defs[cls_def_cnt + cat_def_cnt]; 5597 }; 5598 */ 5599 5600 Result += "\nstruct _objc_symtab {\n"; 5601 Result += "\tlong sel_ref_cnt;\n"; 5602 Result += "\tSEL *refs;\n"; 5603 Result += "\tshort cls_def_cnt;\n"; 5604 Result += "\tshort cat_def_cnt;\n"; 5605 Result += "\tvoid *defs[" + utostr(ClsDefCount + CatDefCount)+ "];\n"; 5606 Result += "};\n\n"; 5607 5608 Result += "static struct _objc_symtab " 5609 "_OBJC_SYMBOLS __attribute__((used, section (\"__OBJC, __symbols\")))= {\n"; 5610 Result += "\t0, 0, " + utostr(ClsDefCount) 5611 + ", " + utostr(CatDefCount) + "\n"; 5612 for (int i = 0; i < ClsDefCount; i++) { 5613 Result += "\t,&_OBJC_CLASS_"; 5614 Result += ClassImplementation[i]->getNameAsString(); 5615 Result += "\n"; 5616 } 5617 5618 for (int i = 0; i < CatDefCount; i++) { 5619 Result += "\t,&_OBJC_CATEGORY_"; 5620 Result += CategoryImplementation[i]->getClassInterface()->getNameAsString(); 5621 Result += "_"; 5622 Result += CategoryImplementation[i]->getNameAsString(); 5623 Result += "\n"; 5624 } 5625 5626 Result += "};\n\n"; 5627 5628 // Write objc_module metadata 5629 5630 /* 5631 struct _objc_module { 5632 long version; 5633 long size; 5634 const char *name; 5635 struct _objc_symtab *symtab; 5636 } 5637 */ 5638 5639 Result += "\nstruct _objc_module {\n"; 5640 Result += "\tlong version;\n"; 5641 Result += "\tlong size;\n"; 5642 Result += "\tconst char *name;\n"; 5643 Result += "\tstruct _objc_symtab *symtab;\n"; 5644 Result += "};\n\n"; 5645 Result += "static struct _objc_module " 5646 "_OBJC_MODULES __attribute__ ((used, section (\"__OBJC, __module_info\")))= {\n"; 5647 Result += "\t" + utostr(OBJC_ABI_VERSION) + 5648 ", sizeof(struct _objc_module), \"\", &_OBJC_SYMBOLS\n"; 5649 Result += "};\n\n"; 5650 5651 if (LangOpts.MicrosoftExt) { 5652 if (ProtocolExprDecls.size()) { 5653 Result += "#pragma section(\".objc_protocol$B\",long,read,write)\n"; 5654 Result += "#pragma data_seg(push, \".objc_protocol$B\")\n"; 5655 for (ObjCProtocolDecl *ProtDecl : ProtocolExprDecls) { 5656 Result += "static struct _objc_protocol *_POINTER_OBJC_PROTOCOL_"; 5657 Result += ProtDecl->getNameAsString(); 5658 Result += " = &_OBJC_PROTOCOL_"; 5659 Result += ProtDecl->getNameAsString(); 5660 Result += ";\n"; 5661 } 5662 Result += "#pragma data_seg(pop)\n\n"; 5663 } 5664 Result += "#pragma section(\".objc_module_info$B\",long,read,write)\n"; 5665 Result += "#pragma data_seg(push, \".objc_module_info$B\")\n"; 5666 Result += "static struct _objc_module *_POINTER_OBJC_MODULES = "; 5667 Result += "&_OBJC_MODULES;\n"; 5668 Result += "#pragma data_seg(pop)\n\n"; 5669 } 5670 } 5671 5672 /// RewriteObjCCategoryImplDecl - Rewrite metadata for each category 5673 /// implementation. 5674 void RewriteObjCFragileABI::RewriteObjCCategoryImplDecl(ObjCCategoryImplDecl *IDecl, 5675 std::string &Result) { 5676 ObjCInterfaceDecl *ClassDecl = IDecl->getClassInterface(); 5677 // Find category declaration for this implementation. 5678 ObjCCategoryDecl *CDecl 5679 = ClassDecl->FindCategoryDeclaration(IDecl->getIdentifier()); 5680 5681 std::string FullCategoryName = ClassDecl->getNameAsString(); 5682 FullCategoryName += '_'; 5683 FullCategoryName += IDecl->getNameAsString(); 5684 5685 // Build _objc_method_list for class's instance methods if needed 5686 SmallVector<ObjCMethodDecl *, 32> InstanceMethods(IDecl->instance_methods()); 5687 5688 // If any of our property implementations have associated getters or 5689 // setters, produce metadata for them as well. 5690 for (const auto *Prop : IDecl->property_impls()) { 5691 if (Prop->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic) 5692 continue; 5693 if (!Prop->getPropertyIvarDecl()) 5694 continue; 5695 ObjCPropertyDecl *PD = Prop->getPropertyDecl(); 5696 if (!PD) 5697 continue; 5698 if (ObjCMethodDecl *Getter = PD->getGetterMethodDecl()) 5699 InstanceMethods.push_back(Getter); 5700 if (PD->isReadOnly()) 5701 continue; 5702 if (ObjCMethodDecl *Setter = PD->getSetterMethodDecl()) 5703 InstanceMethods.push_back(Setter); 5704 } 5705 RewriteObjCMethodsMetaData(InstanceMethods.begin(), InstanceMethods.end(), 5706 true, "CATEGORY_", FullCategoryName.c_str(), 5707 Result); 5708 5709 // Build _objc_method_list for class's class methods if needed 5710 RewriteObjCMethodsMetaData(IDecl->classmeth_begin(), IDecl->classmeth_end(), 5711 false, "CATEGORY_", FullCategoryName.c_str(), 5712 Result); 5713 5714 // Protocols referenced in class declaration? 5715 // Null CDecl is case of a category implementation with no category interface 5716 if (CDecl) 5717 RewriteObjCProtocolListMetaData(CDecl->getReferencedProtocols(), "CATEGORY", 5718 FullCategoryName, Result); 5719 /* struct _objc_category { 5720 char *category_name; 5721 char *class_name; 5722 struct _objc_method_list *instance_methods; 5723 struct _objc_method_list *class_methods; 5724 struct _objc_protocol_list *protocols; 5725 // Objective-C 1.0 extensions 5726 uint32_t size; // sizeof (struct _objc_category) 5727 struct _objc_property_list *instance_properties; // category's own 5728 // @property decl. 5729 }; 5730 */ 5731 5732 static bool objc_category = false; 5733 if (!objc_category) { 5734 Result += "\nstruct _objc_category {\n"; 5735 Result += "\tchar *category_name;\n"; 5736 Result += "\tchar *class_name;\n"; 5737 Result += "\tstruct _objc_method_list *instance_methods;\n"; 5738 Result += "\tstruct _objc_method_list *class_methods;\n"; 5739 Result += "\tstruct _objc_protocol_list *protocols;\n"; 5740 Result += "\tunsigned int size;\n"; 5741 Result += "\tstruct _objc_property_list *instance_properties;\n"; 5742 Result += "};\n"; 5743 objc_category = true; 5744 } 5745 Result += "\nstatic struct _objc_category _OBJC_CATEGORY_"; 5746 Result += FullCategoryName; 5747 Result += " __attribute__ ((used, section (\"__OBJC, __category\")))= {\n\t\""; 5748 Result += IDecl->getNameAsString(); 5749 Result += "\"\n\t, \""; 5750 Result += ClassDecl->getNameAsString(); 5751 Result += "\"\n"; 5752 5753 if (IDecl->instmeth_begin() != IDecl->instmeth_end()) { 5754 Result += "\t, (struct _objc_method_list *)" 5755 "&_OBJC_CATEGORY_INSTANCE_METHODS_"; 5756 Result += FullCategoryName; 5757 Result += "\n"; 5758 } 5759 else 5760 Result += "\t, 0\n"; 5761 if (IDecl->classmeth_begin() != IDecl->classmeth_end()) { 5762 Result += "\t, (struct _objc_method_list *)" 5763 "&_OBJC_CATEGORY_CLASS_METHODS_"; 5764 Result += FullCategoryName; 5765 Result += "\n"; 5766 } 5767 else 5768 Result += "\t, 0\n"; 5769 5770 if (CDecl && CDecl->protocol_begin() != CDecl->protocol_end()) { 5771 Result += "\t, (struct _objc_protocol_list *)&_OBJC_CATEGORY_PROTOCOLS_"; 5772 Result += FullCategoryName; 5773 Result += "\n"; 5774 } 5775 else 5776 Result += "\t, 0\n"; 5777 Result += "\t, sizeof(struct _objc_category), 0\n};\n"; 5778 } 5779 5780 // RewriteObjCMethodsMetaData - Rewrite methods metadata for instance or 5781 /// class methods. 5782 template<typename MethodIterator> 5783 void RewriteObjCFragileABI::RewriteObjCMethodsMetaData(MethodIterator MethodBegin, 5784 MethodIterator MethodEnd, 5785 bool IsInstanceMethod, 5786 StringRef prefix, 5787 StringRef ClassName, 5788 std::string &Result) { 5789 if (MethodBegin == MethodEnd) return; 5790 5791 if (!objc_impl_method) { 5792 /* struct _objc_method { 5793 SEL _cmd; 5794 char *method_types; 5795 void *_imp; 5796 } 5797 */ 5798 Result += "\nstruct _objc_method {\n"; 5799 Result += "\tSEL _cmd;\n"; 5800 Result += "\tchar *method_types;\n"; 5801 Result += "\tvoid *_imp;\n"; 5802 Result += "};\n"; 5803 5804 objc_impl_method = true; 5805 } 5806 5807 // Build _objc_method_list for class's methods if needed 5808 5809 /* struct { 5810 struct _objc_method_list *next_method; 5811 int method_count; 5812 struct _objc_method method_list[]; 5813 } 5814 */ 5815 unsigned NumMethods = std::distance(MethodBegin, MethodEnd); 5816 Result += "\nstatic struct {\n"; 5817 Result += "\tstruct _objc_method_list *next_method;\n"; 5818 Result += "\tint method_count;\n"; 5819 Result += "\tstruct _objc_method method_list["; 5820 Result += utostr(NumMethods); 5821 Result += "];\n} _OBJC_"; 5822 Result += prefix; 5823 Result += IsInstanceMethod ? "INSTANCE" : "CLASS"; 5824 Result += "_METHODS_"; 5825 Result += ClassName; 5826 Result += " __attribute__ ((used, section (\"__OBJC, __"; 5827 Result += IsInstanceMethod ? "inst" : "cls"; 5828 Result += "_meth\")))= "; 5829 Result += "{\n\t0, " + utostr(NumMethods) + "\n"; 5830 5831 Result += "\t,{{(SEL)\""; 5832 Result += (*MethodBegin)->getSelector().getAsString().c_str(); 5833 std::string MethodTypeString; 5834 Context->getObjCEncodingForMethodDecl(*MethodBegin, MethodTypeString); 5835 Result += "\", \""; 5836 Result += MethodTypeString; 5837 Result += "\", (void *)"; 5838 Result += MethodInternalNames[*MethodBegin]; 5839 Result += "}\n"; 5840 for (++MethodBegin; MethodBegin != MethodEnd; ++MethodBegin) { 5841 Result += "\t ,{(SEL)\""; 5842 Result += (*MethodBegin)->getSelector().getAsString().c_str(); 5843 std::string MethodTypeString; 5844 Context->getObjCEncodingForMethodDecl(*MethodBegin, MethodTypeString); 5845 Result += "\", \""; 5846 Result += MethodTypeString; 5847 Result += "\", (void *)"; 5848 Result += MethodInternalNames[*MethodBegin]; 5849 Result += "}\n"; 5850 } 5851 Result += "\t }\n};\n"; 5852 } 5853 5854 Stmt *RewriteObjCFragileABI::RewriteObjCIvarRefExpr(ObjCIvarRefExpr *IV) { 5855 SourceRange OldRange = IV->getSourceRange(); 5856 Expr *BaseExpr = IV->getBase(); 5857 5858 // Rewrite the base, but without actually doing replaces. 5859 { 5860 DisableReplaceStmtScope S(*this); 5861 BaseExpr = cast<Expr>(RewriteFunctionBodyOrGlobalInitializer(BaseExpr)); 5862 IV->setBase(BaseExpr); 5863 } 5864 5865 ObjCIvarDecl *D = IV->getDecl(); 5866 5867 Expr *Replacement = IV; 5868 if (CurMethodDef) { 5869 if (BaseExpr->getType()->isObjCObjectPointerType()) { 5870 const ObjCInterfaceType *iFaceDecl = 5871 dyn_cast<ObjCInterfaceType>(BaseExpr->getType()->getPointeeType()); 5872 assert(iFaceDecl && "RewriteObjCIvarRefExpr - iFaceDecl is null"); 5873 // lookup which class implements the instance variable. 5874 ObjCInterfaceDecl *clsDeclared = nullptr; 5875 iFaceDecl->getDecl()->lookupInstanceVariable(D->getIdentifier(), 5876 clsDeclared); 5877 assert(clsDeclared && "RewriteObjCIvarRefExpr(): Can't find class"); 5878 5879 // Synthesize an explicit cast to gain access to the ivar. 5880 std::string RecName = clsDeclared->getIdentifier()->getName(); 5881 RecName += "_IMPL"; 5882 IdentifierInfo *II = &Context->Idents.get(RecName); 5883 RecordDecl *RD = RecordDecl::Create(*Context, TTK_Struct, TUDecl, 5884 SourceLocation(), SourceLocation(), 5885 II); 5886 assert(RD && "RewriteObjCIvarRefExpr(): Can't find RecordDecl"); 5887 QualType castT = Context->getPointerType(Context->getTagDeclType(RD)); 5888 CastExpr *castExpr = NoTypeInfoCStyleCastExpr(Context, castT, 5889 CK_BitCast, 5890 IV->getBase()); 5891 // Don't forget the parens to enforce the proper binding. 5892 ParenExpr *PE = new (Context) ParenExpr(OldRange.getBegin(), 5893 OldRange.getEnd(), 5894 castExpr); 5895 if (IV->isFreeIvar() && 5896 declaresSameEntity(CurMethodDef->getClassInterface(), iFaceDecl->getDecl())) { 5897 MemberExpr *ME = new (Context) MemberExpr(PE, true, D, 5898 IV->getLocation(), 5899 D->getType(), 5900 VK_LValue, OK_Ordinary); 5901 Replacement = ME; 5902 } else { 5903 IV->setBase(PE); 5904 } 5905 } 5906 } else { // we are outside a method. 5907 assert(!IV->isFreeIvar() && "Cannot have a free standing ivar outside a method"); 5908 5909 // Explicit ivar refs need to have a cast inserted. 5910 // FIXME: consider sharing some of this code with the code above. 5911 if (BaseExpr->getType()->isObjCObjectPointerType()) { 5912 const ObjCInterfaceType *iFaceDecl = 5913 dyn_cast<ObjCInterfaceType>(BaseExpr->getType()->getPointeeType()); 5914 // lookup which class implements the instance variable. 5915 ObjCInterfaceDecl *clsDeclared = nullptr; 5916 iFaceDecl->getDecl()->lookupInstanceVariable(D->getIdentifier(), 5917 clsDeclared); 5918 assert(clsDeclared && "RewriteObjCIvarRefExpr(): Can't find class"); 5919 5920 // Synthesize an explicit cast to gain access to the ivar. 5921 std::string RecName = clsDeclared->getIdentifier()->getName(); 5922 RecName += "_IMPL"; 5923 IdentifierInfo *II = &Context->Idents.get(RecName); 5924 RecordDecl *RD = RecordDecl::Create(*Context, TTK_Struct, TUDecl, 5925 SourceLocation(), SourceLocation(), 5926 II); 5927 assert(RD && "RewriteObjCIvarRefExpr(): Can't find RecordDecl"); 5928 QualType castT = Context->getPointerType(Context->getTagDeclType(RD)); 5929 CastExpr *castExpr = NoTypeInfoCStyleCastExpr(Context, castT, 5930 CK_BitCast, 5931 IV->getBase()); 5932 // Don't forget the parens to enforce the proper binding. 5933 ParenExpr *PE = new (Context) ParenExpr(IV->getBase()->getLocStart(), 5934 IV->getBase()->getLocEnd(), castExpr); 5935 // Cannot delete IV->getBase(), since PE points to it. 5936 // Replace the old base with the cast. This is important when doing 5937 // embedded rewrites. For example, [newInv->_container addObject:0]. 5938 IV->setBase(PE); 5939 } 5940 } 5941 5942 ReplaceStmtWithRange(IV, Replacement, OldRange); 5943 return Replacement; 5944 } 5945 5946 #endif 5947