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