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/Basic/TargetInfo.h" 24 #include "clang/Lex/Lexer.h" 25 #include "clang/Rewrite/Core/Rewriter.h" 26 #include "llvm/ADT/DenseSet.h" 27 #include "llvm/ADT/SmallPtrSet.h" 28 #include "llvm/ADT/StringExtras.h" 29 #include "llvm/Support/MemoryBuffer.h" 30 #include "llvm/Support/raw_ostream.h" 31 #include <memory> 32 33 #ifdef CLANG_ENABLE_OBJC_REWRITER 34 35 using namespace clang; 36 using llvm::utostr; 37 38 namespace { 39 class RewriteModernObjC : public ASTConsumer { 40 protected: 41 42 enum { 43 BLOCK_FIELD_IS_OBJECT = 3, /* id, NSObject, __attribute__((NSObject)), 44 block, ... */ 45 BLOCK_FIELD_IS_BLOCK = 7, /* a block variable */ 46 BLOCK_FIELD_IS_BYREF = 8, /* the on stack structure holding the 47 __block variable */ 48 BLOCK_FIELD_IS_WEAK = 16, /* declared __weak, only used in byref copy 49 helpers */ 50 BLOCK_BYREF_CALLER = 128, /* called from __block (byref) copy/dispose 51 support routines */ 52 BLOCK_BYREF_CURRENT_MAX = 256 53 }; 54 55 enum { 56 BLOCK_NEEDS_FREE = (1 << 24), 57 BLOCK_HAS_COPY_DISPOSE = (1 << 25), 58 BLOCK_HAS_CXX_OBJ = (1 << 26), 59 BLOCK_IS_GC = (1 << 27), 60 BLOCK_IS_GLOBAL = (1 << 28), 61 BLOCK_HAS_DESCRIPTOR = (1 << 29) 62 }; 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 Expr *GlobalConstructionExp; 81 unsigned RewriteFailedDiag; 82 unsigned GlobalBlockRewriteFailedDiag; 83 // ObjC string constant support. 84 unsigned NumObjCStringLiterals; 85 VarDecl *ConstantStringClassReference; 86 RecordDecl *NSStringRecord; 87 88 // ObjC foreach break/continue generation support. 89 int BcLabelCount; 90 91 unsigned TryFinallyContainsReturnDiag; 92 // Needed for super. 93 ObjCMethodDecl *CurMethodDef; 94 RecordDecl *SuperStructDecl; 95 RecordDecl *ConstantStringDecl; 96 97 FunctionDecl *MsgSendFunctionDecl; 98 FunctionDecl *MsgSendSuperFunctionDecl; 99 FunctionDecl *MsgSendStretFunctionDecl; 100 FunctionDecl *MsgSendSuperStretFunctionDecl; 101 FunctionDecl *MsgSendFpretFunctionDecl; 102 FunctionDecl *GetClassFunctionDecl; 103 FunctionDecl *GetMetaClassFunctionDecl; 104 FunctionDecl *GetSuperClassFunctionDecl; 105 FunctionDecl *SelGetUidFunctionDecl; 106 FunctionDecl *CFStringFunctionDecl; 107 FunctionDecl *SuperConstructorFunctionDecl; 108 FunctionDecl *CurFunctionDef; 109 110 /* Misc. containers needed for meta-data rewrite. */ 111 SmallVector<ObjCImplementationDecl *, 8> ClassImplementation; 112 SmallVector<ObjCCategoryImplDecl *, 8> CategoryImplementation; 113 llvm::SmallPtrSet<ObjCInterfaceDecl*, 8> ObjCSynthesizedStructs; 114 llvm::SmallPtrSet<ObjCProtocolDecl*, 8> ObjCSynthesizedProtocols; 115 llvm::SmallPtrSet<ObjCInterfaceDecl*, 8> ObjCWrittenInterfaces; 116 llvm::SmallPtrSet<TagDecl*, 32> GlobalDefinedTags; 117 SmallVector<ObjCInterfaceDecl*, 32> ObjCInterfacesSeen; 118 /// DefinedNonLazyClasses - List of defined "non-lazy" classes. 119 SmallVector<ObjCInterfaceDecl*, 8> DefinedNonLazyClasses; 120 121 /// DefinedNonLazyCategories - List of defined "non-lazy" categories. 122 SmallVector<ObjCCategoryDecl *, 8> DefinedNonLazyCategories; 123 124 SmallVector<Stmt *, 32> Stmts; 125 SmallVector<int, 8> ObjCBcLabelNo; 126 // Remember all the @protocol(<expr>) expressions. 127 llvm::SmallPtrSet<ObjCProtocolDecl *, 32> ProtocolExprDecls; 128 129 llvm::DenseSet<uint64_t> CopyDestroyCache; 130 131 // Block expressions. 132 SmallVector<BlockExpr *, 32> Blocks; 133 SmallVector<int, 32> InnerDeclRefsCount; 134 SmallVector<DeclRefExpr *, 32> InnerDeclRefs; 135 136 SmallVector<DeclRefExpr *, 32> BlockDeclRefs; 137 138 139 // Block related declarations. 140 SmallVector<ValueDecl *, 8> BlockByCopyDecls; 141 llvm::SmallPtrSet<ValueDecl *, 8> BlockByCopyDeclsPtrSet; 142 SmallVector<ValueDecl *, 8> BlockByRefDecls; 143 llvm::SmallPtrSet<ValueDecl *, 8> BlockByRefDeclsPtrSet; 144 llvm::DenseMap<ValueDecl *, unsigned> BlockByRefDeclNo; 145 llvm::SmallPtrSet<ValueDecl *, 8> ImportedBlockDecls; 146 llvm::SmallPtrSet<VarDecl *, 8> ImportedLocalExternalDecls; 147 148 llvm::DenseMap<BlockExpr *, std::string> RewrittenBlockExprs; 149 llvm::DenseMap<ObjCInterfaceDecl *, 150 llvm::SmallPtrSet<ObjCIvarDecl *, 8> > ReferencedIvars; 151 152 // ivar bitfield grouping containers 153 llvm::DenseSet<const ObjCInterfaceDecl *> ObjCInterefaceHasBitfieldGroups; 154 llvm::DenseMap<const ObjCIvarDecl* , unsigned> IvarGroupNumber; 155 // This container maps an <class, group number for ivar> tuple to the type 156 // of the struct where the bitfield belongs. 157 llvm::DenseMap<std::pair<const ObjCInterfaceDecl*, unsigned>, QualType> GroupRecordType; 158 SmallVector<FunctionDecl*, 32> FunctionDefinitionsSeen; 159 160 // This maps an original source AST to it's rewritten form. This allows 161 // us to avoid rewriting the same node twice (which is very uncommon). 162 // This is needed to support some of the exotic property rewriting. 163 llvm::DenseMap<Stmt *, Stmt *> ReplacedNodes; 164 165 // Needed for header files being rewritten 166 bool IsHeader; 167 bool SilenceRewriteMacroWarning; 168 bool GenerateLineInfo; 169 bool objc_impl_method; 170 171 bool DisableReplaceStmt; 172 class DisableReplaceStmtScope { 173 RewriteModernObjC &R; 174 bool SavedValue; 175 176 public: 177 DisableReplaceStmtScope(RewriteModernObjC &R) 178 : R(R), SavedValue(R.DisableReplaceStmt) { 179 R.DisableReplaceStmt = true; 180 } 181 ~DisableReplaceStmtScope() { 182 R.DisableReplaceStmt = SavedValue; 183 } 184 }; 185 void InitializeCommon(ASTContext &context); 186 187 public: 188 llvm::DenseMap<ObjCMethodDecl*, std::string> MethodInternalNames; 189 // Top Level Driver code. 190 bool HandleTopLevelDecl(DeclGroupRef D) override { 191 for (DeclGroupRef::iterator I = D.begin(), E = D.end(); I != E; ++I) { 192 if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(*I)) { 193 if (!Class->isThisDeclarationADefinition()) { 194 RewriteForwardClassDecl(D); 195 break; 196 } else { 197 // Keep track of all interface declarations seen. 198 ObjCInterfacesSeen.push_back(Class); 199 break; 200 } 201 } 202 203 if (ObjCProtocolDecl *Proto = dyn_cast<ObjCProtocolDecl>(*I)) { 204 if (!Proto->isThisDeclarationADefinition()) { 205 RewriteForwardProtocolDecl(D); 206 break; 207 } 208 } 209 210 if (FunctionDecl *FDecl = dyn_cast<FunctionDecl>(*I)) { 211 // Under modern abi, we cannot translate body of the function 212 // yet until all class extensions and its implementation is seen. 213 // This is because they may introduce new bitfields which must go 214 // into their grouping struct. 215 if (FDecl->isThisDeclarationADefinition() && 216 // Not c functions defined inside an objc container. 217 !FDecl->isTopLevelDeclInObjCContainer()) { 218 FunctionDefinitionsSeen.push_back(FDecl); 219 break; 220 } 221 } 222 HandleTopLevelSingleDecl(*I); 223 } 224 return true; 225 } 226 227 void HandleTopLevelDeclInObjCContainer(DeclGroupRef D) override { 228 for (DeclGroupRef::iterator I = D.begin(), E = D.end(); I != E; ++I) { 229 if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(*I)) { 230 if (isTopLevelBlockPointerType(TD->getUnderlyingType())) 231 RewriteBlockPointerDecl(TD); 232 else if (TD->getUnderlyingType()->isFunctionPointerType()) 233 CheckFunctionPointerDecl(TD->getUnderlyingType(), TD); 234 else 235 RewriteObjCQualifiedInterfaceTypes(TD); 236 } 237 } 238 return; 239 } 240 241 void HandleTopLevelSingleDecl(Decl *D); 242 void HandleDeclInMainFile(Decl *D); 243 RewriteModernObjC(std::string inFile, raw_ostream *OS, 244 DiagnosticsEngine &D, const LangOptions &LOpts, 245 bool silenceMacroWarn, bool LineInfo); 246 247 ~RewriteModernObjC() {} 248 249 void HandleTranslationUnit(ASTContext &C) override; 250 251 void ReplaceStmt(Stmt *Old, Stmt *New) { 252 Stmt *ReplacingStmt = ReplacedNodes[Old]; 253 254 if (ReplacingStmt) 255 return; // We can't rewrite the same node twice. 256 257 if (DisableReplaceStmt) 258 return; 259 260 // If replacement succeeded or warning disabled return with no warning. 261 if (!Rewrite.ReplaceStmt(Old, New)) { 262 ReplacedNodes[Old] = New; 263 return; 264 } 265 if (SilenceRewriteMacroWarning) 266 return; 267 Diags.Report(Context->getFullLoc(Old->getLocStart()), RewriteFailedDiag) 268 << Old->getSourceRange(); 269 } 270 271 void ReplaceStmtWithRange(Stmt *Old, Stmt *New, SourceRange SrcRange) { 272 assert(Old != nullptr && New != nullptr && "Expected non-null Stmt's"); 273 if (DisableReplaceStmt) 274 return; 275 276 // Measure the old text. 277 int Size = Rewrite.getRangeSize(SrcRange); 278 if (Size == -1) { 279 Diags.Report(Context->getFullLoc(Old->getLocStart()), RewriteFailedDiag) 280 << Old->getSourceRange(); 281 return; 282 } 283 // Get the new text. 284 std::string SStr; 285 llvm::raw_string_ostream S(SStr); 286 New->printPretty(S, nullptr, PrintingPolicy(LangOpts)); 287 const std::string &Str = S.str(); 288 289 // If replacement succeeded or warning disabled return with no warning. 290 if (!Rewrite.ReplaceText(SrcRange.getBegin(), Size, Str)) { 291 ReplacedNodes[Old] = New; 292 return; 293 } 294 if (SilenceRewriteMacroWarning) 295 return; 296 Diags.Report(Context->getFullLoc(Old->getLocStart()), RewriteFailedDiag) 297 << Old->getSourceRange(); 298 } 299 300 void InsertText(SourceLocation Loc, StringRef Str, 301 bool InsertAfter = true) { 302 // If insertion succeeded or warning disabled return with no warning. 303 if (!Rewrite.InsertText(Loc, Str, InsertAfter) || 304 SilenceRewriteMacroWarning) 305 return; 306 307 Diags.Report(Context->getFullLoc(Loc), RewriteFailedDiag); 308 } 309 310 void ReplaceText(SourceLocation Start, unsigned OrigLength, 311 StringRef Str) { 312 // If removal succeeded or warning disabled return with no warning. 313 if (!Rewrite.ReplaceText(Start, OrigLength, Str) || 314 SilenceRewriteMacroWarning) 315 return; 316 317 Diags.Report(Context->getFullLoc(Start), RewriteFailedDiag); 318 } 319 320 // Syntactic Rewriting. 321 void RewriteRecordBody(RecordDecl *RD); 322 void RewriteInclude(); 323 void RewriteLineDirective(const Decl *D); 324 void ConvertSourceLocationToLineDirective(SourceLocation Loc, 325 std::string &LineString); 326 void RewriteForwardClassDecl(DeclGroupRef D); 327 void RewriteForwardClassDecl(const SmallVectorImpl<Decl *> &DG); 328 void RewriteForwardClassEpilogue(ObjCInterfaceDecl *ClassDecl, 329 const std::string &typedefString); 330 void RewriteImplementations(); 331 void RewritePropertyImplDecl(ObjCPropertyImplDecl *PID, 332 ObjCImplementationDecl *IMD, 333 ObjCCategoryImplDecl *CID); 334 void RewriteInterfaceDecl(ObjCInterfaceDecl *Dcl); 335 void RewriteImplementationDecl(Decl *Dcl); 336 void RewriteObjCMethodDecl(const ObjCInterfaceDecl *IDecl, 337 ObjCMethodDecl *MDecl, std::string &ResultStr); 338 void RewriteTypeIntoString(QualType T, std::string &ResultStr, 339 const FunctionType *&FPRetType); 340 void RewriteByRefString(std::string &ResultStr, const std::string &Name, 341 ValueDecl *VD, bool def=false); 342 void RewriteCategoryDecl(ObjCCategoryDecl *Dcl); 343 void RewriteProtocolDecl(ObjCProtocolDecl *Dcl); 344 void RewriteForwardProtocolDecl(DeclGroupRef D); 345 void RewriteForwardProtocolDecl(const SmallVectorImpl<Decl *> &DG); 346 void RewriteMethodDeclaration(ObjCMethodDecl *Method); 347 void RewriteProperty(ObjCPropertyDecl *prop); 348 void RewriteFunctionDecl(FunctionDecl *FD); 349 void RewriteBlockPointerType(std::string& Str, QualType Type); 350 void RewriteBlockPointerTypeVariable(std::string& Str, ValueDecl *VD); 351 void RewriteBlockLiteralFunctionDecl(FunctionDecl *FD); 352 void RewriteObjCQualifiedInterfaceTypes(Decl *Dcl); 353 void RewriteTypeOfDecl(VarDecl *VD); 354 void RewriteObjCQualifiedInterfaceTypes(Expr *E); 355 356 std::string getIvarAccessString(ObjCIvarDecl *D); 357 358 // Expression Rewriting. 359 Stmt *RewriteFunctionBodyOrGlobalInitializer(Stmt *S); 360 Stmt *RewriteAtEncode(ObjCEncodeExpr *Exp); 361 Stmt *RewritePropertyOrImplicitGetter(PseudoObjectExpr *Pseudo); 362 Stmt *RewritePropertyOrImplicitSetter(PseudoObjectExpr *Pseudo); 363 Stmt *RewriteAtSelector(ObjCSelectorExpr *Exp); 364 Stmt *RewriteMessageExpr(ObjCMessageExpr *Exp); 365 Stmt *RewriteObjCStringLiteral(ObjCStringLiteral *Exp); 366 Stmt *RewriteObjCBoolLiteralExpr(ObjCBoolLiteralExpr *Exp); 367 Stmt *RewriteObjCBoxedExpr(ObjCBoxedExpr *Exp); 368 Stmt *RewriteObjCArrayLiteralExpr(ObjCArrayLiteral *Exp); 369 Stmt *RewriteObjCDictionaryLiteralExpr(ObjCDictionaryLiteral *Exp); 370 Stmt *RewriteObjCProtocolExpr(ObjCProtocolExpr *Exp); 371 Stmt *RewriteObjCTryStmt(ObjCAtTryStmt *S); 372 Stmt *RewriteObjCAutoreleasePoolStmt(ObjCAutoreleasePoolStmt *S); 373 Stmt *RewriteObjCSynchronizedStmt(ObjCAtSynchronizedStmt *S); 374 Stmt *RewriteObjCThrowStmt(ObjCAtThrowStmt *S); 375 Stmt *RewriteObjCForCollectionStmt(ObjCForCollectionStmt *S, 376 SourceLocation OrigEnd); 377 Stmt *RewriteBreakStmt(BreakStmt *S); 378 Stmt *RewriteContinueStmt(ContinueStmt *S); 379 void RewriteCastExpr(CStyleCastExpr *CE); 380 void RewriteImplicitCastObjCExpr(CastExpr *IE); 381 void RewriteLinkageSpec(LinkageSpecDecl *LSD); 382 383 // Computes ivar bitfield group no. 384 unsigned ObjCIvarBitfieldGroupNo(ObjCIvarDecl *IV); 385 // Names field decl. for ivar bitfield group. 386 void ObjCIvarBitfieldGroupDecl(ObjCIvarDecl *IV, std::string &Result); 387 // Names struct type for ivar bitfield group. 388 void ObjCIvarBitfieldGroupType(ObjCIvarDecl *IV, std::string &Result); 389 // Names symbol for ivar bitfield group field offset. 390 void ObjCIvarBitfieldGroupOffset(ObjCIvarDecl *IV, std::string &Result); 391 // Given an ivar bitfield, it builds (or finds) its group record type. 392 QualType GetGroupRecordTypeForObjCIvarBitfield(ObjCIvarDecl *IV); 393 QualType SynthesizeBitfieldGroupStructType( 394 ObjCIvarDecl *IV, 395 SmallVectorImpl<ObjCIvarDecl *> &IVars); 396 397 // Block rewriting. 398 void RewriteBlocksInFunctionProtoType(QualType funcType, NamedDecl *D); 399 400 // Block specific rewrite rules. 401 void RewriteBlockPointerDecl(NamedDecl *VD); 402 void RewriteByRefVar(VarDecl *VD, bool firstDecl, bool lastDecl); 403 Stmt *RewriteBlockDeclRefExpr(DeclRefExpr *VD); 404 Stmt *RewriteLocalVariableExternalStorage(DeclRefExpr *DRE); 405 void RewriteBlockPointerFunctionArgs(FunctionDecl *FD); 406 407 void RewriteObjCInternalStruct(ObjCInterfaceDecl *CDecl, 408 std::string &Result); 409 410 void RewriteObjCFieldDecl(FieldDecl *fieldDecl, std::string &Result); 411 bool IsTagDefinedInsideClass(ObjCContainerDecl *IDecl, TagDecl *Tag, 412 bool &IsNamedDefinition); 413 void RewriteLocallyDefinedNamedAggregates(FieldDecl *fieldDecl, 414 std::string &Result); 415 416 bool RewriteObjCFieldDeclType(QualType &Type, std::string &Result); 417 418 void RewriteIvarOffsetSymbols(ObjCInterfaceDecl *CDecl, 419 std::string &Result); 420 421 void Initialize(ASTContext &context) override; 422 423 // Misc. AST transformation routines. Sometimes they end up calling 424 // rewriting routines on the new ASTs. 425 CallExpr *SynthesizeCallToFunctionDecl(FunctionDecl *FD, 426 Expr **args, unsigned nargs, 427 SourceLocation StartLoc=SourceLocation(), 428 SourceLocation EndLoc=SourceLocation()); 429 430 Expr *SynthMsgSendStretCallExpr(FunctionDecl *MsgSendStretFlavor, 431 QualType returnType, 432 SmallVectorImpl<QualType> &ArgTypes, 433 SmallVectorImpl<Expr*> &MsgExprs, 434 ObjCMethodDecl *Method); 435 436 Stmt *SynthMessageExpr(ObjCMessageExpr *Exp, 437 SourceLocation StartLoc=SourceLocation(), 438 SourceLocation EndLoc=SourceLocation()); 439 440 void SynthCountByEnumWithState(std::string &buf); 441 void SynthMsgSendFunctionDecl(); 442 void SynthMsgSendSuperFunctionDecl(); 443 void SynthMsgSendStretFunctionDecl(); 444 void SynthMsgSendFpretFunctionDecl(); 445 void SynthMsgSendSuperStretFunctionDecl(); 446 void SynthGetClassFunctionDecl(); 447 void SynthGetMetaClassFunctionDecl(); 448 void SynthGetSuperClassFunctionDecl(); 449 void SynthSelGetUidFunctionDecl(); 450 void SynthSuperConstructorFunctionDecl(); 451 452 // Rewriting metadata 453 template<typename MethodIterator> 454 void RewriteObjCMethodsMetaData(MethodIterator MethodBegin, 455 MethodIterator MethodEnd, 456 bool IsInstanceMethod, 457 StringRef prefix, 458 StringRef ClassName, 459 std::string &Result); 460 void RewriteObjCProtocolMetaData(ObjCProtocolDecl *Protocol, 461 std::string &Result); 462 void RewriteObjCProtocolListMetaData( 463 const ObjCList<ObjCProtocolDecl> &Prots, 464 StringRef prefix, StringRef ClassName, std::string &Result); 465 void RewriteObjCClassMetaData(ObjCImplementationDecl *IDecl, 466 std::string &Result); 467 void RewriteClassSetupInitHook(std::string &Result); 468 469 void RewriteMetaDataIntoBuffer(std::string &Result); 470 void WriteImageInfo(std::string &Result); 471 void RewriteObjCCategoryImplDecl(ObjCCategoryImplDecl *CDecl, 472 std::string &Result); 473 void RewriteCategorySetupInitHook(std::string &Result); 474 475 // Rewriting ivar 476 void RewriteIvarOffsetComputation(ObjCIvarDecl *ivar, 477 std::string &Result); 478 Stmt *RewriteObjCIvarRefExpr(ObjCIvarRefExpr *IV); 479 480 481 std::string SynthesizeByrefCopyDestroyHelper(VarDecl *VD, int flag); 482 std::string SynthesizeBlockHelperFuncs(BlockExpr *CE, int i, 483 StringRef funcName, std::string Tag); 484 std::string SynthesizeBlockFunc(BlockExpr *CE, int i, 485 StringRef funcName, std::string Tag); 486 std::string SynthesizeBlockImpl(BlockExpr *CE, 487 std::string Tag, std::string Desc); 488 std::string SynthesizeBlockDescriptor(std::string DescTag, 489 std::string ImplTag, 490 int i, StringRef funcName, 491 unsigned hasCopy); 492 Stmt *SynthesizeBlockCall(CallExpr *Exp, const Expr* BlockExp); 493 void SynthesizeBlockLiterals(SourceLocation FunLocStart, 494 StringRef FunName); 495 FunctionDecl *SynthBlockInitFunctionDecl(StringRef name); 496 Stmt *SynthBlockInitExpr(BlockExpr *Exp, 497 const SmallVectorImpl<DeclRefExpr *> &InnerBlockDeclRefs); 498 499 // Misc. helper routines. 500 QualType getProtocolType(); 501 void WarnAboutReturnGotoStmts(Stmt *S); 502 void CheckFunctionPointerDecl(QualType dType, NamedDecl *ND); 503 void InsertBlockLiteralsWithinFunction(FunctionDecl *FD); 504 void InsertBlockLiteralsWithinMethod(ObjCMethodDecl *MD); 505 506 bool IsDeclStmtInForeachHeader(DeclStmt *DS); 507 void CollectBlockDeclRefInfo(BlockExpr *Exp); 508 void GetBlockDeclRefExprs(Stmt *S); 509 void GetInnerBlockDeclRefExprs(Stmt *S, 510 SmallVectorImpl<DeclRefExpr *> &InnerBlockDeclRefs, 511 llvm::SmallPtrSet<const DeclContext *, 8> &InnerContexts); 512 513 // We avoid calling Type::isBlockPointerType(), since it operates on the 514 // canonical type. We only care if the top-level type is a closure pointer. 515 bool isTopLevelBlockPointerType(QualType T) { 516 return isa<BlockPointerType>(T); 517 } 518 519 /// convertBlockPointerToFunctionPointer - Converts a block-pointer type 520 /// to a function pointer type and upon success, returns true; false 521 /// otherwise. 522 bool convertBlockPointerToFunctionPointer(QualType &T) { 523 if (isTopLevelBlockPointerType(T)) { 524 const BlockPointerType *BPT = T->getAs<BlockPointerType>(); 525 T = Context->getPointerType(BPT->getPointeeType()); 526 return true; 527 } 528 return false; 529 } 530 531 bool convertObjCTypeToCStyleType(QualType &T); 532 533 bool needToScanForQualifiers(QualType T); 534 QualType getSuperStructType(); 535 QualType getConstantStringStructType(); 536 QualType convertFunctionTypeOfBlocks(const FunctionType *FT); 537 bool BufferContainsPPDirectives(const char *startBuf, const char *endBuf); 538 539 void convertToUnqualifiedObjCType(QualType &T) { 540 if (T->isObjCQualifiedIdType()) { 541 bool isConst = T.isConstQualified(); 542 T = isConst ? Context->getObjCIdType().withConst() 543 : Context->getObjCIdType(); 544 } 545 else if (T->isObjCQualifiedClassType()) 546 T = Context->getObjCClassType(); 547 else if (T->isObjCObjectPointerType() && 548 T->getPointeeType()->isObjCQualifiedInterfaceType()) { 549 if (const ObjCObjectPointerType * OBJPT = 550 T->getAsObjCInterfacePointerType()) { 551 const ObjCInterfaceType *IFaceT = OBJPT->getInterfaceType(); 552 T = QualType(IFaceT, 0); 553 T = Context->getPointerType(T); 554 } 555 } 556 } 557 558 // FIXME: This predicate seems like it would be useful to add to ASTContext. 559 bool isObjCType(QualType T) { 560 if (!LangOpts.ObjC1 && !LangOpts.ObjC2) 561 return false; 562 563 QualType OCT = Context->getCanonicalType(T).getUnqualifiedType(); 564 565 if (OCT == Context->getCanonicalType(Context->getObjCIdType()) || 566 OCT == Context->getCanonicalType(Context->getObjCClassType())) 567 return true; 568 569 if (const PointerType *PT = OCT->getAs<PointerType>()) { 570 if (isa<ObjCInterfaceType>(PT->getPointeeType()) || 571 PT->getPointeeType()->isObjCQualifiedIdType()) 572 return true; 573 } 574 return false; 575 } 576 bool PointerTypeTakesAnyBlockArguments(QualType QT); 577 bool PointerTypeTakesAnyObjCQualifiedType(QualType QT); 578 void GetExtentOfArgList(const char *Name, const char *&LParen, 579 const char *&RParen); 580 581 void QuoteDoublequotes(std::string &From, std::string &To) { 582 for (unsigned i = 0; i < From.length(); i++) { 583 if (From[i] == '"') 584 To += "\\\""; 585 else 586 To += From[i]; 587 } 588 } 589 590 QualType getSimpleFunctionType(QualType result, 591 ArrayRef<QualType> args, 592 bool variadic = false) { 593 if (result == Context->getObjCInstanceType()) 594 result = Context->getObjCIdType(); 595 FunctionProtoType::ExtProtoInfo fpi; 596 fpi.Variadic = variadic; 597 return Context->getFunctionType(result, args, fpi); 598 } 599 600 // Helper function: create a CStyleCastExpr with trivial type source info. 601 CStyleCastExpr* NoTypeInfoCStyleCastExpr(ASTContext *Ctx, QualType Ty, 602 CastKind Kind, Expr *E) { 603 TypeSourceInfo *TInfo = Ctx->getTrivialTypeSourceInfo(Ty, SourceLocation()); 604 return CStyleCastExpr::Create(*Ctx, Ty, VK_RValue, Kind, E, nullptr, 605 TInfo, SourceLocation(), SourceLocation()); 606 } 607 608 bool ImplementationIsNonLazy(const ObjCImplDecl *OD) const { 609 IdentifierInfo* II = &Context->Idents.get("load"); 610 Selector LoadSel = Context->Selectors.getSelector(0, &II); 611 return OD->getClassMethod(LoadSel) != nullptr; 612 } 613 614 StringLiteral *getStringLiteral(StringRef Str) { 615 QualType StrType = Context->getConstantArrayType( 616 Context->CharTy, llvm::APInt(32, Str.size() + 1), ArrayType::Normal, 617 0); 618 return StringLiteral::Create(*Context, Str, StringLiteral::Ascii, 619 /*Pascal=*/false, StrType, SourceLocation()); 620 } 621 }; 622 623 } 624 625 void RewriteModernObjC::RewriteBlocksInFunctionProtoType(QualType funcType, 626 NamedDecl *D) { 627 if (const FunctionProtoType *fproto 628 = dyn_cast<FunctionProtoType>(funcType.IgnoreParens())) { 629 for (const auto &I : fproto->param_types()) 630 if (isTopLevelBlockPointerType(I)) { 631 // All the args are checked/rewritten. Don't call twice! 632 RewriteBlockPointerDecl(D); 633 break; 634 } 635 } 636 } 637 638 void RewriteModernObjC::CheckFunctionPointerDecl(QualType funcType, NamedDecl *ND) { 639 const PointerType *PT = funcType->getAs<PointerType>(); 640 if (PT && PointerTypeTakesAnyBlockArguments(funcType)) 641 RewriteBlocksInFunctionProtoType(PT->getPointeeType(), ND); 642 } 643 644 static bool IsHeaderFile(const std::string &Filename) { 645 std::string::size_type DotPos = Filename.rfind('.'); 646 647 if (DotPos == std::string::npos) { 648 // no file extension 649 return false; 650 } 651 652 std::string Ext = std::string(Filename.begin()+DotPos+1, Filename.end()); 653 // C header: .h 654 // C++ header: .hh or .H; 655 return Ext == "h" || Ext == "hh" || Ext == "H"; 656 } 657 658 RewriteModernObjC::RewriteModernObjC(std::string inFile, raw_ostream* OS, 659 DiagnosticsEngine &D, const LangOptions &LOpts, 660 bool silenceMacroWarn, 661 bool LineInfo) 662 : Diags(D), LangOpts(LOpts), InFileName(inFile), OutFile(OS), 663 SilenceRewriteMacroWarning(silenceMacroWarn), GenerateLineInfo(LineInfo) { 664 IsHeader = IsHeaderFile(inFile); 665 RewriteFailedDiag = Diags.getCustomDiagID(DiagnosticsEngine::Warning, 666 "rewriting sub-expression within a macro (may not be correct)"); 667 // FIXME. This should be an error. But if block is not called, it is OK. And it 668 // may break including some headers. 669 GlobalBlockRewriteFailedDiag = Diags.getCustomDiagID(DiagnosticsEngine::Warning, 670 "rewriting block literal declared in global scope is not implemented"); 671 672 TryFinallyContainsReturnDiag = Diags.getCustomDiagID( 673 DiagnosticsEngine::Warning, 674 "rewriter doesn't support user-specified control flow semantics " 675 "for @try/@finally (code may not execute properly)"); 676 } 677 678 ASTConsumer *clang::CreateModernObjCRewriter(const std::string& InFile, 679 raw_ostream* OS, 680 DiagnosticsEngine &Diags, 681 const LangOptions &LOpts, 682 bool SilenceRewriteMacroWarning, 683 bool LineInfo) { 684 return new RewriteModernObjC(InFile, OS, Diags, LOpts, 685 SilenceRewriteMacroWarning, LineInfo); 686 } 687 688 void RewriteModernObjC::InitializeCommon(ASTContext &context) { 689 Context = &context; 690 SM = &Context->getSourceManager(); 691 TUDecl = Context->getTranslationUnitDecl(); 692 MsgSendFunctionDecl = nullptr; 693 MsgSendSuperFunctionDecl = nullptr; 694 MsgSendStretFunctionDecl = nullptr; 695 MsgSendSuperStretFunctionDecl = nullptr; 696 MsgSendFpretFunctionDecl = nullptr; 697 GetClassFunctionDecl = nullptr; 698 GetMetaClassFunctionDecl = nullptr; 699 GetSuperClassFunctionDecl = nullptr; 700 SelGetUidFunctionDecl = nullptr; 701 CFStringFunctionDecl = nullptr; 702 ConstantStringClassReference = nullptr; 703 NSStringRecord = nullptr; 704 CurMethodDef = nullptr; 705 CurFunctionDef = nullptr; 706 GlobalVarDecl = nullptr; 707 GlobalConstructionExp = nullptr; 708 SuperStructDecl = nullptr; 709 ProtocolTypeDecl = nullptr; 710 ConstantStringDecl = nullptr; 711 BcLabelCount = 0; 712 SuperConstructorFunctionDecl = nullptr; 713 NumObjCStringLiterals = 0; 714 PropParentMap = nullptr; 715 CurrentBody = nullptr; 716 DisableReplaceStmt = false; 717 objc_impl_method = false; 718 719 // Get the ID and start/end of the main file. 720 MainFileID = SM->getMainFileID(); 721 const llvm::MemoryBuffer *MainBuf = SM->getBuffer(MainFileID); 722 MainFileStart = MainBuf->getBufferStart(); 723 MainFileEnd = MainBuf->getBufferEnd(); 724 725 Rewrite.setSourceMgr(Context->getSourceManager(), Context->getLangOpts()); 726 } 727 728 //===----------------------------------------------------------------------===// 729 // Top Level Driver Code 730 //===----------------------------------------------------------------------===// 731 732 void RewriteModernObjC::HandleTopLevelSingleDecl(Decl *D) { 733 if (Diags.hasErrorOccurred()) 734 return; 735 736 // Two cases: either the decl could be in the main file, or it could be in a 737 // #included file. If the former, rewrite it now. If the later, check to see 738 // if we rewrote the #include/#import. 739 SourceLocation Loc = D->getLocation(); 740 Loc = SM->getExpansionLoc(Loc); 741 742 // If this is for a builtin, ignore it. 743 if (Loc.isInvalid()) return; 744 745 // Look for built-in declarations that we need to refer during the rewrite. 746 if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { 747 RewriteFunctionDecl(FD); 748 } else if (VarDecl *FVD = dyn_cast<VarDecl>(D)) { 749 // declared in <Foundation/NSString.h> 750 if (FVD->getName() == "_NSConstantStringClassReference") { 751 ConstantStringClassReference = FVD; 752 return; 753 } 754 } else if (ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(D)) { 755 RewriteCategoryDecl(CD); 756 } else if (ObjCProtocolDecl *PD = dyn_cast<ObjCProtocolDecl>(D)) { 757 if (PD->isThisDeclarationADefinition()) 758 RewriteProtocolDecl(PD); 759 } else if (LinkageSpecDecl *LSD = dyn_cast<LinkageSpecDecl>(D)) { 760 // FIXME. This will not work in all situations and leaving it out 761 // is harmless. 762 // RewriteLinkageSpec(LSD); 763 764 // Recurse into linkage specifications 765 for (DeclContext::decl_iterator DI = LSD->decls_begin(), 766 DIEnd = LSD->decls_end(); 767 DI != DIEnd; ) { 768 if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>((*DI))) { 769 if (!IFace->isThisDeclarationADefinition()) { 770 SmallVector<Decl *, 8> DG; 771 SourceLocation StartLoc = IFace->getLocStart(); 772 do { 773 if (isa<ObjCInterfaceDecl>(*DI) && 774 !cast<ObjCInterfaceDecl>(*DI)->isThisDeclarationADefinition() && 775 StartLoc == (*DI)->getLocStart()) 776 DG.push_back(*DI); 777 else 778 break; 779 780 ++DI; 781 } while (DI != DIEnd); 782 RewriteForwardClassDecl(DG); 783 continue; 784 } 785 else { 786 // Keep track of all interface declarations seen. 787 ObjCInterfacesSeen.push_back(IFace); 788 ++DI; 789 continue; 790 } 791 } 792 793 if (ObjCProtocolDecl *Proto = dyn_cast<ObjCProtocolDecl>((*DI))) { 794 if (!Proto->isThisDeclarationADefinition()) { 795 SmallVector<Decl *, 8> DG; 796 SourceLocation StartLoc = Proto->getLocStart(); 797 do { 798 if (isa<ObjCProtocolDecl>(*DI) && 799 !cast<ObjCProtocolDecl>(*DI)->isThisDeclarationADefinition() && 800 StartLoc == (*DI)->getLocStart()) 801 DG.push_back(*DI); 802 else 803 break; 804 805 ++DI; 806 } while (DI != DIEnd); 807 RewriteForwardProtocolDecl(DG); 808 continue; 809 } 810 } 811 812 HandleTopLevelSingleDecl(*DI); 813 ++DI; 814 } 815 } 816 // If we have a decl in the main file, see if we should rewrite it. 817 if (SM->isWrittenInMainFile(Loc)) 818 return HandleDeclInMainFile(D); 819 } 820 821 //===----------------------------------------------------------------------===// 822 // Syntactic (non-AST) Rewriting Code 823 //===----------------------------------------------------------------------===// 824 825 void RewriteModernObjC::RewriteInclude() { 826 SourceLocation LocStart = SM->getLocForStartOfFile(MainFileID); 827 StringRef MainBuf = SM->getBufferData(MainFileID); 828 const char *MainBufStart = MainBuf.begin(); 829 const char *MainBufEnd = MainBuf.end(); 830 size_t ImportLen = strlen("import"); 831 832 // Loop over the whole file, looking for includes. 833 for (const char *BufPtr = MainBufStart; BufPtr < MainBufEnd; ++BufPtr) { 834 if (*BufPtr == '#') { 835 if (++BufPtr == MainBufEnd) 836 return; 837 while (*BufPtr == ' ' || *BufPtr == '\t') 838 if (++BufPtr == MainBufEnd) 839 return; 840 if (!strncmp(BufPtr, "import", ImportLen)) { 841 // replace import with include 842 SourceLocation ImportLoc = 843 LocStart.getLocWithOffset(BufPtr-MainBufStart); 844 ReplaceText(ImportLoc, ImportLen, "include"); 845 BufPtr += ImportLen; 846 } 847 } 848 } 849 } 850 851 static void WriteInternalIvarName(const ObjCInterfaceDecl *IDecl, 852 ObjCIvarDecl *IvarDecl, std::string &Result) { 853 Result += "OBJC_IVAR_$_"; 854 Result += IDecl->getName(); 855 Result += "$"; 856 Result += IvarDecl->getName(); 857 } 858 859 std::string 860 RewriteModernObjC::getIvarAccessString(ObjCIvarDecl *D) { 861 const ObjCInterfaceDecl *ClassDecl = D->getContainingInterface(); 862 863 // Build name of symbol holding ivar offset. 864 std::string IvarOffsetName; 865 if (D->isBitField()) 866 ObjCIvarBitfieldGroupOffset(D, IvarOffsetName); 867 else 868 WriteInternalIvarName(ClassDecl, D, IvarOffsetName); 869 870 871 std::string S = "(*("; 872 QualType IvarT = D->getType(); 873 if (D->isBitField()) 874 IvarT = GetGroupRecordTypeForObjCIvarBitfield(D); 875 876 if (!isa<TypedefType>(IvarT) && IvarT->isRecordType()) { 877 RecordDecl *RD = IvarT->getAs<RecordType>()->getDecl(); 878 RD = RD->getDefinition(); 879 if (RD && !RD->getDeclName().getAsIdentifierInfo()) { 880 // decltype(((Foo_IMPL*)0)->bar) * 881 ObjCContainerDecl *CDecl = 882 dyn_cast<ObjCContainerDecl>(D->getDeclContext()); 883 // ivar in class extensions requires special treatment. 884 if (ObjCCategoryDecl *CatDecl = dyn_cast<ObjCCategoryDecl>(CDecl)) 885 CDecl = CatDecl->getClassInterface(); 886 std::string RecName = CDecl->getName(); 887 RecName += "_IMPL"; 888 RecordDecl *RD = RecordDecl::Create(*Context, TTK_Struct, TUDecl, 889 SourceLocation(), SourceLocation(), 890 &Context->Idents.get(RecName.c_str())); 891 QualType PtrStructIMPL = Context->getPointerType(Context->getTagDeclType(RD)); 892 unsigned UnsignedIntSize = 893 static_cast<unsigned>(Context->getTypeSize(Context->UnsignedIntTy)); 894 Expr *Zero = IntegerLiteral::Create(*Context, 895 llvm::APInt(UnsignedIntSize, 0), 896 Context->UnsignedIntTy, SourceLocation()); 897 Zero = NoTypeInfoCStyleCastExpr(Context, PtrStructIMPL, CK_BitCast, Zero); 898 ParenExpr *PE = new (Context) ParenExpr(SourceLocation(), SourceLocation(), 899 Zero); 900 FieldDecl *FD = FieldDecl::Create(*Context, nullptr, SourceLocation(), 901 SourceLocation(), 902 &Context->Idents.get(D->getNameAsString()), 903 IvarT, nullptr, 904 /*BitWidth=*/nullptr, /*Mutable=*/true, 905 ICIS_NoInit); 906 MemberExpr *ME = new (Context) MemberExpr(PE, true, FD, SourceLocation(), 907 FD->getType(), VK_LValue, 908 OK_Ordinary); 909 IvarT = Context->getDecltypeType(ME, ME->getType()); 910 } 911 } 912 convertObjCTypeToCStyleType(IvarT); 913 QualType castT = Context->getPointerType(IvarT); 914 std::string TypeString(castT.getAsString(Context->getPrintingPolicy())); 915 S += TypeString; 916 S += ")"; 917 918 // ((char *)self + IVAR_OFFSET_SYMBOL_NAME) 919 S += "((char *)self + "; 920 S += IvarOffsetName; 921 S += "))"; 922 if (D->isBitField()) { 923 S += "."; 924 S += D->getNameAsString(); 925 } 926 ReferencedIvars[const_cast<ObjCInterfaceDecl *>(ClassDecl)].insert(D); 927 return S; 928 } 929 930 /// mustSynthesizeSetterGetterMethod - returns true if setter or getter has not 931 /// been found in the class implementation. In this case, it must be synthesized. 932 static bool mustSynthesizeSetterGetterMethod(ObjCImplementationDecl *IMP, 933 ObjCPropertyDecl *PD, 934 bool getter) { 935 return getter ? !IMP->getInstanceMethod(PD->getGetterName()) 936 : !IMP->getInstanceMethod(PD->getSetterName()); 937 938 } 939 940 void RewriteModernObjC::RewritePropertyImplDecl(ObjCPropertyImplDecl *PID, 941 ObjCImplementationDecl *IMD, 942 ObjCCategoryImplDecl *CID) { 943 static bool objcGetPropertyDefined = false; 944 static bool objcSetPropertyDefined = false; 945 SourceLocation startGetterSetterLoc; 946 947 if (PID->getLocStart().isValid()) { 948 SourceLocation startLoc = PID->getLocStart(); 949 InsertText(startLoc, "// "); 950 const char *startBuf = SM->getCharacterData(startLoc); 951 assert((*startBuf == '@') && "bogus @synthesize location"); 952 const char *semiBuf = strchr(startBuf, ';'); 953 assert((*semiBuf == ';') && "@synthesize: can't find ';'"); 954 startGetterSetterLoc = startLoc.getLocWithOffset(semiBuf-startBuf+1); 955 } 956 else 957 startGetterSetterLoc = IMD ? IMD->getLocEnd() : CID->getLocEnd(); 958 959 if (PID->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic) 960 return; // FIXME: is this correct? 961 962 // Generate the 'getter' function. 963 ObjCPropertyDecl *PD = PID->getPropertyDecl(); 964 ObjCIvarDecl *OID = PID->getPropertyIvarDecl(); 965 assert(IMD && OID && "Synthesized ivars must be attached to @implementation"); 966 967 unsigned Attributes = PD->getPropertyAttributes(); 968 if (mustSynthesizeSetterGetterMethod(IMD, PD, true /*getter*/)) { 969 bool GenGetProperty = !(Attributes & ObjCPropertyDecl::OBJC_PR_nonatomic) && 970 (Attributes & (ObjCPropertyDecl::OBJC_PR_retain | 971 ObjCPropertyDecl::OBJC_PR_copy)); 972 std::string Getr; 973 if (GenGetProperty && !objcGetPropertyDefined) { 974 objcGetPropertyDefined = true; 975 // FIXME. Is this attribute correct in all cases? 976 Getr = "\nextern \"C\" __declspec(dllimport) " 977 "id objc_getProperty(id, SEL, long, bool);\n"; 978 } 979 RewriteObjCMethodDecl(OID->getContainingInterface(), 980 PD->getGetterMethodDecl(), Getr); 981 Getr += "{ "; 982 // Synthesize an explicit cast to gain access to the ivar. 983 // See objc-act.c:objc_synthesize_new_getter() for details. 984 if (GenGetProperty) { 985 // return objc_getProperty(self, _cmd, offsetof(ClassDecl, OID), 1) 986 Getr += "typedef "; 987 const FunctionType *FPRetType = nullptr; 988 RewriteTypeIntoString(PD->getGetterMethodDecl()->getReturnType(), Getr, 989 FPRetType); 990 Getr += " _TYPE"; 991 if (FPRetType) { 992 Getr += ")"; // close the precedence "scope" for "*". 993 994 // Now, emit the argument types (if any). 995 if (const FunctionProtoType *FT = dyn_cast<FunctionProtoType>(FPRetType)){ 996 Getr += "("; 997 for (unsigned i = 0, e = FT->getNumParams(); i != e; ++i) { 998 if (i) Getr += ", "; 999 std::string ParamStr = 1000 FT->getParamType(i).getAsString(Context->getPrintingPolicy()); 1001 Getr += ParamStr; 1002 } 1003 if (FT->isVariadic()) { 1004 if (FT->getNumParams()) 1005 Getr += ", "; 1006 Getr += "..."; 1007 } 1008 Getr += ")"; 1009 } else 1010 Getr += "()"; 1011 } 1012 Getr += ";\n"; 1013 Getr += "return (_TYPE)"; 1014 Getr += "objc_getProperty(self, _cmd, "; 1015 RewriteIvarOffsetComputation(OID, Getr); 1016 Getr += ", 1)"; 1017 } 1018 else 1019 Getr += "return " + getIvarAccessString(OID); 1020 Getr += "; }"; 1021 InsertText(startGetterSetterLoc, Getr); 1022 } 1023 1024 if (PD->isReadOnly() || 1025 !mustSynthesizeSetterGetterMethod(IMD, PD, false /*setter*/)) 1026 return; 1027 1028 // Generate the 'setter' function. 1029 std::string Setr; 1030 bool GenSetProperty = Attributes & (ObjCPropertyDecl::OBJC_PR_retain | 1031 ObjCPropertyDecl::OBJC_PR_copy); 1032 if (GenSetProperty && !objcSetPropertyDefined) { 1033 objcSetPropertyDefined = true; 1034 // FIXME. Is this attribute correct in all cases? 1035 Setr = "\nextern \"C\" __declspec(dllimport) " 1036 "void objc_setProperty (id, SEL, long, id, bool, bool);\n"; 1037 } 1038 1039 RewriteObjCMethodDecl(OID->getContainingInterface(), 1040 PD->getSetterMethodDecl(), Setr); 1041 Setr += "{ "; 1042 // Synthesize an explicit cast to initialize the ivar. 1043 // See objc-act.c:objc_synthesize_new_setter() for details. 1044 if (GenSetProperty) { 1045 Setr += "objc_setProperty (self, _cmd, "; 1046 RewriteIvarOffsetComputation(OID, Setr); 1047 Setr += ", (id)"; 1048 Setr += PD->getName(); 1049 Setr += ", "; 1050 if (Attributes & ObjCPropertyDecl::OBJC_PR_nonatomic) 1051 Setr += "0, "; 1052 else 1053 Setr += "1, "; 1054 if (Attributes & ObjCPropertyDecl::OBJC_PR_copy) 1055 Setr += "1)"; 1056 else 1057 Setr += "0)"; 1058 } 1059 else { 1060 Setr += getIvarAccessString(OID) + " = "; 1061 Setr += PD->getName(); 1062 } 1063 Setr += "; }\n"; 1064 InsertText(startGetterSetterLoc, Setr); 1065 } 1066 1067 static void RewriteOneForwardClassDecl(ObjCInterfaceDecl *ForwardDecl, 1068 std::string &typedefString) { 1069 typedefString += "\n#ifndef _REWRITER_typedef_"; 1070 typedefString += ForwardDecl->getNameAsString(); 1071 typedefString += "\n"; 1072 typedefString += "#define _REWRITER_typedef_"; 1073 typedefString += ForwardDecl->getNameAsString(); 1074 typedefString += "\n"; 1075 typedefString += "typedef struct objc_object "; 1076 typedefString += ForwardDecl->getNameAsString(); 1077 // typedef struct { } _objc_exc_Classname; 1078 typedefString += ";\ntypedef struct {} _objc_exc_"; 1079 typedefString += ForwardDecl->getNameAsString(); 1080 typedefString += ";\n#endif\n"; 1081 } 1082 1083 void RewriteModernObjC::RewriteForwardClassEpilogue(ObjCInterfaceDecl *ClassDecl, 1084 const std::string &typedefString) { 1085 SourceLocation startLoc = ClassDecl->getLocStart(); 1086 const char *startBuf = SM->getCharacterData(startLoc); 1087 const char *semiPtr = strchr(startBuf, ';'); 1088 // Replace the @class with typedefs corresponding to the classes. 1089 ReplaceText(startLoc, semiPtr-startBuf+1, typedefString); 1090 } 1091 1092 void RewriteModernObjC::RewriteForwardClassDecl(DeclGroupRef D) { 1093 std::string typedefString; 1094 for (DeclGroupRef::iterator I = D.begin(), E = D.end(); I != E; ++I) { 1095 if (ObjCInterfaceDecl *ForwardDecl = dyn_cast<ObjCInterfaceDecl>(*I)) { 1096 if (I == D.begin()) { 1097 // Translate to typedef's that forward reference structs with the same name 1098 // as the class. As a convenience, we include the original declaration 1099 // as a comment. 1100 typedefString += "// @class "; 1101 typedefString += ForwardDecl->getNameAsString(); 1102 typedefString += ";"; 1103 } 1104 RewriteOneForwardClassDecl(ForwardDecl, typedefString); 1105 } 1106 else 1107 HandleTopLevelSingleDecl(*I); 1108 } 1109 DeclGroupRef::iterator I = D.begin(); 1110 RewriteForwardClassEpilogue(cast<ObjCInterfaceDecl>(*I), typedefString); 1111 } 1112 1113 void RewriteModernObjC::RewriteForwardClassDecl( 1114 const SmallVectorImpl<Decl *> &D) { 1115 std::string typedefString; 1116 for (unsigned i = 0; i < D.size(); i++) { 1117 ObjCInterfaceDecl *ForwardDecl = cast<ObjCInterfaceDecl>(D[i]); 1118 if (i == 0) { 1119 typedefString += "// @class "; 1120 typedefString += ForwardDecl->getNameAsString(); 1121 typedefString += ";"; 1122 } 1123 RewriteOneForwardClassDecl(ForwardDecl, typedefString); 1124 } 1125 RewriteForwardClassEpilogue(cast<ObjCInterfaceDecl>(D[0]), typedefString); 1126 } 1127 1128 void RewriteModernObjC::RewriteMethodDeclaration(ObjCMethodDecl *Method) { 1129 // When method is a synthesized one, such as a getter/setter there is 1130 // nothing to rewrite. 1131 if (Method->isImplicit()) 1132 return; 1133 SourceLocation LocStart = Method->getLocStart(); 1134 SourceLocation LocEnd = Method->getLocEnd(); 1135 1136 if (SM->getExpansionLineNumber(LocEnd) > 1137 SM->getExpansionLineNumber(LocStart)) { 1138 InsertText(LocStart, "#if 0\n"); 1139 ReplaceText(LocEnd, 1, ";\n#endif\n"); 1140 } else { 1141 InsertText(LocStart, "// "); 1142 } 1143 } 1144 1145 void RewriteModernObjC::RewriteProperty(ObjCPropertyDecl *prop) { 1146 SourceLocation Loc = prop->getAtLoc(); 1147 1148 ReplaceText(Loc, 0, "// "); 1149 // FIXME: handle properties that are declared across multiple lines. 1150 } 1151 1152 void RewriteModernObjC::RewriteCategoryDecl(ObjCCategoryDecl *CatDecl) { 1153 SourceLocation LocStart = CatDecl->getLocStart(); 1154 1155 // FIXME: handle category headers that are declared across multiple lines. 1156 if (CatDecl->getIvarRBraceLoc().isValid()) { 1157 ReplaceText(LocStart, 1, "/** "); 1158 ReplaceText(CatDecl->getIvarRBraceLoc(), 1, "**/ "); 1159 } 1160 else { 1161 ReplaceText(LocStart, 0, "// "); 1162 } 1163 1164 for (auto *I : CatDecl->properties()) 1165 RewriteProperty(I); 1166 1167 for (auto *I : CatDecl->instance_methods()) 1168 RewriteMethodDeclaration(I); 1169 for (auto *I : CatDecl->class_methods()) 1170 RewriteMethodDeclaration(I); 1171 1172 // Lastly, comment out the @end. 1173 ReplaceText(CatDecl->getAtEndRange().getBegin(), 1174 strlen("@end"), "/* @end */\n"); 1175 } 1176 1177 void RewriteModernObjC::RewriteProtocolDecl(ObjCProtocolDecl *PDecl) { 1178 SourceLocation LocStart = PDecl->getLocStart(); 1179 assert(PDecl->isThisDeclarationADefinition()); 1180 1181 // FIXME: handle protocol headers that are declared across multiple lines. 1182 ReplaceText(LocStart, 0, "// "); 1183 1184 for (auto *I : PDecl->instance_methods()) 1185 RewriteMethodDeclaration(I); 1186 for (auto *I : PDecl->class_methods()) 1187 RewriteMethodDeclaration(I); 1188 for (auto *I : PDecl->properties()) 1189 RewriteProperty(I); 1190 1191 // Lastly, comment out the @end. 1192 SourceLocation LocEnd = PDecl->getAtEndRange().getBegin(); 1193 ReplaceText(LocEnd, strlen("@end"), "/* @end */\n"); 1194 1195 // Must comment out @optional/@required 1196 const char *startBuf = SM->getCharacterData(LocStart); 1197 const char *endBuf = SM->getCharacterData(LocEnd); 1198 for (const char *p = startBuf; p < endBuf; p++) { 1199 if (*p == '@' && !strncmp(p+1, "optional", strlen("optional"))) { 1200 SourceLocation OptionalLoc = LocStart.getLocWithOffset(p-startBuf); 1201 ReplaceText(OptionalLoc, strlen("@optional"), "/* @optional */"); 1202 1203 } 1204 else if (*p == '@' && !strncmp(p+1, "required", strlen("required"))) { 1205 SourceLocation OptionalLoc = LocStart.getLocWithOffset(p-startBuf); 1206 ReplaceText(OptionalLoc, strlen("@required"), "/* @required */"); 1207 1208 } 1209 } 1210 } 1211 1212 void RewriteModernObjC::RewriteForwardProtocolDecl(DeclGroupRef D) { 1213 SourceLocation LocStart = (*D.begin())->getLocStart(); 1214 if (LocStart.isInvalid()) 1215 llvm_unreachable("Invalid SourceLocation"); 1216 // FIXME: handle forward protocol that are declared across multiple lines. 1217 ReplaceText(LocStart, 0, "// "); 1218 } 1219 1220 void 1221 RewriteModernObjC::RewriteForwardProtocolDecl(const SmallVectorImpl<Decl *> &DG) { 1222 SourceLocation LocStart = DG[0]->getLocStart(); 1223 if (LocStart.isInvalid()) 1224 llvm_unreachable("Invalid SourceLocation"); 1225 // FIXME: handle forward protocol that are declared across multiple lines. 1226 ReplaceText(LocStart, 0, "// "); 1227 } 1228 1229 void 1230 RewriteModernObjC::RewriteLinkageSpec(LinkageSpecDecl *LSD) { 1231 SourceLocation LocStart = LSD->getExternLoc(); 1232 if (LocStart.isInvalid()) 1233 llvm_unreachable("Invalid extern SourceLocation"); 1234 1235 ReplaceText(LocStart, 0, "// "); 1236 if (!LSD->hasBraces()) 1237 return; 1238 // FIXME. We don't rewrite well if '{' is not on same line as 'extern'. 1239 SourceLocation LocRBrace = LSD->getRBraceLoc(); 1240 if (LocRBrace.isInvalid()) 1241 llvm_unreachable("Invalid rbrace SourceLocation"); 1242 ReplaceText(LocRBrace, 0, "// "); 1243 } 1244 1245 void RewriteModernObjC::RewriteTypeIntoString(QualType T, std::string &ResultStr, 1246 const FunctionType *&FPRetType) { 1247 if (T->isObjCQualifiedIdType()) 1248 ResultStr += "id"; 1249 else if (T->isFunctionPointerType() || 1250 T->isBlockPointerType()) { 1251 // needs special handling, since pointer-to-functions have special 1252 // syntax (where a decaration models use). 1253 QualType retType = T; 1254 QualType PointeeTy; 1255 if (const PointerType* PT = retType->getAs<PointerType>()) 1256 PointeeTy = PT->getPointeeType(); 1257 else if (const BlockPointerType *BPT = retType->getAs<BlockPointerType>()) 1258 PointeeTy = BPT->getPointeeType(); 1259 if ((FPRetType = PointeeTy->getAs<FunctionType>())) { 1260 ResultStr += 1261 FPRetType->getReturnType().getAsString(Context->getPrintingPolicy()); 1262 ResultStr += "(*"; 1263 } 1264 } else 1265 ResultStr += T.getAsString(Context->getPrintingPolicy()); 1266 } 1267 1268 void RewriteModernObjC::RewriteObjCMethodDecl(const ObjCInterfaceDecl *IDecl, 1269 ObjCMethodDecl *OMD, 1270 std::string &ResultStr) { 1271 //fprintf(stderr,"In RewriteObjCMethodDecl\n"); 1272 const FunctionType *FPRetType = nullptr; 1273 ResultStr += "\nstatic "; 1274 RewriteTypeIntoString(OMD->getReturnType(), ResultStr, FPRetType); 1275 ResultStr += " "; 1276 1277 // Unique method name 1278 std::string NameStr; 1279 1280 if (OMD->isInstanceMethod()) 1281 NameStr += "_I_"; 1282 else 1283 NameStr += "_C_"; 1284 1285 NameStr += IDecl->getNameAsString(); 1286 NameStr += "_"; 1287 1288 if (ObjCCategoryImplDecl *CID = 1289 dyn_cast<ObjCCategoryImplDecl>(OMD->getDeclContext())) { 1290 NameStr += CID->getNameAsString(); 1291 NameStr += "_"; 1292 } 1293 // Append selector names, replacing ':' with '_' 1294 { 1295 std::string selString = OMD->getSelector().getAsString(); 1296 int len = selString.size(); 1297 for (int i = 0; i < len; i++) 1298 if (selString[i] == ':') 1299 selString[i] = '_'; 1300 NameStr += selString; 1301 } 1302 // Remember this name for metadata emission 1303 MethodInternalNames[OMD] = NameStr; 1304 ResultStr += NameStr; 1305 1306 // Rewrite arguments 1307 ResultStr += "("; 1308 1309 // invisible arguments 1310 if (OMD->isInstanceMethod()) { 1311 QualType selfTy = Context->getObjCInterfaceType(IDecl); 1312 selfTy = Context->getPointerType(selfTy); 1313 if (!LangOpts.MicrosoftExt) { 1314 if (ObjCSynthesizedStructs.count(const_cast<ObjCInterfaceDecl*>(IDecl))) 1315 ResultStr += "struct "; 1316 } 1317 // When rewriting for Microsoft, explicitly omit the structure name. 1318 ResultStr += IDecl->getNameAsString(); 1319 ResultStr += " *"; 1320 } 1321 else 1322 ResultStr += Context->getObjCClassType().getAsString( 1323 Context->getPrintingPolicy()); 1324 1325 ResultStr += " self, "; 1326 ResultStr += Context->getObjCSelType().getAsString(Context->getPrintingPolicy()); 1327 ResultStr += " _cmd"; 1328 1329 // Method arguments. 1330 for (const auto *PDecl : OMD->params()) { 1331 ResultStr += ", "; 1332 if (PDecl->getType()->isObjCQualifiedIdType()) { 1333 ResultStr += "id "; 1334 ResultStr += PDecl->getNameAsString(); 1335 } else { 1336 std::string Name = PDecl->getNameAsString(); 1337 QualType QT = PDecl->getType(); 1338 // Make sure we convert "t (^)(...)" to "t (*)(...)". 1339 (void)convertBlockPointerToFunctionPointer(QT); 1340 QT.getAsStringInternal(Name, Context->getPrintingPolicy()); 1341 ResultStr += Name; 1342 } 1343 } 1344 if (OMD->isVariadic()) 1345 ResultStr += ", ..."; 1346 ResultStr += ") "; 1347 1348 if (FPRetType) { 1349 ResultStr += ")"; // close the precedence "scope" for "*". 1350 1351 // Now, emit the argument types (if any). 1352 if (const FunctionProtoType *FT = dyn_cast<FunctionProtoType>(FPRetType)) { 1353 ResultStr += "("; 1354 for (unsigned i = 0, e = FT->getNumParams(); i != e; ++i) { 1355 if (i) ResultStr += ", "; 1356 std::string ParamStr = 1357 FT->getParamType(i).getAsString(Context->getPrintingPolicy()); 1358 ResultStr += ParamStr; 1359 } 1360 if (FT->isVariadic()) { 1361 if (FT->getNumParams()) 1362 ResultStr += ", "; 1363 ResultStr += "..."; 1364 } 1365 ResultStr += ")"; 1366 } else { 1367 ResultStr += "()"; 1368 } 1369 } 1370 } 1371 void RewriteModernObjC::RewriteImplementationDecl(Decl *OID) { 1372 ObjCImplementationDecl *IMD = dyn_cast<ObjCImplementationDecl>(OID); 1373 ObjCCategoryImplDecl *CID = dyn_cast<ObjCCategoryImplDecl>(OID); 1374 1375 if (IMD) { 1376 if (IMD->getIvarRBraceLoc().isValid()) { 1377 ReplaceText(IMD->getLocStart(), 1, "/** "); 1378 ReplaceText(IMD->getIvarRBraceLoc(), 1, "**/ "); 1379 } 1380 else { 1381 InsertText(IMD->getLocStart(), "// "); 1382 } 1383 } 1384 else 1385 InsertText(CID->getLocStart(), "// "); 1386 1387 for (auto *OMD : IMD ? IMD->instance_methods() : CID->instance_methods()) { 1388 std::string ResultStr; 1389 RewriteObjCMethodDecl(OMD->getClassInterface(), OMD, ResultStr); 1390 SourceLocation LocStart = OMD->getLocStart(); 1391 SourceLocation LocEnd = OMD->getCompoundBody()->getLocStart(); 1392 1393 const char *startBuf = SM->getCharacterData(LocStart); 1394 const char *endBuf = SM->getCharacterData(LocEnd); 1395 ReplaceText(LocStart, endBuf-startBuf, ResultStr); 1396 } 1397 1398 for (auto *OMD : IMD ? IMD->class_methods() : CID->class_methods()) { 1399 std::string ResultStr; 1400 RewriteObjCMethodDecl(OMD->getClassInterface(), OMD, ResultStr); 1401 SourceLocation LocStart = OMD->getLocStart(); 1402 SourceLocation LocEnd = OMD->getCompoundBody()->getLocStart(); 1403 1404 const char *startBuf = SM->getCharacterData(LocStart); 1405 const char *endBuf = SM->getCharacterData(LocEnd); 1406 ReplaceText(LocStart, endBuf-startBuf, ResultStr); 1407 } 1408 for (auto *I : IMD ? IMD->property_impls() : CID->property_impls()) 1409 RewritePropertyImplDecl(I, IMD, CID); 1410 1411 InsertText(IMD ? IMD->getLocEnd() : CID->getLocEnd(), "// "); 1412 } 1413 1414 void RewriteModernObjC::RewriteInterfaceDecl(ObjCInterfaceDecl *ClassDecl) { 1415 // Do not synthesize more than once. 1416 if (ObjCSynthesizedStructs.count(ClassDecl)) 1417 return; 1418 // Make sure super class's are written before current class is written. 1419 ObjCInterfaceDecl *SuperClass = ClassDecl->getSuperClass(); 1420 while (SuperClass) { 1421 RewriteInterfaceDecl(SuperClass); 1422 SuperClass = SuperClass->getSuperClass(); 1423 } 1424 std::string ResultStr; 1425 if (!ObjCWrittenInterfaces.count(ClassDecl->getCanonicalDecl())) { 1426 // we haven't seen a forward decl - generate a typedef. 1427 RewriteOneForwardClassDecl(ClassDecl, ResultStr); 1428 RewriteIvarOffsetSymbols(ClassDecl, ResultStr); 1429 1430 RewriteObjCInternalStruct(ClassDecl, ResultStr); 1431 // Mark this typedef as having been written into its c++ equivalent. 1432 ObjCWrittenInterfaces.insert(ClassDecl->getCanonicalDecl()); 1433 1434 for (auto *I : ClassDecl->properties()) 1435 RewriteProperty(I); 1436 for (auto *I : ClassDecl->instance_methods()) 1437 RewriteMethodDeclaration(I); 1438 for (auto *I : ClassDecl->class_methods()) 1439 RewriteMethodDeclaration(I); 1440 1441 // Lastly, comment out the @end. 1442 ReplaceText(ClassDecl->getAtEndRange().getBegin(), strlen("@end"), 1443 "/* @end */\n"); 1444 } 1445 } 1446 1447 Stmt *RewriteModernObjC::RewritePropertyOrImplicitSetter(PseudoObjectExpr *PseudoOp) { 1448 SourceRange OldRange = PseudoOp->getSourceRange(); 1449 1450 // We just magically know some things about the structure of this 1451 // expression. 1452 ObjCMessageExpr *OldMsg = 1453 cast<ObjCMessageExpr>(PseudoOp->getSemanticExpr( 1454 PseudoOp->getNumSemanticExprs() - 1)); 1455 1456 // Because the rewriter doesn't allow us to rewrite rewritten code, 1457 // we need to suppress rewriting the sub-statements. 1458 Expr *Base; 1459 SmallVector<Expr*, 2> Args; 1460 { 1461 DisableReplaceStmtScope S(*this); 1462 1463 // Rebuild the base expression if we have one. 1464 Base = nullptr; 1465 if (OldMsg->getReceiverKind() == ObjCMessageExpr::Instance) { 1466 Base = OldMsg->getInstanceReceiver(); 1467 Base = cast<OpaqueValueExpr>(Base)->getSourceExpr(); 1468 Base = cast<Expr>(RewriteFunctionBodyOrGlobalInitializer(Base)); 1469 } 1470 1471 unsigned numArgs = OldMsg->getNumArgs(); 1472 for (unsigned i = 0; i < numArgs; i++) { 1473 Expr *Arg = OldMsg->getArg(i); 1474 if (isa<OpaqueValueExpr>(Arg)) 1475 Arg = cast<OpaqueValueExpr>(Arg)->getSourceExpr(); 1476 Arg = cast<Expr>(RewriteFunctionBodyOrGlobalInitializer(Arg)); 1477 Args.push_back(Arg); 1478 } 1479 } 1480 1481 // TODO: avoid this copy. 1482 SmallVector<SourceLocation, 1> SelLocs; 1483 OldMsg->getSelectorLocs(SelLocs); 1484 1485 ObjCMessageExpr *NewMsg = nullptr; 1486 switch (OldMsg->getReceiverKind()) { 1487 case ObjCMessageExpr::Class: 1488 NewMsg = ObjCMessageExpr::Create(*Context, OldMsg->getType(), 1489 OldMsg->getValueKind(), 1490 OldMsg->getLeftLoc(), 1491 OldMsg->getClassReceiverTypeInfo(), 1492 OldMsg->getSelector(), 1493 SelLocs, 1494 OldMsg->getMethodDecl(), 1495 Args, 1496 OldMsg->getRightLoc(), 1497 OldMsg->isImplicit()); 1498 break; 1499 1500 case ObjCMessageExpr::Instance: 1501 NewMsg = ObjCMessageExpr::Create(*Context, OldMsg->getType(), 1502 OldMsg->getValueKind(), 1503 OldMsg->getLeftLoc(), 1504 Base, 1505 OldMsg->getSelector(), 1506 SelLocs, 1507 OldMsg->getMethodDecl(), 1508 Args, 1509 OldMsg->getRightLoc(), 1510 OldMsg->isImplicit()); 1511 break; 1512 1513 case ObjCMessageExpr::SuperClass: 1514 case ObjCMessageExpr::SuperInstance: 1515 NewMsg = ObjCMessageExpr::Create(*Context, OldMsg->getType(), 1516 OldMsg->getValueKind(), 1517 OldMsg->getLeftLoc(), 1518 OldMsg->getSuperLoc(), 1519 OldMsg->getReceiverKind() == ObjCMessageExpr::SuperInstance, 1520 OldMsg->getSuperType(), 1521 OldMsg->getSelector(), 1522 SelLocs, 1523 OldMsg->getMethodDecl(), 1524 Args, 1525 OldMsg->getRightLoc(), 1526 OldMsg->isImplicit()); 1527 break; 1528 } 1529 1530 Stmt *Replacement = SynthMessageExpr(NewMsg); 1531 ReplaceStmtWithRange(PseudoOp, Replacement, OldRange); 1532 return Replacement; 1533 } 1534 1535 Stmt *RewriteModernObjC::RewritePropertyOrImplicitGetter(PseudoObjectExpr *PseudoOp) { 1536 SourceRange OldRange = PseudoOp->getSourceRange(); 1537 1538 // We just magically know some things about the structure of this 1539 // expression. 1540 ObjCMessageExpr *OldMsg = 1541 cast<ObjCMessageExpr>(PseudoOp->getResultExpr()->IgnoreImplicit()); 1542 1543 // Because the rewriter doesn't allow us to rewrite rewritten code, 1544 // we need to suppress rewriting the sub-statements. 1545 Expr *Base = nullptr; 1546 SmallVector<Expr*, 1> Args; 1547 { 1548 DisableReplaceStmtScope S(*this); 1549 // Rebuild the base expression if we have one. 1550 if (OldMsg->getReceiverKind() == ObjCMessageExpr::Instance) { 1551 Base = OldMsg->getInstanceReceiver(); 1552 Base = cast<OpaqueValueExpr>(Base)->getSourceExpr(); 1553 Base = cast<Expr>(RewriteFunctionBodyOrGlobalInitializer(Base)); 1554 } 1555 unsigned numArgs = OldMsg->getNumArgs(); 1556 for (unsigned i = 0; i < numArgs; i++) { 1557 Expr *Arg = OldMsg->getArg(i); 1558 if (isa<OpaqueValueExpr>(Arg)) 1559 Arg = cast<OpaqueValueExpr>(Arg)->getSourceExpr(); 1560 Arg = cast<Expr>(RewriteFunctionBodyOrGlobalInitializer(Arg)); 1561 Args.push_back(Arg); 1562 } 1563 } 1564 1565 // Intentionally empty. 1566 SmallVector<SourceLocation, 1> SelLocs; 1567 1568 ObjCMessageExpr *NewMsg = nullptr; 1569 switch (OldMsg->getReceiverKind()) { 1570 case ObjCMessageExpr::Class: 1571 NewMsg = ObjCMessageExpr::Create(*Context, OldMsg->getType(), 1572 OldMsg->getValueKind(), 1573 OldMsg->getLeftLoc(), 1574 OldMsg->getClassReceiverTypeInfo(), 1575 OldMsg->getSelector(), 1576 SelLocs, 1577 OldMsg->getMethodDecl(), 1578 Args, 1579 OldMsg->getRightLoc(), 1580 OldMsg->isImplicit()); 1581 break; 1582 1583 case ObjCMessageExpr::Instance: 1584 NewMsg = ObjCMessageExpr::Create(*Context, OldMsg->getType(), 1585 OldMsg->getValueKind(), 1586 OldMsg->getLeftLoc(), 1587 Base, 1588 OldMsg->getSelector(), 1589 SelLocs, 1590 OldMsg->getMethodDecl(), 1591 Args, 1592 OldMsg->getRightLoc(), 1593 OldMsg->isImplicit()); 1594 break; 1595 1596 case ObjCMessageExpr::SuperClass: 1597 case ObjCMessageExpr::SuperInstance: 1598 NewMsg = ObjCMessageExpr::Create(*Context, OldMsg->getType(), 1599 OldMsg->getValueKind(), 1600 OldMsg->getLeftLoc(), 1601 OldMsg->getSuperLoc(), 1602 OldMsg->getReceiverKind() == ObjCMessageExpr::SuperInstance, 1603 OldMsg->getSuperType(), 1604 OldMsg->getSelector(), 1605 SelLocs, 1606 OldMsg->getMethodDecl(), 1607 Args, 1608 OldMsg->getRightLoc(), 1609 OldMsg->isImplicit()); 1610 break; 1611 } 1612 1613 Stmt *Replacement = SynthMessageExpr(NewMsg); 1614 ReplaceStmtWithRange(PseudoOp, Replacement, OldRange); 1615 return Replacement; 1616 } 1617 1618 /// SynthCountByEnumWithState - To print: 1619 /// ((NSUInteger (*) 1620 /// (id, SEL, struct __objcFastEnumerationState *, id *, NSUInteger)) 1621 /// (void *)objc_msgSend)((id)l_collection, 1622 /// sel_registerName( 1623 /// "countByEnumeratingWithState:objects:count:"), 1624 /// &enumState, 1625 /// (id *)__rw_items, (NSUInteger)16) 1626 /// 1627 void RewriteModernObjC::SynthCountByEnumWithState(std::string &buf) { 1628 buf += "((_WIN_NSUInteger (*) (id, SEL, struct __objcFastEnumerationState *, " 1629 "id *, _WIN_NSUInteger))(void *)objc_msgSend)"; 1630 buf += "\n\t\t"; 1631 buf += "((id)l_collection,\n\t\t"; 1632 buf += "sel_registerName(\"countByEnumeratingWithState:objects:count:\"),"; 1633 buf += "\n\t\t"; 1634 buf += "&enumState, " 1635 "(id *)__rw_items, (_WIN_NSUInteger)16)"; 1636 } 1637 1638 /// RewriteBreakStmt - Rewrite for a break-stmt inside an ObjC2's foreach 1639 /// statement to exit to its outer synthesized loop. 1640 /// 1641 Stmt *RewriteModernObjC::RewriteBreakStmt(BreakStmt *S) { 1642 if (Stmts.empty() || !isa<ObjCForCollectionStmt>(Stmts.back())) 1643 return S; 1644 // replace break with goto __break_label 1645 std::string buf; 1646 1647 SourceLocation startLoc = S->getLocStart(); 1648 buf = "goto __break_label_"; 1649 buf += utostr(ObjCBcLabelNo.back()); 1650 ReplaceText(startLoc, strlen("break"), buf); 1651 1652 return nullptr; 1653 } 1654 1655 void RewriteModernObjC::ConvertSourceLocationToLineDirective( 1656 SourceLocation Loc, 1657 std::string &LineString) { 1658 if (Loc.isFileID() && GenerateLineInfo) { 1659 LineString += "\n#line "; 1660 PresumedLoc PLoc = SM->getPresumedLoc(Loc); 1661 LineString += utostr(PLoc.getLine()); 1662 LineString += " \""; 1663 LineString += Lexer::Stringify(PLoc.getFilename()); 1664 LineString += "\"\n"; 1665 } 1666 } 1667 1668 /// RewriteContinueStmt - Rewrite for a continue-stmt inside an ObjC2's foreach 1669 /// statement to continue with its inner synthesized loop. 1670 /// 1671 Stmt *RewriteModernObjC::RewriteContinueStmt(ContinueStmt *S) { 1672 if (Stmts.empty() || !isa<ObjCForCollectionStmt>(Stmts.back())) 1673 return S; 1674 // replace continue with goto __continue_label 1675 std::string buf; 1676 1677 SourceLocation startLoc = S->getLocStart(); 1678 buf = "goto __continue_label_"; 1679 buf += utostr(ObjCBcLabelNo.back()); 1680 ReplaceText(startLoc, strlen("continue"), buf); 1681 1682 return nullptr; 1683 } 1684 1685 /// RewriteObjCForCollectionStmt - Rewriter for ObjC2's foreach statement. 1686 /// It rewrites: 1687 /// for ( type elem in collection) { stmts; } 1688 1689 /// Into: 1690 /// { 1691 /// type elem; 1692 /// struct __objcFastEnumerationState enumState = { 0 }; 1693 /// id __rw_items[16]; 1694 /// id l_collection = (id)collection; 1695 /// NSUInteger limit = [l_collection countByEnumeratingWithState:&enumState 1696 /// objects:__rw_items count:16]; 1697 /// if (limit) { 1698 /// unsigned long startMutations = *enumState.mutationsPtr; 1699 /// do { 1700 /// unsigned long counter = 0; 1701 /// do { 1702 /// if (startMutations != *enumState.mutationsPtr) 1703 /// objc_enumerationMutation(l_collection); 1704 /// elem = (type)enumState.itemsPtr[counter++]; 1705 /// stmts; 1706 /// __continue_label: ; 1707 /// } while (counter < limit); 1708 /// } while ((limit = [l_collection countByEnumeratingWithState:&enumState 1709 /// objects:__rw_items count:16])); 1710 /// elem = nil; 1711 /// __break_label: ; 1712 /// } 1713 /// else 1714 /// elem = nil; 1715 /// } 1716 /// 1717 Stmt *RewriteModernObjC::RewriteObjCForCollectionStmt(ObjCForCollectionStmt *S, 1718 SourceLocation OrigEnd) { 1719 assert(!Stmts.empty() && "ObjCForCollectionStmt - Statement stack empty"); 1720 assert(isa<ObjCForCollectionStmt>(Stmts.back()) && 1721 "ObjCForCollectionStmt Statement stack mismatch"); 1722 assert(!ObjCBcLabelNo.empty() && 1723 "ObjCForCollectionStmt - Label No stack empty"); 1724 1725 SourceLocation startLoc = S->getLocStart(); 1726 const char *startBuf = SM->getCharacterData(startLoc); 1727 StringRef elementName; 1728 std::string elementTypeAsString; 1729 std::string buf; 1730 // line directive first. 1731 SourceLocation ForEachLoc = S->getForLoc(); 1732 ConvertSourceLocationToLineDirective(ForEachLoc, buf); 1733 buf += "{\n\t"; 1734 if (DeclStmt *DS = dyn_cast<DeclStmt>(S->getElement())) { 1735 // type elem; 1736 NamedDecl* D = cast<NamedDecl>(DS->getSingleDecl()); 1737 QualType ElementType = cast<ValueDecl>(D)->getType(); 1738 if (ElementType->isObjCQualifiedIdType() || 1739 ElementType->isObjCQualifiedInterfaceType()) 1740 // Simply use 'id' for all qualified types. 1741 elementTypeAsString = "id"; 1742 else 1743 elementTypeAsString = ElementType.getAsString(Context->getPrintingPolicy()); 1744 buf += elementTypeAsString; 1745 buf += " "; 1746 elementName = D->getName(); 1747 buf += elementName; 1748 buf += ";\n\t"; 1749 } 1750 else { 1751 DeclRefExpr *DR = cast<DeclRefExpr>(S->getElement()); 1752 elementName = DR->getDecl()->getName(); 1753 ValueDecl *VD = cast<ValueDecl>(DR->getDecl()); 1754 if (VD->getType()->isObjCQualifiedIdType() || 1755 VD->getType()->isObjCQualifiedInterfaceType()) 1756 // Simply use 'id' for all qualified types. 1757 elementTypeAsString = "id"; 1758 else 1759 elementTypeAsString = VD->getType().getAsString(Context->getPrintingPolicy()); 1760 } 1761 1762 // struct __objcFastEnumerationState enumState = { 0 }; 1763 buf += "struct __objcFastEnumerationState enumState = { 0 };\n\t"; 1764 // id __rw_items[16]; 1765 buf += "id __rw_items[16];\n\t"; 1766 // id l_collection = (id) 1767 buf += "id l_collection = (id)"; 1768 // Find start location of 'collection' the hard way! 1769 const char *startCollectionBuf = startBuf; 1770 startCollectionBuf += 3; // skip 'for' 1771 startCollectionBuf = strchr(startCollectionBuf, '('); 1772 startCollectionBuf++; // skip '(' 1773 // find 'in' and skip it. 1774 while (*startCollectionBuf != ' ' || 1775 *(startCollectionBuf+1) != 'i' || *(startCollectionBuf+2) != 'n' || 1776 (*(startCollectionBuf+3) != ' ' && 1777 *(startCollectionBuf+3) != '[' && *(startCollectionBuf+3) != '(')) 1778 startCollectionBuf++; 1779 startCollectionBuf += 3; 1780 1781 // Replace: "for (type element in" with string constructed thus far. 1782 ReplaceText(startLoc, startCollectionBuf - startBuf, buf); 1783 // Replace ')' in for '(' type elem in collection ')' with ';' 1784 SourceLocation rightParenLoc = S->getRParenLoc(); 1785 const char *rparenBuf = SM->getCharacterData(rightParenLoc); 1786 SourceLocation lparenLoc = startLoc.getLocWithOffset(rparenBuf-startBuf); 1787 buf = ";\n\t"; 1788 1789 // unsigned long limit = [l_collection countByEnumeratingWithState:&enumState 1790 // objects:__rw_items count:16]; 1791 // which is synthesized into: 1792 // NSUInteger limit = 1793 // ((NSUInteger (*) 1794 // (id, SEL, struct __objcFastEnumerationState *, id *, NSUInteger)) 1795 // (void *)objc_msgSend)((id)l_collection, 1796 // sel_registerName( 1797 // "countByEnumeratingWithState:objects:count:"), 1798 // (struct __objcFastEnumerationState *)&state, 1799 // (id *)__rw_items, (NSUInteger)16); 1800 buf += "_WIN_NSUInteger limit =\n\t\t"; 1801 SynthCountByEnumWithState(buf); 1802 buf += ";\n\t"; 1803 /// if (limit) { 1804 /// unsigned long startMutations = *enumState.mutationsPtr; 1805 /// do { 1806 /// unsigned long counter = 0; 1807 /// do { 1808 /// if (startMutations != *enumState.mutationsPtr) 1809 /// objc_enumerationMutation(l_collection); 1810 /// elem = (type)enumState.itemsPtr[counter++]; 1811 buf += "if (limit) {\n\t"; 1812 buf += "unsigned long startMutations = *enumState.mutationsPtr;\n\t"; 1813 buf += "do {\n\t\t"; 1814 buf += "unsigned long counter = 0;\n\t\t"; 1815 buf += "do {\n\t\t\t"; 1816 buf += "if (startMutations != *enumState.mutationsPtr)\n\t\t\t\t"; 1817 buf += "objc_enumerationMutation(l_collection);\n\t\t\t"; 1818 buf += elementName; 1819 buf += " = ("; 1820 buf += elementTypeAsString; 1821 buf += ")enumState.itemsPtr[counter++];"; 1822 // Replace ')' in for '(' type elem in collection ')' with all of these. 1823 ReplaceText(lparenLoc, 1, buf); 1824 1825 /// __continue_label: ; 1826 /// } while (counter < limit); 1827 /// } while ((limit = [l_collection countByEnumeratingWithState:&enumState 1828 /// objects:__rw_items count:16])); 1829 /// elem = nil; 1830 /// __break_label: ; 1831 /// } 1832 /// else 1833 /// elem = nil; 1834 /// } 1835 /// 1836 buf = ";\n\t"; 1837 buf += "__continue_label_"; 1838 buf += utostr(ObjCBcLabelNo.back()); 1839 buf += ": ;"; 1840 buf += "\n\t\t"; 1841 buf += "} while (counter < limit);\n\t"; 1842 buf += "} while ((limit = "; 1843 SynthCountByEnumWithState(buf); 1844 buf += "));\n\t"; 1845 buf += elementName; 1846 buf += " = (("; 1847 buf += elementTypeAsString; 1848 buf += ")0);\n\t"; 1849 buf += "__break_label_"; 1850 buf += utostr(ObjCBcLabelNo.back()); 1851 buf += ": ;\n\t"; 1852 buf += "}\n\t"; 1853 buf += "else\n\t\t"; 1854 buf += elementName; 1855 buf += " = (("; 1856 buf += elementTypeAsString; 1857 buf += ")0);\n\t"; 1858 buf += "}\n"; 1859 1860 // Insert all these *after* the statement body. 1861 // FIXME: If this should support Obj-C++, support CXXTryStmt 1862 if (isa<CompoundStmt>(S->getBody())) { 1863 SourceLocation endBodyLoc = OrigEnd.getLocWithOffset(1); 1864 InsertText(endBodyLoc, buf); 1865 } else { 1866 /* Need to treat single statements specially. For example: 1867 * 1868 * for (A *a in b) if (stuff()) break; 1869 * for (A *a in b) xxxyy; 1870 * 1871 * The following code simply scans ahead to the semi to find the actual end. 1872 */ 1873 const char *stmtBuf = SM->getCharacterData(OrigEnd); 1874 const char *semiBuf = strchr(stmtBuf, ';'); 1875 assert(semiBuf && "Can't find ';'"); 1876 SourceLocation endBodyLoc = OrigEnd.getLocWithOffset(semiBuf-stmtBuf+1); 1877 InsertText(endBodyLoc, buf); 1878 } 1879 Stmts.pop_back(); 1880 ObjCBcLabelNo.pop_back(); 1881 return nullptr; 1882 } 1883 1884 static void Write_RethrowObject(std::string &buf) { 1885 buf += "{ struct _FIN { _FIN(id reth) : rethrow(reth) {}\n"; 1886 buf += "\t~_FIN() { if (rethrow) objc_exception_throw(rethrow); }\n"; 1887 buf += "\tid rethrow;\n"; 1888 buf += "\t} _fin_force_rethow(_rethrow);"; 1889 } 1890 1891 /// RewriteObjCSynchronizedStmt - 1892 /// This routine rewrites @synchronized(expr) stmt; 1893 /// into: 1894 /// objc_sync_enter(expr); 1895 /// @try stmt @finally { objc_sync_exit(expr); } 1896 /// 1897 Stmt *RewriteModernObjC::RewriteObjCSynchronizedStmt(ObjCAtSynchronizedStmt *S) { 1898 // Get the start location and compute the semi location. 1899 SourceLocation startLoc = S->getLocStart(); 1900 const char *startBuf = SM->getCharacterData(startLoc); 1901 1902 assert((*startBuf == '@') && "bogus @synchronized location"); 1903 1904 std::string buf; 1905 SourceLocation SynchLoc = S->getAtSynchronizedLoc(); 1906 ConvertSourceLocationToLineDirective(SynchLoc, buf); 1907 buf += "{ id _rethrow = 0; id _sync_obj = (id)"; 1908 1909 const char *lparenBuf = startBuf; 1910 while (*lparenBuf != '(') lparenBuf++; 1911 ReplaceText(startLoc, lparenBuf-startBuf+1, buf); 1912 1913 buf = "; objc_sync_enter(_sync_obj);\n"; 1914 buf += "try {\n\tstruct _SYNC_EXIT { _SYNC_EXIT(id arg) : sync_exit(arg) {}"; 1915 buf += "\n\t~_SYNC_EXIT() {objc_sync_exit(sync_exit);}"; 1916 buf += "\n\tid sync_exit;"; 1917 buf += "\n\t} _sync_exit(_sync_obj);\n"; 1918 1919 // We can't use S->getSynchExpr()->getLocEnd() to find the end location, since 1920 // the sync expression is typically a message expression that's already 1921 // been rewritten! (which implies the SourceLocation's are invalid). 1922 SourceLocation RParenExprLoc = S->getSynchBody()->getLocStart(); 1923 const char *RParenExprLocBuf = SM->getCharacterData(RParenExprLoc); 1924 while (*RParenExprLocBuf != ')') RParenExprLocBuf--; 1925 RParenExprLoc = startLoc.getLocWithOffset(RParenExprLocBuf-startBuf); 1926 1927 SourceLocation LBranceLoc = S->getSynchBody()->getLocStart(); 1928 const char *LBraceLocBuf = SM->getCharacterData(LBranceLoc); 1929 assert (*LBraceLocBuf == '{'); 1930 ReplaceText(RParenExprLoc, (LBraceLocBuf - SM->getCharacterData(RParenExprLoc) + 1), buf); 1931 1932 SourceLocation startRBraceLoc = S->getSynchBody()->getLocEnd(); 1933 assert((*SM->getCharacterData(startRBraceLoc) == '}') && 1934 "bogus @synchronized block"); 1935 1936 buf = "} catch (id e) {_rethrow = e;}\n"; 1937 Write_RethrowObject(buf); 1938 buf += "}\n"; 1939 buf += "}\n"; 1940 1941 ReplaceText(startRBraceLoc, 1, buf); 1942 1943 return nullptr; 1944 } 1945 1946 void RewriteModernObjC::WarnAboutReturnGotoStmts(Stmt *S) 1947 { 1948 // Perform a bottom up traversal of all children. 1949 for (Stmt::child_range CI = S->children(); CI; ++CI) 1950 if (*CI) 1951 WarnAboutReturnGotoStmts(*CI); 1952 1953 if (isa<ReturnStmt>(S) || isa<GotoStmt>(S)) { 1954 Diags.Report(Context->getFullLoc(S->getLocStart()), 1955 TryFinallyContainsReturnDiag); 1956 } 1957 return; 1958 } 1959 1960 Stmt *RewriteModernObjC::RewriteObjCAutoreleasePoolStmt(ObjCAutoreleasePoolStmt *S) { 1961 SourceLocation startLoc = S->getAtLoc(); 1962 ReplaceText(startLoc, strlen("@autoreleasepool"), "/* @autoreleasepool */"); 1963 ReplaceText(S->getSubStmt()->getLocStart(), 1, 1964 "{ __AtAutoreleasePool __autoreleasepool; "); 1965 1966 return nullptr; 1967 } 1968 1969 Stmt *RewriteModernObjC::RewriteObjCTryStmt(ObjCAtTryStmt *S) { 1970 ObjCAtFinallyStmt *finalStmt = S->getFinallyStmt(); 1971 bool noCatch = S->getNumCatchStmts() == 0; 1972 std::string buf; 1973 SourceLocation TryLocation = S->getAtTryLoc(); 1974 ConvertSourceLocationToLineDirective(TryLocation, buf); 1975 1976 if (finalStmt) { 1977 if (noCatch) 1978 buf += "{ id volatile _rethrow = 0;\n"; 1979 else { 1980 buf += "{ id volatile _rethrow = 0;\ntry {\n"; 1981 } 1982 } 1983 // Get the start location and compute the semi location. 1984 SourceLocation startLoc = S->getLocStart(); 1985 const char *startBuf = SM->getCharacterData(startLoc); 1986 1987 assert((*startBuf == '@') && "bogus @try location"); 1988 if (finalStmt) 1989 ReplaceText(startLoc, 1, buf); 1990 else 1991 // @try -> try 1992 ReplaceText(startLoc, 1, ""); 1993 1994 for (unsigned I = 0, N = S->getNumCatchStmts(); I != N; ++I) { 1995 ObjCAtCatchStmt *Catch = S->getCatchStmt(I); 1996 VarDecl *catchDecl = Catch->getCatchParamDecl(); 1997 1998 startLoc = Catch->getLocStart(); 1999 bool AtRemoved = false; 2000 if (catchDecl) { 2001 QualType t = catchDecl->getType(); 2002 if (const ObjCObjectPointerType *Ptr = t->getAs<ObjCObjectPointerType>()) { 2003 // Should be a pointer to a class. 2004 ObjCInterfaceDecl *IDecl = Ptr->getObjectType()->getInterface(); 2005 if (IDecl) { 2006 std::string Result; 2007 ConvertSourceLocationToLineDirective(Catch->getLocStart(), Result); 2008 2009 startBuf = SM->getCharacterData(startLoc); 2010 assert((*startBuf == '@') && "bogus @catch location"); 2011 SourceLocation rParenLoc = Catch->getRParenLoc(); 2012 const char *rParenBuf = SM->getCharacterData(rParenLoc); 2013 2014 // _objc_exc_Foo *_e as argument to catch. 2015 Result += "catch (_objc_exc_"; Result += IDecl->getNameAsString(); 2016 Result += " *_"; Result += catchDecl->getNameAsString(); 2017 Result += ")"; 2018 ReplaceText(startLoc, rParenBuf-startBuf+1, Result); 2019 // Foo *e = (Foo *)_e; 2020 Result.clear(); 2021 Result = "{ "; 2022 Result += IDecl->getNameAsString(); 2023 Result += " *"; Result += catchDecl->getNameAsString(); 2024 Result += " = ("; Result += IDecl->getNameAsString(); Result += "*)"; 2025 Result += "_"; Result += catchDecl->getNameAsString(); 2026 2027 Result += "; "; 2028 SourceLocation lBraceLoc = Catch->getCatchBody()->getLocStart(); 2029 ReplaceText(lBraceLoc, 1, Result); 2030 AtRemoved = true; 2031 } 2032 } 2033 } 2034 if (!AtRemoved) 2035 // @catch -> catch 2036 ReplaceText(startLoc, 1, ""); 2037 2038 } 2039 if (finalStmt) { 2040 buf.clear(); 2041 SourceLocation FinallyLoc = finalStmt->getLocStart(); 2042 2043 if (noCatch) { 2044 ConvertSourceLocationToLineDirective(FinallyLoc, buf); 2045 buf += "catch (id e) {_rethrow = e;}\n"; 2046 } 2047 else { 2048 buf += "}\n"; 2049 ConvertSourceLocationToLineDirective(FinallyLoc, buf); 2050 buf += "catch (id e) {_rethrow = e;}\n"; 2051 } 2052 2053 SourceLocation startFinalLoc = finalStmt->getLocStart(); 2054 ReplaceText(startFinalLoc, 8, buf); 2055 Stmt *body = finalStmt->getFinallyBody(); 2056 SourceLocation startFinalBodyLoc = body->getLocStart(); 2057 buf.clear(); 2058 Write_RethrowObject(buf); 2059 ReplaceText(startFinalBodyLoc, 1, buf); 2060 2061 SourceLocation endFinalBodyLoc = body->getLocEnd(); 2062 ReplaceText(endFinalBodyLoc, 1, "}\n}"); 2063 // Now check for any return/continue/go statements within the @try. 2064 WarnAboutReturnGotoStmts(S->getTryBody()); 2065 } 2066 2067 return nullptr; 2068 } 2069 2070 // This can't be done with ReplaceStmt(S, ThrowExpr), since 2071 // the throw expression is typically a message expression that's already 2072 // been rewritten! (which implies the SourceLocation's are invalid). 2073 Stmt *RewriteModernObjC::RewriteObjCThrowStmt(ObjCAtThrowStmt *S) { 2074 // Get the start location and compute the semi location. 2075 SourceLocation startLoc = S->getLocStart(); 2076 const char *startBuf = SM->getCharacterData(startLoc); 2077 2078 assert((*startBuf == '@') && "bogus @throw location"); 2079 2080 std::string buf; 2081 /* void objc_exception_throw(id) __attribute__((noreturn)); */ 2082 if (S->getThrowExpr()) 2083 buf = "objc_exception_throw("; 2084 else 2085 buf = "throw"; 2086 2087 // handle "@ throw" correctly. 2088 const char *wBuf = strchr(startBuf, 'w'); 2089 assert((*wBuf == 'w') && "@throw: can't find 'w'"); 2090 ReplaceText(startLoc, wBuf-startBuf+1, buf); 2091 2092 SourceLocation endLoc = S->getLocEnd(); 2093 const char *endBuf = SM->getCharacterData(endLoc); 2094 const char *semiBuf = strchr(endBuf, ';'); 2095 assert((*semiBuf == ';') && "@throw: can't find ';'"); 2096 SourceLocation semiLoc = startLoc.getLocWithOffset(semiBuf-startBuf); 2097 if (S->getThrowExpr()) 2098 ReplaceText(semiLoc, 1, ");"); 2099 return nullptr; 2100 } 2101 2102 Stmt *RewriteModernObjC::RewriteAtEncode(ObjCEncodeExpr *Exp) { 2103 // Create a new string expression. 2104 std::string StrEncoding; 2105 Context->getObjCEncodingForType(Exp->getEncodedType(), StrEncoding); 2106 Expr *Replacement = getStringLiteral(StrEncoding); 2107 ReplaceStmt(Exp, Replacement); 2108 2109 // Replace this subexpr in the parent. 2110 // delete Exp; leak for now, see RewritePropertyOrImplicitSetter() usage for more info. 2111 return Replacement; 2112 } 2113 2114 Stmt *RewriteModernObjC::RewriteAtSelector(ObjCSelectorExpr *Exp) { 2115 if (!SelGetUidFunctionDecl) 2116 SynthSelGetUidFunctionDecl(); 2117 assert(SelGetUidFunctionDecl && "Can't find sel_registerName() decl"); 2118 // Create a call to sel_registerName("selName"). 2119 SmallVector<Expr*, 8> SelExprs; 2120 SelExprs.push_back(getStringLiteral(Exp->getSelector().getAsString())); 2121 CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl, 2122 &SelExprs[0], SelExprs.size()); 2123 ReplaceStmt(Exp, SelExp); 2124 // delete Exp; leak for now, see RewritePropertyOrImplicitSetter() usage for more info. 2125 return SelExp; 2126 } 2127 2128 CallExpr *RewriteModernObjC::SynthesizeCallToFunctionDecl( 2129 FunctionDecl *FD, Expr **args, unsigned nargs, SourceLocation StartLoc, 2130 SourceLocation EndLoc) { 2131 // Get the type, we will need to reference it in a couple spots. 2132 QualType msgSendType = FD->getType(); 2133 2134 // Create a reference to the objc_msgSend() declaration. 2135 DeclRefExpr *DRE = 2136 new (Context) DeclRefExpr(FD, false, msgSendType, VK_LValue, SourceLocation()); 2137 2138 // Now, we cast the reference to a pointer to the objc_msgSend type. 2139 QualType pToFunc = Context->getPointerType(msgSendType); 2140 ImplicitCastExpr *ICE = 2141 ImplicitCastExpr::Create(*Context, pToFunc, CK_FunctionToPointerDecay, 2142 DRE, nullptr, VK_RValue); 2143 2144 const FunctionType *FT = msgSendType->getAs<FunctionType>(); 2145 2146 CallExpr *Exp = 2147 new (Context) CallExpr(*Context, ICE, llvm::makeArrayRef(args, nargs), 2148 FT->getCallResultType(*Context), 2149 VK_RValue, EndLoc); 2150 return Exp; 2151 } 2152 2153 static bool scanForProtocolRefs(const char *startBuf, const char *endBuf, 2154 const char *&startRef, const char *&endRef) { 2155 while (startBuf < endBuf) { 2156 if (*startBuf == '<') 2157 startRef = startBuf; // mark the start. 2158 if (*startBuf == '>') { 2159 if (startRef && *startRef == '<') { 2160 endRef = startBuf; // mark the end. 2161 return true; 2162 } 2163 return false; 2164 } 2165 startBuf++; 2166 } 2167 return false; 2168 } 2169 2170 static void scanToNextArgument(const char *&argRef) { 2171 int angle = 0; 2172 while (*argRef != ')' && (*argRef != ',' || angle > 0)) { 2173 if (*argRef == '<') 2174 angle++; 2175 else if (*argRef == '>') 2176 angle--; 2177 argRef++; 2178 } 2179 assert(angle == 0 && "scanToNextArgument - bad protocol type syntax"); 2180 } 2181 2182 bool RewriteModernObjC::needToScanForQualifiers(QualType T) { 2183 if (T->isObjCQualifiedIdType()) 2184 return true; 2185 if (const PointerType *PT = T->getAs<PointerType>()) { 2186 if (PT->getPointeeType()->isObjCQualifiedIdType()) 2187 return true; 2188 } 2189 if (T->isObjCObjectPointerType()) { 2190 T = T->getPointeeType(); 2191 return T->isObjCQualifiedInterfaceType(); 2192 } 2193 if (T->isArrayType()) { 2194 QualType ElemTy = Context->getBaseElementType(T); 2195 return needToScanForQualifiers(ElemTy); 2196 } 2197 return false; 2198 } 2199 2200 void RewriteModernObjC::RewriteObjCQualifiedInterfaceTypes(Expr *E) { 2201 QualType Type = E->getType(); 2202 if (needToScanForQualifiers(Type)) { 2203 SourceLocation Loc, EndLoc; 2204 2205 if (const CStyleCastExpr *ECE = dyn_cast<CStyleCastExpr>(E)) { 2206 Loc = ECE->getLParenLoc(); 2207 EndLoc = ECE->getRParenLoc(); 2208 } else { 2209 Loc = E->getLocStart(); 2210 EndLoc = E->getLocEnd(); 2211 } 2212 // This will defend against trying to rewrite synthesized expressions. 2213 if (Loc.isInvalid() || EndLoc.isInvalid()) 2214 return; 2215 2216 const char *startBuf = SM->getCharacterData(Loc); 2217 const char *endBuf = SM->getCharacterData(EndLoc); 2218 const char *startRef = nullptr, *endRef = nullptr; 2219 if (scanForProtocolRefs(startBuf, endBuf, startRef, endRef)) { 2220 // Get the locations of the startRef, endRef. 2221 SourceLocation LessLoc = Loc.getLocWithOffset(startRef-startBuf); 2222 SourceLocation GreaterLoc = Loc.getLocWithOffset(endRef-startBuf+1); 2223 // Comment out the protocol references. 2224 InsertText(LessLoc, "/*"); 2225 InsertText(GreaterLoc, "*/"); 2226 } 2227 } 2228 } 2229 2230 void RewriteModernObjC::RewriteObjCQualifiedInterfaceTypes(Decl *Dcl) { 2231 SourceLocation Loc; 2232 QualType Type; 2233 const FunctionProtoType *proto = nullptr; 2234 if (VarDecl *VD = dyn_cast<VarDecl>(Dcl)) { 2235 Loc = VD->getLocation(); 2236 Type = VD->getType(); 2237 } 2238 else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(Dcl)) { 2239 Loc = FD->getLocation(); 2240 // Check for ObjC 'id' and class types that have been adorned with protocol 2241 // information (id<p>, C<p>*). The protocol references need to be rewritten! 2242 const FunctionType *funcType = FD->getType()->getAs<FunctionType>(); 2243 assert(funcType && "missing function type"); 2244 proto = dyn_cast<FunctionProtoType>(funcType); 2245 if (!proto) 2246 return; 2247 Type = proto->getReturnType(); 2248 } 2249 else if (FieldDecl *FD = dyn_cast<FieldDecl>(Dcl)) { 2250 Loc = FD->getLocation(); 2251 Type = FD->getType(); 2252 } 2253 else if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(Dcl)) { 2254 Loc = TD->getLocation(); 2255 Type = TD->getUnderlyingType(); 2256 } 2257 else 2258 return; 2259 2260 if (needToScanForQualifiers(Type)) { 2261 // Since types are unique, we need to scan the buffer. 2262 2263 const char *endBuf = SM->getCharacterData(Loc); 2264 const char *startBuf = endBuf; 2265 while (*startBuf != ';' && *startBuf != '<' && startBuf != MainFileStart) 2266 startBuf--; // scan backward (from the decl location) for return type. 2267 const char *startRef = nullptr, *endRef = nullptr; 2268 if (scanForProtocolRefs(startBuf, endBuf, startRef, endRef)) { 2269 // Get the locations of the startRef, endRef. 2270 SourceLocation LessLoc = Loc.getLocWithOffset(startRef-endBuf); 2271 SourceLocation GreaterLoc = Loc.getLocWithOffset(endRef-endBuf+1); 2272 // Comment out the protocol references. 2273 InsertText(LessLoc, "/*"); 2274 InsertText(GreaterLoc, "*/"); 2275 } 2276 } 2277 if (!proto) 2278 return; // most likely, was a variable 2279 // Now check arguments. 2280 const char *startBuf = SM->getCharacterData(Loc); 2281 const char *startFuncBuf = startBuf; 2282 for (unsigned i = 0; i < proto->getNumParams(); i++) { 2283 if (needToScanForQualifiers(proto->getParamType(i))) { 2284 // Since types are unique, we need to scan the buffer. 2285 2286 const char *endBuf = startBuf; 2287 // scan forward (from the decl location) for argument types. 2288 scanToNextArgument(endBuf); 2289 const char *startRef = nullptr, *endRef = nullptr; 2290 if (scanForProtocolRefs(startBuf, endBuf, startRef, endRef)) { 2291 // Get the locations of the startRef, endRef. 2292 SourceLocation LessLoc = 2293 Loc.getLocWithOffset(startRef-startFuncBuf); 2294 SourceLocation GreaterLoc = 2295 Loc.getLocWithOffset(endRef-startFuncBuf+1); 2296 // Comment out the protocol references. 2297 InsertText(LessLoc, "/*"); 2298 InsertText(GreaterLoc, "*/"); 2299 } 2300 startBuf = ++endBuf; 2301 } 2302 else { 2303 // If the function name is derived from a macro expansion, then the 2304 // argument buffer will not follow the name. Need to speak with Chris. 2305 while (*startBuf && *startBuf != ')' && *startBuf != ',') 2306 startBuf++; // scan forward (from the decl location) for argument types. 2307 startBuf++; 2308 } 2309 } 2310 } 2311 2312 void RewriteModernObjC::RewriteTypeOfDecl(VarDecl *ND) { 2313 QualType QT = ND->getType(); 2314 const Type* TypePtr = QT->getAs<Type>(); 2315 if (!isa<TypeOfExprType>(TypePtr)) 2316 return; 2317 while (isa<TypeOfExprType>(TypePtr)) { 2318 const TypeOfExprType *TypeOfExprTypePtr = cast<TypeOfExprType>(TypePtr); 2319 QT = TypeOfExprTypePtr->getUnderlyingExpr()->getType(); 2320 TypePtr = QT->getAs<Type>(); 2321 } 2322 // FIXME. This will not work for multiple declarators; as in: 2323 // __typeof__(a) b,c,d; 2324 std::string TypeAsString(QT.getAsString(Context->getPrintingPolicy())); 2325 SourceLocation DeclLoc = ND->getTypeSpecStartLoc(); 2326 const char *startBuf = SM->getCharacterData(DeclLoc); 2327 if (ND->getInit()) { 2328 std::string Name(ND->getNameAsString()); 2329 TypeAsString += " " + Name + " = "; 2330 Expr *E = ND->getInit(); 2331 SourceLocation startLoc; 2332 if (const CStyleCastExpr *ECE = dyn_cast<CStyleCastExpr>(E)) 2333 startLoc = ECE->getLParenLoc(); 2334 else 2335 startLoc = E->getLocStart(); 2336 startLoc = SM->getExpansionLoc(startLoc); 2337 const char *endBuf = SM->getCharacterData(startLoc); 2338 ReplaceText(DeclLoc, endBuf-startBuf-1, TypeAsString); 2339 } 2340 else { 2341 SourceLocation X = ND->getLocEnd(); 2342 X = SM->getExpansionLoc(X); 2343 const char *endBuf = SM->getCharacterData(X); 2344 ReplaceText(DeclLoc, endBuf-startBuf-1, TypeAsString); 2345 } 2346 } 2347 2348 // SynthSelGetUidFunctionDecl - SEL sel_registerName(const char *str); 2349 void RewriteModernObjC::SynthSelGetUidFunctionDecl() { 2350 IdentifierInfo *SelGetUidIdent = &Context->Idents.get("sel_registerName"); 2351 SmallVector<QualType, 16> ArgTys; 2352 ArgTys.push_back(Context->getPointerType(Context->CharTy.withConst())); 2353 QualType getFuncType = 2354 getSimpleFunctionType(Context->getObjCSelType(), ArgTys); 2355 SelGetUidFunctionDecl = FunctionDecl::Create(*Context, TUDecl, 2356 SourceLocation(), 2357 SourceLocation(), 2358 SelGetUidIdent, getFuncType, 2359 nullptr, SC_Extern); 2360 } 2361 2362 void RewriteModernObjC::RewriteFunctionDecl(FunctionDecl *FD) { 2363 // declared in <objc/objc.h> 2364 if (FD->getIdentifier() && 2365 FD->getName() == "sel_registerName") { 2366 SelGetUidFunctionDecl = FD; 2367 return; 2368 } 2369 RewriteObjCQualifiedInterfaceTypes(FD); 2370 } 2371 2372 void RewriteModernObjC::RewriteBlockPointerType(std::string& Str, QualType Type) { 2373 std::string TypeString(Type.getAsString(Context->getPrintingPolicy())); 2374 const char *argPtr = TypeString.c_str(); 2375 if (!strchr(argPtr, '^')) { 2376 Str += TypeString; 2377 return; 2378 } 2379 while (*argPtr) { 2380 Str += (*argPtr == '^' ? '*' : *argPtr); 2381 argPtr++; 2382 } 2383 } 2384 2385 // FIXME. Consolidate this routine with RewriteBlockPointerType. 2386 void RewriteModernObjC::RewriteBlockPointerTypeVariable(std::string& Str, 2387 ValueDecl *VD) { 2388 QualType Type = VD->getType(); 2389 std::string TypeString(Type.getAsString(Context->getPrintingPolicy())); 2390 const char *argPtr = TypeString.c_str(); 2391 int paren = 0; 2392 while (*argPtr) { 2393 switch (*argPtr) { 2394 case '(': 2395 Str += *argPtr; 2396 paren++; 2397 break; 2398 case ')': 2399 Str += *argPtr; 2400 paren--; 2401 break; 2402 case '^': 2403 Str += '*'; 2404 if (paren == 1) 2405 Str += VD->getNameAsString(); 2406 break; 2407 default: 2408 Str += *argPtr; 2409 break; 2410 } 2411 argPtr++; 2412 } 2413 } 2414 2415 void RewriteModernObjC::RewriteBlockLiteralFunctionDecl(FunctionDecl *FD) { 2416 SourceLocation FunLocStart = FD->getTypeSpecStartLoc(); 2417 const FunctionType *funcType = FD->getType()->getAs<FunctionType>(); 2418 const FunctionProtoType *proto = dyn_cast<FunctionProtoType>(funcType); 2419 if (!proto) 2420 return; 2421 QualType Type = proto->getReturnType(); 2422 std::string FdStr = Type.getAsString(Context->getPrintingPolicy()); 2423 FdStr += " "; 2424 FdStr += FD->getName(); 2425 FdStr += "("; 2426 unsigned numArgs = proto->getNumParams(); 2427 for (unsigned i = 0; i < numArgs; i++) { 2428 QualType ArgType = proto->getParamType(i); 2429 RewriteBlockPointerType(FdStr, ArgType); 2430 if (i+1 < numArgs) 2431 FdStr += ", "; 2432 } 2433 if (FD->isVariadic()) { 2434 FdStr += (numArgs > 0) ? ", ...);\n" : "...);\n"; 2435 } 2436 else 2437 FdStr += ");\n"; 2438 InsertText(FunLocStart, FdStr); 2439 } 2440 2441 // SynthSuperConstructorFunctionDecl - id __rw_objc_super(id obj, id super); 2442 void RewriteModernObjC::SynthSuperConstructorFunctionDecl() { 2443 if (SuperConstructorFunctionDecl) 2444 return; 2445 IdentifierInfo *msgSendIdent = &Context->Idents.get("__rw_objc_super"); 2446 SmallVector<QualType, 16> ArgTys; 2447 QualType argT = Context->getObjCIdType(); 2448 assert(!argT.isNull() && "Can't find 'id' type"); 2449 ArgTys.push_back(argT); 2450 ArgTys.push_back(argT); 2451 QualType msgSendType = getSimpleFunctionType(Context->getObjCIdType(), 2452 ArgTys); 2453 SuperConstructorFunctionDecl = FunctionDecl::Create(*Context, TUDecl, 2454 SourceLocation(), 2455 SourceLocation(), 2456 msgSendIdent, msgSendType, 2457 nullptr, SC_Extern); 2458 } 2459 2460 // SynthMsgSendFunctionDecl - id objc_msgSend(id self, SEL op, ...); 2461 void RewriteModernObjC::SynthMsgSendFunctionDecl() { 2462 IdentifierInfo *msgSendIdent = &Context->Idents.get("objc_msgSend"); 2463 SmallVector<QualType, 16> ArgTys; 2464 QualType argT = Context->getObjCIdType(); 2465 assert(!argT.isNull() && "Can't find 'id' type"); 2466 ArgTys.push_back(argT); 2467 argT = Context->getObjCSelType(); 2468 assert(!argT.isNull() && "Can't find 'SEL' type"); 2469 ArgTys.push_back(argT); 2470 QualType msgSendType = getSimpleFunctionType(Context->getObjCIdType(), 2471 ArgTys, /*isVariadic=*/true); 2472 MsgSendFunctionDecl = FunctionDecl::Create(*Context, TUDecl, 2473 SourceLocation(), 2474 SourceLocation(), 2475 msgSendIdent, msgSendType, nullptr, 2476 SC_Extern); 2477 } 2478 2479 // SynthMsgSendSuperFunctionDecl - id objc_msgSendSuper(void); 2480 void RewriteModernObjC::SynthMsgSendSuperFunctionDecl() { 2481 IdentifierInfo *msgSendIdent = &Context->Idents.get("objc_msgSendSuper"); 2482 SmallVector<QualType, 2> ArgTys; 2483 ArgTys.push_back(Context->VoidTy); 2484 QualType msgSendType = getSimpleFunctionType(Context->getObjCIdType(), 2485 ArgTys, /*isVariadic=*/true); 2486 MsgSendSuperFunctionDecl = FunctionDecl::Create(*Context, TUDecl, 2487 SourceLocation(), 2488 SourceLocation(), 2489 msgSendIdent, msgSendType, 2490 nullptr, SC_Extern); 2491 } 2492 2493 // SynthMsgSendStretFunctionDecl - id objc_msgSend_stret(id self, SEL op, ...); 2494 void RewriteModernObjC::SynthMsgSendStretFunctionDecl() { 2495 IdentifierInfo *msgSendIdent = &Context->Idents.get("objc_msgSend_stret"); 2496 SmallVector<QualType, 16> ArgTys; 2497 QualType argT = Context->getObjCIdType(); 2498 assert(!argT.isNull() && "Can't find 'id' type"); 2499 ArgTys.push_back(argT); 2500 argT = Context->getObjCSelType(); 2501 assert(!argT.isNull() && "Can't find 'SEL' type"); 2502 ArgTys.push_back(argT); 2503 QualType msgSendType = getSimpleFunctionType(Context->getObjCIdType(), 2504 ArgTys, /*isVariadic=*/true); 2505 MsgSendStretFunctionDecl = FunctionDecl::Create(*Context, TUDecl, 2506 SourceLocation(), 2507 SourceLocation(), 2508 msgSendIdent, msgSendType, 2509 nullptr, SC_Extern); 2510 } 2511 2512 // SynthMsgSendSuperStretFunctionDecl - 2513 // id objc_msgSendSuper_stret(void); 2514 void RewriteModernObjC::SynthMsgSendSuperStretFunctionDecl() { 2515 IdentifierInfo *msgSendIdent = 2516 &Context->Idents.get("objc_msgSendSuper_stret"); 2517 SmallVector<QualType, 2> ArgTys; 2518 ArgTys.push_back(Context->VoidTy); 2519 QualType msgSendType = getSimpleFunctionType(Context->getObjCIdType(), 2520 ArgTys, /*isVariadic=*/true); 2521 MsgSendSuperStretFunctionDecl = FunctionDecl::Create(*Context, TUDecl, 2522 SourceLocation(), 2523 SourceLocation(), 2524 msgSendIdent, 2525 msgSendType, nullptr, 2526 SC_Extern); 2527 } 2528 2529 // SynthMsgSendFpretFunctionDecl - double objc_msgSend_fpret(id self, SEL op, ...); 2530 void RewriteModernObjC::SynthMsgSendFpretFunctionDecl() { 2531 IdentifierInfo *msgSendIdent = &Context->Idents.get("objc_msgSend_fpret"); 2532 SmallVector<QualType, 16> ArgTys; 2533 QualType argT = Context->getObjCIdType(); 2534 assert(!argT.isNull() && "Can't find 'id' type"); 2535 ArgTys.push_back(argT); 2536 argT = Context->getObjCSelType(); 2537 assert(!argT.isNull() && "Can't find 'SEL' type"); 2538 ArgTys.push_back(argT); 2539 QualType msgSendType = getSimpleFunctionType(Context->DoubleTy, 2540 ArgTys, /*isVariadic=*/true); 2541 MsgSendFpretFunctionDecl = FunctionDecl::Create(*Context, TUDecl, 2542 SourceLocation(), 2543 SourceLocation(), 2544 msgSendIdent, msgSendType, 2545 nullptr, SC_Extern); 2546 } 2547 2548 // SynthGetClassFunctionDecl - Class objc_getClass(const char *name); 2549 void RewriteModernObjC::SynthGetClassFunctionDecl() { 2550 IdentifierInfo *getClassIdent = &Context->Idents.get("objc_getClass"); 2551 SmallVector<QualType, 16> ArgTys; 2552 ArgTys.push_back(Context->getPointerType(Context->CharTy.withConst())); 2553 QualType getClassType = getSimpleFunctionType(Context->getObjCClassType(), 2554 ArgTys); 2555 GetClassFunctionDecl = FunctionDecl::Create(*Context, TUDecl, 2556 SourceLocation(), 2557 SourceLocation(), 2558 getClassIdent, getClassType, 2559 nullptr, SC_Extern); 2560 } 2561 2562 // SynthGetSuperClassFunctionDecl - Class class_getSuperclass(Class cls); 2563 void RewriteModernObjC::SynthGetSuperClassFunctionDecl() { 2564 IdentifierInfo *getSuperClassIdent = 2565 &Context->Idents.get("class_getSuperclass"); 2566 SmallVector<QualType, 16> ArgTys; 2567 ArgTys.push_back(Context->getObjCClassType()); 2568 QualType getClassType = getSimpleFunctionType(Context->getObjCClassType(), 2569 ArgTys); 2570 GetSuperClassFunctionDecl = FunctionDecl::Create(*Context, TUDecl, 2571 SourceLocation(), 2572 SourceLocation(), 2573 getSuperClassIdent, 2574 getClassType, nullptr, 2575 SC_Extern); 2576 } 2577 2578 // SynthGetMetaClassFunctionDecl - Class objc_getMetaClass(const char *name); 2579 void RewriteModernObjC::SynthGetMetaClassFunctionDecl() { 2580 IdentifierInfo *getClassIdent = &Context->Idents.get("objc_getMetaClass"); 2581 SmallVector<QualType, 16> ArgTys; 2582 ArgTys.push_back(Context->getPointerType(Context->CharTy.withConst())); 2583 QualType getClassType = getSimpleFunctionType(Context->getObjCClassType(), 2584 ArgTys); 2585 GetMetaClassFunctionDecl = FunctionDecl::Create(*Context, TUDecl, 2586 SourceLocation(), 2587 SourceLocation(), 2588 getClassIdent, getClassType, 2589 nullptr, SC_Extern); 2590 } 2591 2592 Stmt *RewriteModernObjC::RewriteObjCStringLiteral(ObjCStringLiteral *Exp) { 2593 assert (Exp != nullptr && "Expected non-null ObjCStringLiteral"); 2594 QualType strType = getConstantStringStructType(); 2595 2596 std::string S = "__NSConstantStringImpl_"; 2597 2598 std::string tmpName = InFileName; 2599 unsigned i; 2600 for (i=0; i < tmpName.length(); i++) { 2601 char c = tmpName.at(i); 2602 // replace any non-alphanumeric characters with '_'. 2603 if (!isAlphanumeric(c)) 2604 tmpName[i] = '_'; 2605 } 2606 S += tmpName; 2607 S += "_"; 2608 S += utostr(NumObjCStringLiterals++); 2609 2610 Preamble += "static __NSConstantStringImpl " + S; 2611 Preamble += " __attribute__ ((section (\"__DATA, __cfstring\"))) = {__CFConstantStringClassReference,"; 2612 Preamble += "0x000007c8,"; // utf8_str 2613 // The pretty printer for StringLiteral handles escape characters properly. 2614 std::string prettyBufS; 2615 llvm::raw_string_ostream prettyBuf(prettyBufS); 2616 Exp->getString()->printPretty(prettyBuf, nullptr, PrintingPolicy(LangOpts)); 2617 Preamble += prettyBuf.str(); 2618 Preamble += ","; 2619 Preamble += utostr(Exp->getString()->getByteLength()) + "};\n"; 2620 2621 VarDecl *NewVD = VarDecl::Create(*Context, TUDecl, SourceLocation(), 2622 SourceLocation(), &Context->Idents.get(S), 2623 strType, nullptr, SC_Static); 2624 DeclRefExpr *DRE = new (Context) DeclRefExpr(NewVD, false, strType, VK_LValue, 2625 SourceLocation()); 2626 Expr *Unop = new (Context) UnaryOperator(DRE, UO_AddrOf, 2627 Context->getPointerType(DRE->getType()), 2628 VK_RValue, OK_Ordinary, 2629 SourceLocation()); 2630 // cast to NSConstantString * 2631 CastExpr *cast = NoTypeInfoCStyleCastExpr(Context, Exp->getType(), 2632 CK_CPointerToObjCPointerCast, Unop); 2633 ReplaceStmt(Exp, cast); 2634 // delete Exp; leak for now, see RewritePropertyOrImplicitSetter() usage for more info. 2635 return cast; 2636 } 2637 2638 Stmt *RewriteModernObjC::RewriteObjCBoolLiteralExpr(ObjCBoolLiteralExpr *Exp) { 2639 unsigned IntSize = 2640 static_cast<unsigned>(Context->getTypeSize(Context->IntTy)); 2641 2642 Expr *FlagExp = IntegerLiteral::Create(*Context, 2643 llvm::APInt(IntSize, Exp->getValue()), 2644 Context->IntTy, Exp->getLocation()); 2645 CastExpr *cast = NoTypeInfoCStyleCastExpr(Context, Context->ObjCBuiltinBoolTy, 2646 CK_BitCast, FlagExp); 2647 ParenExpr *PE = new (Context) ParenExpr(Exp->getLocation(), Exp->getExprLoc(), 2648 cast); 2649 ReplaceStmt(Exp, PE); 2650 return PE; 2651 } 2652 2653 Stmt *RewriteModernObjC::RewriteObjCBoxedExpr(ObjCBoxedExpr *Exp) { 2654 // synthesize declaration of helper functions needed in this routine. 2655 if (!SelGetUidFunctionDecl) 2656 SynthSelGetUidFunctionDecl(); 2657 // use objc_msgSend() for all. 2658 if (!MsgSendFunctionDecl) 2659 SynthMsgSendFunctionDecl(); 2660 if (!GetClassFunctionDecl) 2661 SynthGetClassFunctionDecl(); 2662 2663 FunctionDecl *MsgSendFlavor = MsgSendFunctionDecl; 2664 SourceLocation StartLoc = Exp->getLocStart(); 2665 SourceLocation EndLoc = Exp->getLocEnd(); 2666 2667 // Synthesize a call to objc_msgSend(). 2668 SmallVector<Expr*, 4> MsgExprs; 2669 SmallVector<Expr*, 4> ClsExprs; 2670 2671 // Create a call to objc_getClass("<BoxingClass>"). It will be the 1st argument. 2672 ObjCMethodDecl *BoxingMethod = Exp->getBoxingMethod(); 2673 ObjCInterfaceDecl *BoxingClass = BoxingMethod->getClassInterface(); 2674 2675 IdentifierInfo *clsName = BoxingClass->getIdentifier(); 2676 ClsExprs.push_back(getStringLiteral(clsName->getName())); 2677 CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl, 2678 &ClsExprs[0], 2679 ClsExprs.size(), 2680 StartLoc, EndLoc); 2681 MsgExprs.push_back(Cls); 2682 2683 // Create a call to sel_registerName("<BoxingMethod>:"), etc. 2684 // it will be the 2nd argument. 2685 SmallVector<Expr*, 4> SelExprs; 2686 SelExprs.push_back( 2687 getStringLiteral(BoxingMethod->getSelector().getAsString())); 2688 CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl, 2689 &SelExprs[0], SelExprs.size(), 2690 StartLoc, EndLoc); 2691 MsgExprs.push_back(SelExp); 2692 2693 // User provided sub-expression is the 3rd, and last, argument. 2694 Expr *subExpr = Exp->getSubExpr(); 2695 if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(subExpr)) { 2696 QualType type = ICE->getType(); 2697 const Expr *SubExpr = ICE->IgnoreParenImpCasts(); 2698 CastKind CK = CK_BitCast; 2699 if (SubExpr->getType()->isIntegralType(*Context) && type->isBooleanType()) 2700 CK = CK_IntegralToBoolean; 2701 subExpr = NoTypeInfoCStyleCastExpr(Context, type, CK, subExpr); 2702 } 2703 MsgExprs.push_back(subExpr); 2704 2705 SmallVector<QualType, 4> ArgTypes; 2706 ArgTypes.push_back(Context->getObjCIdType()); 2707 ArgTypes.push_back(Context->getObjCSelType()); 2708 for (const auto PI : BoxingMethod->parameters()) 2709 ArgTypes.push_back(PI->getType()); 2710 2711 QualType returnType = Exp->getType(); 2712 // Get the type, we will need to reference it in a couple spots. 2713 QualType msgSendType = MsgSendFlavor->getType(); 2714 2715 // Create a reference to the objc_msgSend() declaration. 2716 DeclRefExpr *DRE = new (Context) DeclRefExpr(MsgSendFlavor, false, msgSendType, 2717 VK_LValue, SourceLocation()); 2718 2719 CastExpr *cast = NoTypeInfoCStyleCastExpr(Context, 2720 Context->getPointerType(Context->VoidTy), 2721 CK_BitCast, DRE); 2722 2723 // Now do the "normal" pointer to function cast. 2724 QualType castType = 2725 getSimpleFunctionType(returnType, ArgTypes, BoxingMethod->isVariadic()); 2726 castType = Context->getPointerType(castType); 2727 cast = NoTypeInfoCStyleCastExpr(Context, castType, CK_BitCast, 2728 cast); 2729 2730 // Don't forget the parens to enforce the proper binding. 2731 ParenExpr *PE = new (Context) ParenExpr(StartLoc, EndLoc, cast); 2732 2733 const FunctionType *FT = msgSendType->getAs<FunctionType>(); 2734 CallExpr *CE = new (Context) 2735 CallExpr(*Context, PE, MsgExprs, FT->getReturnType(), VK_RValue, EndLoc); 2736 ReplaceStmt(Exp, CE); 2737 return CE; 2738 } 2739 2740 Stmt *RewriteModernObjC::RewriteObjCArrayLiteralExpr(ObjCArrayLiteral *Exp) { 2741 // synthesize declaration of helper functions needed in this routine. 2742 if (!SelGetUidFunctionDecl) 2743 SynthSelGetUidFunctionDecl(); 2744 // use objc_msgSend() for all. 2745 if (!MsgSendFunctionDecl) 2746 SynthMsgSendFunctionDecl(); 2747 if (!GetClassFunctionDecl) 2748 SynthGetClassFunctionDecl(); 2749 2750 FunctionDecl *MsgSendFlavor = MsgSendFunctionDecl; 2751 SourceLocation StartLoc = Exp->getLocStart(); 2752 SourceLocation EndLoc = Exp->getLocEnd(); 2753 2754 // Build the expression: __NSContainer_literal(int, ...).arr 2755 QualType IntQT = Context->IntTy; 2756 QualType NSArrayFType = 2757 getSimpleFunctionType(Context->VoidTy, IntQT, true); 2758 std::string NSArrayFName("__NSContainer_literal"); 2759 FunctionDecl *NSArrayFD = SynthBlockInitFunctionDecl(NSArrayFName); 2760 DeclRefExpr *NSArrayDRE = 2761 new (Context) DeclRefExpr(NSArrayFD, false, NSArrayFType, VK_RValue, 2762 SourceLocation()); 2763 2764 SmallVector<Expr*, 16> InitExprs; 2765 unsigned NumElements = Exp->getNumElements(); 2766 unsigned UnsignedIntSize = 2767 static_cast<unsigned>(Context->getTypeSize(Context->UnsignedIntTy)); 2768 Expr *count = IntegerLiteral::Create(*Context, 2769 llvm::APInt(UnsignedIntSize, NumElements), 2770 Context->UnsignedIntTy, SourceLocation()); 2771 InitExprs.push_back(count); 2772 for (unsigned i = 0; i < NumElements; i++) 2773 InitExprs.push_back(Exp->getElement(i)); 2774 Expr *NSArrayCallExpr = 2775 new (Context) CallExpr(*Context, NSArrayDRE, InitExprs, 2776 NSArrayFType, VK_LValue, SourceLocation()); 2777 2778 FieldDecl *ARRFD = FieldDecl::Create(*Context, nullptr, SourceLocation(), 2779 SourceLocation(), 2780 &Context->Idents.get("arr"), 2781 Context->getPointerType(Context->VoidPtrTy), 2782 nullptr, /*BitWidth=*/nullptr, 2783 /*Mutable=*/true, ICIS_NoInit); 2784 MemberExpr *ArrayLiteralME = 2785 new (Context) MemberExpr(NSArrayCallExpr, false, ARRFD, 2786 SourceLocation(), 2787 ARRFD->getType(), VK_LValue, 2788 OK_Ordinary); 2789 QualType ConstIdT = Context->getObjCIdType().withConst(); 2790 CStyleCastExpr * ArrayLiteralObjects = 2791 NoTypeInfoCStyleCastExpr(Context, 2792 Context->getPointerType(ConstIdT), 2793 CK_BitCast, 2794 ArrayLiteralME); 2795 2796 // Synthesize a call to objc_msgSend(). 2797 SmallVector<Expr*, 32> MsgExprs; 2798 SmallVector<Expr*, 4> ClsExprs; 2799 QualType expType = Exp->getType(); 2800 2801 // Create a call to objc_getClass("NSArray"). It will be th 1st argument. 2802 ObjCInterfaceDecl *Class = 2803 expType->getPointeeType()->getAs<ObjCObjectType>()->getInterface(); 2804 2805 IdentifierInfo *clsName = Class->getIdentifier(); 2806 ClsExprs.push_back(getStringLiteral(clsName->getName())); 2807 CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl, 2808 &ClsExprs[0], 2809 ClsExprs.size(), 2810 StartLoc, EndLoc); 2811 MsgExprs.push_back(Cls); 2812 2813 // Create a call to sel_registerName("arrayWithObjects:count:"). 2814 // it will be the 2nd argument. 2815 SmallVector<Expr*, 4> SelExprs; 2816 ObjCMethodDecl *ArrayMethod = Exp->getArrayWithObjectsMethod(); 2817 SelExprs.push_back( 2818 getStringLiteral(ArrayMethod->getSelector().getAsString())); 2819 CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl, 2820 &SelExprs[0], SelExprs.size(), 2821 StartLoc, EndLoc); 2822 MsgExprs.push_back(SelExp); 2823 2824 // (const id [])objects 2825 MsgExprs.push_back(ArrayLiteralObjects); 2826 2827 // (NSUInteger)cnt 2828 Expr *cnt = IntegerLiteral::Create(*Context, 2829 llvm::APInt(UnsignedIntSize, NumElements), 2830 Context->UnsignedIntTy, SourceLocation()); 2831 MsgExprs.push_back(cnt); 2832 2833 2834 SmallVector<QualType, 4> ArgTypes; 2835 ArgTypes.push_back(Context->getObjCIdType()); 2836 ArgTypes.push_back(Context->getObjCSelType()); 2837 for (const auto *PI : ArrayMethod->params()) 2838 ArgTypes.push_back(PI->getType()); 2839 2840 QualType returnType = Exp->getType(); 2841 // Get the type, we will need to reference it in a couple spots. 2842 QualType msgSendType = MsgSendFlavor->getType(); 2843 2844 // Create a reference to the objc_msgSend() declaration. 2845 DeclRefExpr *DRE = new (Context) DeclRefExpr(MsgSendFlavor, false, msgSendType, 2846 VK_LValue, SourceLocation()); 2847 2848 CastExpr *cast = NoTypeInfoCStyleCastExpr(Context, 2849 Context->getPointerType(Context->VoidTy), 2850 CK_BitCast, DRE); 2851 2852 // Now do the "normal" pointer to function cast. 2853 QualType castType = 2854 getSimpleFunctionType(returnType, ArgTypes, ArrayMethod->isVariadic()); 2855 castType = Context->getPointerType(castType); 2856 cast = NoTypeInfoCStyleCastExpr(Context, castType, CK_BitCast, 2857 cast); 2858 2859 // Don't forget the parens to enforce the proper binding. 2860 ParenExpr *PE = new (Context) ParenExpr(StartLoc, EndLoc, cast); 2861 2862 const FunctionType *FT = msgSendType->getAs<FunctionType>(); 2863 CallExpr *CE = new (Context) 2864 CallExpr(*Context, PE, MsgExprs, FT->getReturnType(), VK_RValue, EndLoc); 2865 ReplaceStmt(Exp, CE); 2866 return CE; 2867 } 2868 2869 Stmt *RewriteModernObjC::RewriteObjCDictionaryLiteralExpr(ObjCDictionaryLiteral *Exp) { 2870 // synthesize declaration of helper functions needed in this routine. 2871 if (!SelGetUidFunctionDecl) 2872 SynthSelGetUidFunctionDecl(); 2873 // use objc_msgSend() for all. 2874 if (!MsgSendFunctionDecl) 2875 SynthMsgSendFunctionDecl(); 2876 if (!GetClassFunctionDecl) 2877 SynthGetClassFunctionDecl(); 2878 2879 FunctionDecl *MsgSendFlavor = MsgSendFunctionDecl; 2880 SourceLocation StartLoc = Exp->getLocStart(); 2881 SourceLocation EndLoc = Exp->getLocEnd(); 2882 2883 // Build the expression: __NSContainer_literal(int, ...).arr 2884 QualType IntQT = Context->IntTy; 2885 QualType NSDictFType = 2886 getSimpleFunctionType(Context->VoidTy, IntQT, true); 2887 std::string NSDictFName("__NSContainer_literal"); 2888 FunctionDecl *NSDictFD = SynthBlockInitFunctionDecl(NSDictFName); 2889 DeclRefExpr *NSDictDRE = 2890 new (Context) DeclRefExpr(NSDictFD, false, NSDictFType, VK_RValue, 2891 SourceLocation()); 2892 2893 SmallVector<Expr*, 16> KeyExprs; 2894 SmallVector<Expr*, 16> ValueExprs; 2895 2896 unsigned NumElements = Exp->getNumElements(); 2897 unsigned UnsignedIntSize = 2898 static_cast<unsigned>(Context->getTypeSize(Context->UnsignedIntTy)); 2899 Expr *count = IntegerLiteral::Create(*Context, 2900 llvm::APInt(UnsignedIntSize, NumElements), 2901 Context->UnsignedIntTy, SourceLocation()); 2902 KeyExprs.push_back(count); 2903 ValueExprs.push_back(count); 2904 for (unsigned i = 0; i < NumElements; i++) { 2905 ObjCDictionaryElement Element = Exp->getKeyValueElement(i); 2906 KeyExprs.push_back(Element.Key); 2907 ValueExprs.push_back(Element.Value); 2908 } 2909 2910 // (const id [])objects 2911 Expr *NSValueCallExpr = 2912 new (Context) CallExpr(*Context, NSDictDRE, ValueExprs, 2913 NSDictFType, VK_LValue, SourceLocation()); 2914 2915 FieldDecl *ARRFD = FieldDecl::Create(*Context, nullptr, SourceLocation(), 2916 SourceLocation(), 2917 &Context->Idents.get("arr"), 2918 Context->getPointerType(Context->VoidPtrTy), 2919 nullptr, /*BitWidth=*/nullptr, 2920 /*Mutable=*/true, ICIS_NoInit); 2921 MemberExpr *DictLiteralValueME = 2922 new (Context) MemberExpr(NSValueCallExpr, false, ARRFD, 2923 SourceLocation(), 2924 ARRFD->getType(), VK_LValue, 2925 OK_Ordinary); 2926 QualType ConstIdT = Context->getObjCIdType().withConst(); 2927 CStyleCastExpr * DictValueObjects = 2928 NoTypeInfoCStyleCastExpr(Context, 2929 Context->getPointerType(ConstIdT), 2930 CK_BitCast, 2931 DictLiteralValueME); 2932 // (const id <NSCopying> [])keys 2933 Expr *NSKeyCallExpr = 2934 new (Context) CallExpr(*Context, NSDictDRE, KeyExprs, 2935 NSDictFType, VK_LValue, SourceLocation()); 2936 2937 MemberExpr *DictLiteralKeyME = 2938 new (Context) MemberExpr(NSKeyCallExpr, false, ARRFD, 2939 SourceLocation(), 2940 ARRFD->getType(), VK_LValue, 2941 OK_Ordinary); 2942 2943 CStyleCastExpr * DictKeyObjects = 2944 NoTypeInfoCStyleCastExpr(Context, 2945 Context->getPointerType(ConstIdT), 2946 CK_BitCast, 2947 DictLiteralKeyME); 2948 2949 2950 2951 // Synthesize a call to objc_msgSend(). 2952 SmallVector<Expr*, 32> MsgExprs; 2953 SmallVector<Expr*, 4> ClsExprs; 2954 QualType expType = Exp->getType(); 2955 2956 // Create a call to objc_getClass("NSArray"). It will be th 1st argument. 2957 ObjCInterfaceDecl *Class = 2958 expType->getPointeeType()->getAs<ObjCObjectType>()->getInterface(); 2959 2960 IdentifierInfo *clsName = Class->getIdentifier(); 2961 ClsExprs.push_back(getStringLiteral(clsName->getName())); 2962 CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl, 2963 &ClsExprs[0], 2964 ClsExprs.size(), 2965 StartLoc, EndLoc); 2966 MsgExprs.push_back(Cls); 2967 2968 // Create a call to sel_registerName("arrayWithObjects:count:"). 2969 // it will be the 2nd argument. 2970 SmallVector<Expr*, 4> SelExprs; 2971 ObjCMethodDecl *DictMethod = Exp->getDictWithObjectsMethod(); 2972 SelExprs.push_back(getStringLiteral(DictMethod->getSelector().getAsString())); 2973 CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl, 2974 &SelExprs[0], SelExprs.size(), 2975 StartLoc, EndLoc); 2976 MsgExprs.push_back(SelExp); 2977 2978 // (const id [])objects 2979 MsgExprs.push_back(DictValueObjects); 2980 2981 // (const id <NSCopying> [])keys 2982 MsgExprs.push_back(DictKeyObjects); 2983 2984 // (NSUInteger)cnt 2985 Expr *cnt = IntegerLiteral::Create(*Context, 2986 llvm::APInt(UnsignedIntSize, NumElements), 2987 Context->UnsignedIntTy, SourceLocation()); 2988 MsgExprs.push_back(cnt); 2989 2990 2991 SmallVector<QualType, 8> ArgTypes; 2992 ArgTypes.push_back(Context->getObjCIdType()); 2993 ArgTypes.push_back(Context->getObjCSelType()); 2994 for (const auto *PI : DictMethod->params()) { 2995 QualType T = PI->getType(); 2996 if (const PointerType* PT = T->getAs<PointerType>()) { 2997 QualType PointeeTy = PT->getPointeeType(); 2998 convertToUnqualifiedObjCType(PointeeTy); 2999 T = Context->getPointerType(PointeeTy); 3000 } 3001 ArgTypes.push_back(T); 3002 } 3003 3004 QualType returnType = Exp->getType(); 3005 // Get the type, we will need to reference it in a couple spots. 3006 QualType msgSendType = MsgSendFlavor->getType(); 3007 3008 // Create a reference to the objc_msgSend() declaration. 3009 DeclRefExpr *DRE = new (Context) DeclRefExpr(MsgSendFlavor, false, msgSendType, 3010 VK_LValue, SourceLocation()); 3011 3012 CastExpr *cast = NoTypeInfoCStyleCastExpr(Context, 3013 Context->getPointerType(Context->VoidTy), 3014 CK_BitCast, DRE); 3015 3016 // Now do the "normal" pointer to function cast. 3017 QualType castType = 3018 getSimpleFunctionType(returnType, ArgTypes, DictMethod->isVariadic()); 3019 castType = Context->getPointerType(castType); 3020 cast = NoTypeInfoCStyleCastExpr(Context, castType, CK_BitCast, 3021 cast); 3022 3023 // Don't forget the parens to enforce the proper binding. 3024 ParenExpr *PE = new (Context) ParenExpr(StartLoc, EndLoc, cast); 3025 3026 const FunctionType *FT = msgSendType->getAs<FunctionType>(); 3027 CallExpr *CE = new (Context) 3028 CallExpr(*Context, PE, MsgExprs, FT->getReturnType(), VK_RValue, EndLoc); 3029 ReplaceStmt(Exp, CE); 3030 return CE; 3031 } 3032 3033 // struct __rw_objc_super { 3034 // struct objc_object *object; struct objc_object *superClass; 3035 // }; 3036 QualType RewriteModernObjC::getSuperStructType() { 3037 if (!SuperStructDecl) { 3038 SuperStructDecl = RecordDecl::Create(*Context, TTK_Struct, TUDecl, 3039 SourceLocation(), SourceLocation(), 3040 &Context->Idents.get("__rw_objc_super")); 3041 QualType FieldTypes[2]; 3042 3043 // struct objc_object *object; 3044 FieldTypes[0] = Context->getObjCIdType(); 3045 // struct objc_object *superClass; 3046 FieldTypes[1] = Context->getObjCIdType(); 3047 3048 // Create fields 3049 for (unsigned i = 0; i < 2; ++i) { 3050 SuperStructDecl->addDecl(FieldDecl::Create(*Context, SuperStructDecl, 3051 SourceLocation(), 3052 SourceLocation(), nullptr, 3053 FieldTypes[i], nullptr, 3054 /*BitWidth=*/nullptr, 3055 /*Mutable=*/false, 3056 ICIS_NoInit)); 3057 } 3058 3059 SuperStructDecl->completeDefinition(); 3060 } 3061 return Context->getTagDeclType(SuperStructDecl); 3062 } 3063 3064 QualType RewriteModernObjC::getConstantStringStructType() { 3065 if (!ConstantStringDecl) { 3066 ConstantStringDecl = RecordDecl::Create(*Context, TTK_Struct, TUDecl, 3067 SourceLocation(), SourceLocation(), 3068 &Context->Idents.get("__NSConstantStringImpl")); 3069 QualType FieldTypes[4]; 3070 3071 // struct objc_object *receiver; 3072 FieldTypes[0] = Context->getObjCIdType(); 3073 // int flags; 3074 FieldTypes[1] = Context->IntTy; 3075 // char *str; 3076 FieldTypes[2] = Context->getPointerType(Context->CharTy); 3077 // long length; 3078 FieldTypes[3] = Context->LongTy; 3079 3080 // Create fields 3081 for (unsigned i = 0; i < 4; ++i) { 3082 ConstantStringDecl->addDecl(FieldDecl::Create(*Context, 3083 ConstantStringDecl, 3084 SourceLocation(), 3085 SourceLocation(), nullptr, 3086 FieldTypes[i], nullptr, 3087 /*BitWidth=*/nullptr, 3088 /*Mutable=*/true, 3089 ICIS_NoInit)); 3090 } 3091 3092 ConstantStringDecl->completeDefinition(); 3093 } 3094 return Context->getTagDeclType(ConstantStringDecl); 3095 } 3096 3097 /// getFunctionSourceLocation - returns start location of a function 3098 /// definition. Complication arises when function has declared as 3099 /// extern "C" or extern "C" {...} 3100 static SourceLocation getFunctionSourceLocation (RewriteModernObjC &R, 3101 FunctionDecl *FD) { 3102 if (FD->isExternC() && !FD->isMain()) { 3103 const DeclContext *DC = FD->getDeclContext(); 3104 if (const LinkageSpecDecl *LSD = dyn_cast<LinkageSpecDecl>(DC)) 3105 // if it is extern "C" {...}, return function decl's own location. 3106 if (!LSD->getRBraceLoc().isValid()) 3107 return LSD->getExternLoc(); 3108 } 3109 if (FD->getStorageClass() != SC_None) 3110 R.RewriteBlockLiteralFunctionDecl(FD); 3111 return FD->getTypeSpecStartLoc(); 3112 } 3113 3114 void RewriteModernObjC::RewriteLineDirective(const Decl *D) { 3115 3116 SourceLocation Location = D->getLocation(); 3117 3118 if (Location.isFileID() && GenerateLineInfo) { 3119 std::string LineString("\n#line "); 3120 PresumedLoc PLoc = SM->getPresumedLoc(Location); 3121 LineString += utostr(PLoc.getLine()); 3122 LineString += " \""; 3123 LineString += Lexer::Stringify(PLoc.getFilename()); 3124 if (isa<ObjCMethodDecl>(D)) 3125 LineString += "\""; 3126 else LineString += "\"\n"; 3127 3128 Location = D->getLocStart(); 3129 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { 3130 if (FD->isExternC() && !FD->isMain()) { 3131 const DeclContext *DC = FD->getDeclContext(); 3132 if (const LinkageSpecDecl *LSD = dyn_cast<LinkageSpecDecl>(DC)) 3133 // if it is extern "C" {...}, return function decl's own location. 3134 if (!LSD->getRBraceLoc().isValid()) 3135 Location = LSD->getExternLoc(); 3136 } 3137 } 3138 InsertText(Location, LineString); 3139 } 3140 } 3141 3142 /// SynthMsgSendStretCallExpr - This routine translates message expression 3143 /// into a call to objc_msgSend_stret() entry point. Tricky part is that 3144 /// nil check on receiver must be performed before calling objc_msgSend_stret. 3145 /// MsgSendStretFlavor - function declaration objc_msgSend_stret(...) 3146 /// msgSendType - function type of objc_msgSend_stret(...) 3147 /// returnType - Result type of the method being synthesized. 3148 /// ArgTypes - type of the arguments passed to objc_msgSend_stret, starting with receiver type. 3149 /// MsgExprs - list of argument expressions being passed to objc_msgSend_stret, 3150 /// starting with receiver. 3151 /// Method - Method being rewritten. 3152 Expr *RewriteModernObjC::SynthMsgSendStretCallExpr(FunctionDecl *MsgSendStretFlavor, 3153 QualType returnType, 3154 SmallVectorImpl<QualType> &ArgTypes, 3155 SmallVectorImpl<Expr*> &MsgExprs, 3156 ObjCMethodDecl *Method) { 3157 // Now do the "normal" pointer to function cast. 3158 QualType castType = getSimpleFunctionType(returnType, ArgTypes, 3159 Method ? Method->isVariadic() 3160 : false); 3161 castType = Context->getPointerType(castType); 3162 3163 // build type for containing the objc_msgSend_stret object. 3164 static unsigned stretCount=0; 3165 std::string name = "__Stret"; name += utostr(stretCount); 3166 std::string str = 3167 "extern \"C\" void * __cdecl memset(void *_Dst, int _Val, size_t _Size);\n"; 3168 str += "namespace {\n"; 3169 str += "struct "; str += name; 3170 str += " {\n\t"; 3171 str += name; 3172 str += "(id receiver, SEL sel"; 3173 for (unsigned i = 2; i < ArgTypes.size(); i++) { 3174 std::string ArgName = "arg"; ArgName += utostr(i); 3175 ArgTypes[i].getAsStringInternal(ArgName, Context->getPrintingPolicy()); 3176 str += ", "; str += ArgName; 3177 } 3178 // could be vararg. 3179 for (unsigned i = ArgTypes.size(); i < MsgExprs.size(); i++) { 3180 std::string ArgName = "arg"; ArgName += utostr(i); 3181 MsgExprs[i]->getType().getAsStringInternal(ArgName, 3182 Context->getPrintingPolicy()); 3183 str += ", "; str += ArgName; 3184 } 3185 3186 str += ") {\n"; 3187 str += "\t unsigned size = sizeof("; 3188 str += returnType.getAsString(Context->getPrintingPolicy()); str += ");\n"; 3189 3190 str += "\t if (size == 1 || size == 2 || size == 4 || size == 8)\n"; 3191 3192 str += "\t s = (("; str += castType.getAsString(Context->getPrintingPolicy()); 3193 str += ")(void *)objc_msgSend)(receiver, sel"; 3194 for (unsigned i = 2; i < ArgTypes.size(); i++) { 3195 str += ", arg"; str += utostr(i); 3196 } 3197 // could be vararg. 3198 for (unsigned i = ArgTypes.size(); i < MsgExprs.size(); i++) { 3199 str += ", arg"; str += utostr(i); 3200 } 3201 str+= ");\n"; 3202 3203 str += "\t else if (receiver == 0)\n"; 3204 str += "\t memset((void*)&s, 0, sizeof(s));\n"; 3205 str += "\t else\n"; 3206 3207 3208 str += "\t s = (("; str += castType.getAsString(Context->getPrintingPolicy()); 3209 str += ")(void *)objc_msgSend_stret)(receiver, sel"; 3210 for (unsigned i = 2; i < ArgTypes.size(); i++) { 3211 str += ", arg"; str += utostr(i); 3212 } 3213 // could be vararg. 3214 for (unsigned i = ArgTypes.size(); i < MsgExprs.size(); i++) { 3215 str += ", arg"; str += utostr(i); 3216 } 3217 str += ");\n"; 3218 3219 3220 str += "\t}\n"; 3221 str += "\t"; str += returnType.getAsString(Context->getPrintingPolicy()); 3222 str += " s;\n"; 3223 str += "};\n};\n\n"; 3224 SourceLocation FunLocStart; 3225 if (CurFunctionDef) 3226 FunLocStart = getFunctionSourceLocation(*this, CurFunctionDef); 3227 else { 3228 assert(CurMethodDef && "SynthMsgSendStretCallExpr - CurMethodDef is null"); 3229 FunLocStart = CurMethodDef->getLocStart(); 3230 } 3231 3232 InsertText(FunLocStart, str); 3233 ++stretCount; 3234 3235 // AST for __Stretn(receiver, args).s; 3236 IdentifierInfo *ID = &Context->Idents.get(name); 3237 FunctionDecl *FD = FunctionDecl::Create(*Context, TUDecl, SourceLocation(), 3238 SourceLocation(), ID, castType, 3239 nullptr, SC_Extern, false, false); 3240 DeclRefExpr *DRE = new (Context) DeclRefExpr(FD, false, castType, VK_RValue, 3241 SourceLocation()); 3242 CallExpr *STCE = new (Context) CallExpr(*Context, DRE, MsgExprs, 3243 castType, VK_LValue, SourceLocation()); 3244 3245 FieldDecl *FieldD = FieldDecl::Create(*Context, nullptr, SourceLocation(), 3246 SourceLocation(), 3247 &Context->Idents.get("s"), 3248 returnType, nullptr, 3249 /*BitWidth=*/nullptr, 3250 /*Mutable=*/true, ICIS_NoInit); 3251 MemberExpr *ME = new (Context) MemberExpr(STCE, false, FieldD, SourceLocation(), 3252 FieldD->getType(), VK_LValue, 3253 OK_Ordinary); 3254 3255 return ME; 3256 } 3257 3258 Stmt *RewriteModernObjC::SynthMessageExpr(ObjCMessageExpr *Exp, 3259 SourceLocation StartLoc, 3260 SourceLocation EndLoc) { 3261 if (!SelGetUidFunctionDecl) 3262 SynthSelGetUidFunctionDecl(); 3263 if (!MsgSendFunctionDecl) 3264 SynthMsgSendFunctionDecl(); 3265 if (!MsgSendSuperFunctionDecl) 3266 SynthMsgSendSuperFunctionDecl(); 3267 if (!MsgSendStretFunctionDecl) 3268 SynthMsgSendStretFunctionDecl(); 3269 if (!MsgSendSuperStretFunctionDecl) 3270 SynthMsgSendSuperStretFunctionDecl(); 3271 if (!MsgSendFpretFunctionDecl) 3272 SynthMsgSendFpretFunctionDecl(); 3273 if (!GetClassFunctionDecl) 3274 SynthGetClassFunctionDecl(); 3275 if (!GetSuperClassFunctionDecl) 3276 SynthGetSuperClassFunctionDecl(); 3277 if (!GetMetaClassFunctionDecl) 3278 SynthGetMetaClassFunctionDecl(); 3279 3280 // default to objc_msgSend(). 3281 FunctionDecl *MsgSendFlavor = MsgSendFunctionDecl; 3282 // May need to use objc_msgSend_stret() as well. 3283 FunctionDecl *MsgSendStretFlavor = nullptr; 3284 if (ObjCMethodDecl *mDecl = Exp->getMethodDecl()) { 3285 QualType resultType = mDecl->getReturnType(); 3286 if (resultType->isRecordType()) 3287 MsgSendStretFlavor = MsgSendStretFunctionDecl; 3288 else if (resultType->isRealFloatingType()) 3289 MsgSendFlavor = MsgSendFpretFunctionDecl; 3290 } 3291 3292 // Synthesize a call to objc_msgSend(). 3293 SmallVector<Expr*, 8> MsgExprs; 3294 switch (Exp->getReceiverKind()) { 3295 case ObjCMessageExpr::SuperClass: { 3296 MsgSendFlavor = MsgSendSuperFunctionDecl; 3297 if (MsgSendStretFlavor) 3298 MsgSendStretFlavor = MsgSendSuperStretFunctionDecl; 3299 assert(MsgSendFlavor && "MsgSendFlavor is NULL!"); 3300 3301 ObjCInterfaceDecl *ClassDecl = CurMethodDef->getClassInterface(); 3302 3303 SmallVector<Expr*, 4> InitExprs; 3304 3305 // set the receiver to self, the first argument to all methods. 3306 InitExprs.push_back( 3307 NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(), 3308 CK_BitCast, 3309 new (Context) DeclRefExpr(CurMethodDef->getSelfDecl(), 3310 false, 3311 Context->getObjCIdType(), 3312 VK_RValue, 3313 SourceLocation())) 3314 ); // set the 'receiver'. 3315 3316 // (id)class_getSuperclass((Class)objc_getClass("CurrentClass")) 3317 SmallVector<Expr*, 8> ClsExprs; 3318 ClsExprs.push_back(getStringLiteral(ClassDecl->getIdentifier()->getName())); 3319 // (Class)objc_getClass("CurrentClass") 3320 CallExpr *Cls = SynthesizeCallToFunctionDecl(GetMetaClassFunctionDecl, 3321 &ClsExprs[0], 3322 ClsExprs.size(), 3323 StartLoc, 3324 EndLoc); 3325 ClsExprs.clear(); 3326 ClsExprs.push_back(Cls); 3327 Cls = SynthesizeCallToFunctionDecl(GetSuperClassFunctionDecl, 3328 &ClsExprs[0], ClsExprs.size(), 3329 StartLoc, EndLoc); 3330 3331 // (id)class_getSuperclass((Class)objc_getClass("CurrentClass")) 3332 // To turn off a warning, type-cast to 'id' 3333 InitExprs.push_back( // set 'super class', using class_getSuperclass(). 3334 NoTypeInfoCStyleCastExpr(Context, 3335 Context->getObjCIdType(), 3336 CK_BitCast, Cls)); 3337 // struct __rw_objc_super 3338 QualType superType = getSuperStructType(); 3339 Expr *SuperRep; 3340 3341 if (LangOpts.MicrosoftExt) { 3342 SynthSuperConstructorFunctionDecl(); 3343 // Simulate a constructor call... 3344 DeclRefExpr *DRE = new (Context) DeclRefExpr(SuperConstructorFunctionDecl, 3345 false, superType, VK_LValue, 3346 SourceLocation()); 3347 SuperRep = new (Context) CallExpr(*Context, DRE, InitExprs, 3348 superType, VK_LValue, 3349 SourceLocation()); 3350 // The code for super is a little tricky to prevent collision with 3351 // the structure definition in the header. The rewriter has it's own 3352 // internal definition (__rw_objc_super) that is uses. This is why 3353 // we need the cast below. For example: 3354 // (struct __rw_objc_super *)&__rw_objc_super((id)self, (id)objc_getClass("SUPER")) 3355 // 3356 SuperRep = new (Context) UnaryOperator(SuperRep, UO_AddrOf, 3357 Context->getPointerType(SuperRep->getType()), 3358 VK_RValue, OK_Ordinary, 3359 SourceLocation()); 3360 SuperRep = NoTypeInfoCStyleCastExpr(Context, 3361 Context->getPointerType(superType), 3362 CK_BitCast, SuperRep); 3363 } else { 3364 // (struct __rw_objc_super) { <exprs from above> } 3365 InitListExpr *ILE = 3366 new (Context) InitListExpr(*Context, SourceLocation(), InitExprs, 3367 SourceLocation()); 3368 TypeSourceInfo *superTInfo 3369 = Context->getTrivialTypeSourceInfo(superType); 3370 SuperRep = new (Context) CompoundLiteralExpr(SourceLocation(), superTInfo, 3371 superType, VK_LValue, 3372 ILE, false); 3373 // struct __rw_objc_super * 3374 SuperRep = new (Context) UnaryOperator(SuperRep, UO_AddrOf, 3375 Context->getPointerType(SuperRep->getType()), 3376 VK_RValue, OK_Ordinary, 3377 SourceLocation()); 3378 } 3379 MsgExprs.push_back(SuperRep); 3380 break; 3381 } 3382 3383 case ObjCMessageExpr::Class: { 3384 SmallVector<Expr*, 8> ClsExprs; 3385 ObjCInterfaceDecl *Class 3386 = Exp->getClassReceiver()->getAs<ObjCObjectType>()->getInterface(); 3387 IdentifierInfo *clsName = Class->getIdentifier(); 3388 ClsExprs.push_back(getStringLiteral(clsName->getName())); 3389 CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl, 3390 &ClsExprs[0], 3391 ClsExprs.size(), 3392 StartLoc, EndLoc); 3393 CastExpr *ArgExpr = NoTypeInfoCStyleCastExpr(Context, 3394 Context->getObjCIdType(), 3395 CK_BitCast, Cls); 3396 MsgExprs.push_back(ArgExpr); 3397 break; 3398 } 3399 3400 case ObjCMessageExpr::SuperInstance:{ 3401 MsgSendFlavor = MsgSendSuperFunctionDecl; 3402 if (MsgSendStretFlavor) 3403 MsgSendStretFlavor = MsgSendSuperStretFunctionDecl; 3404 assert(MsgSendFlavor && "MsgSendFlavor is NULL!"); 3405 ObjCInterfaceDecl *ClassDecl = CurMethodDef->getClassInterface(); 3406 SmallVector<Expr*, 4> InitExprs; 3407 3408 InitExprs.push_back( 3409 NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(), 3410 CK_BitCast, 3411 new (Context) DeclRefExpr(CurMethodDef->getSelfDecl(), 3412 false, 3413 Context->getObjCIdType(), 3414 VK_RValue, SourceLocation())) 3415 ); // set the 'receiver'. 3416 3417 // (id)class_getSuperclass((Class)objc_getClass("CurrentClass")) 3418 SmallVector<Expr*, 8> ClsExprs; 3419 ClsExprs.push_back(getStringLiteral(ClassDecl->getIdentifier()->getName())); 3420 // (Class)objc_getClass("CurrentClass") 3421 CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl, 3422 &ClsExprs[0], 3423 ClsExprs.size(), 3424 StartLoc, EndLoc); 3425 ClsExprs.clear(); 3426 ClsExprs.push_back(Cls); 3427 Cls = SynthesizeCallToFunctionDecl(GetSuperClassFunctionDecl, 3428 &ClsExprs[0], ClsExprs.size(), 3429 StartLoc, EndLoc); 3430 3431 // (id)class_getSuperclass((Class)objc_getClass("CurrentClass")) 3432 // To turn off a warning, type-cast to 'id' 3433 InitExprs.push_back( 3434 // set 'super class', using class_getSuperclass(). 3435 NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(), 3436 CK_BitCast, Cls)); 3437 // struct __rw_objc_super 3438 QualType superType = getSuperStructType(); 3439 Expr *SuperRep; 3440 3441 if (LangOpts.MicrosoftExt) { 3442 SynthSuperConstructorFunctionDecl(); 3443 // Simulate a constructor call... 3444 DeclRefExpr *DRE = new (Context) DeclRefExpr(SuperConstructorFunctionDecl, 3445 false, superType, VK_LValue, 3446 SourceLocation()); 3447 SuperRep = new (Context) CallExpr(*Context, DRE, InitExprs, 3448 superType, VK_LValue, SourceLocation()); 3449 // The code for super is a little tricky to prevent collision with 3450 // the structure definition in the header. The rewriter has it's own 3451 // internal definition (__rw_objc_super) that is uses. This is why 3452 // we need the cast below. For example: 3453 // (struct __rw_objc_super *)&__rw_objc_super((id)self, (id)objc_getClass("SUPER")) 3454 // 3455 SuperRep = new (Context) UnaryOperator(SuperRep, UO_AddrOf, 3456 Context->getPointerType(SuperRep->getType()), 3457 VK_RValue, OK_Ordinary, 3458 SourceLocation()); 3459 SuperRep = NoTypeInfoCStyleCastExpr(Context, 3460 Context->getPointerType(superType), 3461 CK_BitCast, SuperRep); 3462 } else { 3463 // (struct __rw_objc_super) { <exprs from above> } 3464 InitListExpr *ILE = 3465 new (Context) InitListExpr(*Context, SourceLocation(), InitExprs, 3466 SourceLocation()); 3467 TypeSourceInfo *superTInfo 3468 = Context->getTrivialTypeSourceInfo(superType); 3469 SuperRep = new (Context) CompoundLiteralExpr(SourceLocation(), superTInfo, 3470 superType, VK_RValue, ILE, 3471 false); 3472 } 3473 MsgExprs.push_back(SuperRep); 3474 break; 3475 } 3476 3477 case ObjCMessageExpr::Instance: { 3478 // Remove all type-casts because it may contain objc-style types; e.g. 3479 // Foo<Proto> *. 3480 Expr *recExpr = Exp->getInstanceReceiver(); 3481 while (CStyleCastExpr *CE = dyn_cast<CStyleCastExpr>(recExpr)) 3482 recExpr = CE->getSubExpr(); 3483 CastKind CK = recExpr->getType()->isObjCObjectPointerType() 3484 ? CK_BitCast : recExpr->getType()->isBlockPointerType() 3485 ? CK_BlockPointerToObjCPointerCast 3486 : CK_CPointerToObjCPointerCast; 3487 3488 recExpr = NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(), 3489 CK, recExpr); 3490 MsgExprs.push_back(recExpr); 3491 break; 3492 } 3493 } 3494 3495 // Create a call to sel_registerName("selName"), it will be the 2nd argument. 3496 SmallVector<Expr*, 8> SelExprs; 3497 SelExprs.push_back(getStringLiteral(Exp->getSelector().getAsString())); 3498 CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl, 3499 &SelExprs[0], SelExprs.size(), 3500 StartLoc, 3501 EndLoc); 3502 MsgExprs.push_back(SelExp); 3503 3504 // Now push any user supplied arguments. 3505 for (unsigned i = 0; i < Exp->getNumArgs(); i++) { 3506 Expr *userExpr = Exp->getArg(i); 3507 // Make all implicit casts explicit...ICE comes in handy:-) 3508 if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(userExpr)) { 3509 // Reuse the ICE type, it is exactly what the doctor ordered. 3510 QualType type = ICE->getType(); 3511 if (needToScanForQualifiers(type)) 3512 type = Context->getObjCIdType(); 3513 // Make sure we convert "type (^)(...)" to "type (*)(...)". 3514 (void)convertBlockPointerToFunctionPointer(type); 3515 const Expr *SubExpr = ICE->IgnoreParenImpCasts(); 3516 CastKind CK; 3517 if (SubExpr->getType()->isIntegralType(*Context) && 3518 type->isBooleanType()) { 3519 CK = CK_IntegralToBoolean; 3520 } else if (type->isObjCObjectPointerType()) { 3521 if (SubExpr->getType()->isBlockPointerType()) { 3522 CK = CK_BlockPointerToObjCPointerCast; 3523 } else if (SubExpr->getType()->isPointerType()) { 3524 CK = CK_CPointerToObjCPointerCast; 3525 } else { 3526 CK = CK_BitCast; 3527 } 3528 } else { 3529 CK = CK_BitCast; 3530 } 3531 3532 userExpr = NoTypeInfoCStyleCastExpr(Context, type, CK, userExpr); 3533 } 3534 // Make id<P...> cast into an 'id' cast. 3535 else if (CStyleCastExpr *CE = dyn_cast<CStyleCastExpr>(userExpr)) { 3536 if (CE->getType()->isObjCQualifiedIdType()) { 3537 while ((CE = dyn_cast<CStyleCastExpr>(userExpr))) 3538 userExpr = CE->getSubExpr(); 3539 CastKind CK; 3540 if (userExpr->getType()->isIntegralType(*Context)) { 3541 CK = CK_IntegralToPointer; 3542 } else if (userExpr->getType()->isBlockPointerType()) { 3543 CK = CK_BlockPointerToObjCPointerCast; 3544 } else if (userExpr->getType()->isPointerType()) { 3545 CK = CK_CPointerToObjCPointerCast; 3546 } else { 3547 CK = CK_BitCast; 3548 } 3549 userExpr = NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(), 3550 CK, userExpr); 3551 } 3552 } 3553 MsgExprs.push_back(userExpr); 3554 // We've transferred the ownership to MsgExprs. For now, we *don't* null 3555 // out the argument in the original expression (since we aren't deleting 3556 // the ObjCMessageExpr). See RewritePropertyOrImplicitSetter() usage for more info. 3557 //Exp->setArg(i, 0); 3558 } 3559 // Generate the funky cast. 3560 CastExpr *cast; 3561 SmallVector<QualType, 8> ArgTypes; 3562 QualType returnType; 3563 3564 // Push 'id' and 'SEL', the 2 implicit arguments. 3565 if (MsgSendFlavor == MsgSendSuperFunctionDecl) 3566 ArgTypes.push_back(Context->getPointerType(getSuperStructType())); 3567 else 3568 ArgTypes.push_back(Context->getObjCIdType()); 3569 ArgTypes.push_back(Context->getObjCSelType()); 3570 if (ObjCMethodDecl *OMD = Exp->getMethodDecl()) { 3571 // Push any user argument types. 3572 for (const auto *PI : OMD->params()) { 3573 QualType t = PI->getType()->isObjCQualifiedIdType() 3574 ? Context->getObjCIdType() 3575 : PI->getType(); 3576 // Make sure we convert "t (^)(...)" to "t (*)(...)". 3577 (void)convertBlockPointerToFunctionPointer(t); 3578 ArgTypes.push_back(t); 3579 } 3580 returnType = Exp->getType(); 3581 convertToUnqualifiedObjCType(returnType); 3582 (void)convertBlockPointerToFunctionPointer(returnType); 3583 } else { 3584 returnType = Context->getObjCIdType(); 3585 } 3586 // Get the type, we will need to reference it in a couple spots. 3587 QualType msgSendType = MsgSendFlavor->getType(); 3588 3589 // Create a reference to the objc_msgSend() declaration. 3590 DeclRefExpr *DRE = new (Context) DeclRefExpr(MsgSendFlavor, false, msgSendType, 3591 VK_LValue, SourceLocation()); 3592 3593 // Need to cast objc_msgSend to "void *" (to workaround a GCC bandaid). 3594 // If we don't do this cast, we get the following bizarre warning/note: 3595 // xx.m:13: warning: function called through a non-compatible type 3596 // xx.m:13: note: if this code is reached, the program will abort 3597 cast = NoTypeInfoCStyleCastExpr(Context, 3598 Context->getPointerType(Context->VoidTy), 3599 CK_BitCast, DRE); 3600 3601 // Now do the "normal" pointer to function cast. 3602 // If we don't have a method decl, force a variadic cast. 3603 const ObjCMethodDecl *MD = Exp->getMethodDecl(); 3604 QualType castType = 3605 getSimpleFunctionType(returnType, ArgTypes, MD ? MD->isVariadic() : true); 3606 castType = Context->getPointerType(castType); 3607 cast = NoTypeInfoCStyleCastExpr(Context, castType, CK_BitCast, 3608 cast); 3609 3610 // Don't forget the parens to enforce the proper binding. 3611 ParenExpr *PE = new (Context) ParenExpr(StartLoc, EndLoc, cast); 3612 3613 const FunctionType *FT = msgSendType->getAs<FunctionType>(); 3614 CallExpr *CE = new (Context) 3615 CallExpr(*Context, PE, MsgExprs, FT->getReturnType(), VK_RValue, EndLoc); 3616 Stmt *ReplacingStmt = CE; 3617 if (MsgSendStretFlavor) { 3618 // We have the method which returns a struct/union. Must also generate 3619 // call to objc_msgSend_stret and hang both varieties on a conditional 3620 // expression which dictate which one to envoke depending on size of 3621 // method's return type. 3622 3623 Expr *STCE = SynthMsgSendStretCallExpr(MsgSendStretFlavor, 3624 returnType, 3625 ArgTypes, MsgExprs, 3626 Exp->getMethodDecl()); 3627 ReplacingStmt = STCE; 3628 } 3629 // delete Exp; leak for now, see RewritePropertyOrImplicitSetter() usage for more info. 3630 return ReplacingStmt; 3631 } 3632 3633 Stmt *RewriteModernObjC::RewriteMessageExpr(ObjCMessageExpr *Exp) { 3634 Stmt *ReplacingStmt = SynthMessageExpr(Exp, Exp->getLocStart(), 3635 Exp->getLocEnd()); 3636 3637 // Now do the actual rewrite. 3638 ReplaceStmt(Exp, ReplacingStmt); 3639 3640 // delete Exp; leak for now, see RewritePropertyOrImplicitSetter() usage for more info. 3641 return ReplacingStmt; 3642 } 3643 3644 // typedef struct objc_object Protocol; 3645 QualType RewriteModernObjC::getProtocolType() { 3646 if (!ProtocolTypeDecl) { 3647 TypeSourceInfo *TInfo 3648 = Context->getTrivialTypeSourceInfo(Context->getObjCIdType()); 3649 ProtocolTypeDecl = TypedefDecl::Create(*Context, TUDecl, 3650 SourceLocation(), SourceLocation(), 3651 &Context->Idents.get("Protocol"), 3652 TInfo); 3653 } 3654 return Context->getTypeDeclType(ProtocolTypeDecl); 3655 } 3656 3657 /// RewriteObjCProtocolExpr - Rewrite a protocol expression into 3658 /// a synthesized/forward data reference (to the protocol's metadata). 3659 /// The forward references (and metadata) are generated in 3660 /// RewriteModernObjC::HandleTranslationUnit(). 3661 Stmt *RewriteModernObjC::RewriteObjCProtocolExpr(ObjCProtocolExpr *Exp) { 3662 std::string Name = "_OBJC_PROTOCOL_REFERENCE_$_" + 3663 Exp->getProtocol()->getNameAsString(); 3664 IdentifierInfo *ID = &Context->Idents.get(Name); 3665 VarDecl *VD = VarDecl::Create(*Context, TUDecl, SourceLocation(), 3666 SourceLocation(), ID, getProtocolType(), 3667 nullptr, SC_Extern); 3668 DeclRefExpr *DRE = new (Context) DeclRefExpr(VD, false, getProtocolType(), 3669 VK_LValue, SourceLocation()); 3670 CastExpr *castExpr = 3671 NoTypeInfoCStyleCastExpr( 3672 Context, Context->getPointerType(DRE->getType()), CK_BitCast, DRE); 3673 ReplaceStmt(Exp, castExpr); 3674 ProtocolExprDecls.insert(Exp->getProtocol()->getCanonicalDecl()); 3675 // delete Exp; leak for now, see RewritePropertyOrImplicitSetter() usage for more info. 3676 return castExpr; 3677 3678 } 3679 3680 bool RewriteModernObjC::BufferContainsPPDirectives(const char *startBuf, 3681 const char *endBuf) { 3682 while (startBuf < endBuf) { 3683 if (*startBuf == '#') { 3684 // Skip whitespace. 3685 for (++startBuf; startBuf[0] == ' ' || startBuf[0] == '\t'; ++startBuf) 3686 ; 3687 if (!strncmp(startBuf, "if", strlen("if")) || 3688 !strncmp(startBuf, "ifdef", strlen("ifdef")) || 3689 !strncmp(startBuf, "ifndef", strlen("ifndef")) || 3690 !strncmp(startBuf, "define", strlen("define")) || 3691 !strncmp(startBuf, "undef", strlen("undef")) || 3692 !strncmp(startBuf, "else", strlen("else")) || 3693 !strncmp(startBuf, "elif", strlen("elif")) || 3694 !strncmp(startBuf, "endif", strlen("endif")) || 3695 !strncmp(startBuf, "pragma", strlen("pragma")) || 3696 !strncmp(startBuf, "include", strlen("include")) || 3697 !strncmp(startBuf, "import", strlen("import")) || 3698 !strncmp(startBuf, "include_next", strlen("include_next"))) 3699 return true; 3700 } 3701 startBuf++; 3702 } 3703 return false; 3704 } 3705 3706 /// IsTagDefinedInsideClass - This routine checks that a named tagged type 3707 /// is defined inside an objective-c class. If so, it returns true. 3708 bool RewriteModernObjC::IsTagDefinedInsideClass(ObjCContainerDecl *IDecl, 3709 TagDecl *Tag, 3710 bool &IsNamedDefinition) { 3711 if (!IDecl) 3712 return false; 3713 SourceLocation TagLocation; 3714 if (RecordDecl *RD = dyn_cast<RecordDecl>(Tag)) { 3715 RD = RD->getDefinition(); 3716 if (!RD || !RD->getDeclName().getAsIdentifierInfo()) 3717 return false; 3718 IsNamedDefinition = true; 3719 TagLocation = RD->getLocation(); 3720 return Context->getSourceManager().isBeforeInTranslationUnit( 3721 IDecl->getLocation(), TagLocation); 3722 } 3723 if (EnumDecl *ED = dyn_cast<EnumDecl>(Tag)) { 3724 if (!ED || !ED->getDeclName().getAsIdentifierInfo()) 3725 return false; 3726 IsNamedDefinition = true; 3727 TagLocation = ED->getLocation(); 3728 return Context->getSourceManager().isBeforeInTranslationUnit( 3729 IDecl->getLocation(), TagLocation); 3730 3731 } 3732 return false; 3733 } 3734 3735 /// RewriteObjCFieldDeclType - This routine rewrites a type into the buffer. 3736 /// It handles elaborated types, as well as enum types in the process. 3737 bool RewriteModernObjC::RewriteObjCFieldDeclType(QualType &Type, 3738 std::string &Result) { 3739 if (isa<TypedefType>(Type)) { 3740 Result += "\t"; 3741 return false; 3742 } 3743 3744 if (Type->isArrayType()) { 3745 QualType ElemTy = Context->getBaseElementType(Type); 3746 return RewriteObjCFieldDeclType(ElemTy, Result); 3747 } 3748 else if (Type->isRecordType()) { 3749 RecordDecl *RD = Type->getAs<RecordType>()->getDecl(); 3750 if (RD->isCompleteDefinition()) { 3751 if (RD->isStruct()) 3752 Result += "\n\tstruct "; 3753 else if (RD->isUnion()) 3754 Result += "\n\tunion "; 3755 else 3756 assert(false && "class not allowed as an ivar type"); 3757 3758 Result += RD->getName(); 3759 if (GlobalDefinedTags.count(RD)) { 3760 // struct/union is defined globally, use it. 3761 Result += " "; 3762 return true; 3763 } 3764 Result += " {\n"; 3765 for (auto *FD : RD->fields()) 3766 RewriteObjCFieldDecl(FD, Result); 3767 Result += "\t} "; 3768 return true; 3769 } 3770 } 3771 else if (Type->isEnumeralType()) { 3772 EnumDecl *ED = Type->getAs<EnumType>()->getDecl(); 3773 if (ED->isCompleteDefinition()) { 3774 Result += "\n\tenum "; 3775 Result += ED->getName(); 3776 if (GlobalDefinedTags.count(ED)) { 3777 // Enum is globall defined, use it. 3778 Result += " "; 3779 return true; 3780 } 3781 3782 Result += " {\n"; 3783 for (const auto *EC : ED->enumerators()) { 3784 Result += "\t"; Result += EC->getName(); Result += " = "; 3785 llvm::APSInt Val = EC->getInitVal(); 3786 Result += Val.toString(10); 3787 Result += ",\n"; 3788 } 3789 Result += "\t} "; 3790 return true; 3791 } 3792 } 3793 3794 Result += "\t"; 3795 convertObjCTypeToCStyleType(Type); 3796 return false; 3797 } 3798 3799 3800 /// RewriteObjCFieldDecl - This routine rewrites a field into the buffer. 3801 /// It handles elaborated types, as well as enum types in the process. 3802 void RewriteModernObjC::RewriteObjCFieldDecl(FieldDecl *fieldDecl, 3803 std::string &Result) { 3804 QualType Type = fieldDecl->getType(); 3805 std::string Name = fieldDecl->getNameAsString(); 3806 3807 bool EleboratedType = RewriteObjCFieldDeclType(Type, Result); 3808 if (!EleboratedType) 3809 Type.getAsStringInternal(Name, Context->getPrintingPolicy()); 3810 Result += Name; 3811 if (fieldDecl->isBitField()) { 3812 Result += " : "; Result += utostr(fieldDecl->getBitWidthValue(*Context)); 3813 } 3814 else if (EleboratedType && Type->isArrayType()) { 3815 const ArrayType *AT = Context->getAsArrayType(Type); 3816 do { 3817 if (const ConstantArrayType *CAT = dyn_cast<ConstantArrayType>(AT)) { 3818 Result += "["; 3819 llvm::APInt Dim = CAT->getSize(); 3820 Result += utostr(Dim.getZExtValue()); 3821 Result += "]"; 3822 } 3823 AT = Context->getAsArrayType(AT->getElementType()); 3824 } while (AT); 3825 } 3826 3827 Result += ";\n"; 3828 } 3829 3830 /// RewriteLocallyDefinedNamedAggregates - This routine rewrites locally defined 3831 /// named aggregate types into the input buffer. 3832 void RewriteModernObjC::RewriteLocallyDefinedNamedAggregates(FieldDecl *fieldDecl, 3833 std::string &Result) { 3834 QualType Type = fieldDecl->getType(); 3835 if (isa<TypedefType>(Type)) 3836 return; 3837 if (Type->isArrayType()) 3838 Type = Context->getBaseElementType(Type); 3839 ObjCContainerDecl *IDecl = 3840 dyn_cast<ObjCContainerDecl>(fieldDecl->getDeclContext()); 3841 3842 TagDecl *TD = nullptr; 3843 if (Type->isRecordType()) { 3844 TD = Type->getAs<RecordType>()->getDecl(); 3845 } 3846 else if (Type->isEnumeralType()) { 3847 TD = Type->getAs<EnumType>()->getDecl(); 3848 } 3849 3850 if (TD) { 3851 if (GlobalDefinedTags.count(TD)) 3852 return; 3853 3854 bool IsNamedDefinition = false; 3855 if (IsTagDefinedInsideClass(IDecl, TD, IsNamedDefinition)) { 3856 RewriteObjCFieldDeclType(Type, Result); 3857 Result += ";"; 3858 } 3859 if (IsNamedDefinition) 3860 GlobalDefinedTags.insert(TD); 3861 } 3862 3863 } 3864 3865 unsigned RewriteModernObjC::ObjCIvarBitfieldGroupNo(ObjCIvarDecl *IV) { 3866 const ObjCInterfaceDecl *CDecl = IV->getContainingInterface(); 3867 if (ObjCInterefaceHasBitfieldGroups.count(CDecl)) { 3868 return IvarGroupNumber[IV]; 3869 } 3870 unsigned GroupNo = 0; 3871 SmallVector<const ObjCIvarDecl *, 8> IVars; 3872 for (const ObjCIvarDecl *IVD = CDecl->all_declared_ivar_begin(); 3873 IVD; IVD = IVD->getNextIvar()) 3874 IVars.push_back(IVD); 3875 3876 for (unsigned i = 0, e = IVars.size(); i < e; i++) 3877 if (IVars[i]->isBitField()) { 3878 IvarGroupNumber[IVars[i++]] = ++GroupNo; 3879 while (i < e && IVars[i]->isBitField()) 3880 IvarGroupNumber[IVars[i++]] = GroupNo; 3881 if (i < e) 3882 --i; 3883 } 3884 3885 ObjCInterefaceHasBitfieldGroups.insert(CDecl); 3886 return IvarGroupNumber[IV]; 3887 } 3888 3889 QualType RewriteModernObjC::SynthesizeBitfieldGroupStructType( 3890 ObjCIvarDecl *IV, 3891 SmallVectorImpl<ObjCIvarDecl *> &IVars) { 3892 std::string StructTagName; 3893 ObjCIvarBitfieldGroupType(IV, StructTagName); 3894 RecordDecl *RD = RecordDecl::Create(*Context, TTK_Struct, 3895 Context->getTranslationUnitDecl(), 3896 SourceLocation(), SourceLocation(), 3897 &Context->Idents.get(StructTagName)); 3898 for (unsigned i=0, e = IVars.size(); i < e; i++) { 3899 ObjCIvarDecl *Ivar = IVars[i]; 3900 RD->addDecl(FieldDecl::Create(*Context, RD, SourceLocation(), SourceLocation(), 3901 &Context->Idents.get(Ivar->getName()), 3902 Ivar->getType(), 3903 nullptr, /*Expr *BW */Ivar->getBitWidth(), 3904 false, ICIS_NoInit)); 3905 } 3906 RD->completeDefinition(); 3907 return Context->getTagDeclType(RD); 3908 } 3909 3910 QualType RewriteModernObjC::GetGroupRecordTypeForObjCIvarBitfield(ObjCIvarDecl *IV) { 3911 const ObjCInterfaceDecl *CDecl = IV->getContainingInterface(); 3912 unsigned GroupNo = ObjCIvarBitfieldGroupNo(IV); 3913 std::pair<const ObjCInterfaceDecl*, unsigned> tuple = std::make_pair(CDecl, GroupNo); 3914 if (GroupRecordType.count(tuple)) 3915 return GroupRecordType[tuple]; 3916 3917 SmallVector<ObjCIvarDecl *, 8> IVars; 3918 for (const ObjCIvarDecl *IVD = CDecl->all_declared_ivar_begin(); 3919 IVD; IVD = IVD->getNextIvar()) { 3920 if (IVD->isBitField()) 3921 IVars.push_back(const_cast<ObjCIvarDecl *>(IVD)); 3922 else { 3923 if (!IVars.empty()) { 3924 unsigned GroupNo = ObjCIvarBitfieldGroupNo(IVars[0]); 3925 // Generate the struct type for this group of bitfield ivars. 3926 GroupRecordType[std::make_pair(CDecl, GroupNo)] = 3927 SynthesizeBitfieldGroupStructType(IVars[0], IVars); 3928 IVars.clear(); 3929 } 3930 } 3931 } 3932 if (!IVars.empty()) { 3933 // Do the last one. 3934 unsigned GroupNo = ObjCIvarBitfieldGroupNo(IVars[0]); 3935 GroupRecordType[std::make_pair(CDecl, GroupNo)] = 3936 SynthesizeBitfieldGroupStructType(IVars[0], IVars); 3937 } 3938 QualType RetQT = GroupRecordType[tuple]; 3939 assert(!RetQT.isNull() && "GetGroupRecordTypeForObjCIvarBitfield struct type is NULL"); 3940 3941 return RetQT; 3942 } 3943 3944 /// ObjCIvarBitfieldGroupDecl - Names field decl. for ivar bitfield group. 3945 /// Name would be: classname__GRBF_n where n is the group number for this ivar. 3946 void RewriteModernObjC::ObjCIvarBitfieldGroupDecl(ObjCIvarDecl *IV, 3947 std::string &Result) { 3948 const ObjCInterfaceDecl *CDecl = IV->getContainingInterface(); 3949 Result += CDecl->getName(); 3950 Result += "__GRBF_"; 3951 unsigned GroupNo = ObjCIvarBitfieldGroupNo(IV); 3952 Result += utostr(GroupNo); 3953 return; 3954 } 3955 3956 /// ObjCIvarBitfieldGroupType - Names struct type for ivar bitfield group. 3957 /// Name of the struct would be: classname__T_n where n is the group number for 3958 /// this ivar. 3959 void RewriteModernObjC::ObjCIvarBitfieldGroupType(ObjCIvarDecl *IV, 3960 std::string &Result) { 3961 const ObjCInterfaceDecl *CDecl = IV->getContainingInterface(); 3962 Result += CDecl->getName(); 3963 Result += "__T_"; 3964 unsigned GroupNo = ObjCIvarBitfieldGroupNo(IV); 3965 Result += utostr(GroupNo); 3966 return; 3967 } 3968 3969 /// ObjCIvarBitfieldGroupOffset - Names symbol for ivar bitfield group field offset. 3970 /// Name would be: OBJC_IVAR_$_classname__GRBF_n where n is the group number for 3971 /// this ivar. 3972 void RewriteModernObjC::ObjCIvarBitfieldGroupOffset(ObjCIvarDecl *IV, 3973 std::string &Result) { 3974 Result += "OBJC_IVAR_$_"; 3975 ObjCIvarBitfieldGroupDecl(IV, Result); 3976 } 3977 3978 #define SKIP_BITFIELDS(IX, ENDIX, VEC) { \ 3979 while ((IX < ENDIX) && VEC[IX]->isBitField()) \ 3980 ++IX; \ 3981 if (IX < ENDIX) \ 3982 --IX; \ 3983 } 3984 3985 /// RewriteObjCInternalStruct - Rewrite one internal struct corresponding to 3986 /// an objective-c class with ivars. 3987 void RewriteModernObjC::RewriteObjCInternalStruct(ObjCInterfaceDecl *CDecl, 3988 std::string &Result) { 3989 assert(CDecl && "Class missing in SynthesizeObjCInternalStruct"); 3990 assert(CDecl->getName() != "" && 3991 "Name missing in SynthesizeObjCInternalStruct"); 3992 ObjCInterfaceDecl *RCDecl = CDecl->getSuperClass(); 3993 SmallVector<ObjCIvarDecl *, 8> IVars; 3994 for (ObjCIvarDecl *IVD = CDecl->all_declared_ivar_begin(); 3995 IVD; IVD = IVD->getNextIvar()) 3996 IVars.push_back(IVD); 3997 3998 SourceLocation LocStart = CDecl->getLocStart(); 3999 SourceLocation LocEnd = CDecl->getEndOfDefinitionLoc(); 4000 4001 const char *startBuf = SM->getCharacterData(LocStart); 4002 const char *endBuf = SM->getCharacterData(LocEnd); 4003 4004 // If no ivars and no root or if its root, directly or indirectly, 4005 // have no ivars (thus not synthesized) then no need to synthesize this class. 4006 if ((!CDecl->isThisDeclarationADefinition() || IVars.size() == 0) && 4007 (!RCDecl || !ObjCSynthesizedStructs.count(RCDecl))) { 4008 endBuf += Lexer::MeasureTokenLength(LocEnd, *SM, LangOpts); 4009 ReplaceText(LocStart, endBuf-startBuf, Result); 4010 return; 4011 } 4012 4013 // Insert named struct/union definitions inside class to 4014 // outer scope. This follows semantics of locally defined 4015 // struct/unions in objective-c classes. 4016 for (unsigned i = 0, e = IVars.size(); i < e; i++) 4017 RewriteLocallyDefinedNamedAggregates(IVars[i], Result); 4018 4019 // Insert named structs which are syntheized to group ivar bitfields 4020 // to outer scope as well. 4021 for (unsigned i = 0, e = IVars.size(); i < e; i++) 4022 if (IVars[i]->isBitField()) { 4023 ObjCIvarDecl *IV = IVars[i]; 4024 QualType QT = GetGroupRecordTypeForObjCIvarBitfield(IV); 4025 RewriteObjCFieldDeclType(QT, Result); 4026 Result += ";"; 4027 // skip over ivar bitfields in this group. 4028 SKIP_BITFIELDS(i , e, IVars); 4029 } 4030 4031 Result += "\nstruct "; 4032 Result += CDecl->getNameAsString(); 4033 Result += "_IMPL {\n"; 4034 4035 if (RCDecl && ObjCSynthesizedStructs.count(RCDecl)) { 4036 Result += "\tstruct "; Result += RCDecl->getNameAsString(); 4037 Result += "_IMPL "; Result += RCDecl->getNameAsString(); 4038 Result += "_IVARS;\n"; 4039 } 4040 4041 for (unsigned i = 0, e = IVars.size(); i < e; i++) { 4042 if (IVars[i]->isBitField()) { 4043 ObjCIvarDecl *IV = IVars[i]; 4044 Result += "\tstruct "; 4045 ObjCIvarBitfieldGroupType(IV, Result); Result += " "; 4046 ObjCIvarBitfieldGroupDecl(IV, Result); Result += ";\n"; 4047 // skip over ivar bitfields in this group. 4048 SKIP_BITFIELDS(i , e, IVars); 4049 } 4050 else 4051 RewriteObjCFieldDecl(IVars[i], Result); 4052 } 4053 4054 Result += "};\n"; 4055 endBuf += Lexer::MeasureTokenLength(LocEnd, *SM, LangOpts); 4056 ReplaceText(LocStart, endBuf-startBuf, Result); 4057 // Mark this struct as having been generated. 4058 if (!ObjCSynthesizedStructs.insert(CDecl)) 4059 llvm_unreachable("struct already synthesize- RewriteObjCInternalStruct"); 4060 } 4061 4062 /// RewriteIvarOffsetSymbols - Rewrite ivar offset symbols of those ivars which 4063 /// have been referenced in an ivar access expression. 4064 void RewriteModernObjC::RewriteIvarOffsetSymbols(ObjCInterfaceDecl *CDecl, 4065 std::string &Result) { 4066 // write out ivar offset symbols which have been referenced in an ivar 4067 // access expression. 4068 llvm::SmallPtrSet<ObjCIvarDecl *, 8> Ivars = ReferencedIvars[CDecl]; 4069 if (Ivars.empty()) 4070 return; 4071 4072 llvm::DenseSet<std::pair<const ObjCInterfaceDecl*, unsigned> > GroupSymbolOutput; 4073 for (llvm::SmallPtrSet<ObjCIvarDecl *, 8>::iterator i = Ivars.begin(), 4074 e = Ivars.end(); i != e; i++) { 4075 ObjCIvarDecl *IvarDecl = (*i); 4076 const ObjCInterfaceDecl *IDecl = IvarDecl->getContainingInterface(); 4077 unsigned GroupNo = 0; 4078 if (IvarDecl->isBitField()) { 4079 GroupNo = ObjCIvarBitfieldGroupNo(IvarDecl); 4080 if (GroupSymbolOutput.count(std::make_pair(IDecl, GroupNo))) 4081 continue; 4082 } 4083 Result += "\n"; 4084 if (LangOpts.MicrosoftExt) 4085 Result += "__declspec(allocate(\".objc_ivar$B\")) "; 4086 Result += "extern \"C\" "; 4087 if (LangOpts.MicrosoftExt && 4088 IvarDecl->getAccessControl() != ObjCIvarDecl::Private && 4089 IvarDecl->getAccessControl() != ObjCIvarDecl::Package) 4090 Result += "__declspec(dllimport) "; 4091 4092 Result += "unsigned long "; 4093 if (IvarDecl->isBitField()) { 4094 ObjCIvarBitfieldGroupOffset(IvarDecl, Result); 4095 GroupSymbolOutput.insert(std::make_pair(IDecl, GroupNo)); 4096 } 4097 else 4098 WriteInternalIvarName(CDecl, IvarDecl, Result); 4099 Result += ";"; 4100 } 4101 } 4102 4103 //===----------------------------------------------------------------------===// 4104 // Meta Data Emission 4105 //===----------------------------------------------------------------------===// 4106 4107 4108 /// RewriteImplementations - This routine rewrites all method implementations 4109 /// and emits meta-data. 4110 4111 void RewriteModernObjC::RewriteImplementations() { 4112 int ClsDefCount = ClassImplementation.size(); 4113 int CatDefCount = CategoryImplementation.size(); 4114 4115 // Rewrite implemented methods 4116 for (int i = 0; i < ClsDefCount; i++) { 4117 ObjCImplementationDecl *OIMP = ClassImplementation[i]; 4118 ObjCInterfaceDecl *CDecl = OIMP->getClassInterface(); 4119 if (CDecl->isImplicitInterfaceDecl()) 4120 assert(false && 4121 "Legacy implicit interface rewriting not supported in moder abi"); 4122 RewriteImplementationDecl(OIMP); 4123 } 4124 4125 for (int i = 0; i < CatDefCount; i++) { 4126 ObjCCategoryImplDecl *CIMP = CategoryImplementation[i]; 4127 ObjCInterfaceDecl *CDecl = CIMP->getClassInterface(); 4128 if (CDecl->isImplicitInterfaceDecl()) 4129 assert(false && 4130 "Legacy implicit interface rewriting not supported in moder abi"); 4131 RewriteImplementationDecl(CIMP); 4132 } 4133 } 4134 4135 void RewriteModernObjC::RewriteByRefString(std::string &ResultStr, 4136 const std::string &Name, 4137 ValueDecl *VD, bool def) { 4138 assert(BlockByRefDeclNo.count(VD) && 4139 "RewriteByRefString: ByRef decl missing"); 4140 if (def) 4141 ResultStr += "struct "; 4142 ResultStr += "__Block_byref_" + Name + 4143 "_" + utostr(BlockByRefDeclNo[VD]) ; 4144 } 4145 4146 static bool HasLocalVariableExternalStorage(ValueDecl *VD) { 4147 if (VarDecl *Var = dyn_cast<VarDecl>(VD)) 4148 return (Var->isFunctionOrMethodVarDecl() && !Var->hasLocalStorage()); 4149 return false; 4150 } 4151 4152 std::string RewriteModernObjC::SynthesizeBlockFunc(BlockExpr *CE, int i, 4153 StringRef funcName, 4154 std::string Tag) { 4155 const FunctionType *AFT = CE->getFunctionType(); 4156 QualType RT = AFT->getReturnType(); 4157 std::string StructRef = "struct " + Tag; 4158 SourceLocation BlockLoc = CE->getExprLoc(); 4159 std::string S; 4160 ConvertSourceLocationToLineDirective(BlockLoc, S); 4161 4162 S += "static " + RT.getAsString(Context->getPrintingPolicy()) + " __" + 4163 funcName.str() + "_block_func_" + utostr(i); 4164 4165 BlockDecl *BD = CE->getBlockDecl(); 4166 4167 if (isa<FunctionNoProtoType>(AFT)) { 4168 // No user-supplied arguments. Still need to pass in a pointer to the 4169 // block (to reference imported block decl refs). 4170 S += "(" + StructRef + " *__cself)"; 4171 } else if (BD->param_empty()) { 4172 S += "(" + StructRef + " *__cself)"; 4173 } else { 4174 const FunctionProtoType *FT = cast<FunctionProtoType>(AFT); 4175 assert(FT && "SynthesizeBlockFunc: No function proto"); 4176 S += '('; 4177 // first add the implicit argument. 4178 S += StructRef + " *__cself, "; 4179 std::string ParamStr; 4180 for (BlockDecl::param_iterator AI = BD->param_begin(), 4181 E = BD->param_end(); AI != E; ++AI) { 4182 if (AI != BD->param_begin()) S += ", "; 4183 ParamStr = (*AI)->getNameAsString(); 4184 QualType QT = (*AI)->getType(); 4185 (void)convertBlockPointerToFunctionPointer(QT); 4186 QT.getAsStringInternal(ParamStr, Context->getPrintingPolicy()); 4187 S += ParamStr; 4188 } 4189 if (FT->isVariadic()) { 4190 if (!BD->param_empty()) S += ", "; 4191 S += "..."; 4192 } 4193 S += ')'; 4194 } 4195 S += " {\n"; 4196 4197 // Create local declarations to avoid rewriting all closure decl ref exprs. 4198 // First, emit a declaration for all "by ref" decls. 4199 for (SmallVectorImpl<ValueDecl *>::iterator I = BlockByRefDecls.begin(), 4200 E = BlockByRefDecls.end(); I != E; ++I) { 4201 S += " "; 4202 std::string Name = (*I)->getNameAsString(); 4203 std::string TypeString; 4204 RewriteByRefString(TypeString, Name, (*I)); 4205 TypeString += " *"; 4206 Name = TypeString + Name; 4207 S += Name + " = __cself->" + (*I)->getNameAsString() + "; // bound by ref\n"; 4208 } 4209 // Next, emit a declaration for all "by copy" declarations. 4210 for (SmallVectorImpl<ValueDecl *>::iterator I = BlockByCopyDecls.begin(), 4211 E = BlockByCopyDecls.end(); I != E; ++I) { 4212 S += " "; 4213 // Handle nested closure invocation. For example: 4214 // 4215 // void (^myImportedClosure)(void); 4216 // myImportedClosure = ^(void) { setGlobalInt(x + y); }; 4217 // 4218 // void (^anotherClosure)(void); 4219 // anotherClosure = ^(void) { 4220 // myImportedClosure(); // import and invoke the closure 4221 // }; 4222 // 4223 if (isTopLevelBlockPointerType((*I)->getType())) { 4224 RewriteBlockPointerTypeVariable(S, (*I)); 4225 S += " = ("; 4226 RewriteBlockPointerType(S, (*I)->getType()); 4227 S += ")"; 4228 S += "__cself->" + (*I)->getNameAsString() + "; // bound by copy\n"; 4229 } 4230 else { 4231 std::string Name = (*I)->getNameAsString(); 4232 QualType QT = (*I)->getType(); 4233 if (HasLocalVariableExternalStorage(*I)) 4234 QT = Context->getPointerType(QT); 4235 QT.getAsStringInternal(Name, Context->getPrintingPolicy()); 4236 S += Name + " = __cself->" + 4237 (*I)->getNameAsString() + "; // bound by copy\n"; 4238 } 4239 } 4240 std::string RewrittenStr = RewrittenBlockExprs[CE]; 4241 const char *cstr = RewrittenStr.c_str(); 4242 while (*cstr++ != '{') ; 4243 S += cstr; 4244 S += "\n"; 4245 return S; 4246 } 4247 4248 std::string RewriteModernObjC::SynthesizeBlockHelperFuncs(BlockExpr *CE, int i, 4249 StringRef funcName, 4250 std::string Tag) { 4251 std::string StructRef = "struct " + Tag; 4252 std::string S = "static void __"; 4253 4254 S += funcName; 4255 S += "_block_copy_" + utostr(i); 4256 S += "(" + StructRef; 4257 S += "*dst, " + StructRef; 4258 S += "*src) {"; 4259 for (llvm::SmallPtrSet<ValueDecl*,8>::iterator I = ImportedBlockDecls.begin(), 4260 E = ImportedBlockDecls.end(); I != E; ++I) { 4261 ValueDecl *VD = (*I); 4262 S += "_Block_object_assign((void*)&dst->"; 4263 S += (*I)->getNameAsString(); 4264 S += ", (void*)src->"; 4265 S += (*I)->getNameAsString(); 4266 if (BlockByRefDeclsPtrSet.count((*I))) 4267 S += ", " + utostr(BLOCK_FIELD_IS_BYREF) + "/*BLOCK_FIELD_IS_BYREF*/);"; 4268 else if (VD->getType()->isBlockPointerType()) 4269 S += ", " + utostr(BLOCK_FIELD_IS_BLOCK) + "/*BLOCK_FIELD_IS_BLOCK*/);"; 4270 else 4271 S += ", " + utostr(BLOCK_FIELD_IS_OBJECT) + "/*BLOCK_FIELD_IS_OBJECT*/);"; 4272 } 4273 S += "}\n"; 4274 4275 S += "\nstatic void __"; 4276 S += funcName; 4277 S += "_block_dispose_" + utostr(i); 4278 S += "(" + StructRef; 4279 S += "*src) {"; 4280 for (llvm::SmallPtrSet<ValueDecl*,8>::iterator I = ImportedBlockDecls.begin(), 4281 E = ImportedBlockDecls.end(); I != E; ++I) { 4282 ValueDecl *VD = (*I); 4283 S += "_Block_object_dispose((void*)src->"; 4284 S += (*I)->getNameAsString(); 4285 if (BlockByRefDeclsPtrSet.count((*I))) 4286 S += ", " + utostr(BLOCK_FIELD_IS_BYREF) + "/*BLOCK_FIELD_IS_BYREF*/);"; 4287 else if (VD->getType()->isBlockPointerType()) 4288 S += ", " + utostr(BLOCK_FIELD_IS_BLOCK) + "/*BLOCK_FIELD_IS_BLOCK*/);"; 4289 else 4290 S += ", " + utostr(BLOCK_FIELD_IS_OBJECT) + "/*BLOCK_FIELD_IS_OBJECT*/);"; 4291 } 4292 S += "}\n"; 4293 return S; 4294 } 4295 4296 std::string RewriteModernObjC::SynthesizeBlockImpl(BlockExpr *CE, std::string Tag, 4297 std::string Desc) { 4298 std::string S = "\nstruct " + Tag; 4299 std::string Constructor = " " + Tag; 4300 4301 S += " {\n struct __block_impl impl;\n"; 4302 S += " struct " + Desc; 4303 S += "* Desc;\n"; 4304 4305 Constructor += "(void *fp, "; // Invoke function pointer. 4306 Constructor += "struct " + Desc; // Descriptor pointer. 4307 Constructor += " *desc"; 4308 4309 if (BlockDeclRefs.size()) { 4310 // Output all "by copy" declarations. 4311 for (SmallVectorImpl<ValueDecl *>::iterator I = BlockByCopyDecls.begin(), 4312 E = BlockByCopyDecls.end(); I != E; ++I) { 4313 S += " "; 4314 std::string FieldName = (*I)->getNameAsString(); 4315 std::string ArgName = "_" + FieldName; 4316 // Handle nested closure invocation. For example: 4317 // 4318 // void (^myImportedBlock)(void); 4319 // myImportedBlock = ^(void) { setGlobalInt(x + y); }; 4320 // 4321 // void (^anotherBlock)(void); 4322 // anotherBlock = ^(void) { 4323 // myImportedBlock(); // import and invoke the closure 4324 // }; 4325 // 4326 if (isTopLevelBlockPointerType((*I)->getType())) { 4327 S += "struct __block_impl *"; 4328 Constructor += ", void *" + ArgName; 4329 } else { 4330 QualType QT = (*I)->getType(); 4331 if (HasLocalVariableExternalStorage(*I)) 4332 QT = Context->getPointerType(QT); 4333 QT.getAsStringInternal(FieldName, Context->getPrintingPolicy()); 4334 QT.getAsStringInternal(ArgName, Context->getPrintingPolicy()); 4335 Constructor += ", " + ArgName; 4336 } 4337 S += FieldName + ";\n"; 4338 } 4339 // Output all "by ref" declarations. 4340 for (SmallVectorImpl<ValueDecl *>::iterator I = BlockByRefDecls.begin(), 4341 E = BlockByRefDecls.end(); I != E; ++I) { 4342 S += " "; 4343 std::string FieldName = (*I)->getNameAsString(); 4344 std::string ArgName = "_" + FieldName; 4345 { 4346 std::string TypeString; 4347 RewriteByRefString(TypeString, FieldName, (*I)); 4348 TypeString += " *"; 4349 FieldName = TypeString + FieldName; 4350 ArgName = TypeString + ArgName; 4351 Constructor += ", " + ArgName; 4352 } 4353 S += FieldName + "; // by ref\n"; 4354 } 4355 // Finish writing the constructor. 4356 Constructor += ", int flags=0)"; 4357 // Initialize all "by copy" arguments. 4358 bool firsTime = true; 4359 for (SmallVectorImpl<ValueDecl *>::iterator I = BlockByCopyDecls.begin(), 4360 E = BlockByCopyDecls.end(); I != E; ++I) { 4361 std::string Name = (*I)->getNameAsString(); 4362 if (firsTime) { 4363 Constructor += " : "; 4364 firsTime = false; 4365 } 4366 else 4367 Constructor += ", "; 4368 if (isTopLevelBlockPointerType((*I)->getType())) 4369 Constructor += Name + "((struct __block_impl *)_" + Name + ")"; 4370 else 4371 Constructor += Name + "(_" + Name + ")"; 4372 } 4373 // Initialize all "by ref" arguments. 4374 for (SmallVectorImpl<ValueDecl *>::iterator I = BlockByRefDecls.begin(), 4375 E = BlockByRefDecls.end(); I != E; ++I) { 4376 std::string Name = (*I)->getNameAsString(); 4377 if (firsTime) { 4378 Constructor += " : "; 4379 firsTime = false; 4380 } 4381 else 4382 Constructor += ", "; 4383 Constructor += Name + "(_" + Name + "->__forwarding)"; 4384 } 4385 4386 Constructor += " {\n"; 4387 if (GlobalVarDecl) 4388 Constructor += " impl.isa = &_NSConcreteGlobalBlock;\n"; 4389 else 4390 Constructor += " impl.isa = &_NSConcreteStackBlock;\n"; 4391 Constructor += " impl.Flags = flags;\n impl.FuncPtr = fp;\n"; 4392 4393 Constructor += " Desc = desc;\n"; 4394 } else { 4395 // Finish writing the constructor. 4396 Constructor += ", int flags=0) {\n"; 4397 if (GlobalVarDecl) 4398 Constructor += " impl.isa = &_NSConcreteGlobalBlock;\n"; 4399 else 4400 Constructor += " impl.isa = &_NSConcreteStackBlock;\n"; 4401 Constructor += " impl.Flags = flags;\n impl.FuncPtr = fp;\n"; 4402 Constructor += " Desc = desc;\n"; 4403 } 4404 Constructor += " "; 4405 Constructor += "}\n"; 4406 S += Constructor; 4407 S += "};\n"; 4408 return S; 4409 } 4410 4411 std::string RewriteModernObjC::SynthesizeBlockDescriptor(std::string DescTag, 4412 std::string ImplTag, int i, 4413 StringRef FunName, 4414 unsigned hasCopy) { 4415 std::string S = "\nstatic struct " + DescTag; 4416 4417 S += " {\n size_t reserved;\n"; 4418 S += " size_t Block_size;\n"; 4419 if (hasCopy) { 4420 S += " void (*copy)(struct "; 4421 S += ImplTag; S += "*, struct "; 4422 S += ImplTag; S += "*);\n"; 4423 4424 S += " void (*dispose)(struct "; 4425 S += ImplTag; S += "*);\n"; 4426 } 4427 S += "} "; 4428 4429 S += DescTag + "_DATA = { 0, sizeof(struct "; 4430 S += ImplTag + ")"; 4431 if (hasCopy) { 4432 S += ", __" + FunName.str() + "_block_copy_" + utostr(i); 4433 S += ", __" + FunName.str() + "_block_dispose_" + utostr(i); 4434 } 4435 S += "};\n"; 4436 return S; 4437 } 4438 4439 void RewriteModernObjC::SynthesizeBlockLiterals(SourceLocation FunLocStart, 4440 StringRef FunName) { 4441 bool RewriteSC = (GlobalVarDecl && 4442 !Blocks.empty() && 4443 GlobalVarDecl->getStorageClass() == SC_Static && 4444 GlobalVarDecl->getType().getCVRQualifiers()); 4445 if (RewriteSC) { 4446 std::string SC(" void __"); 4447 SC += GlobalVarDecl->getNameAsString(); 4448 SC += "() {}"; 4449 InsertText(FunLocStart, SC); 4450 } 4451 4452 // Insert closures that were part of the function. 4453 for (unsigned i = 0, count=0; i < Blocks.size(); i++) { 4454 CollectBlockDeclRefInfo(Blocks[i]); 4455 // Need to copy-in the inner copied-in variables not actually used in this 4456 // block. 4457 for (int j = 0; j < InnerDeclRefsCount[i]; j++) { 4458 DeclRefExpr *Exp = InnerDeclRefs[count++]; 4459 ValueDecl *VD = Exp->getDecl(); 4460 BlockDeclRefs.push_back(Exp); 4461 if (!VD->hasAttr<BlocksAttr>()) { 4462 if (!BlockByCopyDeclsPtrSet.count(VD)) { 4463 BlockByCopyDeclsPtrSet.insert(VD); 4464 BlockByCopyDecls.push_back(VD); 4465 } 4466 continue; 4467 } 4468 4469 if (!BlockByRefDeclsPtrSet.count(VD)) { 4470 BlockByRefDeclsPtrSet.insert(VD); 4471 BlockByRefDecls.push_back(VD); 4472 } 4473 4474 // imported objects in the inner blocks not used in the outer 4475 // blocks must be copied/disposed in the outer block as well. 4476 if (VD->getType()->isObjCObjectPointerType() || 4477 VD->getType()->isBlockPointerType()) 4478 ImportedBlockDecls.insert(VD); 4479 } 4480 4481 std::string ImplTag = "__" + FunName.str() + "_block_impl_" + utostr(i); 4482 std::string DescTag = "__" + FunName.str() + "_block_desc_" + utostr(i); 4483 4484 std::string CI = SynthesizeBlockImpl(Blocks[i], ImplTag, DescTag); 4485 4486 InsertText(FunLocStart, CI); 4487 4488 std::string CF = SynthesizeBlockFunc(Blocks[i], i, FunName, ImplTag); 4489 4490 InsertText(FunLocStart, CF); 4491 4492 if (ImportedBlockDecls.size()) { 4493 std::string HF = SynthesizeBlockHelperFuncs(Blocks[i], i, FunName, ImplTag); 4494 InsertText(FunLocStart, HF); 4495 } 4496 std::string BD = SynthesizeBlockDescriptor(DescTag, ImplTag, i, FunName, 4497 ImportedBlockDecls.size() > 0); 4498 InsertText(FunLocStart, BD); 4499 4500 BlockDeclRefs.clear(); 4501 BlockByRefDecls.clear(); 4502 BlockByRefDeclsPtrSet.clear(); 4503 BlockByCopyDecls.clear(); 4504 BlockByCopyDeclsPtrSet.clear(); 4505 ImportedBlockDecls.clear(); 4506 } 4507 if (RewriteSC) { 4508 // Must insert any 'const/volatile/static here. Since it has been 4509 // removed as result of rewriting of block literals. 4510 std::string SC; 4511 if (GlobalVarDecl->getStorageClass() == SC_Static) 4512 SC = "static "; 4513 if (GlobalVarDecl->getType().isConstQualified()) 4514 SC += "const "; 4515 if (GlobalVarDecl->getType().isVolatileQualified()) 4516 SC += "volatile "; 4517 if (GlobalVarDecl->getType().isRestrictQualified()) 4518 SC += "restrict "; 4519 InsertText(FunLocStart, SC); 4520 } 4521 if (GlobalConstructionExp) { 4522 // extra fancy dance for global literal expression. 4523 4524 // Always the latest block expression on the block stack. 4525 std::string Tag = "__"; 4526 Tag += FunName; 4527 Tag += "_block_impl_"; 4528 Tag += utostr(Blocks.size()-1); 4529 std::string globalBuf = "static "; 4530 globalBuf += Tag; globalBuf += " "; 4531 std::string SStr; 4532 4533 llvm::raw_string_ostream constructorExprBuf(SStr); 4534 GlobalConstructionExp->printPretty(constructorExprBuf, nullptr, 4535 PrintingPolicy(LangOpts)); 4536 globalBuf += constructorExprBuf.str(); 4537 globalBuf += ";\n"; 4538 InsertText(FunLocStart, globalBuf); 4539 GlobalConstructionExp = nullptr; 4540 } 4541 4542 Blocks.clear(); 4543 InnerDeclRefsCount.clear(); 4544 InnerDeclRefs.clear(); 4545 RewrittenBlockExprs.clear(); 4546 } 4547 4548 void RewriteModernObjC::InsertBlockLiteralsWithinFunction(FunctionDecl *FD) { 4549 SourceLocation FunLocStart = 4550 (!Blocks.empty()) ? getFunctionSourceLocation(*this, FD) 4551 : FD->getTypeSpecStartLoc(); 4552 StringRef FuncName = FD->getName(); 4553 4554 SynthesizeBlockLiterals(FunLocStart, FuncName); 4555 } 4556 4557 static void BuildUniqueMethodName(std::string &Name, 4558 ObjCMethodDecl *MD) { 4559 ObjCInterfaceDecl *IFace = MD->getClassInterface(); 4560 Name = IFace->getName(); 4561 Name += "__" + MD->getSelector().getAsString(); 4562 // Convert colons to underscores. 4563 std::string::size_type loc = 0; 4564 while ((loc = Name.find(":", loc)) != std::string::npos) 4565 Name.replace(loc, 1, "_"); 4566 } 4567 4568 void RewriteModernObjC::InsertBlockLiteralsWithinMethod(ObjCMethodDecl *MD) { 4569 //fprintf(stderr,"In InsertBlockLiteralsWitinMethod\n"); 4570 //SourceLocation FunLocStart = MD->getLocStart(); 4571 SourceLocation FunLocStart = MD->getLocStart(); 4572 std::string FuncName; 4573 BuildUniqueMethodName(FuncName, MD); 4574 SynthesizeBlockLiterals(FunLocStart, FuncName); 4575 } 4576 4577 void RewriteModernObjC::GetBlockDeclRefExprs(Stmt *S) { 4578 for (Stmt::child_range CI = S->children(); CI; ++CI) 4579 if (*CI) { 4580 if (BlockExpr *CBE = dyn_cast<BlockExpr>(*CI)) 4581 GetBlockDeclRefExprs(CBE->getBody()); 4582 else 4583 GetBlockDeclRefExprs(*CI); 4584 } 4585 // Handle specific things. 4586 if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(S)) { 4587 if (DRE->refersToEnclosingLocal()) { 4588 // FIXME: Handle enums. 4589 if (!isa<FunctionDecl>(DRE->getDecl())) 4590 BlockDeclRefs.push_back(DRE); 4591 if (HasLocalVariableExternalStorage(DRE->getDecl())) 4592 BlockDeclRefs.push_back(DRE); 4593 } 4594 } 4595 4596 return; 4597 } 4598 4599 void RewriteModernObjC::GetInnerBlockDeclRefExprs(Stmt *S, 4600 SmallVectorImpl<DeclRefExpr *> &InnerBlockDeclRefs, 4601 llvm::SmallPtrSet<const DeclContext *, 8> &InnerContexts) { 4602 for (Stmt::child_range CI = S->children(); CI; ++CI) 4603 if (*CI) { 4604 if (BlockExpr *CBE = dyn_cast<BlockExpr>(*CI)) { 4605 InnerContexts.insert(cast<DeclContext>(CBE->getBlockDecl())); 4606 GetInnerBlockDeclRefExprs(CBE->getBody(), 4607 InnerBlockDeclRefs, 4608 InnerContexts); 4609 } 4610 else 4611 GetInnerBlockDeclRefExprs(*CI, 4612 InnerBlockDeclRefs, 4613 InnerContexts); 4614 4615 } 4616 // Handle specific things. 4617 if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(S)) { 4618 if (DRE->refersToEnclosingLocal()) { 4619 if (!isa<FunctionDecl>(DRE->getDecl()) && 4620 !InnerContexts.count(DRE->getDecl()->getDeclContext())) 4621 InnerBlockDeclRefs.push_back(DRE); 4622 if (VarDecl *Var = dyn_cast<VarDecl>(DRE->getDecl())) 4623 if (Var->isFunctionOrMethodVarDecl()) 4624 ImportedLocalExternalDecls.insert(Var); 4625 } 4626 } 4627 4628 return; 4629 } 4630 4631 /// convertObjCTypeToCStyleType - This routine converts such objc types 4632 /// as qualified objects, and blocks to their closest c/c++ types that 4633 /// it can. It returns true if input type was modified. 4634 bool RewriteModernObjC::convertObjCTypeToCStyleType(QualType &T) { 4635 QualType oldT = T; 4636 convertBlockPointerToFunctionPointer(T); 4637 if (T->isFunctionPointerType()) { 4638 QualType PointeeTy; 4639 if (const PointerType* PT = T->getAs<PointerType>()) { 4640 PointeeTy = PT->getPointeeType(); 4641 if (const FunctionType *FT = PointeeTy->getAs<FunctionType>()) { 4642 T = convertFunctionTypeOfBlocks(FT); 4643 T = Context->getPointerType(T); 4644 } 4645 } 4646 } 4647 4648 convertToUnqualifiedObjCType(T); 4649 return T != oldT; 4650 } 4651 4652 /// convertFunctionTypeOfBlocks - This routine converts a function type 4653 /// whose result type may be a block pointer or whose argument type(s) 4654 /// might be block pointers to an equivalent function type replacing 4655 /// all block pointers to function pointers. 4656 QualType RewriteModernObjC::convertFunctionTypeOfBlocks(const FunctionType *FT) { 4657 const FunctionProtoType *FTP = dyn_cast<FunctionProtoType>(FT); 4658 // FTP will be null for closures that don't take arguments. 4659 // Generate a funky cast. 4660 SmallVector<QualType, 8> ArgTypes; 4661 QualType Res = FT->getReturnType(); 4662 bool modified = convertObjCTypeToCStyleType(Res); 4663 4664 if (FTP) { 4665 for (auto &I : FTP->param_types()) { 4666 QualType t = I; 4667 // Make sure we convert "t (^)(...)" to "t (*)(...)". 4668 if (convertObjCTypeToCStyleType(t)) 4669 modified = true; 4670 ArgTypes.push_back(t); 4671 } 4672 } 4673 QualType FuncType; 4674 if (modified) 4675 FuncType = getSimpleFunctionType(Res, ArgTypes); 4676 else FuncType = QualType(FT, 0); 4677 return FuncType; 4678 } 4679 4680 Stmt *RewriteModernObjC::SynthesizeBlockCall(CallExpr *Exp, const Expr *BlockExp) { 4681 // Navigate to relevant type information. 4682 const BlockPointerType *CPT = nullptr; 4683 4684 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(BlockExp)) { 4685 CPT = DRE->getType()->getAs<BlockPointerType>(); 4686 } else if (const MemberExpr *MExpr = dyn_cast<MemberExpr>(BlockExp)) { 4687 CPT = MExpr->getType()->getAs<BlockPointerType>(); 4688 } 4689 else if (const ParenExpr *PRE = dyn_cast<ParenExpr>(BlockExp)) { 4690 return SynthesizeBlockCall(Exp, PRE->getSubExpr()); 4691 } 4692 else if (const ImplicitCastExpr *IEXPR = dyn_cast<ImplicitCastExpr>(BlockExp)) 4693 CPT = IEXPR->getType()->getAs<BlockPointerType>(); 4694 else if (const ConditionalOperator *CEXPR = 4695 dyn_cast<ConditionalOperator>(BlockExp)) { 4696 Expr *LHSExp = CEXPR->getLHS(); 4697 Stmt *LHSStmt = SynthesizeBlockCall(Exp, LHSExp); 4698 Expr *RHSExp = CEXPR->getRHS(); 4699 Stmt *RHSStmt = SynthesizeBlockCall(Exp, RHSExp); 4700 Expr *CONDExp = CEXPR->getCond(); 4701 ConditionalOperator *CondExpr = 4702 new (Context) ConditionalOperator(CONDExp, 4703 SourceLocation(), cast<Expr>(LHSStmt), 4704 SourceLocation(), cast<Expr>(RHSStmt), 4705 Exp->getType(), VK_RValue, OK_Ordinary); 4706 return CondExpr; 4707 } else if (const ObjCIvarRefExpr *IRE = dyn_cast<ObjCIvarRefExpr>(BlockExp)) { 4708 CPT = IRE->getType()->getAs<BlockPointerType>(); 4709 } else if (const PseudoObjectExpr *POE 4710 = dyn_cast<PseudoObjectExpr>(BlockExp)) { 4711 CPT = POE->getType()->castAs<BlockPointerType>(); 4712 } else { 4713 assert(1 && "RewriteBlockClass: Bad type"); 4714 } 4715 assert(CPT && "RewriteBlockClass: Bad type"); 4716 const FunctionType *FT = CPT->getPointeeType()->getAs<FunctionType>(); 4717 assert(FT && "RewriteBlockClass: Bad type"); 4718 const FunctionProtoType *FTP = dyn_cast<FunctionProtoType>(FT); 4719 // FTP will be null for closures that don't take arguments. 4720 4721 RecordDecl *RD = RecordDecl::Create(*Context, TTK_Struct, TUDecl, 4722 SourceLocation(), SourceLocation(), 4723 &Context->Idents.get("__block_impl")); 4724 QualType PtrBlock = Context->getPointerType(Context->getTagDeclType(RD)); 4725 4726 // Generate a funky cast. 4727 SmallVector<QualType, 8> ArgTypes; 4728 4729 // Push the block argument type. 4730 ArgTypes.push_back(PtrBlock); 4731 if (FTP) { 4732 for (auto &I : FTP->param_types()) { 4733 QualType t = I; 4734 // Make sure we convert "t (^)(...)" to "t (*)(...)". 4735 if (!convertBlockPointerToFunctionPointer(t)) 4736 convertToUnqualifiedObjCType(t); 4737 ArgTypes.push_back(t); 4738 } 4739 } 4740 // Now do the pointer to function cast. 4741 QualType PtrToFuncCastType = getSimpleFunctionType(Exp->getType(), ArgTypes); 4742 4743 PtrToFuncCastType = Context->getPointerType(PtrToFuncCastType); 4744 4745 CastExpr *BlkCast = NoTypeInfoCStyleCastExpr(Context, PtrBlock, 4746 CK_BitCast, 4747 const_cast<Expr*>(BlockExp)); 4748 // Don't forget the parens to enforce the proper binding. 4749 ParenExpr *PE = new (Context) ParenExpr(SourceLocation(), SourceLocation(), 4750 BlkCast); 4751 //PE->dump(); 4752 4753 FieldDecl *FD = FieldDecl::Create(*Context, nullptr, SourceLocation(), 4754 SourceLocation(), 4755 &Context->Idents.get("FuncPtr"), 4756 Context->VoidPtrTy, nullptr, 4757 /*BitWidth=*/nullptr, /*Mutable=*/true, 4758 ICIS_NoInit); 4759 MemberExpr *ME = new (Context) MemberExpr(PE, true, FD, SourceLocation(), 4760 FD->getType(), VK_LValue, 4761 OK_Ordinary); 4762 4763 4764 CastExpr *FunkCast = NoTypeInfoCStyleCastExpr(Context, PtrToFuncCastType, 4765 CK_BitCast, ME); 4766 PE = new (Context) ParenExpr(SourceLocation(), SourceLocation(), FunkCast); 4767 4768 SmallVector<Expr*, 8> BlkExprs; 4769 // Add the implicit argument. 4770 BlkExprs.push_back(BlkCast); 4771 // Add the user arguments. 4772 for (CallExpr::arg_iterator I = Exp->arg_begin(), 4773 E = Exp->arg_end(); I != E; ++I) { 4774 BlkExprs.push_back(*I); 4775 } 4776 CallExpr *CE = new (Context) CallExpr(*Context, PE, BlkExprs, 4777 Exp->getType(), VK_RValue, 4778 SourceLocation()); 4779 return CE; 4780 } 4781 4782 // We need to return the rewritten expression to handle cases where the 4783 // DeclRefExpr is embedded in another expression being rewritten. 4784 // For example: 4785 // 4786 // int main() { 4787 // __block Foo *f; 4788 // __block int i; 4789 // 4790 // void (^myblock)() = ^() { 4791 // [f test]; // f is a DeclRefExpr embedded in a message (which is being rewritten). 4792 // i = 77; 4793 // }; 4794 //} 4795 Stmt *RewriteModernObjC::RewriteBlockDeclRefExpr(DeclRefExpr *DeclRefExp) { 4796 // Rewrite the byref variable into BYREFVAR->__forwarding->BYREFVAR 4797 // for each DeclRefExp where BYREFVAR is name of the variable. 4798 ValueDecl *VD = DeclRefExp->getDecl(); 4799 bool isArrow = DeclRefExp->refersToEnclosingLocal(); 4800 4801 FieldDecl *FD = FieldDecl::Create(*Context, nullptr, SourceLocation(), 4802 SourceLocation(), 4803 &Context->Idents.get("__forwarding"), 4804 Context->VoidPtrTy, nullptr, 4805 /*BitWidth=*/nullptr, /*Mutable=*/true, 4806 ICIS_NoInit); 4807 MemberExpr *ME = new (Context) MemberExpr(DeclRefExp, isArrow, 4808 FD, SourceLocation(), 4809 FD->getType(), VK_LValue, 4810 OK_Ordinary); 4811 4812 StringRef Name = VD->getName(); 4813 FD = FieldDecl::Create(*Context, nullptr, SourceLocation(), SourceLocation(), 4814 &Context->Idents.get(Name), 4815 Context->VoidPtrTy, nullptr, 4816 /*BitWidth=*/nullptr, /*Mutable=*/true, 4817 ICIS_NoInit); 4818 ME = new (Context) MemberExpr(ME, true, FD, SourceLocation(), 4819 DeclRefExp->getType(), VK_LValue, OK_Ordinary); 4820 4821 4822 4823 // Need parens to enforce precedence. 4824 ParenExpr *PE = new (Context) ParenExpr(DeclRefExp->getExprLoc(), 4825 DeclRefExp->getExprLoc(), 4826 ME); 4827 ReplaceStmt(DeclRefExp, PE); 4828 return PE; 4829 } 4830 4831 // Rewrites the imported local variable V with external storage 4832 // (static, extern, etc.) as *V 4833 // 4834 Stmt *RewriteModernObjC::RewriteLocalVariableExternalStorage(DeclRefExpr *DRE) { 4835 ValueDecl *VD = DRE->getDecl(); 4836 if (VarDecl *Var = dyn_cast<VarDecl>(VD)) 4837 if (!ImportedLocalExternalDecls.count(Var)) 4838 return DRE; 4839 Expr *Exp = new (Context) UnaryOperator(DRE, UO_Deref, DRE->getType(), 4840 VK_LValue, OK_Ordinary, 4841 DRE->getLocation()); 4842 // Need parens to enforce precedence. 4843 ParenExpr *PE = new (Context) ParenExpr(SourceLocation(), SourceLocation(), 4844 Exp); 4845 ReplaceStmt(DRE, PE); 4846 return PE; 4847 } 4848 4849 void RewriteModernObjC::RewriteCastExpr(CStyleCastExpr *CE) { 4850 SourceLocation LocStart = CE->getLParenLoc(); 4851 SourceLocation LocEnd = CE->getRParenLoc(); 4852 4853 // Need to avoid trying to rewrite synthesized casts. 4854 if (LocStart.isInvalid()) 4855 return; 4856 // Need to avoid trying to rewrite casts contained in macros. 4857 if (!Rewriter::isRewritable(LocStart) || !Rewriter::isRewritable(LocEnd)) 4858 return; 4859 4860 const char *startBuf = SM->getCharacterData(LocStart); 4861 const char *endBuf = SM->getCharacterData(LocEnd); 4862 QualType QT = CE->getType(); 4863 const Type* TypePtr = QT->getAs<Type>(); 4864 if (isa<TypeOfExprType>(TypePtr)) { 4865 const TypeOfExprType *TypeOfExprTypePtr = cast<TypeOfExprType>(TypePtr); 4866 QT = TypeOfExprTypePtr->getUnderlyingExpr()->getType(); 4867 std::string TypeAsString = "("; 4868 RewriteBlockPointerType(TypeAsString, QT); 4869 TypeAsString += ")"; 4870 ReplaceText(LocStart, endBuf-startBuf+1, TypeAsString); 4871 return; 4872 } 4873 // advance the location to startArgList. 4874 const char *argPtr = startBuf; 4875 4876 while (*argPtr++ && (argPtr < endBuf)) { 4877 switch (*argPtr) { 4878 case '^': 4879 // Replace the '^' with '*'. 4880 LocStart = LocStart.getLocWithOffset(argPtr-startBuf); 4881 ReplaceText(LocStart, 1, "*"); 4882 break; 4883 } 4884 } 4885 return; 4886 } 4887 4888 void RewriteModernObjC::RewriteImplicitCastObjCExpr(CastExpr *IC) { 4889 CastKind CastKind = IC->getCastKind(); 4890 if (CastKind != CK_BlockPointerToObjCPointerCast && 4891 CastKind != CK_AnyPointerToBlockPointerCast) 4892 return; 4893 4894 QualType QT = IC->getType(); 4895 (void)convertBlockPointerToFunctionPointer(QT); 4896 std::string TypeString(QT.getAsString(Context->getPrintingPolicy())); 4897 std::string Str = "("; 4898 Str += TypeString; 4899 Str += ")"; 4900 InsertText(IC->getSubExpr()->getLocStart(), &Str[0], Str.size()); 4901 4902 return; 4903 } 4904 4905 void RewriteModernObjC::RewriteBlockPointerFunctionArgs(FunctionDecl *FD) { 4906 SourceLocation DeclLoc = FD->getLocation(); 4907 unsigned parenCount = 0; 4908 4909 // We have 1 or more arguments that have closure pointers. 4910 const char *startBuf = SM->getCharacterData(DeclLoc); 4911 const char *startArgList = strchr(startBuf, '('); 4912 4913 assert((*startArgList == '(') && "Rewriter fuzzy parser confused"); 4914 4915 parenCount++; 4916 // advance the location to startArgList. 4917 DeclLoc = DeclLoc.getLocWithOffset(startArgList-startBuf); 4918 assert((DeclLoc.isValid()) && "Invalid DeclLoc"); 4919 4920 const char *argPtr = startArgList; 4921 4922 while (*argPtr++ && parenCount) { 4923 switch (*argPtr) { 4924 case '^': 4925 // Replace the '^' with '*'. 4926 DeclLoc = DeclLoc.getLocWithOffset(argPtr-startArgList); 4927 ReplaceText(DeclLoc, 1, "*"); 4928 break; 4929 case '(': 4930 parenCount++; 4931 break; 4932 case ')': 4933 parenCount--; 4934 break; 4935 } 4936 } 4937 return; 4938 } 4939 4940 bool RewriteModernObjC::PointerTypeTakesAnyBlockArguments(QualType QT) { 4941 const FunctionProtoType *FTP; 4942 const PointerType *PT = QT->getAs<PointerType>(); 4943 if (PT) { 4944 FTP = PT->getPointeeType()->getAs<FunctionProtoType>(); 4945 } else { 4946 const BlockPointerType *BPT = QT->getAs<BlockPointerType>(); 4947 assert(BPT && "BlockPointerTypeTakeAnyBlockArguments(): not a block pointer type"); 4948 FTP = BPT->getPointeeType()->getAs<FunctionProtoType>(); 4949 } 4950 if (FTP) { 4951 for (const auto &I : FTP->param_types()) 4952 if (isTopLevelBlockPointerType(I)) 4953 return true; 4954 } 4955 return false; 4956 } 4957 4958 bool RewriteModernObjC::PointerTypeTakesAnyObjCQualifiedType(QualType QT) { 4959 const FunctionProtoType *FTP; 4960 const PointerType *PT = QT->getAs<PointerType>(); 4961 if (PT) { 4962 FTP = PT->getPointeeType()->getAs<FunctionProtoType>(); 4963 } else { 4964 const BlockPointerType *BPT = QT->getAs<BlockPointerType>(); 4965 assert(BPT && "BlockPointerTypeTakeAnyBlockArguments(): not a block pointer type"); 4966 FTP = BPT->getPointeeType()->getAs<FunctionProtoType>(); 4967 } 4968 if (FTP) { 4969 for (const auto &I : FTP->param_types()) { 4970 if (I->isObjCQualifiedIdType()) 4971 return true; 4972 if (I->isObjCObjectPointerType() && 4973 I->getPointeeType()->isObjCQualifiedInterfaceType()) 4974 return true; 4975 } 4976 4977 } 4978 return false; 4979 } 4980 4981 void RewriteModernObjC::GetExtentOfArgList(const char *Name, const char *&LParen, 4982 const char *&RParen) { 4983 const char *argPtr = strchr(Name, '('); 4984 assert((*argPtr == '(') && "Rewriter fuzzy parser confused"); 4985 4986 LParen = argPtr; // output the start. 4987 argPtr++; // skip past the left paren. 4988 unsigned parenCount = 1; 4989 4990 while (*argPtr && parenCount) { 4991 switch (*argPtr) { 4992 case '(': parenCount++; break; 4993 case ')': parenCount--; break; 4994 default: break; 4995 } 4996 if (parenCount) argPtr++; 4997 } 4998 assert((*argPtr == ')') && "Rewriter fuzzy parser confused"); 4999 RParen = argPtr; // output the end 5000 } 5001 5002 void RewriteModernObjC::RewriteBlockPointerDecl(NamedDecl *ND) { 5003 if (FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) { 5004 RewriteBlockPointerFunctionArgs(FD); 5005 return; 5006 } 5007 // Handle Variables and Typedefs. 5008 SourceLocation DeclLoc = ND->getLocation(); 5009 QualType DeclT; 5010 if (VarDecl *VD = dyn_cast<VarDecl>(ND)) 5011 DeclT = VD->getType(); 5012 else if (TypedefNameDecl *TDD = dyn_cast<TypedefNameDecl>(ND)) 5013 DeclT = TDD->getUnderlyingType(); 5014 else if (FieldDecl *FD = dyn_cast<FieldDecl>(ND)) 5015 DeclT = FD->getType(); 5016 else 5017 llvm_unreachable("RewriteBlockPointerDecl(): Decl type not yet handled"); 5018 5019 const char *startBuf = SM->getCharacterData(DeclLoc); 5020 const char *endBuf = startBuf; 5021 // scan backward (from the decl location) for the end of the previous decl. 5022 while (*startBuf != '^' && *startBuf != ';' && startBuf != MainFileStart) 5023 startBuf--; 5024 SourceLocation Start = DeclLoc.getLocWithOffset(startBuf-endBuf); 5025 std::string buf; 5026 unsigned OrigLength=0; 5027 // *startBuf != '^' if we are dealing with a pointer to function that 5028 // may take block argument types (which will be handled below). 5029 if (*startBuf == '^') { 5030 // Replace the '^' with '*', computing a negative offset. 5031 buf = '*'; 5032 startBuf++; 5033 OrigLength++; 5034 } 5035 while (*startBuf != ')') { 5036 buf += *startBuf; 5037 startBuf++; 5038 OrigLength++; 5039 } 5040 buf += ')'; 5041 OrigLength++; 5042 5043 if (PointerTypeTakesAnyBlockArguments(DeclT) || 5044 PointerTypeTakesAnyObjCQualifiedType(DeclT)) { 5045 // Replace the '^' with '*' for arguments. 5046 // Replace id<P> with id/*<>*/ 5047 DeclLoc = ND->getLocation(); 5048 startBuf = SM->getCharacterData(DeclLoc); 5049 const char *argListBegin, *argListEnd; 5050 GetExtentOfArgList(startBuf, argListBegin, argListEnd); 5051 while (argListBegin < argListEnd) { 5052 if (*argListBegin == '^') 5053 buf += '*'; 5054 else if (*argListBegin == '<') { 5055 buf += "/*"; 5056 buf += *argListBegin++; 5057 OrigLength++; 5058 while (*argListBegin != '>') { 5059 buf += *argListBegin++; 5060 OrigLength++; 5061 } 5062 buf += *argListBegin; 5063 buf += "*/"; 5064 } 5065 else 5066 buf += *argListBegin; 5067 argListBegin++; 5068 OrigLength++; 5069 } 5070 buf += ')'; 5071 OrigLength++; 5072 } 5073 ReplaceText(Start, OrigLength, buf); 5074 5075 return; 5076 } 5077 5078 5079 /// SynthesizeByrefCopyDestroyHelper - This routine synthesizes: 5080 /// void __Block_byref_id_object_copy(struct Block_byref_id_object *dst, 5081 /// struct Block_byref_id_object *src) { 5082 /// _Block_object_assign (&_dest->object, _src->object, 5083 /// BLOCK_BYREF_CALLER | BLOCK_FIELD_IS_OBJECT 5084 /// [|BLOCK_FIELD_IS_WEAK]) // object 5085 /// _Block_object_assign(&_dest->object, _src->object, 5086 /// BLOCK_BYREF_CALLER | BLOCK_FIELD_IS_BLOCK 5087 /// [|BLOCK_FIELD_IS_WEAK]) // block 5088 /// } 5089 /// And: 5090 /// void __Block_byref_id_object_dispose(struct Block_byref_id_object *_src) { 5091 /// _Block_object_dispose(_src->object, 5092 /// BLOCK_BYREF_CALLER | BLOCK_FIELD_IS_OBJECT 5093 /// [|BLOCK_FIELD_IS_WEAK]) // object 5094 /// _Block_object_dispose(_src->object, 5095 /// BLOCK_BYREF_CALLER | BLOCK_FIELD_IS_BLOCK 5096 /// [|BLOCK_FIELD_IS_WEAK]) // block 5097 /// } 5098 5099 std::string RewriteModernObjC::SynthesizeByrefCopyDestroyHelper(VarDecl *VD, 5100 int flag) { 5101 std::string S; 5102 if (CopyDestroyCache.count(flag)) 5103 return S; 5104 CopyDestroyCache.insert(flag); 5105 S = "static void __Block_byref_id_object_copy_"; 5106 S += utostr(flag); 5107 S += "(void *dst, void *src) {\n"; 5108 5109 // offset into the object pointer is computed as: 5110 // void * + void* + int + int + void* + void * 5111 unsigned IntSize = 5112 static_cast<unsigned>(Context->getTypeSize(Context->IntTy)); 5113 unsigned VoidPtrSize = 5114 static_cast<unsigned>(Context->getTypeSize(Context->VoidPtrTy)); 5115 5116 unsigned offset = (VoidPtrSize*4 + IntSize + IntSize)/Context->getCharWidth(); 5117 S += " _Block_object_assign((char*)dst + "; 5118 S += utostr(offset); 5119 S += ", *(void * *) ((char*)src + "; 5120 S += utostr(offset); 5121 S += "), "; 5122 S += utostr(flag); 5123 S += ");\n}\n"; 5124 5125 S += "static void __Block_byref_id_object_dispose_"; 5126 S += utostr(flag); 5127 S += "(void *src) {\n"; 5128 S += " _Block_object_dispose(*(void * *) ((char*)src + "; 5129 S += utostr(offset); 5130 S += "), "; 5131 S += utostr(flag); 5132 S += ");\n}\n"; 5133 return S; 5134 } 5135 5136 /// RewriteByRefVar - For each __block typex ND variable this routine transforms 5137 /// the declaration into: 5138 /// struct __Block_byref_ND { 5139 /// void *__isa; // NULL for everything except __weak pointers 5140 /// struct __Block_byref_ND *__forwarding; 5141 /// int32_t __flags; 5142 /// int32_t __size; 5143 /// void *__Block_byref_id_object_copy; // If variable is __block ObjC object 5144 /// void *__Block_byref_id_object_dispose; // If variable is __block ObjC object 5145 /// typex ND; 5146 /// }; 5147 /// 5148 /// It then replaces declaration of ND variable with: 5149 /// struct __Block_byref_ND ND = {__isa=0B, __forwarding=&ND, __flags=some_flag, 5150 /// __size=sizeof(struct __Block_byref_ND), 5151 /// ND=initializer-if-any}; 5152 /// 5153 /// 5154 void RewriteModernObjC::RewriteByRefVar(VarDecl *ND, bool firstDecl, 5155 bool lastDecl) { 5156 int flag = 0; 5157 int isa = 0; 5158 SourceLocation DeclLoc = ND->getTypeSpecStartLoc(); 5159 if (DeclLoc.isInvalid()) 5160 // If type location is missing, it is because of missing type (a warning). 5161 // Use variable's location which is good for this case. 5162 DeclLoc = ND->getLocation(); 5163 const char *startBuf = SM->getCharacterData(DeclLoc); 5164 SourceLocation X = ND->getLocEnd(); 5165 X = SM->getExpansionLoc(X); 5166 const char *endBuf = SM->getCharacterData(X); 5167 std::string Name(ND->getNameAsString()); 5168 std::string ByrefType; 5169 RewriteByRefString(ByrefType, Name, ND, true); 5170 ByrefType += " {\n"; 5171 ByrefType += " void *__isa;\n"; 5172 RewriteByRefString(ByrefType, Name, ND); 5173 ByrefType += " *__forwarding;\n"; 5174 ByrefType += " int __flags;\n"; 5175 ByrefType += " int __size;\n"; 5176 // Add void *__Block_byref_id_object_copy; 5177 // void *__Block_byref_id_object_dispose; if needed. 5178 QualType Ty = ND->getType(); 5179 bool HasCopyAndDispose = Context->BlockRequiresCopying(Ty, ND); 5180 if (HasCopyAndDispose) { 5181 ByrefType += " void (*__Block_byref_id_object_copy)(void*, void*);\n"; 5182 ByrefType += " void (*__Block_byref_id_object_dispose)(void*);\n"; 5183 } 5184 5185 QualType T = Ty; 5186 (void)convertBlockPointerToFunctionPointer(T); 5187 T.getAsStringInternal(Name, Context->getPrintingPolicy()); 5188 5189 ByrefType += " " + Name + ";\n"; 5190 ByrefType += "};\n"; 5191 // Insert this type in global scope. It is needed by helper function. 5192 SourceLocation FunLocStart; 5193 if (CurFunctionDef) 5194 FunLocStart = getFunctionSourceLocation(*this, CurFunctionDef); 5195 else { 5196 assert(CurMethodDef && "RewriteByRefVar - CurMethodDef is null"); 5197 FunLocStart = CurMethodDef->getLocStart(); 5198 } 5199 InsertText(FunLocStart, ByrefType); 5200 5201 if (Ty.isObjCGCWeak()) { 5202 flag |= BLOCK_FIELD_IS_WEAK; 5203 isa = 1; 5204 } 5205 if (HasCopyAndDispose) { 5206 flag = BLOCK_BYREF_CALLER; 5207 QualType Ty = ND->getType(); 5208 // FIXME. Handle __weak variable (BLOCK_FIELD_IS_WEAK) as well. 5209 if (Ty->isBlockPointerType()) 5210 flag |= BLOCK_FIELD_IS_BLOCK; 5211 else 5212 flag |= BLOCK_FIELD_IS_OBJECT; 5213 std::string HF = SynthesizeByrefCopyDestroyHelper(ND, flag); 5214 if (!HF.empty()) 5215 Preamble += HF; 5216 } 5217 5218 // struct __Block_byref_ND ND = 5219 // {0, &ND, some_flag, __size=sizeof(struct __Block_byref_ND), 5220 // initializer-if-any}; 5221 bool hasInit = (ND->getInit() != nullptr); 5222 // FIXME. rewriter does not support __block c++ objects which 5223 // require construction. 5224 if (hasInit) 5225 if (CXXConstructExpr *CExp = dyn_cast<CXXConstructExpr>(ND->getInit())) { 5226 CXXConstructorDecl *CXXDecl = CExp->getConstructor(); 5227 if (CXXDecl && CXXDecl->isDefaultConstructor()) 5228 hasInit = false; 5229 } 5230 5231 unsigned flags = 0; 5232 if (HasCopyAndDispose) 5233 flags |= BLOCK_HAS_COPY_DISPOSE; 5234 Name = ND->getNameAsString(); 5235 ByrefType.clear(); 5236 RewriteByRefString(ByrefType, Name, ND); 5237 std::string ForwardingCastType("("); 5238 ForwardingCastType += ByrefType + " *)"; 5239 ByrefType += " " + Name + " = {(void*)"; 5240 ByrefType += utostr(isa); 5241 ByrefType += "," + ForwardingCastType + "&" + Name + ", "; 5242 ByrefType += utostr(flags); 5243 ByrefType += ", "; 5244 ByrefType += "sizeof("; 5245 RewriteByRefString(ByrefType, Name, ND); 5246 ByrefType += ")"; 5247 if (HasCopyAndDispose) { 5248 ByrefType += ", __Block_byref_id_object_copy_"; 5249 ByrefType += utostr(flag); 5250 ByrefType += ", __Block_byref_id_object_dispose_"; 5251 ByrefType += utostr(flag); 5252 } 5253 5254 if (!firstDecl) { 5255 // In multiple __block declarations, and for all but 1st declaration, 5256 // find location of the separating comma. This would be start location 5257 // where new text is to be inserted. 5258 DeclLoc = ND->getLocation(); 5259 const char *startDeclBuf = SM->getCharacterData(DeclLoc); 5260 const char *commaBuf = startDeclBuf; 5261 while (*commaBuf != ',') 5262 commaBuf--; 5263 assert((*commaBuf == ',') && "RewriteByRefVar: can't find ','"); 5264 DeclLoc = DeclLoc.getLocWithOffset(commaBuf - startDeclBuf); 5265 startBuf = commaBuf; 5266 } 5267 5268 if (!hasInit) { 5269 ByrefType += "};\n"; 5270 unsigned nameSize = Name.size(); 5271 // for block or function pointer declaration. Name is aleady 5272 // part of the declaration. 5273 if (Ty->isBlockPointerType() || Ty->isFunctionPointerType()) 5274 nameSize = 1; 5275 ReplaceText(DeclLoc, endBuf-startBuf+nameSize, ByrefType); 5276 } 5277 else { 5278 ByrefType += ", "; 5279 SourceLocation startLoc; 5280 Expr *E = ND->getInit(); 5281 if (const CStyleCastExpr *ECE = dyn_cast<CStyleCastExpr>(E)) 5282 startLoc = ECE->getLParenLoc(); 5283 else 5284 startLoc = E->getLocStart(); 5285 startLoc = SM->getExpansionLoc(startLoc); 5286 endBuf = SM->getCharacterData(startLoc); 5287 ReplaceText(DeclLoc, endBuf-startBuf, ByrefType); 5288 5289 const char separator = lastDecl ? ';' : ','; 5290 const char *startInitializerBuf = SM->getCharacterData(startLoc); 5291 const char *separatorBuf = strchr(startInitializerBuf, separator); 5292 assert((*separatorBuf == separator) && 5293 "RewriteByRefVar: can't find ';' or ','"); 5294 SourceLocation separatorLoc = 5295 startLoc.getLocWithOffset(separatorBuf-startInitializerBuf); 5296 5297 InsertText(separatorLoc, lastDecl ? "}" : "};\n"); 5298 } 5299 return; 5300 } 5301 5302 void RewriteModernObjC::CollectBlockDeclRefInfo(BlockExpr *Exp) { 5303 // Add initializers for any closure decl refs. 5304 GetBlockDeclRefExprs(Exp->getBody()); 5305 if (BlockDeclRefs.size()) { 5306 // Unique all "by copy" declarations. 5307 for (unsigned i = 0; i < BlockDeclRefs.size(); i++) 5308 if (!BlockDeclRefs[i]->getDecl()->hasAttr<BlocksAttr>()) { 5309 if (!BlockByCopyDeclsPtrSet.count(BlockDeclRefs[i]->getDecl())) { 5310 BlockByCopyDeclsPtrSet.insert(BlockDeclRefs[i]->getDecl()); 5311 BlockByCopyDecls.push_back(BlockDeclRefs[i]->getDecl()); 5312 } 5313 } 5314 // Unique all "by ref" declarations. 5315 for (unsigned i = 0; i < BlockDeclRefs.size(); i++) 5316 if (BlockDeclRefs[i]->getDecl()->hasAttr<BlocksAttr>()) { 5317 if (!BlockByRefDeclsPtrSet.count(BlockDeclRefs[i]->getDecl())) { 5318 BlockByRefDeclsPtrSet.insert(BlockDeclRefs[i]->getDecl()); 5319 BlockByRefDecls.push_back(BlockDeclRefs[i]->getDecl()); 5320 } 5321 } 5322 // Find any imported blocks...they will need special attention. 5323 for (unsigned i = 0; i < BlockDeclRefs.size(); i++) 5324 if (BlockDeclRefs[i]->getDecl()->hasAttr<BlocksAttr>() || 5325 BlockDeclRefs[i]->getType()->isObjCObjectPointerType() || 5326 BlockDeclRefs[i]->getType()->isBlockPointerType()) 5327 ImportedBlockDecls.insert(BlockDeclRefs[i]->getDecl()); 5328 } 5329 } 5330 5331 FunctionDecl *RewriteModernObjC::SynthBlockInitFunctionDecl(StringRef name) { 5332 IdentifierInfo *ID = &Context->Idents.get(name); 5333 QualType FType = Context->getFunctionNoProtoType(Context->VoidPtrTy); 5334 return FunctionDecl::Create(*Context, TUDecl, SourceLocation(), 5335 SourceLocation(), ID, FType, nullptr, SC_Extern, 5336 false, false); 5337 } 5338 5339 Stmt *RewriteModernObjC::SynthBlockInitExpr(BlockExpr *Exp, 5340 const SmallVectorImpl<DeclRefExpr *> &InnerBlockDeclRefs) { 5341 5342 const BlockDecl *block = Exp->getBlockDecl(); 5343 5344 Blocks.push_back(Exp); 5345 5346 CollectBlockDeclRefInfo(Exp); 5347 5348 // Add inner imported variables now used in current block. 5349 int countOfInnerDecls = 0; 5350 if (!InnerBlockDeclRefs.empty()) { 5351 for (unsigned i = 0; i < InnerBlockDeclRefs.size(); i++) { 5352 DeclRefExpr *Exp = InnerBlockDeclRefs[i]; 5353 ValueDecl *VD = Exp->getDecl(); 5354 if (!VD->hasAttr<BlocksAttr>() && !BlockByCopyDeclsPtrSet.count(VD)) { 5355 // We need to save the copied-in variables in nested 5356 // blocks because it is needed at the end for some of the API generations. 5357 // See SynthesizeBlockLiterals routine. 5358 InnerDeclRefs.push_back(Exp); countOfInnerDecls++; 5359 BlockDeclRefs.push_back(Exp); 5360 BlockByCopyDeclsPtrSet.insert(VD); 5361 BlockByCopyDecls.push_back(VD); 5362 } 5363 if (VD->hasAttr<BlocksAttr>() && !BlockByRefDeclsPtrSet.count(VD)) { 5364 InnerDeclRefs.push_back(Exp); countOfInnerDecls++; 5365 BlockDeclRefs.push_back(Exp); 5366 BlockByRefDeclsPtrSet.insert(VD); 5367 BlockByRefDecls.push_back(VD); 5368 } 5369 } 5370 // Find any imported blocks...they will need special attention. 5371 for (unsigned i = 0; i < InnerBlockDeclRefs.size(); i++) 5372 if (InnerBlockDeclRefs[i]->getDecl()->hasAttr<BlocksAttr>() || 5373 InnerBlockDeclRefs[i]->getType()->isObjCObjectPointerType() || 5374 InnerBlockDeclRefs[i]->getType()->isBlockPointerType()) 5375 ImportedBlockDecls.insert(InnerBlockDeclRefs[i]->getDecl()); 5376 } 5377 InnerDeclRefsCount.push_back(countOfInnerDecls); 5378 5379 std::string FuncName; 5380 5381 if (CurFunctionDef) 5382 FuncName = CurFunctionDef->getNameAsString(); 5383 else if (CurMethodDef) 5384 BuildUniqueMethodName(FuncName, CurMethodDef); 5385 else if (GlobalVarDecl) 5386 FuncName = std::string(GlobalVarDecl->getNameAsString()); 5387 5388 bool GlobalBlockExpr = 5389 block->getDeclContext()->getRedeclContext()->isFileContext(); 5390 5391 if (GlobalBlockExpr && !GlobalVarDecl) { 5392 Diags.Report(block->getLocation(), GlobalBlockRewriteFailedDiag); 5393 GlobalBlockExpr = false; 5394 } 5395 5396 std::string BlockNumber = utostr(Blocks.size()-1); 5397 5398 std::string Func = "__" + FuncName + "_block_func_" + BlockNumber; 5399 5400 // Get a pointer to the function type so we can cast appropriately. 5401 QualType BFT = convertFunctionTypeOfBlocks(Exp->getFunctionType()); 5402 QualType FType = Context->getPointerType(BFT); 5403 5404 FunctionDecl *FD; 5405 Expr *NewRep; 5406 5407 // Simulate a constructor call... 5408 std::string Tag; 5409 5410 if (GlobalBlockExpr) 5411 Tag = "__global_"; 5412 else 5413 Tag = "__"; 5414 Tag += FuncName + "_block_impl_" + BlockNumber; 5415 5416 FD = SynthBlockInitFunctionDecl(Tag); 5417 DeclRefExpr *DRE = new (Context) DeclRefExpr(FD, false, FType, VK_RValue, 5418 SourceLocation()); 5419 5420 SmallVector<Expr*, 4> InitExprs; 5421 5422 // Initialize the block function. 5423 FD = SynthBlockInitFunctionDecl(Func); 5424 DeclRefExpr *Arg = new (Context) DeclRefExpr(FD, false, FD->getType(), 5425 VK_LValue, SourceLocation()); 5426 CastExpr *castExpr = NoTypeInfoCStyleCastExpr(Context, Context->VoidPtrTy, 5427 CK_BitCast, Arg); 5428 InitExprs.push_back(castExpr); 5429 5430 // Initialize the block descriptor. 5431 std::string DescData = "__" + FuncName + "_block_desc_" + BlockNumber + "_DATA"; 5432 5433 VarDecl *NewVD = VarDecl::Create(*Context, TUDecl, 5434 SourceLocation(), SourceLocation(), 5435 &Context->Idents.get(DescData.c_str()), 5436 Context->VoidPtrTy, nullptr, 5437 SC_Static); 5438 UnaryOperator *DescRefExpr = 5439 new (Context) UnaryOperator(new (Context) DeclRefExpr(NewVD, false, 5440 Context->VoidPtrTy, 5441 VK_LValue, 5442 SourceLocation()), 5443 UO_AddrOf, 5444 Context->getPointerType(Context->VoidPtrTy), 5445 VK_RValue, OK_Ordinary, 5446 SourceLocation()); 5447 InitExprs.push_back(DescRefExpr); 5448 5449 // Add initializers for any closure decl refs. 5450 if (BlockDeclRefs.size()) { 5451 Expr *Exp; 5452 // Output all "by copy" declarations. 5453 for (SmallVectorImpl<ValueDecl *>::iterator I = BlockByCopyDecls.begin(), 5454 E = BlockByCopyDecls.end(); I != E; ++I) { 5455 if (isObjCType((*I)->getType())) { 5456 // FIXME: Conform to ABI ([[obj retain] autorelease]). 5457 FD = SynthBlockInitFunctionDecl((*I)->getName()); 5458 Exp = new (Context) DeclRefExpr(FD, false, FD->getType(), 5459 VK_LValue, SourceLocation()); 5460 if (HasLocalVariableExternalStorage(*I)) { 5461 QualType QT = (*I)->getType(); 5462 QT = Context->getPointerType(QT); 5463 Exp = new (Context) UnaryOperator(Exp, UO_AddrOf, QT, VK_RValue, 5464 OK_Ordinary, SourceLocation()); 5465 } 5466 } else if (isTopLevelBlockPointerType((*I)->getType())) { 5467 FD = SynthBlockInitFunctionDecl((*I)->getName()); 5468 Arg = new (Context) DeclRefExpr(FD, false, FD->getType(), 5469 VK_LValue, SourceLocation()); 5470 Exp = NoTypeInfoCStyleCastExpr(Context, Context->VoidPtrTy, 5471 CK_BitCast, Arg); 5472 } else { 5473 FD = SynthBlockInitFunctionDecl((*I)->getName()); 5474 Exp = new (Context) DeclRefExpr(FD, false, FD->getType(), 5475 VK_LValue, SourceLocation()); 5476 if (HasLocalVariableExternalStorage(*I)) { 5477 QualType QT = (*I)->getType(); 5478 QT = Context->getPointerType(QT); 5479 Exp = new (Context) UnaryOperator(Exp, UO_AddrOf, QT, VK_RValue, 5480 OK_Ordinary, SourceLocation()); 5481 } 5482 5483 } 5484 InitExprs.push_back(Exp); 5485 } 5486 // Output all "by ref" declarations. 5487 for (SmallVectorImpl<ValueDecl *>::iterator I = BlockByRefDecls.begin(), 5488 E = BlockByRefDecls.end(); I != E; ++I) { 5489 ValueDecl *ND = (*I); 5490 std::string Name(ND->getNameAsString()); 5491 std::string RecName; 5492 RewriteByRefString(RecName, Name, ND, true); 5493 IdentifierInfo *II = &Context->Idents.get(RecName.c_str() 5494 + sizeof("struct")); 5495 RecordDecl *RD = RecordDecl::Create(*Context, TTK_Struct, TUDecl, 5496 SourceLocation(), SourceLocation(), 5497 II); 5498 assert(RD && "SynthBlockInitExpr(): Can't find RecordDecl"); 5499 QualType castT = Context->getPointerType(Context->getTagDeclType(RD)); 5500 5501 FD = SynthBlockInitFunctionDecl((*I)->getName()); 5502 Exp = new (Context) DeclRefExpr(FD, false, FD->getType(), VK_LValue, 5503 SourceLocation()); 5504 bool isNestedCapturedVar = false; 5505 if (block) 5506 for (const auto &CI : block->captures()) { 5507 const VarDecl *variable = CI.getVariable(); 5508 if (variable == ND && CI.isNested()) { 5509 assert (CI.isByRef() && 5510 "SynthBlockInitExpr - captured block variable is not byref"); 5511 isNestedCapturedVar = true; 5512 break; 5513 } 5514 } 5515 // captured nested byref variable has its address passed. Do not take 5516 // its address again. 5517 if (!isNestedCapturedVar) 5518 Exp = new (Context) UnaryOperator(Exp, UO_AddrOf, 5519 Context->getPointerType(Exp->getType()), 5520 VK_RValue, OK_Ordinary, SourceLocation()); 5521 Exp = NoTypeInfoCStyleCastExpr(Context, castT, CK_BitCast, Exp); 5522 InitExprs.push_back(Exp); 5523 } 5524 } 5525 if (ImportedBlockDecls.size()) { 5526 // generate BLOCK_HAS_COPY_DISPOSE(have helper funcs) | BLOCK_HAS_DESCRIPTOR 5527 int flag = (BLOCK_HAS_COPY_DISPOSE | BLOCK_HAS_DESCRIPTOR); 5528 unsigned IntSize = 5529 static_cast<unsigned>(Context->getTypeSize(Context->IntTy)); 5530 Expr *FlagExp = IntegerLiteral::Create(*Context, llvm::APInt(IntSize, flag), 5531 Context->IntTy, SourceLocation()); 5532 InitExprs.push_back(FlagExp); 5533 } 5534 NewRep = new (Context) CallExpr(*Context, DRE, InitExprs, 5535 FType, VK_LValue, SourceLocation()); 5536 5537 if (GlobalBlockExpr) { 5538 assert (!GlobalConstructionExp && 5539 "SynthBlockInitExpr - GlobalConstructionExp must be null"); 5540 GlobalConstructionExp = NewRep; 5541 NewRep = DRE; 5542 } 5543 5544 NewRep = new (Context) UnaryOperator(NewRep, UO_AddrOf, 5545 Context->getPointerType(NewRep->getType()), 5546 VK_RValue, OK_Ordinary, SourceLocation()); 5547 NewRep = NoTypeInfoCStyleCastExpr(Context, FType, CK_BitCast, 5548 NewRep); 5549 BlockDeclRefs.clear(); 5550 BlockByRefDecls.clear(); 5551 BlockByRefDeclsPtrSet.clear(); 5552 BlockByCopyDecls.clear(); 5553 BlockByCopyDeclsPtrSet.clear(); 5554 ImportedBlockDecls.clear(); 5555 return NewRep; 5556 } 5557 5558 bool RewriteModernObjC::IsDeclStmtInForeachHeader(DeclStmt *DS) { 5559 if (const ObjCForCollectionStmt * CS = 5560 dyn_cast<ObjCForCollectionStmt>(Stmts.back())) 5561 return CS->getElement() == DS; 5562 return false; 5563 } 5564 5565 //===----------------------------------------------------------------------===// 5566 // Function Body / Expression rewriting 5567 //===----------------------------------------------------------------------===// 5568 5569 Stmt *RewriteModernObjC::RewriteFunctionBodyOrGlobalInitializer(Stmt *S) { 5570 if (isa<SwitchStmt>(S) || isa<WhileStmt>(S) || 5571 isa<DoStmt>(S) || isa<ForStmt>(S)) 5572 Stmts.push_back(S); 5573 else if (isa<ObjCForCollectionStmt>(S)) { 5574 Stmts.push_back(S); 5575 ObjCBcLabelNo.push_back(++BcLabelCount); 5576 } 5577 5578 // Pseudo-object operations and ivar references need special 5579 // treatment because we're going to recursively rewrite them. 5580 if (PseudoObjectExpr *PseudoOp = dyn_cast<PseudoObjectExpr>(S)) { 5581 if (isa<BinaryOperator>(PseudoOp->getSyntacticForm())) { 5582 return RewritePropertyOrImplicitSetter(PseudoOp); 5583 } else { 5584 return RewritePropertyOrImplicitGetter(PseudoOp); 5585 } 5586 } else if (ObjCIvarRefExpr *IvarRefExpr = dyn_cast<ObjCIvarRefExpr>(S)) { 5587 return RewriteObjCIvarRefExpr(IvarRefExpr); 5588 } 5589 else if (isa<OpaqueValueExpr>(S)) 5590 S = cast<OpaqueValueExpr>(S)->getSourceExpr(); 5591 5592 SourceRange OrigStmtRange = S->getSourceRange(); 5593 5594 // Perform a bottom up rewrite of all children. 5595 for (Stmt::child_range CI = S->children(); CI; ++CI) 5596 if (*CI) { 5597 Stmt *childStmt = (*CI); 5598 Stmt *newStmt = RewriteFunctionBodyOrGlobalInitializer(childStmt); 5599 if (newStmt) { 5600 *CI = newStmt; 5601 } 5602 } 5603 5604 if (BlockExpr *BE = dyn_cast<BlockExpr>(S)) { 5605 SmallVector<DeclRefExpr *, 8> InnerBlockDeclRefs; 5606 llvm::SmallPtrSet<const DeclContext *, 8> InnerContexts; 5607 InnerContexts.insert(BE->getBlockDecl()); 5608 ImportedLocalExternalDecls.clear(); 5609 GetInnerBlockDeclRefExprs(BE->getBody(), 5610 InnerBlockDeclRefs, InnerContexts); 5611 // Rewrite the block body in place. 5612 Stmt *SaveCurrentBody = CurrentBody; 5613 CurrentBody = BE->getBody(); 5614 PropParentMap = nullptr; 5615 // block literal on rhs of a property-dot-sytax assignment 5616 // must be replaced by its synthesize ast so getRewrittenText 5617 // works as expected. In this case, what actually ends up on RHS 5618 // is the blockTranscribed which is the helper function for the 5619 // block literal; as in: self.c = ^() {[ace ARR];}; 5620 bool saveDisableReplaceStmt = DisableReplaceStmt; 5621 DisableReplaceStmt = false; 5622 RewriteFunctionBodyOrGlobalInitializer(BE->getBody()); 5623 DisableReplaceStmt = saveDisableReplaceStmt; 5624 CurrentBody = SaveCurrentBody; 5625 PropParentMap = nullptr; 5626 ImportedLocalExternalDecls.clear(); 5627 // Now we snarf the rewritten text and stash it away for later use. 5628 std::string Str = Rewrite.getRewrittenText(BE->getSourceRange()); 5629 RewrittenBlockExprs[BE] = Str; 5630 5631 Stmt *blockTranscribed = SynthBlockInitExpr(BE, InnerBlockDeclRefs); 5632 5633 //blockTranscribed->dump(); 5634 ReplaceStmt(S, blockTranscribed); 5635 return blockTranscribed; 5636 } 5637 // Handle specific things. 5638 if (ObjCEncodeExpr *AtEncode = dyn_cast<ObjCEncodeExpr>(S)) 5639 return RewriteAtEncode(AtEncode); 5640 5641 if (ObjCSelectorExpr *AtSelector = dyn_cast<ObjCSelectorExpr>(S)) 5642 return RewriteAtSelector(AtSelector); 5643 5644 if (ObjCStringLiteral *AtString = dyn_cast<ObjCStringLiteral>(S)) 5645 return RewriteObjCStringLiteral(AtString); 5646 5647 if (ObjCBoolLiteralExpr *BoolLitExpr = dyn_cast<ObjCBoolLiteralExpr>(S)) 5648 return RewriteObjCBoolLiteralExpr(BoolLitExpr); 5649 5650 if (ObjCBoxedExpr *BoxedExpr = dyn_cast<ObjCBoxedExpr>(S)) 5651 return RewriteObjCBoxedExpr(BoxedExpr); 5652 5653 if (ObjCArrayLiteral *ArrayLitExpr = dyn_cast<ObjCArrayLiteral>(S)) 5654 return RewriteObjCArrayLiteralExpr(ArrayLitExpr); 5655 5656 if (ObjCDictionaryLiteral *DictionaryLitExpr = 5657 dyn_cast<ObjCDictionaryLiteral>(S)) 5658 return RewriteObjCDictionaryLiteralExpr(DictionaryLitExpr); 5659 5660 if (ObjCMessageExpr *MessExpr = dyn_cast<ObjCMessageExpr>(S)) { 5661 #if 0 5662 // Before we rewrite it, put the original message expression in a comment. 5663 SourceLocation startLoc = MessExpr->getLocStart(); 5664 SourceLocation endLoc = MessExpr->getLocEnd(); 5665 5666 const char *startBuf = SM->getCharacterData(startLoc); 5667 const char *endBuf = SM->getCharacterData(endLoc); 5668 5669 std::string messString; 5670 messString += "// "; 5671 messString.append(startBuf, endBuf-startBuf+1); 5672 messString += "\n"; 5673 5674 // FIXME: Missing definition of 5675 // InsertText(clang::SourceLocation, char const*, unsigned int). 5676 // InsertText(startLoc, messString.c_str(), messString.size()); 5677 // Tried this, but it didn't work either... 5678 // ReplaceText(startLoc, 0, messString.c_str(), messString.size()); 5679 #endif 5680 return RewriteMessageExpr(MessExpr); 5681 } 5682 5683 if (ObjCAutoreleasePoolStmt *StmtAutoRelease = 5684 dyn_cast<ObjCAutoreleasePoolStmt>(S)) { 5685 return RewriteObjCAutoreleasePoolStmt(StmtAutoRelease); 5686 } 5687 5688 if (ObjCAtTryStmt *StmtTry = dyn_cast<ObjCAtTryStmt>(S)) 5689 return RewriteObjCTryStmt(StmtTry); 5690 5691 if (ObjCAtSynchronizedStmt *StmtTry = dyn_cast<ObjCAtSynchronizedStmt>(S)) 5692 return RewriteObjCSynchronizedStmt(StmtTry); 5693 5694 if (ObjCAtThrowStmt *StmtThrow = dyn_cast<ObjCAtThrowStmt>(S)) 5695 return RewriteObjCThrowStmt(StmtThrow); 5696 5697 if (ObjCProtocolExpr *ProtocolExp = dyn_cast<ObjCProtocolExpr>(S)) 5698 return RewriteObjCProtocolExpr(ProtocolExp); 5699 5700 if (ObjCForCollectionStmt *StmtForCollection = 5701 dyn_cast<ObjCForCollectionStmt>(S)) 5702 return RewriteObjCForCollectionStmt(StmtForCollection, 5703 OrigStmtRange.getEnd()); 5704 if (BreakStmt *StmtBreakStmt = 5705 dyn_cast<BreakStmt>(S)) 5706 return RewriteBreakStmt(StmtBreakStmt); 5707 if (ContinueStmt *StmtContinueStmt = 5708 dyn_cast<ContinueStmt>(S)) 5709 return RewriteContinueStmt(StmtContinueStmt); 5710 5711 // Need to check for protocol refs (id <P>, Foo <P> *) in variable decls 5712 // and cast exprs. 5713 if (DeclStmt *DS = dyn_cast<DeclStmt>(S)) { 5714 // FIXME: What we're doing here is modifying the type-specifier that 5715 // precedes the first Decl. In the future the DeclGroup should have 5716 // a separate type-specifier that we can rewrite. 5717 // NOTE: We need to avoid rewriting the DeclStmt if it is within 5718 // the context of an ObjCForCollectionStmt. For example: 5719 // NSArray *someArray; 5720 // for (id <FooProtocol> index in someArray) ; 5721 // This is because RewriteObjCForCollectionStmt() does textual rewriting 5722 // and it depends on the original text locations/positions. 5723 if (Stmts.empty() || !IsDeclStmtInForeachHeader(DS)) 5724 RewriteObjCQualifiedInterfaceTypes(*DS->decl_begin()); 5725 5726 // Blocks rewrite rules. 5727 for (DeclStmt::decl_iterator DI = DS->decl_begin(), DE = DS->decl_end(); 5728 DI != DE; ++DI) { 5729 Decl *SD = *DI; 5730 if (ValueDecl *ND = dyn_cast<ValueDecl>(SD)) { 5731 if (isTopLevelBlockPointerType(ND->getType())) 5732 RewriteBlockPointerDecl(ND); 5733 else if (ND->getType()->isFunctionPointerType()) 5734 CheckFunctionPointerDecl(ND->getType(), ND); 5735 if (VarDecl *VD = dyn_cast<VarDecl>(SD)) { 5736 if (VD->hasAttr<BlocksAttr>()) { 5737 static unsigned uniqueByrefDeclCount = 0; 5738 assert(!BlockByRefDeclNo.count(ND) && 5739 "RewriteFunctionBodyOrGlobalInitializer: Duplicate byref decl"); 5740 BlockByRefDeclNo[ND] = uniqueByrefDeclCount++; 5741 RewriteByRefVar(VD, (DI == DS->decl_begin()), ((DI+1) == DE)); 5742 } 5743 else 5744 RewriteTypeOfDecl(VD); 5745 } 5746 } 5747 if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(SD)) { 5748 if (isTopLevelBlockPointerType(TD->getUnderlyingType())) 5749 RewriteBlockPointerDecl(TD); 5750 else if (TD->getUnderlyingType()->isFunctionPointerType()) 5751 CheckFunctionPointerDecl(TD->getUnderlyingType(), TD); 5752 } 5753 } 5754 } 5755 5756 if (CStyleCastExpr *CE = dyn_cast<CStyleCastExpr>(S)) 5757 RewriteObjCQualifiedInterfaceTypes(CE); 5758 5759 if (isa<SwitchStmt>(S) || isa<WhileStmt>(S) || 5760 isa<DoStmt>(S) || isa<ForStmt>(S)) { 5761 assert(!Stmts.empty() && "Statement stack is empty"); 5762 assert ((isa<SwitchStmt>(Stmts.back()) || isa<WhileStmt>(Stmts.back()) || 5763 isa<DoStmt>(Stmts.back()) || isa<ForStmt>(Stmts.back())) 5764 && "Statement stack mismatch"); 5765 Stmts.pop_back(); 5766 } 5767 // Handle blocks rewriting. 5768 if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(S)) { 5769 ValueDecl *VD = DRE->getDecl(); 5770 if (VD->hasAttr<BlocksAttr>()) 5771 return RewriteBlockDeclRefExpr(DRE); 5772 if (HasLocalVariableExternalStorage(VD)) 5773 return RewriteLocalVariableExternalStorage(DRE); 5774 } 5775 5776 if (CallExpr *CE = dyn_cast<CallExpr>(S)) { 5777 if (CE->getCallee()->getType()->isBlockPointerType()) { 5778 Stmt *BlockCall = SynthesizeBlockCall(CE, CE->getCallee()); 5779 ReplaceStmt(S, BlockCall); 5780 return BlockCall; 5781 } 5782 } 5783 if (CStyleCastExpr *CE = dyn_cast<CStyleCastExpr>(S)) { 5784 RewriteCastExpr(CE); 5785 } 5786 if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(S)) { 5787 RewriteImplicitCastObjCExpr(ICE); 5788 } 5789 #if 0 5790 5791 if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(S)) { 5792 CastExpr *Replacement = new (Context) CastExpr(ICE->getType(), 5793 ICE->getSubExpr(), 5794 SourceLocation()); 5795 // Get the new text. 5796 std::string SStr; 5797 llvm::raw_string_ostream Buf(SStr); 5798 Replacement->printPretty(Buf); 5799 const std::string &Str = Buf.str(); 5800 5801 printf("CAST = %s\n", &Str[0]); 5802 InsertText(ICE->getSubExpr()->getLocStart(), &Str[0], Str.size()); 5803 delete S; 5804 return Replacement; 5805 } 5806 #endif 5807 // Return this stmt unmodified. 5808 return S; 5809 } 5810 5811 void RewriteModernObjC::RewriteRecordBody(RecordDecl *RD) { 5812 for (auto *FD : RD->fields()) { 5813 if (isTopLevelBlockPointerType(FD->getType())) 5814 RewriteBlockPointerDecl(FD); 5815 if (FD->getType()->isObjCQualifiedIdType() || 5816 FD->getType()->isObjCQualifiedInterfaceType()) 5817 RewriteObjCQualifiedInterfaceTypes(FD); 5818 } 5819 } 5820 5821 /// HandleDeclInMainFile - This is called for each top-level decl defined in the 5822 /// main file of the input. 5823 void RewriteModernObjC::HandleDeclInMainFile(Decl *D) { 5824 switch (D->getKind()) { 5825 case Decl::Function: { 5826 FunctionDecl *FD = cast<FunctionDecl>(D); 5827 if (FD->isOverloadedOperator()) 5828 return; 5829 5830 // Since function prototypes don't have ParmDecl's, we check the function 5831 // prototype. This enables us to rewrite function declarations and 5832 // definitions using the same code. 5833 RewriteBlocksInFunctionProtoType(FD->getType(), FD); 5834 5835 if (!FD->isThisDeclarationADefinition()) 5836 break; 5837 5838 // FIXME: If this should support Obj-C++, support CXXTryStmt 5839 if (CompoundStmt *Body = dyn_cast_or_null<CompoundStmt>(FD->getBody())) { 5840 CurFunctionDef = FD; 5841 CurrentBody = Body; 5842 Body = 5843 cast_or_null<CompoundStmt>(RewriteFunctionBodyOrGlobalInitializer(Body)); 5844 FD->setBody(Body); 5845 CurrentBody = nullptr; 5846 if (PropParentMap) { 5847 delete PropParentMap; 5848 PropParentMap = nullptr; 5849 } 5850 // This synthesizes and inserts the block "impl" struct, invoke function, 5851 // and any copy/dispose helper functions. 5852 InsertBlockLiteralsWithinFunction(FD); 5853 RewriteLineDirective(D); 5854 CurFunctionDef = nullptr; 5855 } 5856 break; 5857 } 5858 case Decl::ObjCMethod: { 5859 ObjCMethodDecl *MD = cast<ObjCMethodDecl>(D); 5860 if (CompoundStmt *Body = MD->getCompoundBody()) { 5861 CurMethodDef = MD; 5862 CurrentBody = Body; 5863 Body = 5864 cast_or_null<CompoundStmt>(RewriteFunctionBodyOrGlobalInitializer(Body)); 5865 MD->setBody(Body); 5866 CurrentBody = nullptr; 5867 if (PropParentMap) { 5868 delete PropParentMap; 5869 PropParentMap = nullptr; 5870 } 5871 InsertBlockLiteralsWithinMethod(MD); 5872 RewriteLineDirective(D); 5873 CurMethodDef = nullptr; 5874 } 5875 break; 5876 } 5877 case Decl::ObjCImplementation: { 5878 ObjCImplementationDecl *CI = cast<ObjCImplementationDecl>(D); 5879 ClassImplementation.push_back(CI); 5880 break; 5881 } 5882 case Decl::ObjCCategoryImpl: { 5883 ObjCCategoryImplDecl *CI = cast<ObjCCategoryImplDecl>(D); 5884 CategoryImplementation.push_back(CI); 5885 break; 5886 } 5887 case Decl::Var: { 5888 VarDecl *VD = cast<VarDecl>(D); 5889 RewriteObjCQualifiedInterfaceTypes(VD); 5890 if (isTopLevelBlockPointerType(VD->getType())) 5891 RewriteBlockPointerDecl(VD); 5892 else if (VD->getType()->isFunctionPointerType()) { 5893 CheckFunctionPointerDecl(VD->getType(), VD); 5894 if (VD->getInit()) { 5895 if (CStyleCastExpr *CE = dyn_cast<CStyleCastExpr>(VD->getInit())) { 5896 RewriteCastExpr(CE); 5897 } 5898 } 5899 } else if (VD->getType()->isRecordType()) { 5900 RecordDecl *RD = VD->getType()->getAs<RecordType>()->getDecl(); 5901 if (RD->isCompleteDefinition()) 5902 RewriteRecordBody(RD); 5903 } 5904 if (VD->getInit()) { 5905 GlobalVarDecl = VD; 5906 CurrentBody = VD->getInit(); 5907 RewriteFunctionBodyOrGlobalInitializer(VD->getInit()); 5908 CurrentBody = nullptr; 5909 if (PropParentMap) { 5910 delete PropParentMap; 5911 PropParentMap = nullptr; 5912 } 5913 SynthesizeBlockLiterals(VD->getTypeSpecStartLoc(), VD->getName()); 5914 GlobalVarDecl = nullptr; 5915 5916 // This is needed for blocks. 5917 if (CStyleCastExpr *CE = dyn_cast<CStyleCastExpr>(VD->getInit())) { 5918 RewriteCastExpr(CE); 5919 } 5920 } 5921 break; 5922 } 5923 case Decl::TypeAlias: 5924 case Decl::Typedef: { 5925 if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D)) { 5926 if (isTopLevelBlockPointerType(TD->getUnderlyingType())) 5927 RewriteBlockPointerDecl(TD); 5928 else if (TD->getUnderlyingType()->isFunctionPointerType()) 5929 CheckFunctionPointerDecl(TD->getUnderlyingType(), TD); 5930 else 5931 RewriteObjCQualifiedInterfaceTypes(TD); 5932 } 5933 break; 5934 } 5935 case Decl::CXXRecord: 5936 case Decl::Record: { 5937 RecordDecl *RD = cast<RecordDecl>(D); 5938 if (RD->isCompleteDefinition()) 5939 RewriteRecordBody(RD); 5940 break; 5941 } 5942 default: 5943 break; 5944 } 5945 // Nothing yet. 5946 } 5947 5948 /// Write_ProtocolExprReferencedMetadata - This routine writer out the 5949 /// protocol reference symbols in the for of: 5950 /// struct _protocol_t *PROTOCOL_REF = &PROTOCOL_METADATA. 5951 static void Write_ProtocolExprReferencedMetadata(ASTContext *Context, 5952 ObjCProtocolDecl *PDecl, 5953 std::string &Result) { 5954 // Also output .objc_protorefs$B section and its meta-data. 5955 if (Context->getLangOpts().MicrosoftExt) 5956 Result += "static "; 5957 Result += "struct _protocol_t *"; 5958 Result += "_OBJC_PROTOCOL_REFERENCE_$_"; 5959 Result += PDecl->getNameAsString(); 5960 Result += " = &"; 5961 Result += "_OBJC_PROTOCOL_"; Result += PDecl->getNameAsString(); 5962 Result += ";\n"; 5963 } 5964 5965 void RewriteModernObjC::HandleTranslationUnit(ASTContext &C) { 5966 if (Diags.hasErrorOccurred()) 5967 return; 5968 5969 RewriteInclude(); 5970 5971 for (unsigned i = 0, e = FunctionDefinitionsSeen.size(); i < e; i++) { 5972 // translation of function bodies were postponed until all class and 5973 // their extensions and implementations are seen. This is because, we 5974 // cannot build grouping structs for bitfields until they are all seen. 5975 FunctionDecl *FDecl = FunctionDefinitionsSeen[i]; 5976 HandleTopLevelSingleDecl(FDecl); 5977 } 5978 5979 // Here's a great place to add any extra declarations that may be needed. 5980 // Write out meta data for each @protocol(<expr>). 5981 for (llvm::SmallPtrSet<ObjCProtocolDecl *,8>::iterator I = ProtocolExprDecls.begin(), 5982 E = ProtocolExprDecls.end(); I != E; ++I) { 5983 RewriteObjCProtocolMetaData(*I, Preamble); 5984 Write_ProtocolExprReferencedMetadata(Context, (*I), Preamble); 5985 } 5986 5987 InsertText(SM->getLocForStartOfFile(MainFileID), Preamble, false); 5988 5989 if (ClassImplementation.size() || CategoryImplementation.size()) 5990 RewriteImplementations(); 5991 5992 for (unsigned i = 0, e = ObjCInterfacesSeen.size(); i < e; i++) { 5993 ObjCInterfaceDecl *CDecl = ObjCInterfacesSeen[i]; 5994 // Write struct declaration for the class matching its ivar declarations. 5995 // Note that for modern abi, this is postponed until the end of TU 5996 // because class extensions and the implementation might declare their own 5997 // private ivars. 5998 RewriteInterfaceDecl(CDecl); 5999 } 6000 6001 // Get the buffer corresponding to MainFileID. If we haven't changed it, then 6002 // we are done. 6003 if (const RewriteBuffer *RewriteBuf = 6004 Rewrite.getRewriteBufferFor(MainFileID)) { 6005 //printf("Changed:\n"); 6006 *OutFile << std::string(RewriteBuf->begin(), RewriteBuf->end()); 6007 } else { 6008 llvm::errs() << "No changes\n"; 6009 } 6010 6011 if (ClassImplementation.size() || CategoryImplementation.size() || 6012 ProtocolExprDecls.size()) { 6013 // Rewrite Objective-c meta data* 6014 std::string ResultStr; 6015 RewriteMetaDataIntoBuffer(ResultStr); 6016 // Emit metadata. 6017 *OutFile << ResultStr; 6018 } 6019 // Emit ImageInfo; 6020 { 6021 std::string ResultStr; 6022 WriteImageInfo(ResultStr); 6023 *OutFile << ResultStr; 6024 } 6025 OutFile->flush(); 6026 } 6027 6028 void RewriteModernObjC::Initialize(ASTContext &context) { 6029 InitializeCommon(context); 6030 6031 Preamble += "#ifndef __OBJC2__\n"; 6032 Preamble += "#define __OBJC2__\n"; 6033 Preamble += "#endif\n"; 6034 6035 // declaring objc_selector outside the parameter list removes a silly 6036 // scope related warning... 6037 if (IsHeader) 6038 Preamble = "#pragma once\n"; 6039 Preamble += "struct objc_selector; struct objc_class;\n"; 6040 Preamble += "struct __rw_objc_super { \n\tstruct objc_object *object; "; 6041 Preamble += "\n\tstruct objc_object *superClass; "; 6042 // Add a constructor for creating temporary objects. 6043 Preamble += "\n\t__rw_objc_super(struct objc_object *o, struct objc_object *s) "; 6044 Preamble += ": object(o), superClass(s) {} "; 6045 Preamble += "\n};\n"; 6046 6047 if (LangOpts.MicrosoftExt) { 6048 // Define all sections using syntax that makes sense. 6049 // These are currently generated. 6050 Preamble += "\n#pragma section(\".objc_classlist$B\", long, read, write)\n"; 6051 Preamble += "#pragma section(\".objc_catlist$B\", long, read, write)\n"; 6052 Preamble += "#pragma section(\".objc_imageinfo$B\", long, read, write)\n"; 6053 Preamble += "#pragma section(\".objc_nlclslist$B\", long, read, write)\n"; 6054 Preamble += "#pragma section(\".objc_nlcatlist$B\", long, read, write)\n"; 6055 // These are generated but not necessary for functionality. 6056 Preamble += "#pragma section(\".cat_cls_meth$B\", long, read, write)\n"; 6057 Preamble += "#pragma section(\".inst_meth$B\", long, read, write)\n"; 6058 Preamble += "#pragma section(\".cls_meth$B\", long, read, write)\n"; 6059 Preamble += "#pragma section(\".objc_ivar$B\", long, read, write)\n"; 6060 6061 // These need be generated for performance. Currently they are not, 6062 // using API calls instead. 6063 Preamble += "#pragma section(\".objc_selrefs$B\", long, read, write)\n"; 6064 Preamble += "#pragma section(\".objc_classrefs$B\", long, read, write)\n"; 6065 Preamble += "#pragma section(\".objc_superrefs$B\", long, read, write)\n"; 6066 6067 } 6068 Preamble += "#ifndef _REWRITER_typedef_Protocol\n"; 6069 Preamble += "typedef struct objc_object Protocol;\n"; 6070 Preamble += "#define _REWRITER_typedef_Protocol\n"; 6071 Preamble += "#endif\n"; 6072 if (LangOpts.MicrosoftExt) { 6073 Preamble += "#define __OBJC_RW_DLLIMPORT extern \"C\" __declspec(dllimport)\n"; 6074 Preamble += "#define __OBJC_RW_STATICIMPORT extern \"C\"\n"; 6075 } 6076 else 6077 Preamble += "#define __OBJC_RW_DLLIMPORT extern\n"; 6078 6079 Preamble += "__OBJC_RW_DLLIMPORT void objc_msgSend(void);\n"; 6080 Preamble += "__OBJC_RW_DLLIMPORT void objc_msgSendSuper(void);\n"; 6081 Preamble += "__OBJC_RW_DLLIMPORT void objc_msgSend_stret(void);\n"; 6082 Preamble += "__OBJC_RW_DLLIMPORT void objc_msgSendSuper_stret(void);\n"; 6083 Preamble += "__OBJC_RW_DLLIMPORT void objc_msgSend_fpret(void);\n"; 6084 6085 Preamble += "__OBJC_RW_DLLIMPORT struct objc_class *objc_getClass"; 6086 Preamble += "(const char *);\n"; 6087 Preamble += "__OBJC_RW_DLLIMPORT struct objc_class *class_getSuperclass"; 6088 Preamble += "(struct objc_class *);\n"; 6089 Preamble += "__OBJC_RW_DLLIMPORT struct objc_class *objc_getMetaClass"; 6090 Preamble += "(const char *);\n"; 6091 Preamble += "__OBJC_RW_DLLIMPORT void objc_exception_throw( struct objc_object *);\n"; 6092 // @synchronized hooks. 6093 Preamble += "__OBJC_RW_DLLIMPORT int objc_sync_enter( struct objc_object *);\n"; 6094 Preamble += "__OBJC_RW_DLLIMPORT int objc_sync_exit( struct objc_object *);\n"; 6095 Preamble += "__OBJC_RW_DLLIMPORT Protocol *objc_getProtocol(const char *);\n"; 6096 Preamble += "#ifdef _WIN64\n"; 6097 Preamble += "typedef unsigned long long _WIN_NSUInteger;\n"; 6098 Preamble += "#else\n"; 6099 Preamble += "typedef unsigned int _WIN_NSUInteger;\n"; 6100 Preamble += "#endif\n"; 6101 Preamble += "#ifndef __FASTENUMERATIONSTATE\n"; 6102 Preamble += "struct __objcFastEnumerationState {\n\t"; 6103 Preamble += "unsigned long state;\n\t"; 6104 Preamble += "void **itemsPtr;\n\t"; 6105 Preamble += "unsigned long *mutationsPtr;\n\t"; 6106 Preamble += "unsigned long extra[5];\n};\n"; 6107 Preamble += "__OBJC_RW_DLLIMPORT void objc_enumerationMutation(struct objc_object *);\n"; 6108 Preamble += "#define __FASTENUMERATIONSTATE\n"; 6109 Preamble += "#endif\n"; 6110 Preamble += "#ifndef __NSCONSTANTSTRINGIMPL\n"; 6111 Preamble += "struct __NSConstantStringImpl {\n"; 6112 Preamble += " int *isa;\n"; 6113 Preamble += " int flags;\n"; 6114 Preamble += " char *str;\n"; 6115 Preamble += "#if _WIN64\n"; 6116 Preamble += " long long length;\n"; 6117 Preamble += "#else\n"; 6118 Preamble += " long length;\n"; 6119 Preamble += "#endif\n"; 6120 Preamble += "};\n"; 6121 Preamble += "#ifdef CF_EXPORT_CONSTANT_STRING\n"; 6122 Preamble += "extern \"C\" __declspec(dllexport) int __CFConstantStringClassReference[];\n"; 6123 Preamble += "#else\n"; 6124 Preamble += "__OBJC_RW_DLLIMPORT int __CFConstantStringClassReference[];\n"; 6125 Preamble += "#endif\n"; 6126 Preamble += "#define __NSCONSTANTSTRINGIMPL\n"; 6127 Preamble += "#endif\n"; 6128 // Blocks preamble. 6129 Preamble += "#ifndef BLOCK_IMPL\n"; 6130 Preamble += "#define BLOCK_IMPL\n"; 6131 Preamble += "struct __block_impl {\n"; 6132 Preamble += " void *isa;\n"; 6133 Preamble += " int Flags;\n"; 6134 Preamble += " int Reserved;\n"; 6135 Preamble += " void *FuncPtr;\n"; 6136 Preamble += "};\n"; 6137 Preamble += "// Runtime copy/destroy helper functions (from Block_private.h)\n"; 6138 Preamble += "#ifdef __OBJC_EXPORT_BLOCKS\n"; 6139 Preamble += "extern \"C\" __declspec(dllexport) " 6140 "void _Block_object_assign(void *, const void *, const int);\n"; 6141 Preamble += "extern \"C\" __declspec(dllexport) void _Block_object_dispose(const void *, const int);\n"; 6142 Preamble += "extern \"C\" __declspec(dllexport) void *_NSConcreteGlobalBlock[32];\n"; 6143 Preamble += "extern \"C\" __declspec(dllexport) void *_NSConcreteStackBlock[32];\n"; 6144 Preamble += "#else\n"; 6145 Preamble += "__OBJC_RW_DLLIMPORT void _Block_object_assign(void *, const void *, const int);\n"; 6146 Preamble += "__OBJC_RW_DLLIMPORT void _Block_object_dispose(const void *, const int);\n"; 6147 Preamble += "__OBJC_RW_DLLIMPORT void *_NSConcreteGlobalBlock[32];\n"; 6148 Preamble += "__OBJC_RW_DLLIMPORT void *_NSConcreteStackBlock[32];\n"; 6149 Preamble += "#endif\n"; 6150 Preamble += "#endif\n"; 6151 if (LangOpts.MicrosoftExt) { 6152 Preamble += "#undef __OBJC_RW_DLLIMPORT\n"; 6153 Preamble += "#undef __OBJC_RW_STATICIMPORT\n"; 6154 Preamble += "#ifndef KEEP_ATTRIBUTES\n"; // We use this for clang tests. 6155 Preamble += "#define __attribute__(X)\n"; 6156 Preamble += "#endif\n"; 6157 Preamble += "#ifndef __weak\n"; 6158 Preamble += "#define __weak\n"; 6159 Preamble += "#endif\n"; 6160 Preamble += "#ifndef __block\n"; 6161 Preamble += "#define __block\n"; 6162 Preamble += "#endif\n"; 6163 } 6164 else { 6165 Preamble += "#define __block\n"; 6166 Preamble += "#define __weak\n"; 6167 } 6168 6169 // Declarations required for modern objective-c array and dictionary literals. 6170 Preamble += "\n#include <stdarg.h>\n"; 6171 Preamble += "struct __NSContainer_literal {\n"; 6172 Preamble += " void * *arr;\n"; 6173 Preamble += " __NSContainer_literal (unsigned int count, ...) {\n"; 6174 Preamble += "\tva_list marker;\n"; 6175 Preamble += "\tva_start(marker, count);\n"; 6176 Preamble += "\tarr = new void *[count];\n"; 6177 Preamble += "\tfor (unsigned i = 0; i < count; i++)\n"; 6178 Preamble += "\t arr[i] = va_arg(marker, void *);\n"; 6179 Preamble += "\tva_end( marker );\n"; 6180 Preamble += " };\n"; 6181 Preamble += " ~__NSContainer_literal() {\n"; 6182 Preamble += "\tdelete[] arr;\n"; 6183 Preamble += " }\n"; 6184 Preamble += "};\n"; 6185 6186 // Declaration required for implementation of @autoreleasepool statement. 6187 Preamble += "extern \"C\" __declspec(dllimport) void * objc_autoreleasePoolPush(void);\n"; 6188 Preamble += "extern \"C\" __declspec(dllimport) void objc_autoreleasePoolPop(void *);\n\n"; 6189 Preamble += "struct __AtAutoreleasePool {\n"; 6190 Preamble += " __AtAutoreleasePool() {atautoreleasepoolobj = objc_autoreleasePoolPush();}\n"; 6191 Preamble += " ~__AtAutoreleasePool() {objc_autoreleasePoolPop(atautoreleasepoolobj);}\n"; 6192 Preamble += " void * atautoreleasepoolobj;\n"; 6193 Preamble += "};\n"; 6194 6195 // NOTE! Windows uses LLP64 for 64bit mode. So, cast pointer to long long 6196 // as this avoids warning in any 64bit/32bit compilation model. 6197 Preamble += "\n#define __OFFSETOFIVAR__(TYPE, MEMBER) ((long long) &((TYPE *)0)->MEMBER)\n"; 6198 } 6199 6200 /// RewriteIvarOffsetComputation - This rutine synthesizes computation of 6201 /// ivar offset. 6202 void RewriteModernObjC::RewriteIvarOffsetComputation(ObjCIvarDecl *ivar, 6203 std::string &Result) { 6204 Result += "__OFFSETOFIVAR__(struct "; 6205 Result += ivar->getContainingInterface()->getNameAsString(); 6206 if (LangOpts.MicrosoftExt) 6207 Result += "_IMPL"; 6208 Result += ", "; 6209 if (ivar->isBitField()) 6210 ObjCIvarBitfieldGroupDecl(ivar, Result); 6211 else 6212 Result += ivar->getNameAsString(); 6213 Result += ")"; 6214 } 6215 6216 /// WriteModernMetadataDeclarations - Writes out metadata declarations for modern ABI. 6217 /// struct _prop_t { 6218 /// const char *name; 6219 /// char *attributes; 6220 /// } 6221 6222 /// struct _prop_list_t { 6223 /// uint32_t entsize; // sizeof(struct _prop_t) 6224 /// uint32_t count_of_properties; 6225 /// struct _prop_t prop_list[count_of_properties]; 6226 /// } 6227 6228 /// struct _protocol_t; 6229 6230 /// struct _protocol_list_t { 6231 /// long protocol_count; // Note, this is 32/64 bit 6232 /// struct _protocol_t * protocol_list[protocol_count]; 6233 /// } 6234 6235 /// struct _objc_method { 6236 /// SEL _cmd; 6237 /// const char *method_type; 6238 /// char *_imp; 6239 /// } 6240 6241 /// struct _method_list_t { 6242 /// uint32_t entsize; // sizeof(struct _objc_method) 6243 /// uint32_t method_count; 6244 /// struct _objc_method method_list[method_count]; 6245 /// } 6246 6247 /// struct _protocol_t { 6248 /// id isa; // NULL 6249 /// const char *protocol_name; 6250 /// const struct _protocol_list_t * protocol_list; // super protocols 6251 /// const struct method_list_t *instance_methods; 6252 /// const struct method_list_t *class_methods; 6253 /// const struct method_list_t *optionalInstanceMethods; 6254 /// const struct method_list_t *optionalClassMethods; 6255 /// const struct _prop_list_t * properties; 6256 /// const uint32_t size; // sizeof(struct _protocol_t) 6257 /// const uint32_t flags; // = 0 6258 /// const char ** extendedMethodTypes; 6259 /// } 6260 6261 /// struct _ivar_t { 6262 /// unsigned long int *offset; // pointer to ivar offset location 6263 /// const char *name; 6264 /// const char *type; 6265 /// uint32_t alignment; 6266 /// uint32_t size; 6267 /// } 6268 6269 /// struct _ivar_list_t { 6270 /// uint32 entsize; // sizeof(struct _ivar_t) 6271 /// uint32 count; 6272 /// struct _ivar_t list[count]; 6273 /// } 6274 6275 /// struct _class_ro_t { 6276 /// uint32_t flags; 6277 /// uint32_t instanceStart; 6278 /// uint32_t instanceSize; 6279 /// uint32_t reserved; // only when building for 64bit targets 6280 /// const uint8_t *ivarLayout; 6281 /// const char *name; 6282 /// const struct _method_list_t *baseMethods; 6283 /// const struct _protocol_list_t *baseProtocols; 6284 /// const struct _ivar_list_t *ivars; 6285 /// const uint8_t *weakIvarLayout; 6286 /// const struct _prop_list_t *properties; 6287 /// } 6288 6289 /// struct _class_t { 6290 /// struct _class_t *isa; 6291 /// struct _class_t *superclass; 6292 /// void *cache; 6293 /// IMP *vtable; 6294 /// struct _class_ro_t *ro; 6295 /// } 6296 6297 /// struct _category_t { 6298 /// const char *name; 6299 /// struct _class_t *cls; 6300 /// const struct _method_list_t *instance_methods; 6301 /// const struct _method_list_t *class_methods; 6302 /// const struct _protocol_list_t *protocols; 6303 /// const struct _prop_list_t *properties; 6304 /// } 6305 6306 /// MessageRefTy - LLVM for: 6307 /// struct _message_ref_t { 6308 /// IMP messenger; 6309 /// SEL name; 6310 /// }; 6311 6312 /// SuperMessageRefTy - LLVM for: 6313 /// struct _super_message_ref_t { 6314 /// SUPER_IMP messenger; 6315 /// SEL name; 6316 /// }; 6317 6318 static void WriteModernMetadataDeclarations(ASTContext *Context, std::string &Result) { 6319 static bool meta_data_declared = false; 6320 if (meta_data_declared) 6321 return; 6322 6323 Result += "\nstruct _prop_t {\n"; 6324 Result += "\tconst char *name;\n"; 6325 Result += "\tconst char *attributes;\n"; 6326 Result += "};\n"; 6327 6328 Result += "\nstruct _protocol_t;\n"; 6329 6330 Result += "\nstruct _objc_method {\n"; 6331 Result += "\tstruct objc_selector * _cmd;\n"; 6332 Result += "\tconst char *method_type;\n"; 6333 Result += "\tvoid *_imp;\n"; 6334 Result += "};\n"; 6335 6336 Result += "\nstruct _protocol_t {\n"; 6337 Result += "\tvoid * isa; // NULL\n"; 6338 Result += "\tconst char *protocol_name;\n"; 6339 Result += "\tconst struct _protocol_list_t * protocol_list; // super protocols\n"; 6340 Result += "\tconst struct method_list_t *instance_methods;\n"; 6341 Result += "\tconst struct method_list_t *class_methods;\n"; 6342 Result += "\tconst struct method_list_t *optionalInstanceMethods;\n"; 6343 Result += "\tconst struct method_list_t *optionalClassMethods;\n"; 6344 Result += "\tconst struct _prop_list_t * properties;\n"; 6345 Result += "\tconst unsigned int size; // sizeof(struct _protocol_t)\n"; 6346 Result += "\tconst unsigned int flags; // = 0\n"; 6347 Result += "\tconst char ** extendedMethodTypes;\n"; 6348 Result += "};\n"; 6349 6350 Result += "\nstruct _ivar_t {\n"; 6351 Result += "\tunsigned long int *offset; // pointer to ivar offset location\n"; 6352 Result += "\tconst char *name;\n"; 6353 Result += "\tconst char *type;\n"; 6354 Result += "\tunsigned int alignment;\n"; 6355 Result += "\tunsigned int size;\n"; 6356 Result += "};\n"; 6357 6358 Result += "\nstruct _class_ro_t {\n"; 6359 Result += "\tunsigned int flags;\n"; 6360 Result += "\tunsigned int instanceStart;\n"; 6361 Result += "\tunsigned int instanceSize;\n"; 6362 const llvm::Triple &Triple(Context->getTargetInfo().getTriple()); 6363 if (Triple.getArch() == llvm::Triple::x86_64) 6364 Result += "\tunsigned int reserved;\n"; 6365 Result += "\tconst unsigned char *ivarLayout;\n"; 6366 Result += "\tconst char *name;\n"; 6367 Result += "\tconst struct _method_list_t *baseMethods;\n"; 6368 Result += "\tconst struct _objc_protocol_list *baseProtocols;\n"; 6369 Result += "\tconst struct _ivar_list_t *ivars;\n"; 6370 Result += "\tconst unsigned char *weakIvarLayout;\n"; 6371 Result += "\tconst struct _prop_list_t *properties;\n"; 6372 Result += "};\n"; 6373 6374 Result += "\nstruct _class_t {\n"; 6375 Result += "\tstruct _class_t *isa;\n"; 6376 Result += "\tstruct _class_t *superclass;\n"; 6377 Result += "\tvoid *cache;\n"; 6378 Result += "\tvoid *vtable;\n"; 6379 Result += "\tstruct _class_ro_t *ro;\n"; 6380 Result += "};\n"; 6381 6382 Result += "\nstruct _category_t {\n"; 6383 Result += "\tconst char *name;\n"; 6384 Result += "\tstruct _class_t *cls;\n"; 6385 Result += "\tconst struct _method_list_t *instance_methods;\n"; 6386 Result += "\tconst struct _method_list_t *class_methods;\n"; 6387 Result += "\tconst struct _protocol_list_t *protocols;\n"; 6388 Result += "\tconst struct _prop_list_t *properties;\n"; 6389 Result += "};\n"; 6390 6391 Result += "extern \"C\" __declspec(dllimport) struct objc_cache _objc_empty_cache;\n"; 6392 Result += "#pragma warning(disable:4273)\n"; 6393 meta_data_declared = true; 6394 } 6395 6396 static void Write_protocol_list_t_TypeDecl(std::string &Result, 6397 long super_protocol_count) { 6398 Result += "struct /*_protocol_list_t*/"; Result += " {\n"; 6399 Result += "\tlong protocol_count; // Note, this is 32/64 bit\n"; 6400 Result += "\tstruct _protocol_t *super_protocols["; 6401 Result += utostr(super_protocol_count); Result += "];\n"; 6402 Result += "}"; 6403 } 6404 6405 static void Write_method_list_t_TypeDecl(std::string &Result, 6406 unsigned int method_count) { 6407 Result += "struct /*_method_list_t*/"; Result += " {\n"; 6408 Result += "\tunsigned int entsize; // sizeof(struct _objc_method)\n"; 6409 Result += "\tunsigned int method_count;\n"; 6410 Result += "\tstruct _objc_method method_list["; 6411 Result += utostr(method_count); Result += "];\n"; 6412 Result += "}"; 6413 } 6414 6415 static void Write__prop_list_t_TypeDecl(std::string &Result, 6416 unsigned int property_count) { 6417 Result += "struct /*_prop_list_t*/"; Result += " {\n"; 6418 Result += "\tunsigned int entsize; // sizeof(struct _prop_t)\n"; 6419 Result += "\tunsigned int count_of_properties;\n"; 6420 Result += "\tstruct _prop_t prop_list["; 6421 Result += utostr(property_count); Result += "];\n"; 6422 Result += "}"; 6423 } 6424 6425 static void Write__ivar_list_t_TypeDecl(std::string &Result, 6426 unsigned int ivar_count) { 6427 Result += "struct /*_ivar_list_t*/"; Result += " {\n"; 6428 Result += "\tunsigned int entsize; // sizeof(struct _prop_t)\n"; 6429 Result += "\tunsigned int count;\n"; 6430 Result += "\tstruct _ivar_t ivar_list["; 6431 Result += utostr(ivar_count); Result += "];\n"; 6432 Result += "}"; 6433 } 6434 6435 static void Write_protocol_list_initializer(ASTContext *Context, std::string &Result, 6436 ArrayRef<ObjCProtocolDecl *> SuperProtocols, 6437 StringRef VarName, 6438 StringRef ProtocolName) { 6439 if (SuperProtocols.size() > 0) { 6440 Result += "\nstatic "; 6441 Write_protocol_list_t_TypeDecl(Result, SuperProtocols.size()); 6442 Result += " "; Result += VarName; 6443 Result += ProtocolName; 6444 Result += " __attribute__ ((used, section (\"__DATA,__objc_const\"))) = {\n"; 6445 Result += "\t"; Result += utostr(SuperProtocols.size()); Result += ",\n"; 6446 for (unsigned i = 0, e = SuperProtocols.size(); i < e; i++) { 6447 ObjCProtocolDecl *SuperPD = SuperProtocols[i]; 6448 Result += "\t&"; Result += "_OBJC_PROTOCOL_"; 6449 Result += SuperPD->getNameAsString(); 6450 if (i == e-1) 6451 Result += "\n};\n"; 6452 else 6453 Result += ",\n"; 6454 } 6455 } 6456 } 6457 6458 static void Write_method_list_t_initializer(RewriteModernObjC &RewriteObj, 6459 ASTContext *Context, std::string &Result, 6460 ArrayRef<ObjCMethodDecl *> Methods, 6461 StringRef VarName, 6462 StringRef TopLevelDeclName, 6463 bool MethodImpl) { 6464 if (Methods.size() > 0) { 6465 Result += "\nstatic "; 6466 Write_method_list_t_TypeDecl(Result, Methods.size()); 6467 Result += " "; Result += VarName; 6468 Result += TopLevelDeclName; 6469 Result += " __attribute__ ((used, section (\"__DATA,__objc_const\"))) = {\n"; 6470 Result += "\t"; Result += "sizeof(_objc_method)"; Result += ",\n"; 6471 Result += "\t"; Result += utostr(Methods.size()); Result += ",\n"; 6472 for (unsigned i = 0, e = Methods.size(); i < e; i++) { 6473 ObjCMethodDecl *MD = Methods[i]; 6474 if (i == 0) 6475 Result += "\t{{(struct objc_selector *)\""; 6476 else 6477 Result += "\t{(struct objc_selector *)\""; 6478 Result += (MD)->getSelector().getAsString(); Result += "\""; 6479 Result += ", "; 6480 std::string MethodTypeString; 6481 Context->getObjCEncodingForMethodDecl(MD, MethodTypeString); 6482 Result += "\""; Result += MethodTypeString; Result += "\""; 6483 Result += ", "; 6484 if (!MethodImpl) 6485 Result += "0"; 6486 else { 6487 Result += "(void *)"; 6488 Result += RewriteObj.MethodInternalNames[MD]; 6489 } 6490 if (i == e-1) 6491 Result += "}}\n"; 6492 else 6493 Result += "},\n"; 6494 } 6495 Result += "};\n"; 6496 } 6497 } 6498 6499 static void Write_prop_list_t_initializer(RewriteModernObjC &RewriteObj, 6500 ASTContext *Context, std::string &Result, 6501 ArrayRef<ObjCPropertyDecl *> Properties, 6502 const Decl *Container, 6503 StringRef VarName, 6504 StringRef ProtocolName) { 6505 if (Properties.size() > 0) { 6506 Result += "\nstatic "; 6507 Write__prop_list_t_TypeDecl(Result, Properties.size()); 6508 Result += " "; Result += VarName; 6509 Result += ProtocolName; 6510 Result += " __attribute__ ((used, section (\"__DATA,__objc_const\"))) = {\n"; 6511 Result += "\t"; Result += "sizeof(_prop_t)"; Result += ",\n"; 6512 Result += "\t"; Result += utostr(Properties.size()); Result += ",\n"; 6513 for (unsigned i = 0, e = Properties.size(); i < e; i++) { 6514 ObjCPropertyDecl *PropDecl = Properties[i]; 6515 if (i == 0) 6516 Result += "\t{{\""; 6517 else 6518 Result += "\t{\""; 6519 Result += PropDecl->getName(); Result += "\","; 6520 std::string PropertyTypeString, QuotePropertyTypeString; 6521 Context->getObjCEncodingForPropertyDecl(PropDecl, Container, PropertyTypeString); 6522 RewriteObj.QuoteDoublequotes(PropertyTypeString, QuotePropertyTypeString); 6523 Result += "\""; Result += QuotePropertyTypeString; Result += "\""; 6524 if (i == e-1) 6525 Result += "}}\n"; 6526 else 6527 Result += "},\n"; 6528 } 6529 Result += "};\n"; 6530 } 6531 } 6532 6533 // Metadata flags 6534 enum MetaDataDlags { 6535 CLS = 0x0, 6536 CLS_META = 0x1, 6537 CLS_ROOT = 0x2, 6538 OBJC2_CLS_HIDDEN = 0x10, 6539 CLS_EXCEPTION = 0x20, 6540 6541 /// (Obsolete) ARC-specific: this class has a .release_ivars method 6542 CLS_HAS_IVAR_RELEASER = 0x40, 6543 /// class was compiled with -fobjc-arr 6544 CLS_COMPILED_BY_ARC = 0x80 // (1<<7) 6545 }; 6546 6547 static void Write__class_ro_t_initializer(ASTContext *Context, std::string &Result, 6548 unsigned int flags, 6549 const std::string &InstanceStart, 6550 const std::string &InstanceSize, 6551 ArrayRef<ObjCMethodDecl *>baseMethods, 6552 ArrayRef<ObjCProtocolDecl *>baseProtocols, 6553 ArrayRef<ObjCIvarDecl *>ivars, 6554 ArrayRef<ObjCPropertyDecl *>Properties, 6555 StringRef VarName, 6556 StringRef ClassName) { 6557 Result += "\nstatic struct _class_ro_t "; 6558 Result += VarName; Result += ClassName; 6559 Result += " __attribute__ ((used, section (\"__DATA,__objc_const\"))) = {\n"; 6560 Result += "\t"; 6561 Result += llvm::utostr(flags); Result += ", "; 6562 Result += InstanceStart; Result += ", "; 6563 Result += InstanceSize; Result += ", \n"; 6564 Result += "\t"; 6565 const llvm::Triple &Triple(Context->getTargetInfo().getTriple()); 6566 if (Triple.getArch() == llvm::Triple::x86_64) 6567 // uint32_t const reserved; // only when building for 64bit targets 6568 Result += "(unsigned int)0, \n\t"; 6569 // const uint8_t * const ivarLayout; 6570 Result += "0, \n\t"; 6571 Result += "\""; Result += ClassName; Result += "\",\n\t"; 6572 bool metaclass = ((flags & CLS_META) != 0); 6573 if (baseMethods.size() > 0) { 6574 Result += "(const struct _method_list_t *)&"; 6575 if (metaclass) 6576 Result += "_OBJC_$_CLASS_METHODS_"; 6577 else 6578 Result += "_OBJC_$_INSTANCE_METHODS_"; 6579 Result += ClassName; 6580 Result += ",\n\t"; 6581 } 6582 else 6583 Result += "0, \n\t"; 6584 6585 if (!metaclass && baseProtocols.size() > 0) { 6586 Result += "(const struct _objc_protocol_list *)&"; 6587 Result += "_OBJC_CLASS_PROTOCOLS_$_"; Result += ClassName; 6588 Result += ",\n\t"; 6589 } 6590 else 6591 Result += "0, \n\t"; 6592 6593 if (!metaclass && ivars.size() > 0) { 6594 Result += "(const struct _ivar_list_t *)&"; 6595 Result += "_OBJC_$_INSTANCE_VARIABLES_"; Result += ClassName; 6596 Result += ",\n\t"; 6597 } 6598 else 6599 Result += "0, \n\t"; 6600 6601 // weakIvarLayout 6602 Result += "0, \n\t"; 6603 if (!metaclass && Properties.size() > 0) { 6604 Result += "(const struct _prop_list_t *)&"; 6605 Result += "_OBJC_$_PROP_LIST_"; Result += ClassName; 6606 Result += ",\n"; 6607 } 6608 else 6609 Result += "0, \n"; 6610 6611 Result += "};\n"; 6612 } 6613 6614 static void Write_class_t(ASTContext *Context, std::string &Result, 6615 StringRef VarName, 6616 const ObjCInterfaceDecl *CDecl, bool metaclass) { 6617 bool rootClass = (!CDecl->getSuperClass()); 6618 const ObjCInterfaceDecl *RootClass = CDecl; 6619 6620 if (!rootClass) { 6621 // Find the Root class 6622 RootClass = CDecl->getSuperClass(); 6623 while (RootClass->getSuperClass()) { 6624 RootClass = RootClass->getSuperClass(); 6625 } 6626 } 6627 6628 if (metaclass && rootClass) { 6629 // Need to handle a case of use of forward declaration. 6630 Result += "\n"; 6631 Result += "extern \"C\" "; 6632 if (CDecl->getImplementation()) 6633 Result += "__declspec(dllexport) "; 6634 else 6635 Result += "__declspec(dllimport) "; 6636 6637 Result += "struct _class_t OBJC_CLASS_$_"; 6638 Result += CDecl->getNameAsString(); 6639 Result += ";\n"; 6640 } 6641 // Also, for possibility of 'super' metadata class not having been defined yet. 6642 if (!rootClass) { 6643 ObjCInterfaceDecl *SuperClass = CDecl->getSuperClass(); 6644 Result += "\n"; 6645 Result += "extern \"C\" "; 6646 if (SuperClass->getImplementation()) 6647 Result += "__declspec(dllexport) "; 6648 else 6649 Result += "__declspec(dllimport) "; 6650 6651 Result += "struct _class_t "; 6652 Result += VarName; 6653 Result += SuperClass->getNameAsString(); 6654 Result += ";\n"; 6655 6656 if (metaclass && RootClass != SuperClass) { 6657 Result += "extern \"C\" "; 6658 if (RootClass->getImplementation()) 6659 Result += "__declspec(dllexport) "; 6660 else 6661 Result += "__declspec(dllimport) "; 6662 6663 Result += "struct _class_t "; 6664 Result += VarName; 6665 Result += RootClass->getNameAsString(); 6666 Result += ";\n"; 6667 } 6668 } 6669 6670 Result += "\nextern \"C\" __declspec(dllexport) struct _class_t "; 6671 Result += VarName; Result += CDecl->getNameAsString(); 6672 Result += " __attribute__ ((used, section (\"__DATA,__objc_data\"))) = {\n"; 6673 Result += "\t"; 6674 if (metaclass) { 6675 if (!rootClass) { 6676 Result += "0, // &"; Result += VarName; 6677 Result += RootClass->getNameAsString(); 6678 Result += ",\n\t"; 6679 Result += "0, // &"; Result += VarName; 6680 Result += CDecl->getSuperClass()->getNameAsString(); 6681 Result += ",\n\t"; 6682 } 6683 else { 6684 Result += "0, // &"; Result += VarName; 6685 Result += CDecl->getNameAsString(); 6686 Result += ",\n\t"; 6687 Result += "0, // &OBJC_CLASS_$_"; Result += CDecl->getNameAsString(); 6688 Result += ",\n\t"; 6689 } 6690 } 6691 else { 6692 Result += "0, // &OBJC_METACLASS_$_"; 6693 Result += CDecl->getNameAsString(); 6694 Result += ",\n\t"; 6695 if (!rootClass) { 6696 Result += "0, // &"; Result += VarName; 6697 Result += CDecl->getSuperClass()->getNameAsString(); 6698 Result += ",\n\t"; 6699 } 6700 else 6701 Result += "0,\n\t"; 6702 } 6703 Result += "0, // (void *)&_objc_empty_cache,\n\t"; 6704 Result += "0, // unused, was (void *)&_objc_empty_vtable,\n\t"; 6705 if (metaclass) 6706 Result += "&_OBJC_METACLASS_RO_$_"; 6707 else 6708 Result += "&_OBJC_CLASS_RO_$_"; 6709 Result += CDecl->getNameAsString(); 6710 Result += ",\n};\n"; 6711 6712 // Add static function to initialize some of the meta-data fields. 6713 // avoid doing it twice. 6714 if (metaclass) 6715 return; 6716 6717 const ObjCInterfaceDecl *SuperClass = 6718 rootClass ? CDecl : CDecl->getSuperClass(); 6719 6720 Result += "static void OBJC_CLASS_SETUP_$_"; 6721 Result += CDecl->getNameAsString(); 6722 Result += "(void ) {\n"; 6723 Result += "\tOBJC_METACLASS_$_"; Result += CDecl->getNameAsString(); 6724 Result += ".isa = "; Result += "&OBJC_METACLASS_$_"; 6725 Result += RootClass->getNameAsString(); Result += ";\n"; 6726 6727 Result += "\tOBJC_METACLASS_$_"; Result += CDecl->getNameAsString(); 6728 Result += ".superclass = "; 6729 if (rootClass) 6730 Result += "&OBJC_CLASS_$_"; 6731 else 6732 Result += "&OBJC_METACLASS_$_"; 6733 6734 Result += SuperClass->getNameAsString(); Result += ";\n"; 6735 6736 Result += "\tOBJC_METACLASS_$_"; Result += CDecl->getNameAsString(); 6737 Result += ".cache = "; Result += "&_objc_empty_cache"; Result += ";\n"; 6738 6739 Result += "\tOBJC_CLASS_$_"; Result += CDecl->getNameAsString(); 6740 Result += ".isa = "; Result += "&OBJC_METACLASS_$_"; 6741 Result += CDecl->getNameAsString(); Result += ";\n"; 6742 6743 if (!rootClass) { 6744 Result += "\tOBJC_CLASS_$_"; Result += CDecl->getNameAsString(); 6745 Result += ".superclass = "; Result += "&OBJC_CLASS_$_"; 6746 Result += SuperClass->getNameAsString(); Result += ";\n"; 6747 } 6748 6749 Result += "\tOBJC_CLASS_$_"; Result += CDecl->getNameAsString(); 6750 Result += ".cache = "; Result += "&_objc_empty_cache"; Result += ";\n"; 6751 Result += "}\n"; 6752 } 6753 6754 static void Write_category_t(RewriteModernObjC &RewriteObj, ASTContext *Context, 6755 std::string &Result, 6756 ObjCCategoryDecl *CatDecl, 6757 ObjCInterfaceDecl *ClassDecl, 6758 ArrayRef<ObjCMethodDecl *> InstanceMethods, 6759 ArrayRef<ObjCMethodDecl *> ClassMethods, 6760 ArrayRef<ObjCProtocolDecl *> RefedProtocols, 6761 ArrayRef<ObjCPropertyDecl *> ClassProperties) { 6762 StringRef CatName = CatDecl->getName(); 6763 StringRef ClassName = ClassDecl->getName(); 6764 // must declare an extern class object in case this class is not implemented 6765 // in this TU. 6766 Result += "\n"; 6767 Result += "extern \"C\" "; 6768 if (ClassDecl->getImplementation()) 6769 Result += "__declspec(dllexport) "; 6770 else 6771 Result += "__declspec(dllimport) "; 6772 6773 Result += "struct _class_t "; 6774 Result += "OBJC_CLASS_$_"; Result += ClassName; 6775 Result += ";\n"; 6776 6777 Result += "\nstatic struct _category_t "; 6778 Result += "_OBJC_$_CATEGORY_"; 6779 Result += ClassName; Result += "_$_"; Result += CatName; 6780 Result += " __attribute__ ((used, section (\"__DATA,__objc_const\"))) = \n"; 6781 Result += "{\n"; 6782 Result += "\t\""; Result += ClassName; Result += "\",\n"; 6783 Result += "\t0, // &"; Result += "OBJC_CLASS_$_"; Result += ClassName; 6784 Result += ",\n"; 6785 if (InstanceMethods.size() > 0) { 6786 Result += "\t(const struct _method_list_t *)&"; 6787 Result += "_OBJC_$_CATEGORY_INSTANCE_METHODS_"; 6788 Result += ClassName; Result += "_$_"; Result += CatName; 6789 Result += ",\n"; 6790 } 6791 else 6792 Result += "\t0,\n"; 6793 6794 if (ClassMethods.size() > 0) { 6795 Result += "\t(const struct _method_list_t *)&"; 6796 Result += "_OBJC_$_CATEGORY_CLASS_METHODS_"; 6797 Result += ClassName; Result += "_$_"; Result += CatName; 6798 Result += ",\n"; 6799 } 6800 else 6801 Result += "\t0,\n"; 6802 6803 if (RefedProtocols.size() > 0) { 6804 Result += "\t(const struct _protocol_list_t *)&"; 6805 Result += "_OBJC_CATEGORY_PROTOCOLS_$_"; 6806 Result += ClassName; Result += "_$_"; Result += CatName; 6807 Result += ",\n"; 6808 } 6809 else 6810 Result += "\t0,\n"; 6811 6812 if (ClassProperties.size() > 0) { 6813 Result += "\t(const struct _prop_list_t *)&"; Result += "_OBJC_$_PROP_LIST_"; 6814 Result += ClassName; Result += "_$_"; Result += CatName; 6815 Result += ",\n"; 6816 } 6817 else 6818 Result += "\t0,\n"; 6819 6820 Result += "};\n"; 6821 6822 // Add static function to initialize the class pointer in the category structure. 6823 Result += "static void OBJC_CATEGORY_SETUP_$_"; 6824 Result += ClassDecl->getNameAsString(); 6825 Result += "_$_"; 6826 Result += CatName; 6827 Result += "(void ) {\n"; 6828 Result += "\t_OBJC_$_CATEGORY_"; 6829 Result += ClassDecl->getNameAsString(); 6830 Result += "_$_"; 6831 Result += CatName; 6832 Result += ".cls = "; Result += "&OBJC_CLASS_$_"; Result += ClassName; 6833 Result += ";\n}\n"; 6834 } 6835 6836 static void Write__extendedMethodTypes_initializer(RewriteModernObjC &RewriteObj, 6837 ASTContext *Context, std::string &Result, 6838 ArrayRef<ObjCMethodDecl *> Methods, 6839 StringRef VarName, 6840 StringRef ProtocolName) { 6841 if (Methods.size() == 0) 6842 return; 6843 6844 Result += "\nstatic const char *"; 6845 Result += VarName; Result += ProtocolName; 6846 Result += " [] __attribute__ ((used, section (\"__DATA,__objc_const\"))) = \n"; 6847 Result += "{\n"; 6848 for (unsigned i = 0, e = Methods.size(); i < e; i++) { 6849 ObjCMethodDecl *MD = Methods[i]; 6850 std::string MethodTypeString, QuoteMethodTypeString; 6851 Context->getObjCEncodingForMethodDecl(MD, MethodTypeString, true); 6852 RewriteObj.QuoteDoublequotes(MethodTypeString, QuoteMethodTypeString); 6853 Result += "\t\""; Result += QuoteMethodTypeString; Result += "\""; 6854 if (i == e-1) 6855 Result += "\n};\n"; 6856 else { 6857 Result += ",\n"; 6858 } 6859 } 6860 } 6861 6862 static void Write_IvarOffsetVar(RewriteModernObjC &RewriteObj, 6863 ASTContext *Context, 6864 std::string &Result, 6865 ArrayRef<ObjCIvarDecl *> Ivars, 6866 ObjCInterfaceDecl *CDecl) { 6867 // FIXME. visibilty of offset symbols may have to be set; for Darwin 6868 // this is what happens: 6869 /** 6870 if (Ivar->getAccessControl() == ObjCIvarDecl::Private || 6871 Ivar->getAccessControl() == ObjCIvarDecl::Package || 6872 Class->getVisibility() == HiddenVisibility) 6873 Visibility shoud be: HiddenVisibility; 6874 else 6875 Visibility shoud be: DefaultVisibility; 6876 */ 6877 6878 Result += "\n"; 6879 for (unsigned i =0, e = Ivars.size(); i < e; i++) { 6880 ObjCIvarDecl *IvarDecl = Ivars[i]; 6881 if (Context->getLangOpts().MicrosoftExt) 6882 Result += "__declspec(allocate(\".objc_ivar$B\")) "; 6883 6884 if (!Context->getLangOpts().MicrosoftExt || 6885 IvarDecl->getAccessControl() == ObjCIvarDecl::Private || 6886 IvarDecl->getAccessControl() == ObjCIvarDecl::Package) 6887 Result += "extern \"C\" unsigned long int "; 6888 else 6889 Result += "extern \"C\" __declspec(dllexport) unsigned long int "; 6890 if (Ivars[i]->isBitField()) 6891 RewriteObj.ObjCIvarBitfieldGroupOffset(IvarDecl, Result); 6892 else 6893 WriteInternalIvarName(CDecl, IvarDecl, Result); 6894 Result += " __attribute__ ((used, section (\"__DATA,__objc_ivar\")))"; 6895 Result += " = "; 6896 RewriteObj.RewriteIvarOffsetComputation(IvarDecl, Result); 6897 Result += ";\n"; 6898 if (Ivars[i]->isBitField()) { 6899 // skip over rest of the ivar bitfields. 6900 SKIP_BITFIELDS(i , e, Ivars); 6901 } 6902 } 6903 } 6904 6905 static void Write__ivar_list_t_initializer(RewriteModernObjC &RewriteObj, 6906 ASTContext *Context, std::string &Result, 6907 ArrayRef<ObjCIvarDecl *> OriginalIvars, 6908 StringRef VarName, 6909 ObjCInterfaceDecl *CDecl) { 6910 if (OriginalIvars.size() > 0) { 6911 Write_IvarOffsetVar(RewriteObj, Context, Result, OriginalIvars, CDecl); 6912 SmallVector<ObjCIvarDecl *, 8> Ivars; 6913 // strip off all but the first ivar bitfield from each group of ivars. 6914 // Such ivars in the ivar list table will be replaced by their grouping struct 6915 // 'ivar'. 6916 for (unsigned i = 0, e = OriginalIvars.size(); i < e; i++) { 6917 if (OriginalIvars[i]->isBitField()) { 6918 Ivars.push_back(OriginalIvars[i]); 6919 // skip over rest of the ivar bitfields. 6920 SKIP_BITFIELDS(i , e, OriginalIvars); 6921 } 6922 else 6923 Ivars.push_back(OriginalIvars[i]); 6924 } 6925 6926 Result += "\nstatic "; 6927 Write__ivar_list_t_TypeDecl(Result, Ivars.size()); 6928 Result += " "; Result += VarName; 6929 Result += CDecl->getNameAsString(); 6930 Result += " __attribute__ ((used, section (\"__DATA,__objc_const\"))) = {\n"; 6931 Result += "\t"; Result += "sizeof(_ivar_t)"; Result += ",\n"; 6932 Result += "\t"; Result += utostr(Ivars.size()); Result += ",\n"; 6933 for (unsigned i =0, e = Ivars.size(); i < e; i++) { 6934 ObjCIvarDecl *IvarDecl = Ivars[i]; 6935 if (i == 0) 6936 Result += "\t{{"; 6937 else 6938 Result += "\t {"; 6939 Result += "(unsigned long int *)&"; 6940 if (Ivars[i]->isBitField()) 6941 RewriteObj.ObjCIvarBitfieldGroupOffset(IvarDecl, Result); 6942 else 6943 WriteInternalIvarName(CDecl, IvarDecl, Result); 6944 Result += ", "; 6945 6946 Result += "\""; 6947 if (Ivars[i]->isBitField()) 6948 RewriteObj.ObjCIvarBitfieldGroupDecl(Ivars[i], Result); 6949 else 6950 Result += IvarDecl->getName(); 6951 Result += "\", "; 6952 6953 QualType IVQT = IvarDecl->getType(); 6954 if (IvarDecl->isBitField()) 6955 IVQT = RewriteObj.GetGroupRecordTypeForObjCIvarBitfield(IvarDecl); 6956 6957 std::string IvarTypeString, QuoteIvarTypeString; 6958 Context->getObjCEncodingForType(IVQT, IvarTypeString, 6959 IvarDecl); 6960 RewriteObj.QuoteDoublequotes(IvarTypeString, QuoteIvarTypeString); 6961 Result += "\""; Result += QuoteIvarTypeString; Result += "\", "; 6962 6963 // FIXME. this alignment represents the host alignment and need be changed to 6964 // represent the target alignment. 6965 unsigned Align = Context->getTypeAlign(IVQT)/8; 6966 Align = llvm::Log2_32(Align); 6967 Result += llvm::utostr(Align); Result += ", "; 6968 CharUnits Size = Context->getTypeSizeInChars(IVQT); 6969 Result += llvm::utostr(Size.getQuantity()); 6970 if (i == e-1) 6971 Result += "}}\n"; 6972 else 6973 Result += "},\n"; 6974 } 6975 Result += "};\n"; 6976 } 6977 } 6978 6979 /// RewriteObjCProtocolMetaData - Rewrite protocols meta-data. 6980 void RewriteModernObjC::RewriteObjCProtocolMetaData(ObjCProtocolDecl *PDecl, 6981 std::string &Result) { 6982 6983 // Do not synthesize the protocol more than once. 6984 if (ObjCSynthesizedProtocols.count(PDecl->getCanonicalDecl())) 6985 return; 6986 WriteModernMetadataDeclarations(Context, Result); 6987 6988 if (ObjCProtocolDecl *Def = PDecl->getDefinition()) 6989 PDecl = Def; 6990 // Must write out all protocol definitions in current qualifier list, 6991 // and in their nested qualifiers before writing out current definition. 6992 for (auto *I : PDecl->protocols()) 6993 RewriteObjCProtocolMetaData(I, Result); 6994 6995 // Construct method lists. 6996 std::vector<ObjCMethodDecl *> InstanceMethods, ClassMethods; 6997 std::vector<ObjCMethodDecl *> OptInstanceMethods, OptClassMethods; 6998 for (auto *MD : PDecl->instance_methods()) { 6999 if (MD->getImplementationControl() == ObjCMethodDecl::Optional) { 7000 OptInstanceMethods.push_back(MD); 7001 } else { 7002 InstanceMethods.push_back(MD); 7003 } 7004 } 7005 7006 for (auto *MD : PDecl->class_methods()) { 7007 if (MD->getImplementationControl() == ObjCMethodDecl::Optional) { 7008 OptClassMethods.push_back(MD); 7009 } else { 7010 ClassMethods.push_back(MD); 7011 } 7012 } 7013 std::vector<ObjCMethodDecl *> AllMethods; 7014 for (unsigned i = 0, e = InstanceMethods.size(); i < e; i++) 7015 AllMethods.push_back(InstanceMethods[i]); 7016 for (unsigned i = 0, e = ClassMethods.size(); i < e; i++) 7017 AllMethods.push_back(ClassMethods[i]); 7018 for (unsigned i = 0, e = OptInstanceMethods.size(); i < e; i++) 7019 AllMethods.push_back(OptInstanceMethods[i]); 7020 for (unsigned i = 0, e = OptClassMethods.size(); i < e; i++) 7021 AllMethods.push_back(OptClassMethods[i]); 7022 7023 Write__extendedMethodTypes_initializer(*this, Context, Result, 7024 AllMethods, 7025 "_OBJC_PROTOCOL_METHOD_TYPES_", 7026 PDecl->getNameAsString()); 7027 // Protocol's super protocol list 7028 SmallVector<ObjCProtocolDecl *, 8> SuperProtocols(PDecl->protocols()); 7029 Write_protocol_list_initializer(Context, Result, SuperProtocols, 7030 "_OBJC_PROTOCOL_REFS_", 7031 PDecl->getNameAsString()); 7032 7033 Write_method_list_t_initializer(*this, Context, Result, InstanceMethods, 7034 "_OBJC_PROTOCOL_INSTANCE_METHODS_", 7035 PDecl->getNameAsString(), false); 7036 7037 Write_method_list_t_initializer(*this, Context, Result, ClassMethods, 7038 "_OBJC_PROTOCOL_CLASS_METHODS_", 7039 PDecl->getNameAsString(), false); 7040 7041 Write_method_list_t_initializer(*this, Context, Result, OptInstanceMethods, 7042 "_OBJC_PROTOCOL_OPT_INSTANCE_METHODS_", 7043 PDecl->getNameAsString(), false); 7044 7045 Write_method_list_t_initializer(*this, Context, Result, OptClassMethods, 7046 "_OBJC_PROTOCOL_OPT_CLASS_METHODS_", 7047 PDecl->getNameAsString(), false); 7048 7049 // Protocol's property metadata. 7050 SmallVector<ObjCPropertyDecl *, 8> ProtocolProperties(PDecl->properties()); 7051 Write_prop_list_t_initializer(*this, Context, Result, ProtocolProperties, 7052 /* Container */nullptr, 7053 "_OBJC_PROTOCOL_PROPERTIES_", 7054 PDecl->getNameAsString()); 7055 7056 // Writer out root metadata for current protocol: struct _protocol_t 7057 Result += "\n"; 7058 if (LangOpts.MicrosoftExt) 7059 Result += "static "; 7060 Result += "struct _protocol_t _OBJC_PROTOCOL_"; 7061 Result += PDecl->getNameAsString(); 7062 Result += " __attribute__ ((used, section (\"__DATA,__datacoal_nt,coalesced\"))) = {\n"; 7063 Result += "\t0,\n"; // id is; is null 7064 Result += "\t\""; Result += PDecl->getNameAsString(); Result += "\",\n"; 7065 if (SuperProtocols.size() > 0) { 7066 Result += "\t(const struct _protocol_list_t *)&"; Result += "_OBJC_PROTOCOL_REFS_"; 7067 Result += PDecl->getNameAsString(); Result += ",\n"; 7068 } 7069 else 7070 Result += "\t0,\n"; 7071 if (InstanceMethods.size() > 0) { 7072 Result += "\t(const struct method_list_t *)&_OBJC_PROTOCOL_INSTANCE_METHODS_"; 7073 Result += PDecl->getNameAsString(); Result += ",\n"; 7074 } 7075 else 7076 Result += "\t0,\n"; 7077 7078 if (ClassMethods.size() > 0) { 7079 Result += "\t(const struct method_list_t *)&_OBJC_PROTOCOL_CLASS_METHODS_"; 7080 Result += PDecl->getNameAsString(); Result += ",\n"; 7081 } 7082 else 7083 Result += "\t0,\n"; 7084 7085 if (OptInstanceMethods.size() > 0) { 7086 Result += "\t(const struct method_list_t *)&_OBJC_PROTOCOL_OPT_INSTANCE_METHODS_"; 7087 Result += PDecl->getNameAsString(); Result += ",\n"; 7088 } 7089 else 7090 Result += "\t0,\n"; 7091 7092 if (OptClassMethods.size() > 0) { 7093 Result += "\t(const struct method_list_t *)&_OBJC_PROTOCOL_OPT_CLASS_METHODS_"; 7094 Result += PDecl->getNameAsString(); Result += ",\n"; 7095 } 7096 else 7097 Result += "\t0,\n"; 7098 7099 if (ProtocolProperties.size() > 0) { 7100 Result += "\t(const struct _prop_list_t *)&_OBJC_PROTOCOL_PROPERTIES_"; 7101 Result += PDecl->getNameAsString(); Result += ",\n"; 7102 } 7103 else 7104 Result += "\t0,\n"; 7105 7106 Result += "\t"; Result += "sizeof(_protocol_t)"; Result += ",\n"; 7107 Result += "\t0,\n"; 7108 7109 if (AllMethods.size() > 0) { 7110 Result += "\t(const char **)&"; Result += "_OBJC_PROTOCOL_METHOD_TYPES_"; 7111 Result += PDecl->getNameAsString(); 7112 Result += "\n};\n"; 7113 } 7114 else 7115 Result += "\t0\n};\n"; 7116 7117 if (LangOpts.MicrosoftExt) 7118 Result += "static "; 7119 Result += "struct _protocol_t *"; 7120 Result += "_OBJC_LABEL_PROTOCOL_$_"; Result += PDecl->getNameAsString(); 7121 Result += " = &_OBJC_PROTOCOL_"; Result += PDecl->getNameAsString(); 7122 Result += ";\n"; 7123 7124 // Mark this protocol as having been generated. 7125 if (!ObjCSynthesizedProtocols.insert(PDecl->getCanonicalDecl())) 7126 llvm_unreachable("protocol already synthesized"); 7127 7128 } 7129 7130 void RewriteModernObjC::RewriteObjCProtocolListMetaData( 7131 const ObjCList<ObjCProtocolDecl> &Protocols, 7132 StringRef prefix, StringRef ClassName, 7133 std::string &Result) { 7134 if (Protocols.empty()) return; 7135 7136 for (unsigned i = 0; i != Protocols.size(); i++) 7137 RewriteObjCProtocolMetaData(Protocols[i], Result); 7138 7139 // Output the top lovel protocol meta-data for the class. 7140 /* struct _objc_protocol_list { 7141 struct _objc_protocol_list *next; 7142 int protocol_count; 7143 struct _objc_protocol *class_protocols[]; 7144 } 7145 */ 7146 Result += "\n"; 7147 if (LangOpts.MicrosoftExt) 7148 Result += "__declspec(allocate(\".cat_cls_meth$B\")) "; 7149 Result += "static struct {\n"; 7150 Result += "\tstruct _objc_protocol_list *next;\n"; 7151 Result += "\tint protocol_count;\n"; 7152 Result += "\tstruct _objc_protocol *class_protocols["; 7153 Result += utostr(Protocols.size()); 7154 Result += "];\n} _OBJC_"; 7155 Result += prefix; 7156 Result += "_PROTOCOLS_"; 7157 Result += ClassName; 7158 Result += " __attribute__ ((used, section (\"__OBJC, __cat_cls_meth\")))= " 7159 "{\n\t0, "; 7160 Result += utostr(Protocols.size()); 7161 Result += "\n"; 7162 7163 Result += "\t,{&_OBJC_PROTOCOL_"; 7164 Result += Protocols[0]->getNameAsString(); 7165 Result += " \n"; 7166 7167 for (unsigned i = 1; i != Protocols.size(); i++) { 7168 Result += "\t ,&_OBJC_PROTOCOL_"; 7169 Result += Protocols[i]->getNameAsString(); 7170 Result += "\n"; 7171 } 7172 Result += "\t }\n};\n"; 7173 } 7174 7175 /// hasObjCExceptionAttribute - Return true if this class or any super 7176 /// class has the __objc_exception__ attribute. 7177 /// FIXME. Move this to ASTContext.cpp as it is also used for IRGen. 7178 static bool hasObjCExceptionAttribute(ASTContext &Context, 7179 const ObjCInterfaceDecl *OID) { 7180 if (OID->hasAttr<ObjCExceptionAttr>()) 7181 return true; 7182 if (const ObjCInterfaceDecl *Super = OID->getSuperClass()) 7183 return hasObjCExceptionAttribute(Context, Super); 7184 return false; 7185 } 7186 7187 void RewriteModernObjC::RewriteObjCClassMetaData(ObjCImplementationDecl *IDecl, 7188 std::string &Result) { 7189 ObjCInterfaceDecl *CDecl = IDecl->getClassInterface(); 7190 7191 // Explicitly declared @interface's are already synthesized. 7192 if (CDecl->isImplicitInterfaceDecl()) 7193 assert(false && 7194 "Legacy implicit interface rewriting not supported in moder abi"); 7195 7196 WriteModernMetadataDeclarations(Context, Result); 7197 SmallVector<ObjCIvarDecl *, 8> IVars; 7198 7199 for (ObjCIvarDecl *IVD = CDecl->all_declared_ivar_begin(); 7200 IVD; IVD = IVD->getNextIvar()) { 7201 // Ignore unnamed bit-fields. 7202 if (!IVD->getDeclName()) 7203 continue; 7204 IVars.push_back(IVD); 7205 } 7206 7207 Write__ivar_list_t_initializer(*this, Context, Result, IVars, 7208 "_OBJC_$_INSTANCE_VARIABLES_", 7209 CDecl); 7210 7211 // Build _objc_method_list for class's instance methods if needed 7212 SmallVector<ObjCMethodDecl *, 32> InstanceMethods(IDecl->instance_methods()); 7213 7214 // If any of our property implementations have associated getters or 7215 // setters, produce metadata for them as well. 7216 for (const auto *Prop : IDecl->property_impls()) { 7217 if (Prop->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic) 7218 continue; 7219 if (!Prop->getPropertyIvarDecl()) 7220 continue; 7221 ObjCPropertyDecl *PD = Prop->getPropertyDecl(); 7222 if (!PD) 7223 continue; 7224 if (ObjCMethodDecl *Getter = PD->getGetterMethodDecl()) 7225 if (mustSynthesizeSetterGetterMethod(IDecl, PD, true /*getter*/)) 7226 InstanceMethods.push_back(Getter); 7227 if (PD->isReadOnly()) 7228 continue; 7229 if (ObjCMethodDecl *Setter = PD->getSetterMethodDecl()) 7230 if (mustSynthesizeSetterGetterMethod(IDecl, PD, false /*setter*/)) 7231 InstanceMethods.push_back(Setter); 7232 } 7233 7234 Write_method_list_t_initializer(*this, Context, Result, InstanceMethods, 7235 "_OBJC_$_INSTANCE_METHODS_", 7236 IDecl->getNameAsString(), true); 7237 7238 SmallVector<ObjCMethodDecl *, 32> ClassMethods(IDecl->class_methods()); 7239 7240 Write_method_list_t_initializer(*this, Context, Result, ClassMethods, 7241 "_OBJC_$_CLASS_METHODS_", 7242 IDecl->getNameAsString(), true); 7243 7244 // Protocols referenced in class declaration? 7245 // Protocol's super protocol list 7246 std::vector<ObjCProtocolDecl *> RefedProtocols; 7247 const ObjCList<ObjCProtocolDecl> &Protocols = CDecl->getReferencedProtocols(); 7248 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(), 7249 E = Protocols.end(); 7250 I != E; ++I) { 7251 RefedProtocols.push_back(*I); 7252 // Must write out all protocol definitions in current qualifier list, 7253 // and in their nested qualifiers before writing out current definition. 7254 RewriteObjCProtocolMetaData(*I, Result); 7255 } 7256 7257 Write_protocol_list_initializer(Context, Result, 7258 RefedProtocols, 7259 "_OBJC_CLASS_PROTOCOLS_$_", 7260 IDecl->getNameAsString()); 7261 7262 // Protocol's property metadata. 7263 SmallVector<ObjCPropertyDecl *, 8> ClassProperties(CDecl->properties()); 7264 Write_prop_list_t_initializer(*this, Context, Result, ClassProperties, 7265 /* Container */IDecl, 7266 "_OBJC_$_PROP_LIST_", 7267 CDecl->getNameAsString()); 7268 7269 7270 // Data for initializing _class_ro_t metaclass meta-data 7271 uint32_t flags = CLS_META; 7272 std::string InstanceSize; 7273 std::string InstanceStart; 7274 7275 7276 bool classIsHidden = CDecl->getVisibility() == HiddenVisibility; 7277 if (classIsHidden) 7278 flags |= OBJC2_CLS_HIDDEN; 7279 7280 if (!CDecl->getSuperClass()) 7281 // class is root 7282 flags |= CLS_ROOT; 7283 InstanceSize = "sizeof(struct _class_t)"; 7284 InstanceStart = InstanceSize; 7285 Write__class_ro_t_initializer(Context, Result, flags, 7286 InstanceStart, InstanceSize, 7287 ClassMethods, 7288 nullptr, 7289 nullptr, 7290 nullptr, 7291 "_OBJC_METACLASS_RO_$_", 7292 CDecl->getNameAsString()); 7293 7294 // Data for initializing _class_ro_t meta-data 7295 flags = CLS; 7296 if (classIsHidden) 7297 flags |= OBJC2_CLS_HIDDEN; 7298 7299 if (hasObjCExceptionAttribute(*Context, CDecl)) 7300 flags |= CLS_EXCEPTION; 7301 7302 if (!CDecl->getSuperClass()) 7303 // class is root 7304 flags |= CLS_ROOT; 7305 7306 InstanceSize.clear(); 7307 InstanceStart.clear(); 7308 if (!ObjCSynthesizedStructs.count(CDecl)) { 7309 InstanceSize = "0"; 7310 InstanceStart = "0"; 7311 } 7312 else { 7313 InstanceSize = "sizeof(struct "; 7314 InstanceSize += CDecl->getNameAsString(); 7315 InstanceSize += "_IMPL)"; 7316 7317 ObjCIvarDecl *IVD = CDecl->all_declared_ivar_begin(); 7318 if (IVD) { 7319 RewriteIvarOffsetComputation(IVD, InstanceStart); 7320 } 7321 else 7322 InstanceStart = InstanceSize; 7323 } 7324 Write__class_ro_t_initializer(Context, Result, flags, 7325 InstanceStart, InstanceSize, 7326 InstanceMethods, 7327 RefedProtocols, 7328 IVars, 7329 ClassProperties, 7330 "_OBJC_CLASS_RO_$_", 7331 CDecl->getNameAsString()); 7332 7333 Write_class_t(Context, Result, 7334 "OBJC_METACLASS_$_", 7335 CDecl, /*metaclass*/true); 7336 7337 Write_class_t(Context, Result, 7338 "OBJC_CLASS_$_", 7339 CDecl, /*metaclass*/false); 7340 7341 if (ImplementationIsNonLazy(IDecl)) 7342 DefinedNonLazyClasses.push_back(CDecl); 7343 7344 } 7345 7346 void RewriteModernObjC::RewriteClassSetupInitHook(std::string &Result) { 7347 int ClsDefCount = ClassImplementation.size(); 7348 if (!ClsDefCount) 7349 return; 7350 Result += "#pragma section(\".objc_inithooks$B\", long, read, write)\n"; 7351 Result += "__declspec(allocate(\".objc_inithooks$B\")) "; 7352 Result += "static void *OBJC_CLASS_SETUP[] = {\n"; 7353 for (int i = 0; i < ClsDefCount; i++) { 7354 ObjCImplementationDecl *IDecl = ClassImplementation[i]; 7355 ObjCInterfaceDecl *CDecl = IDecl->getClassInterface(); 7356 Result += "\t(void *)&OBJC_CLASS_SETUP_$_"; 7357 Result += CDecl->getName(); Result += ",\n"; 7358 } 7359 Result += "};\n"; 7360 } 7361 7362 void RewriteModernObjC::RewriteMetaDataIntoBuffer(std::string &Result) { 7363 int ClsDefCount = ClassImplementation.size(); 7364 int CatDefCount = CategoryImplementation.size(); 7365 7366 // For each implemented class, write out all its meta data. 7367 for (int i = 0; i < ClsDefCount; i++) 7368 RewriteObjCClassMetaData(ClassImplementation[i], Result); 7369 7370 RewriteClassSetupInitHook(Result); 7371 7372 // For each implemented category, write out all its meta data. 7373 for (int i = 0; i < CatDefCount; i++) 7374 RewriteObjCCategoryImplDecl(CategoryImplementation[i], Result); 7375 7376 RewriteCategorySetupInitHook(Result); 7377 7378 if (ClsDefCount > 0) { 7379 if (LangOpts.MicrosoftExt) 7380 Result += "__declspec(allocate(\".objc_classlist$B\")) "; 7381 Result += "static struct _class_t *L_OBJC_LABEL_CLASS_$ ["; 7382 Result += llvm::utostr(ClsDefCount); Result += "]"; 7383 Result += 7384 " __attribute__((used, section (\"__DATA, __objc_classlist," 7385 "regular,no_dead_strip\")))= {\n"; 7386 for (int i = 0; i < ClsDefCount; i++) { 7387 Result += "\t&OBJC_CLASS_$_"; 7388 Result += ClassImplementation[i]->getNameAsString(); 7389 Result += ",\n"; 7390 } 7391 Result += "};\n"; 7392 7393 if (!DefinedNonLazyClasses.empty()) { 7394 if (LangOpts.MicrosoftExt) 7395 Result += "__declspec(allocate(\".objc_nlclslist$B\")) \n"; 7396 Result += "static struct _class_t *_OBJC_LABEL_NONLAZY_CLASS_$[] = {\n\t"; 7397 for (unsigned i = 0, e = DefinedNonLazyClasses.size(); i < e; i++) { 7398 Result += "\t&OBJC_CLASS_$_"; Result += DefinedNonLazyClasses[i]->getNameAsString(); 7399 Result += ",\n"; 7400 } 7401 Result += "};\n"; 7402 } 7403 } 7404 7405 if (CatDefCount > 0) { 7406 if (LangOpts.MicrosoftExt) 7407 Result += "__declspec(allocate(\".objc_catlist$B\")) "; 7408 Result += "static struct _category_t *L_OBJC_LABEL_CATEGORY_$ ["; 7409 Result += llvm::utostr(CatDefCount); Result += "]"; 7410 Result += 7411 " __attribute__((used, section (\"__DATA, __objc_catlist," 7412 "regular,no_dead_strip\")))= {\n"; 7413 for (int i = 0; i < CatDefCount; i++) { 7414 Result += "\t&_OBJC_$_CATEGORY_"; 7415 Result += 7416 CategoryImplementation[i]->getClassInterface()->getNameAsString(); 7417 Result += "_$_"; 7418 Result += CategoryImplementation[i]->getNameAsString(); 7419 Result += ",\n"; 7420 } 7421 Result += "};\n"; 7422 } 7423 7424 if (!DefinedNonLazyCategories.empty()) { 7425 if (LangOpts.MicrosoftExt) 7426 Result += "__declspec(allocate(\".objc_nlcatlist$B\")) \n"; 7427 Result += "static struct _category_t *_OBJC_LABEL_NONLAZY_CATEGORY_$[] = {\n\t"; 7428 for (unsigned i = 0, e = DefinedNonLazyCategories.size(); i < e; i++) { 7429 Result += "\t&_OBJC_$_CATEGORY_"; 7430 Result += 7431 DefinedNonLazyCategories[i]->getClassInterface()->getNameAsString(); 7432 Result += "_$_"; 7433 Result += DefinedNonLazyCategories[i]->getNameAsString(); 7434 Result += ",\n"; 7435 } 7436 Result += "};\n"; 7437 } 7438 } 7439 7440 void RewriteModernObjC::WriteImageInfo(std::string &Result) { 7441 if (LangOpts.MicrosoftExt) 7442 Result += "__declspec(allocate(\".objc_imageinfo$B\")) \n"; 7443 7444 Result += "static struct IMAGE_INFO { unsigned version; unsigned flag; } "; 7445 // version 0, ObjCABI is 2 7446 Result += "_OBJC_IMAGE_INFO = { 0, 2 };\n"; 7447 } 7448 7449 /// RewriteObjCCategoryImplDecl - Rewrite metadata for each category 7450 /// implementation. 7451 void RewriteModernObjC::RewriteObjCCategoryImplDecl(ObjCCategoryImplDecl *IDecl, 7452 std::string &Result) { 7453 WriteModernMetadataDeclarations(Context, Result); 7454 ObjCInterfaceDecl *ClassDecl = IDecl->getClassInterface(); 7455 // Find category declaration for this implementation. 7456 ObjCCategoryDecl *CDecl 7457 = ClassDecl->FindCategoryDeclaration(IDecl->getIdentifier()); 7458 7459 std::string FullCategoryName = ClassDecl->getNameAsString(); 7460 FullCategoryName += "_$_"; 7461 FullCategoryName += CDecl->getNameAsString(); 7462 7463 // Build _objc_method_list for class's instance methods if needed 7464 SmallVector<ObjCMethodDecl *, 32> InstanceMethods(IDecl->instance_methods()); 7465 7466 // If any of our property implementations have associated getters or 7467 // setters, produce metadata for them as well. 7468 for (const auto *Prop : IDecl->property_impls()) { 7469 if (Prop->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic) 7470 continue; 7471 if (!Prop->getPropertyIvarDecl()) 7472 continue; 7473 ObjCPropertyDecl *PD = Prop->getPropertyDecl(); 7474 if (!PD) 7475 continue; 7476 if (ObjCMethodDecl *Getter = PD->getGetterMethodDecl()) 7477 InstanceMethods.push_back(Getter); 7478 if (PD->isReadOnly()) 7479 continue; 7480 if (ObjCMethodDecl *Setter = PD->getSetterMethodDecl()) 7481 InstanceMethods.push_back(Setter); 7482 } 7483 7484 Write_method_list_t_initializer(*this, Context, Result, InstanceMethods, 7485 "_OBJC_$_CATEGORY_INSTANCE_METHODS_", 7486 FullCategoryName, true); 7487 7488 SmallVector<ObjCMethodDecl *, 32> ClassMethods(IDecl->class_methods()); 7489 7490 Write_method_list_t_initializer(*this, Context, Result, ClassMethods, 7491 "_OBJC_$_CATEGORY_CLASS_METHODS_", 7492 FullCategoryName, true); 7493 7494 // Protocols referenced in class declaration? 7495 // Protocol's super protocol list 7496 SmallVector<ObjCProtocolDecl *, 8> RefedProtocols(CDecl->protocols()); 7497 for (auto *I : CDecl->protocols()) 7498 // Must write out all protocol definitions in current qualifier list, 7499 // and in their nested qualifiers before writing out current definition. 7500 RewriteObjCProtocolMetaData(I, Result); 7501 7502 Write_protocol_list_initializer(Context, Result, 7503 RefedProtocols, 7504 "_OBJC_CATEGORY_PROTOCOLS_$_", 7505 FullCategoryName); 7506 7507 // Protocol's property metadata. 7508 SmallVector<ObjCPropertyDecl *, 8> ClassProperties(CDecl->properties()); 7509 Write_prop_list_t_initializer(*this, Context, Result, ClassProperties, 7510 /* Container */IDecl, 7511 "_OBJC_$_PROP_LIST_", 7512 FullCategoryName); 7513 7514 Write_category_t(*this, Context, Result, 7515 CDecl, 7516 ClassDecl, 7517 InstanceMethods, 7518 ClassMethods, 7519 RefedProtocols, 7520 ClassProperties); 7521 7522 // Determine if this category is also "non-lazy". 7523 if (ImplementationIsNonLazy(IDecl)) 7524 DefinedNonLazyCategories.push_back(CDecl); 7525 7526 } 7527 7528 void RewriteModernObjC::RewriteCategorySetupInitHook(std::string &Result) { 7529 int CatDefCount = CategoryImplementation.size(); 7530 if (!CatDefCount) 7531 return; 7532 Result += "#pragma section(\".objc_inithooks$B\", long, read, write)\n"; 7533 Result += "__declspec(allocate(\".objc_inithooks$B\")) "; 7534 Result += "static void *OBJC_CATEGORY_SETUP[] = {\n"; 7535 for (int i = 0; i < CatDefCount; i++) { 7536 ObjCCategoryImplDecl *IDecl = CategoryImplementation[i]; 7537 ObjCCategoryDecl *CatDecl= IDecl->getCategoryDecl(); 7538 ObjCInterfaceDecl *ClassDecl = IDecl->getClassInterface(); 7539 Result += "\t(void *)&OBJC_CATEGORY_SETUP_$_"; 7540 Result += ClassDecl->getName(); 7541 Result += "_$_"; 7542 Result += CatDecl->getName(); 7543 Result += ",\n"; 7544 } 7545 Result += "};\n"; 7546 } 7547 7548 // RewriteObjCMethodsMetaData - Rewrite methods metadata for instance or 7549 /// class methods. 7550 template<typename MethodIterator> 7551 void RewriteModernObjC::RewriteObjCMethodsMetaData(MethodIterator MethodBegin, 7552 MethodIterator MethodEnd, 7553 bool IsInstanceMethod, 7554 StringRef prefix, 7555 StringRef ClassName, 7556 std::string &Result) { 7557 if (MethodBegin == MethodEnd) return; 7558 7559 if (!objc_impl_method) { 7560 /* struct _objc_method { 7561 SEL _cmd; 7562 char *method_types; 7563 void *_imp; 7564 } 7565 */ 7566 Result += "\nstruct _objc_method {\n"; 7567 Result += "\tSEL _cmd;\n"; 7568 Result += "\tchar *method_types;\n"; 7569 Result += "\tvoid *_imp;\n"; 7570 Result += "};\n"; 7571 7572 objc_impl_method = true; 7573 } 7574 7575 // Build _objc_method_list for class's methods if needed 7576 7577 /* struct { 7578 struct _objc_method_list *next_method; 7579 int method_count; 7580 struct _objc_method method_list[]; 7581 } 7582 */ 7583 unsigned NumMethods = std::distance(MethodBegin, MethodEnd); 7584 Result += "\n"; 7585 if (LangOpts.MicrosoftExt) { 7586 if (IsInstanceMethod) 7587 Result += "__declspec(allocate(\".inst_meth$B\")) "; 7588 else 7589 Result += "__declspec(allocate(\".cls_meth$B\")) "; 7590 } 7591 Result += "static struct {\n"; 7592 Result += "\tstruct _objc_method_list *next_method;\n"; 7593 Result += "\tint method_count;\n"; 7594 Result += "\tstruct _objc_method method_list["; 7595 Result += utostr(NumMethods); 7596 Result += "];\n} _OBJC_"; 7597 Result += prefix; 7598 Result += IsInstanceMethod ? "INSTANCE" : "CLASS"; 7599 Result += "_METHODS_"; 7600 Result += ClassName; 7601 Result += " __attribute__ ((used, section (\"__OBJC, __"; 7602 Result += IsInstanceMethod ? "inst" : "cls"; 7603 Result += "_meth\")))= "; 7604 Result += "{\n\t0, " + utostr(NumMethods) + "\n"; 7605 7606 Result += "\t,{{(SEL)\""; 7607 Result += (*MethodBegin)->getSelector().getAsString().c_str(); 7608 std::string MethodTypeString; 7609 Context->getObjCEncodingForMethodDecl(*MethodBegin, MethodTypeString); 7610 Result += "\", \""; 7611 Result += MethodTypeString; 7612 Result += "\", (void *)"; 7613 Result += MethodInternalNames[*MethodBegin]; 7614 Result += "}\n"; 7615 for (++MethodBegin; MethodBegin != MethodEnd; ++MethodBegin) { 7616 Result += "\t ,{(SEL)\""; 7617 Result += (*MethodBegin)->getSelector().getAsString().c_str(); 7618 std::string MethodTypeString; 7619 Context->getObjCEncodingForMethodDecl(*MethodBegin, MethodTypeString); 7620 Result += "\", \""; 7621 Result += MethodTypeString; 7622 Result += "\", (void *)"; 7623 Result += MethodInternalNames[*MethodBegin]; 7624 Result += "}\n"; 7625 } 7626 Result += "\t }\n};\n"; 7627 } 7628 7629 Stmt *RewriteModernObjC::RewriteObjCIvarRefExpr(ObjCIvarRefExpr *IV) { 7630 SourceRange OldRange = IV->getSourceRange(); 7631 Expr *BaseExpr = IV->getBase(); 7632 7633 // Rewrite the base, but without actually doing replaces. 7634 { 7635 DisableReplaceStmtScope S(*this); 7636 BaseExpr = cast<Expr>(RewriteFunctionBodyOrGlobalInitializer(BaseExpr)); 7637 IV->setBase(BaseExpr); 7638 } 7639 7640 ObjCIvarDecl *D = IV->getDecl(); 7641 7642 Expr *Replacement = IV; 7643 7644 if (BaseExpr->getType()->isObjCObjectPointerType()) { 7645 const ObjCInterfaceType *iFaceDecl = 7646 dyn_cast<ObjCInterfaceType>(BaseExpr->getType()->getPointeeType()); 7647 assert(iFaceDecl && "RewriteObjCIvarRefExpr - iFaceDecl is null"); 7648 // lookup which class implements the instance variable. 7649 ObjCInterfaceDecl *clsDeclared = nullptr; 7650 iFaceDecl->getDecl()->lookupInstanceVariable(D->getIdentifier(), 7651 clsDeclared); 7652 assert(clsDeclared && "RewriteObjCIvarRefExpr(): Can't find class"); 7653 7654 // Build name of symbol holding ivar offset. 7655 std::string IvarOffsetName; 7656 if (D->isBitField()) 7657 ObjCIvarBitfieldGroupOffset(D, IvarOffsetName); 7658 else 7659 WriteInternalIvarName(clsDeclared, D, IvarOffsetName); 7660 7661 ReferencedIvars[clsDeclared].insert(D); 7662 7663 // cast offset to "char *". 7664 CastExpr *castExpr = NoTypeInfoCStyleCastExpr(Context, 7665 Context->getPointerType(Context->CharTy), 7666 CK_BitCast, 7667 BaseExpr); 7668 VarDecl *NewVD = VarDecl::Create(*Context, TUDecl, SourceLocation(), 7669 SourceLocation(), &Context->Idents.get(IvarOffsetName), 7670 Context->UnsignedLongTy, nullptr, 7671 SC_Extern); 7672 DeclRefExpr *DRE = new (Context) DeclRefExpr(NewVD, false, 7673 Context->UnsignedLongTy, VK_LValue, 7674 SourceLocation()); 7675 BinaryOperator *addExpr = 7676 new (Context) BinaryOperator(castExpr, DRE, BO_Add, 7677 Context->getPointerType(Context->CharTy), 7678 VK_RValue, OK_Ordinary, SourceLocation(), false); 7679 // Don't forget the parens to enforce the proper binding. 7680 ParenExpr *PE = new (Context) ParenExpr(SourceLocation(), 7681 SourceLocation(), 7682 addExpr); 7683 QualType IvarT = D->getType(); 7684 if (D->isBitField()) 7685 IvarT = GetGroupRecordTypeForObjCIvarBitfield(D); 7686 7687 if (!isa<TypedefType>(IvarT) && IvarT->isRecordType()) { 7688 RecordDecl *RD = IvarT->getAs<RecordType>()->getDecl(); 7689 RD = RD->getDefinition(); 7690 if (RD && !RD->getDeclName().getAsIdentifierInfo()) { 7691 // decltype(((Foo_IMPL*)0)->bar) * 7692 ObjCContainerDecl *CDecl = 7693 dyn_cast<ObjCContainerDecl>(D->getDeclContext()); 7694 // ivar in class extensions requires special treatment. 7695 if (ObjCCategoryDecl *CatDecl = dyn_cast<ObjCCategoryDecl>(CDecl)) 7696 CDecl = CatDecl->getClassInterface(); 7697 std::string RecName = CDecl->getName(); 7698 RecName += "_IMPL"; 7699 RecordDecl *RD = RecordDecl::Create(*Context, TTK_Struct, TUDecl, 7700 SourceLocation(), SourceLocation(), 7701 &Context->Idents.get(RecName.c_str())); 7702 QualType PtrStructIMPL = Context->getPointerType(Context->getTagDeclType(RD)); 7703 unsigned UnsignedIntSize = 7704 static_cast<unsigned>(Context->getTypeSize(Context->UnsignedIntTy)); 7705 Expr *Zero = IntegerLiteral::Create(*Context, 7706 llvm::APInt(UnsignedIntSize, 0), 7707 Context->UnsignedIntTy, SourceLocation()); 7708 Zero = NoTypeInfoCStyleCastExpr(Context, PtrStructIMPL, CK_BitCast, Zero); 7709 ParenExpr *PE = new (Context) ParenExpr(SourceLocation(), SourceLocation(), 7710 Zero); 7711 FieldDecl *FD = FieldDecl::Create(*Context, nullptr, SourceLocation(), 7712 SourceLocation(), 7713 &Context->Idents.get(D->getNameAsString()), 7714 IvarT, nullptr, 7715 /*BitWidth=*/nullptr, 7716 /*Mutable=*/true, ICIS_NoInit); 7717 MemberExpr *ME = new (Context) MemberExpr(PE, true, FD, SourceLocation(), 7718 FD->getType(), VK_LValue, 7719 OK_Ordinary); 7720 IvarT = Context->getDecltypeType(ME, ME->getType()); 7721 } 7722 } 7723 convertObjCTypeToCStyleType(IvarT); 7724 QualType castT = Context->getPointerType(IvarT); 7725 7726 castExpr = NoTypeInfoCStyleCastExpr(Context, 7727 castT, 7728 CK_BitCast, 7729 PE); 7730 7731 7732 Expr *Exp = new (Context) UnaryOperator(castExpr, UO_Deref, IvarT, 7733 VK_LValue, OK_Ordinary, 7734 SourceLocation()); 7735 PE = new (Context) ParenExpr(OldRange.getBegin(), 7736 OldRange.getEnd(), 7737 Exp); 7738 7739 if (D->isBitField()) { 7740 FieldDecl *FD = FieldDecl::Create(*Context, nullptr, SourceLocation(), 7741 SourceLocation(), 7742 &Context->Idents.get(D->getNameAsString()), 7743 D->getType(), nullptr, 7744 /*BitWidth=*/D->getBitWidth(), 7745 /*Mutable=*/true, ICIS_NoInit); 7746 MemberExpr *ME = new (Context) MemberExpr(PE, /*isArrow*/false, FD, SourceLocation(), 7747 FD->getType(), VK_LValue, 7748 OK_Ordinary); 7749 Replacement = ME; 7750 7751 } 7752 else 7753 Replacement = PE; 7754 } 7755 7756 ReplaceStmtWithRange(IV, Replacement, OldRange); 7757 return Replacement; 7758 } 7759 7760 #endif 7761