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