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