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