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