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/Lex/Lexer.h" 24#include "clang/Rewrite/Core/Rewriter.h" 25#include "llvm/ADT/DenseSet.h" 26#include "llvm/ADT/SmallPtrSet.h" 27#include "llvm/ADT/StringExtras.h" 28#include "llvm/Support/MemoryBuffer.h" 29#include "llvm/Support/raw_ostream.h" 30#include <memory> 31 32#ifdef CLANG_ENABLE_OBJC_REWRITER 33 34using namespace clang; 35using llvm::utostr; 36 37namespace { 38 class RewriteObjC : public ASTConsumer { 39 protected: 40 41 enum { 42 BLOCK_FIELD_IS_OBJECT = 3, /* id, NSObject, __attribute__((NSObject)), 43 block, ... */ 44 BLOCK_FIELD_IS_BLOCK = 7, /* a block variable */ 45 BLOCK_FIELD_IS_BYREF = 8, /* the on stack structure holding the 46 __block variable */ 47 BLOCK_FIELD_IS_WEAK = 16, /* declared __weak, only used in byref copy 48 helpers */ 49 BLOCK_BYREF_CALLER = 128, /* called from __block (byref) copy/dispose 50 support routines */ 51 BLOCK_BYREF_CURRENT_MAX = 256 52 }; 53 54 enum { 55 BLOCK_NEEDS_FREE = (1 << 24), 56 BLOCK_HAS_COPY_DISPOSE = (1 << 25), 57 BLOCK_HAS_CXX_OBJ = (1 << 26), 58 BLOCK_IS_GC = (1 << 27), 59 BLOCK_IS_GLOBAL = (1 << 28), 60 BLOCK_HAS_DESCRIPTOR = (1 << 29) 61 }; 62 static const int OBJC_ABI_VERSION = 7; 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 unsigned RewriteFailedDiag; 81 // ObjC string constant support. 82 unsigned NumObjCStringLiterals; 83 VarDecl *ConstantStringClassReference; 84 RecordDecl *NSStringRecord; 85 86 // ObjC foreach break/continue generation support. 87 int BcLabelCount; 88 89 unsigned TryFinallyContainsReturnDiag; 90 // Needed for super. 91 ObjCMethodDecl *CurMethodDef; 92 RecordDecl *SuperStructDecl; 93 RecordDecl *ConstantStringDecl; 94 95 FunctionDecl *MsgSendFunctionDecl; 96 FunctionDecl *MsgSendSuperFunctionDecl; 97 FunctionDecl *MsgSendStretFunctionDecl; 98 FunctionDecl *MsgSendSuperStretFunctionDecl; 99 FunctionDecl *MsgSendFpretFunctionDecl; 100 FunctionDecl *GetClassFunctionDecl; 101 FunctionDecl *GetMetaClassFunctionDecl; 102 FunctionDecl *GetSuperClassFunctionDecl; 103 FunctionDecl *SelGetUidFunctionDecl; 104 FunctionDecl *CFStringFunctionDecl; 105 FunctionDecl *SuperConstructorFunctionDecl; 106 FunctionDecl *CurFunctionDef; 107 FunctionDecl *CurFunctionDeclToDeclareForBlock; 108 109 /* Misc. containers needed for meta-data rewrite. */ 110 SmallVector<ObjCImplementationDecl *, 8> ClassImplementation; 111 SmallVector<ObjCCategoryImplDecl *, 8> CategoryImplementation; 112 llvm::SmallPtrSet<ObjCInterfaceDecl*, 8> ObjCSynthesizedStructs; 113 llvm::SmallPtrSet<ObjCProtocolDecl*, 8> ObjCSynthesizedProtocols; 114 llvm::SmallPtrSet<ObjCInterfaceDecl*, 8> ObjCForwardDecls; 115 llvm::DenseMap<ObjCMethodDecl*, std::string> MethodInternalNames; 116 SmallVector<Stmt *, 32> Stmts; 117 SmallVector<int, 8> ObjCBcLabelNo; 118 // Remember all the @protocol(<expr>) expressions. 119 llvm::SmallPtrSet<ObjCProtocolDecl *, 32> ProtocolExprDecls; 120 121 llvm::DenseSet<uint64_t> CopyDestroyCache; 122 123 // Block expressions. 124 SmallVector<BlockExpr *, 32> Blocks; 125 SmallVector<int, 32> InnerDeclRefsCount; 126 SmallVector<DeclRefExpr *, 32> InnerDeclRefs; 127 128 SmallVector<DeclRefExpr *, 32> BlockDeclRefs; 129 130 // Block related declarations. 131 SmallVector<ValueDecl *, 8> BlockByCopyDecls; 132 llvm::SmallPtrSet<ValueDecl *, 8> BlockByCopyDeclsPtrSet; 133 SmallVector<ValueDecl *, 8> BlockByRefDecls; 134 llvm::SmallPtrSet<ValueDecl *, 8> BlockByRefDeclsPtrSet; 135 llvm::DenseMap<ValueDecl *, unsigned> BlockByRefDeclNo; 136 llvm::SmallPtrSet<ValueDecl *, 8> ImportedBlockDecls; 137 llvm::SmallPtrSet<VarDecl *, 8> ImportedLocalExternalDecls; 138 139 llvm::DenseMap<BlockExpr *, std::string> RewrittenBlockExprs; 140 141 // This maps an original source AST to it's rewritten form. This allows 142 // us to avoid rewriting the same node twice (which is very uncommon). 143 // This is needed to support some of the exotic property rewriting. 144 llvm::DenseMap<Stmt *, Stmt *> ReplacedNodes; 145 146 // Needed for header files being rewritten 147 bool IsHeader; 148 bool SilenceRewriteMacroWarning; 149 bool objc_impl_method; 150 151 bool DisableReplaceStmt; 152 class DisableReplaceStmtScope { 153 RewriteObjC &R; 154 bool SavedValue; 155 156 public: 157 DisableReplaceStmtScope(RewriteObjC &R) 158 : R(R), SavedValue(R.DisableReplaceStmt) { 159 R.DisableReplaceStmt = true; 160 } 161 ~DisableReplaceStmtScope() { 162 R.DisableReplaceStmt = SavedValue; 163 } 164 }; 165 void InitializeCommon(ASTContext &context); 166 167 public: 168 169 // Top Level Driver code. 170 bool HandleTopLevelDecl(DeclGroupRef D) override { 171 for (DeclGroupRef::iterator I = D.begin(), E = D.end(); I != E; ++I) { 172 if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(*I)) { 173 if (!Class->isThisDeclarationADefinition()) { 174 RewriteForwardClassDecl(D); 175 break; 176 } 177 } 178 179 if (ObjCProtocolDecl *Proto = dyn_cast<ObjCProtocolDecl>(*I)) { 180 if (!Proto->isThisDeclarationADefinition()) { 181 RewriteForwardProtocolDecl(D); 182 break; 183 } 184 } 185 186 HandleTopLevelSingleDecl(*I); 187 } 188 return true; 189 } 190 void HandleTopLevelSingleDecl(Decl *D); 191 void HandleDeclInMainFile(Decl *D); 192 RewriteObjC(std::string inFile, raw_ostream *OS, 193 DiagnosticsEngine &D, const LangOptions &LOpts, 194 bool silenceMacroWarn); 195 196 ~RewriteObjC() override {} 197 198 void HandleTranslationUnit(ASTContext &C) override; 199 200 void ReplaceStmt(Stmt *Old, Stmt *New) { 201 ReplaceStmtWithRange(Old, New, Old->getSourceRange()); 202 } 203 204 void ReplaceStmtWithRange(Stmt *Old, Stmt *New, SourceRange SrcRange) { 205 assert(Old != nullptr && New != nullptr && "Expected non-null Stmt's"); 206 207 Stmt *ReplacingStmt = ReplacedNodes[Old]; 208 if (ReplacingStmt) 209 return; // We can't rewrite the same node twice. 210 211 if (DisableReplaceStmt) 212 return; 213 214 // Measure the old text. 215 int Size = Rewrite.getRangeSize(SrcRange); 216 if (Size == -1) { 217 Diags.Report(Context->getFullLoc(Old->getLocStart()), RewriteFailedDiag) 218 << Old->getSourceRange(); 219 return; 220 } 221 // Get the new text. 222 std::string SStr; 223 llvm::raw_string_ostream S(SStr); 224 New->printPretty(S, nullptr, PrintingPolicy(LangOpts)); 225 const std::string &Str = S.str(); 226 227 // If replacement succeeded or warning disabled return with no warning. 228 if (!Rewrite.ReplaceText(SrcRange.getBegin(), Size, Str)) { 229 ReplacedNodes[Old] = New; 230 return; 231 } 232 if (SilenceRewriteMacroWarning) 233 return; 234 Diags.Report(Context->getFullLoc(Old->getLocStart()), RewriteFailedDiag) 235 << Old->getSourceRange(); 236 } 237 238 void InsertText(SourceLocation Loc, StringRef Str, 239 bool InsertAfter = true) { 240 // If insertion succeeded or warning disabled return with no warning. 241 if (!Rewrite.InsertText(Loc, Str, InsertAfter) || 242 SilenceRewriteMacroWarning) 243 return; 244 245 Diags.Report(Context->getFullLoc(Loc), RewriteFailedDiag); 246 } 247 248 void ReplaceText(SourceLocation Start, unsigned OrigLength, 249 StringRef Str) { 250 // If removal succeeded or warning disabled return with no warning. 251 if (!Rewrite.ReplaceText(Start, OrigLength, Str) || 252 SilenceRewriteMacroWarning) 253 return; 254 255 Diags.Report(Context->getFullLoc(Start), RewriteFailedDiag); 256 } 257 258 // Syntactic Rewriting. 259 void RewriteRecordBody(RecordDecl *RD); 260 void RewriteInclude(); 261 void RewriteForwardClassDecl(DeclGroupRef D); 262 void RewriteForwardClassDecl(const SmallVectorImpl<Decl *> &DG); 263 void RewriteForwardClassEpilogue(ObjCInterfaceDecl *ClassDecl, 264 const std::string &typedefString); 265 void RewriteImplementations(); 266 void RewritePropertyImplDecl(ObjCPropertyImplDecl *PID, 267 ObjCImplementationDecl *IMD, 268 ObjCCategoryImplDecl *CID); 269 void RewriteInterfaceDecl(ObjCInterfaceDecl *Dcl); 270 void RewriteImplementationDecl(Decl *Dcl); 271 void RewriteObjCMethodDecl(const ObjCInterfaceDecl *IDecl, 272 ObjCMethodDecl *MDecl, std::string &ResultStr); 273 void RewriteTypeIntoString(QualType T, std::string &ResultStr, 274 const FunctionType *&FPRetType); 275 void RewriteByRefString(std::string &ResultStr, const std::string &Name, 276 ValueDecl *VD, bool def=false); 277 void RewriteCategoryDecl(ObjCCategoryDecl *Dcl); 278 void RewriteProtocolDecl(ObjCProtocolDecl *Dcl); 279 void RewriteForwardProtocolDecl(DeclGroupRef D); 280 void RewriteForwardProtocolDecl(const SmallVectorImpl<Decl *> &DG); 281 void RewriteMethodDeclaration(ObjCMethodDecl *Method); 282 void RewriteProperty(ObjCPropertyDecl *prop); 283 void RewriteFunctionDecl(FunctionDecl *FD); 284 void RewriteBlockPointerType(std::string& Str, QualType Type); 285 void RewriteBlockPointerTypeVariable(std::string& Str, ValueDecl *VD); 286 void RewriteBlockLiteralFunctionDecl(FunctionDecl *FD); 287 void RewriteObjCQualifiedInterfaceTypes(Decl *Dcl); 288 void RewriteTypeOfDecl(VarDecl *VD); 289 void RewriteObjCQualifiedInterfaceTypes(Expr *E); 290 291 // Expression Rewriting. 292 Stmt *RewriteFunctionBodyOrGlobalInitializer(Stmt *S); 293 Stmt *RewriteAtEncode(ObjCEncodeExpr *Exp); 294 Stmt *RewritePropertyOrImplicitGetter(PseudoObjectExpr *Pseudo); 295 Stmt *RewritePropertyOrImplicitSetter(PseudoObjectExpr *Pseudo); 296 Stmt *RewriteAtSelector(ObjCSelectorExpr *Exp); 297 Stmt *RewriteMessageExpr(ObjCMessageExpr *Exp); 298 Stmt *RewriteObjCStringLiteral(ObjCStringLiteral *Exp); 299 Stmt *RewriteObjCProtocolExpr(ObjCProtocolExpr *Exp); 300 void RewriteTryReturnStmts(Stmt *S); 301 void RewriteSyncReturnStmts(Stmt *S, std::string buf); 302 Stmt *RewriteObjCTryStmt(ObjCAtTryStmt *S); 303 Stmt *RewriteObjCSynchronizedStmt(ObjCAtSynchronizedStmt *S); 304 Stmt *RewriteObjCThrowStmt(ObjCAtThrowStmt *S); 305 Stmt *RewriteObjCForCollectionStmt(ObjCForCollectionStmt *S, 306 SourceLocation OrigEnd); 307 Stmt *RewriteBreakStmt(BreakStmt *S); 308 Stmt *RewriteContinueStmt(ContinueStmt *S); 309 void RewriteCastExpr(CStyleCastExpr *CE); 310 311 // Block rewriting. 312 void RewriteBlocksInFunctionProtoType(QualType funcType, NamedDecl *D); 313 314 // Block specific rewrite rules. 315 void RewriteBlockPointerDecl(NamedDecl *VD); 316 void RewriteByRefVar(VarDecl *VD); 317 Stmt *RewriteBlockDeclRefExpr(DeclRefExpr *VD); 318 Stmt *RewriteLocalVariableExternalStorage(DeclRefExpr *DRE); 319 void RewriteBlockPointerFunctionArgs(FunctionDecl *FD); 320 321 void RewriteObjCInternalStruct(ObjCInterfaceDecl *CDecl, 322 std::string &Result); 323 324 void Initialize(ASTContext &context) override = 0; 325 326 // Metadata Rewriting. 327 virtual void RewriteMetaDataIntoBuffer(std::string &Result) = 0; 328 virtual void RewriteObjCProtocolListMetaData(const ObjCList<ObjCProtocolDecl> &Prots, 329 StringRef prefix, 330 StringRef ClassName, 331 std::string &Result) = 0; 332 virtual void RewriteObjCCategoryImplDecl(ObjCCategoryImplDecl *CDecl, 333 std::string &Result) = 0; 334 virtual void RewriteObjCProtocolMetaData(ObjCProtocolDecl *Protocol, 335 StringRef prefix, 336 StringRef ClassName, 337 std::string &Result) = 0; 338 virtual void RewriteObjCClassMetaData(ObjCImplementationDecl *IDecl, 339 std::string &Result) = 0; 340 341 // Rewriting ivar access 342 virtual Stmt *RewriteObjCIvarRefExpr(ObjCIvarRefExpr *IV) = 0; 343 virtual void RewriteIvarOffsetComputation(ObjCIvarDecl *ivar, 344 std::string &Result) = 0; 345 346 // Misc. AST transformation routines. Sometimes they end up calling 347 // rewriting routines on the new ASTs. 348 CallExpr *SynthesizeCallToFunctionDecl(FunctionDecl *FD, 349 Expr **args, unsigned nargs, 350 SourceLocation StartLoc=SourceLocation(), 351 SourceLocation EndLoc=SourceLocation()); 352 CallExpr *SynthMsgSendStretCallExpr(FunctionDecl *MsgSendStretFlavor, 353 QualType msgSendType, 354 QualType returnType, 355 SmallVectorImpl<QualType> &ArgTypes, 356 SmallVectorImpl<Expr*> &MsgExprs, 357 ObjCMethodDecl *Method); 358 Stmt *SynthMessageExpr(ObjCMessageExpr *Exp, 359 SourceLocation StartLoc=SourceLocation(), 360 SourceLocation EndLoc=SourceLocation()); 361 362 void SynthCountByEnumWithState(std::string &buf); 363 void SynthMsgSendFunctionDecl(); 364 void SynthMsgSendSuperFunctionDecl(); 365 void SynthMsgSendStretFunctionDecl(); 366 void SynthMsgSendFpretFunctionDecl(); 367 void SynthMsgSendSuperStretFunctionDecl(); 368 void SynthGetClassFunctionDecl(); 369 void SynthGetMetaClassFunctionDecl(); 370 void SynthGetSuperClassFunctionDecl(); 371 void SynthSelGetUidFunctionDecl(); 372 void SynthSuperConstructorFunctionDecl(); 373 374 std::string SynthesizeByrefCopyDestroyHelper(VarDecl *VD, int flag); 375 std::string SynthesizeBlockHelperFuncs(BlockExpr *CE, int i, 376 StringRef funcName, std::string Tag); 377 std::string SynthesizeBlockFunc(BlockExpr *CE, int i, 378 StringRef funcName, std::string Tag); 379 std::string SynthesizeBlockImpl(BlockExpr *CE, 380 std::string Tag, std::string Desc); 381 std::string SynthesizeBlockDescriptor(std::string DescTag, 382 std::string ImplTag, 383 int i, StringRef funcName, 384 unsigned hasCopy); 385 Stmt *SynthesizeBlockCall(CallExpr *Exp, const Expr* BlockExp); 386 void SynthesizeBlockLiterals(SourceLocation FunLocStart, 387 StringRef FunName); 388 FunctionDecl *SynthBlockInitFunctionDecl(StringRef name); 389 Stmt *SynthBlockInitExpr(BlockExpr *Exp, 390 const SmallVectorImpl<DeclRefExpr *> &InnerBlockDeclRefs); 391 392 // Misc. helper routines. 393 QualType getProtocolType(); 394 void WarnAboutReturnGotoStmts(Stmt *S); 395 void HasReturnStmts(Stmt *S, bool &hasReturns); 396 void CheckFunctionPointerDecl(QualType dType, NamedDecl *ND); 397 void InsertBlockLiteralsWithinFunction(FunctionDecl *FD); 398 void InsertBlockLiteralsWithinMethod(ObjCMethodDecl *MD); 399 400 bool IsDeclStmtInForeachHeader(DeclStmt *DS); 401 void CollectBlockDeclRefInfo(BlockExpr *Exp); 402 void GetBlockDeclRefExprs(Stmt *S); 403 void GetInnerBlockDeclRefExprs(Stmt *S, 404 SmallVectorImpl<DeclRefExpr *> &InnerBlockDeclRefs, 405 llvm::SmallPtrSetImpl<const DeclContext *> &InnerContexts); 406 407 // We avoid calling Type::isBlockPointerType(), since it operates on the 408 // canonical type. We only care if the top-level type is a closure pointer. 409 bool isTopLevelBlockPointerType(QualType T) { 410 return isa<BlockPointerType>(T); 411 } 412 413 /// convertBlockPointerToFunctionPointer - Converts a block-pointer type 414 /// to a function pointer type and upon success, returns true; false 415 /// otherwise. 416 bool convertBlockPointerToFunctionPointer(QualType &T) { 417 if (isTopLevelBlockPointerType(T)) { 418 const BlockPointerType *BPT = T->getAs<BlockPointerType>(); 419 T = Context->getPointerType(BPT->getPointeeType()); 420 return true; 421 } 422 return false; 423 } 424 425 bool needToScanForQualifiers(QualType T); 426 QualType getSuperStructType(); 427 QualType getConstantStringStructType(); 428 QualType convertFunctionTypeOfBlocks(const FunctionType *FT); 429 bool BufferContainsPPDirectives(const char *startBuf, const char *endBuf); 430 431 void convertToUnqualifiedObjCType(QualType &T) { 432 if (T->isObjCQualifiedIdType()) 433 T = Context->getObjCIdType(); 434 else if (T->isObjCQualifiedClassType()) 435 T = Context->getObjCClassType(); 436 else if (T->isObjCObjectPointerType() && 437 T->getPointeeType()->isObjCQualifiedInterfaceType()) { 438 if (const ObjCObjectPointerType * OBJPT = 439 T->getAsObjCInterfacePointerType()) { 440 const ObjCInterfaceType *IFaceT = OBJPT->getInterfaceType(); 441 T = QualType(IFaceT, 0); 442 T = Context->getPointerType(T); 443 } 444 } 445 } 446 447 // FIXME: This predicate seems like it would be useful to add to ASTContext. 448 bool isObjCType(QualType T) { 449 if (!LangOpts.ObjC1 && !LangOpts.ObjC2) 450 return false; 451 452 QualType OCT = Context->getCanonicalType(T).getUnqualifiedType(); 453 454 if (OCT == Context->getCanonicalType(Context->getObjCIdType()) || 455 OCT == Context->getCanonicalType(Context->getObjCClassType())) 456 return true; 457 458 if (const PointerType *PT = OCT->getAs<PointerType>()) { 459 if (isa<ObjCInterfaceType>(PT->getPointeeType()) || 460 PT->getPointeeType()->isObjCQualifiedIdType()) 461 return true; 462 } 463 return false; 464 } 465 bool PointerTypeTakesAnyBlockArguments(QualType QT); 466 bool PointerTypeTakesAnyObjCQualifiedType(QualType QT); 467 void GetExtentOfArgList(const char *Name, const char *&LParen, 468 const char *&RParen); 469 470 void QuoteDoublequotes(std::string &From, std::string &To) { 471 for (unsigned i = 0; i < From.length(); i++) { 472 if (From[i] == '"') 473 To += "\\\""; 474 else 475 To += From[i]; 476 } 477 } 478 479 QualType getSimpleFunctionType(QualType result, 480 ArrayRef<QualType> args, 481 bool variadic = false) { 482 if (result == Context->getObjCInstanceType()) 483 result = Context->getObjCIdType(); 484 FunctionProtoType::ExtProtoInfo fpi; 485 fpi.Variadic = variadic; 486 return Context->getFunctionType(result, args, fpi); 487 } 488 489 // Helper function: create a CStyleCastExpr with trivial type source info. 490 CStyleCastExpr* NoTypeInfoCStyleCastExpr(ASTContext *Ctx, QualType Ty, 491 CastKind Kind, Expr *E) { 492 TypeSourceInfo *TInfo = Ctx->getTrivialTypeSourceInfo(Ty, SourceLocation()); 493 return CStyleCastExpr::Create(*Ctx, Ty, VK_RValue, Kind, E, nullptr, 494 TInfo, SourceLocation(), SourceLocation()); 495 } 496 497 StringLiteral *getStringLiteral(StringRef Str) { 498 QualType StrType = Context->getConstantArrayType( 499 Context->CharTy, llvm::APInt(32, Str.size() + 1), ArrayType::Normal, 500 0); 501 return StringLiteral::Create(*Context, Str, StringLiteral::Ascii, 502 /*Pascal=*/false, StrType, SourceLocation()); 503 } 504 }; 505 506 class RewriteObjCFragileABI : public RewriteObjC { 507 public: 508 509 RewriteObjCFragileABI(std::string inFile, raw_ostream *OS, 510 DiagnosticsEngine &D, const LangOptions &LOpts, 511 bool silenceMacroWarn) : RewriteObjC(inFile, OS, 512 D, LOpts, 513 silenceMacroWarn) {} 514 515 ~RewriteObjCFragileABI() override {} 516 void Initialize(ASTContext &context) override; 517 518 // Rewriting metadata 519 template<typename MethodIterator> 520 void RewriteObjCMethodsMetaData(MethodIterator MethodBegin, 521 MethodIterator MethodEnd, 522 bool IsInstanceMethod, 523 StringRef prefix, 524 StringRef ClassName, 525 std::string &Result); 526 void RewriteObjCProtocolMetaData(ObjCProtocolDecl *Protocol, 527 StringRef prefix, StringRef ClassName, 528 std::string &Result) override; 529 void RewriteObjCProtocolListMetaData( 530 const ObjCList<ObjCProtocolDecl> &Prots, 531 StringRef prefix, StringRef ClassName, std::string &Result) override; 532 void RewriteObjCClassMetaData(ObjCImplementationDecl *IDecl, 533 std::string &Result) override; 534 void RewriteMetaDataIntoBuffer(std::string &Result) override; 535 void RewriteObjCCategoryImplDecl(ObjCCategoryImplDecl *CDecl, 536 std::string &Result) override; 537 538 // Rewriting ivar 539 void RewriteIvarOffsetComputation(ObjCIvarDecl *ivar, 540 std::string &Result) override; 541 Stmt *RewriteObjCIvarRefExpr(ObjCIvarRefExpr *IV) override; 542 }; 543} 544 545void RewriteObjC::RewriteBlocksInFunctionProtoType(QualType funcType, 546 NamedDecl *D) { 547 if (const FunctionProtoType *fproto 548 = dyn_cast<FunctionProtoType>(funcType.IgnoreParens())) { 549 for (const auto &I : fproto->param_types()) 550 if (isTopLevelBlockPointerType(I)) { 551 // All the args are checked/rewritten. Don't call twice! 552 RewriteBlockPointerDecl(D); 553 break; 554 } 555 } 556} 557 558void RewriteObjC::CheckFunctionPointerDecl(QualType funcType, NamedDecl *ND) { 559 const PointerType *PT = funcType->getAs<PointerType>(); 560 if (PT && PointerTypeTakesAnyBlockArguments(funcType)) 561 RewriteBlocksInFunctionProtoType(PT->getPointeeType(), ND); 562} 563 564static bool IsHeaderFile(const std::string &Filename) { 565 std::string::size_type DotPos = Filename.rfind('.'); 566 567 if (DotPos == std::string::npos) { 568 // no file extension 569 return false; 570 } 571 572 std::string Ext = std::string(Filename.begin()+DotPos+1, Filename.end()); 573 // C header: .h 574 // C++ header: .hh or .H; 575 return Ext == "h" || Ext == "hh" || Ext == "H"; 576} 577 578RewriteObjC::RewriteObjC(std::string inFile, raw_ostream* OS, 579 DiagnosticsEngine &D, const LangOptions &LOpts, 580 bool silenceMacroWarn) 581 : Diags(D), LangOpts(LOpts), InFileName(inFile), OutFile(OS), 582 SilenceRewriteMacroWarning(silenceMacroWarn) { 583 IsHeader = IsHeaderFile(inFile); 584 RewriteFailedDiag = Diags.getCustomDiagID(DiagnosticsEngine::Warning, 585 "rewriting sub-expression within a macro (may not be correct)"); 586 TryFinallyContainsReturnDiag = Diags.getCustomDiagID( 587 DiagnosticsEngine::Warning, 588 "rewriter doesn't support user-specified control flow semantics " 589 "for @try/@finally (code may not execute properly)"); 590} 591 592std::unique_ptr<ASTConsumer> 593clang::CreateObjCRewriter(const std::string &InFile, raw_ostream *OS, 594 DiagnosticsEngine &Diags, const LangOptions &LOpts, 595 bool SilenceRewriteMacroWarning) { 596 return llvm::make_unique<RewriteObjCFragileABI>(InFile, OS, Diags, LOpts, 597 SilenceRewriteMacroWarning); 598} 599 600void RewriteObjC::InitializeCommon(ASTContext &context) { 601 Context = &context; 602 SM = &Context->getSourceManager(); 603 TUDecl = Context->getTranslationUnitDecl(); 604 MsgSendFunctionDecl = nullptr; 605 MsgSendSuperFunctionDecl = nullptr; 606 MsgSendStretFunctionDecl = nullptr; 607 MsgSendSuperStretFunctionDecl = nullptr; 608 MsgSendFpretFunctionDecl = nullptr; 609 GetClassFunctionDecl = nullptr; 610 GetMetaClassFunctionDecl = nullptr; 611 GetSuperClassFunctionDecl = nullptr; 612 SelGetUidFunctionDecl = nullptr; 613 CFStringFunctionDecl = nullptr; 614 ConstantStringClassReference = nullptr; 615 NSStringRecord = nullptr; 616 CurMethodDef = nullptr; 617 CurFunctionDef = nullptr; 618 CurFunctionDeclToDeclareForBlock = nullptr; 619 GlobalVarDecl = nullptr; 620 SuperStructDecl = nullptr; 621 ProtocolTypeDecl = nullptr; 622 ConstantStringDecl = nullptr; 623 BcLabelCount = 0; 624 SuperConstructorFunctionDecl = nullptr; 625 NumObjCStringLiterals = 0; 626 PropParentMap = nullptr; 627 CurrentBody = nullptr; 628 DisableReplaceStmt = false; 629 objc_impl_method = false; 630 631 // Get the ID and start/end of the main file. 632 MainFileID = SM->getMainFileID(); 633 const llvm::MemoryBuffer *MainBuf = SM->getBuffer(MainFileID); 634 MainFileStart = MainBuf->getBufferStart(); 635 MainFileEnd = MainBuf->getBufferEnd(); 636 637 Rewrite.setSourceMgr(Context->getSourceManager(), Context->getLangOpts()); 638} 639 640//===----------------------------------------------------------------------===// 641// Top Level Driver Code 642//===----------------------------------------------------------------------===// 643 644void RewriteObjC::HandleTopLevelSingleDecl(Decl *D) { 645 if (Diags.hasErrorOccurred()) 646 return; 647 648 // Two cases: either the decl could be in the main file, or it could be in a 649 // #included file. If the former, rewrite it now. If the later, check to see 650 // if we rewrote the #include/#import. 651 SourceLocation Loc = D->getLocation(); 652 Loc = SM->getExpansionLoc(Loc); 653 654 // If this is for a builtin, ignore it. 655 if (Loc.isInvalid()) return; 656 657 // Look for built-in declarations that we need to refer during the rewrite. 658 if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { 659 RewriteFunctionDecl(FD); 660 } else if (VarDecl *FVD = dyn_cast<VarDecl>(D)) { 661 // declared in <Foundation/NSString.h> 662 if (FVD->getName() == "_NSConstantStringClassReference") { 663 ConstantStringClassReference = FVD; 664 return; 665 } 666 } else if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(D)) { 667 if (ID->isThisDeclarationADefinition()) 668 RewriteInterfaceDecl(ID); 669 } else if (ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(D)) { 670 RewriteCategoryDecl(CD); 671 } else if (ObjCProtocolDecl *PD = dyn_cast<ObjCProtocolDecl>(D)) { 672 if (PD->isThisDeclarationADefinition()) 673 RewriteProtocolDecl(PD); 674 } else if (LinkageSpecDecl *LSD = dyn_cast<LinkageSpecDecl>(D)) { 675 // Recurse into linkage specifications 676 for (DeclContext::decl_iterator DI = LSD->decls_begin(), 677 DIEnd = LSD->decls_end(); 678 DI != DIEnd; ) { 679 if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>((*DI))) { 680 if (!IFace->isThisDeclarationADefinition()) { 681 SmallVector<Decl *, 8> DG; 682 SourceLocation StartLoc = IFace->getLocStart(); 683 do { 684 if (isa<ObjCInterfaceDecl>(*DI) && 685 !cast<ObjCInterfaceDecl>(*DI)->isThisDeclarationADefinition() && 686 StartLoc == (*DI)->getLocStart()) 687 DG.push_back(*DI); 688 else 689 break; 690 691 ++DI; 692 } while (DI != DIEnd); 693 RewriteForwardClassDecl(DG); 694 continue; 695 } 696 } 697 698 if (ObjCProtocolDecl *Proto = dyn_cast<ObjCProtocolDecl>((*DI))) { 699 if (!Proto->isThisDeclarationADefinition()) { 700 SmallVector<Decl *, 8> DG; 701 SourceLocation StartLoc = Proto->getLocStart(); 702 do { 703 if (isa<ObjCProtocolDecl>(*DI) && 704 !cast<ObjCProtocolDecl>(*DI)->isThisDeclarationADefinition() && 705 StartLoc == (*DI)->getLocStart()) 706 DG.push_back(*DI); 707 else 708 break; 709 710 ++DI; 711 } while (DI != DIEnd); 712 RewriteForwardProtocolDecl(DG); 713 continue; 714 } 715 } 716 717 HandleTopLevelSingleDecl(*DI); 718 ++DI; 719 } 720 } 721 // If we have a decl in the main file, see if we should rewrite it. 722 if (SM->isWrittenInMainFile(Loc)) 723 return HandleDeclInMainFile(D); 724} 725 726//===----------------------------------------------------------------------===// 727// Syntactic (non-AST) Rewriting Code 728//===----------------------------------------------------------------------===// 729 730void RewriteObjC::RewriteInclude() { 731 SourceLocation LocStart = SM->getLocForStartOfFile(MainFileID); 732 StringRef MainBuf = SM->getBufferData(MainFileID); 733 const char *MainBufStart = MainBuf.begin(); 734 const char *MainBufEnd = MainBuf.end(); 735 size_t ImportLen = strlen("import"); 736 737 // Loop over the whole file, looking for includes. 738 for (const char *BufPtr = MainBufStart; BufPtr < MainBufEnd; ++BufPtr) { 739 if (*BufPtr == '#') { 740 if (++BufPtr == MainBufEnd) 741 return; 742 while (*BufPtr == ' ' || *BufPtr == '\t') 743 if (++BufPtr == MainBufEnd) 744 return; 745 if (!strncmp(BufPtr, "import", ImportLen)) { 746 // replace import with include 747 SourceLocation ImportLoc = 748 LocStart.getLocWithOffset(BufPtr-MainBufStart); 749 ReplaceText(ImportLoc, ImportLen, "include"); 750 BufPtr += ImportLen; 751 } 752 } 753 } 754} 755 756static std::string getIvarAccessString(ObjCIvarDecl *OID) { 757 const ObjCInterfaceDecl *ClassDecl = OID->getContainingInterface(); 758 std::string S; 759 S = "((struct "; 760 S += ClassDecl->getIdentifier()->getName(); 761 S += "_IMPL *)self)->"; 762 S += OID->getName(); 763 return S; 764} 765 766void RewriteObjC::RewritePropertyImplDecl(ObjCPropertyImplDecl *PID, 767 ObjCImplementationDecl *IMD, 768 ObjCCategoryImplDecl *CID) { 769 static bool objcGetPropertyDefined = false; 770 static bool objcSetPropertyDefined = false; 771 SourceLocation startLoc = PID->getLocStart(); 772 InsertText(startLoc, "// "); 773 const char *startBuf = SM->getCharacterData(startLoc); 774 assert((*startBuf == '@') && "bogus @synthesize location"); 775 const char *semiBuf = strchr(startBuf, ';'); 776 assert((*semiBuf == ';') && "@synthesize: can't find ';'"); 777 SourceLocation onePastSemiLoc = 778 startLoc.getLocWithOffset(semiBuf-startBuf+1); 779 780 if (PID->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic) 781 return; // FIXME: is this correct? 782 783 // Generate the 'getter' function. 784 ObjCPropertyDecl *PD = PID->getPropertyDecl(); 785 ObjCIvarDecl *OID = PID->getPropertyIvarDecl(); 786 787 if (!OID) 788 return; 789 unsigned Attributes = PD->getPropertyAttributes(); 790 if (!PD->getGetterMethodDecl()->isDefined()) { 791 bool GenGetProperty = !(Attributes & ObjCPropertyDecl::OBJC_PR_nonatomic) && 792 (Attributes & (ObjCPropertyDecl::OBJC_PR_retain | 793 ObjCPropertyDecl::OBJC_PR_copy)); 794 std::string Getr; 795 if (GenGetProperty && !objcGetPropertyDefined) { 796 objcGetPropertyDefined = true; 797 // FIXME. Is this attribute correct in all cases? 798 Getr = "\nextern \"C\" __declspec(dllimport) " 799 "id objc_getProperty(id, SEL, long, bool);\n"; 800 } 801 RewriteObjCMethodDecl(OID->getContainingInterface(), 802 PD->getGetterMethodDecl(), Getr); 803 Getr += "{ "; 804 // Synthesize an explicit cast to gain access to the ivar. 805 // See objc-act.c:objc_synthesize_new_getter() for details. 806 if (GenGetProperty) { 807 // return objc_getProperty(self, _cmd, offsetof(ClassDecl, OID), 1) 808 Getr += "typedef "; 809 const FunctionType *FPRetType = nullptr; 810 RewriteTypeIntoString(PD->getGetterMethodDecl()->getReturnType(), Getr, 811 FPRetType); 812 Getr += " _TYPE"; 813 if (FPRetType) { 814 Getr += ")"; // close the precedence "scope" for "*". 815 816 // Now, emit the argument types (if any). 817 if (const FunctionProtoType *FT = dyn_cast<FunctionProtoType>(FPRetType)){ 818 Getr += "("; 819 for (unsigned i = 0, e = FT->getNumParams(); i != e; ++i) { 820 if (i) Getr += ", "; 821 std::string ParamStr = 822 FT->getParamType(i).getAsString(Context->getPrintingPolicy()); 823 Getr += ParamStr; 824 } 825 if (FT->isVariadic()) { 826 if (FT->getNumParams()) 827 Getr += ", "; 828 Getr += "..."; 829 } 830 Getr += ")"; 831 } else 832 Getr += "()"; 833 } 834 Getr += ";\n"; 835 Getr += "return (_TYPE)"; 836 Getr += "objc_getProperty(self, _cmd, "; 837 RewriteIvarOffsetComputation(OID, Getr); 838 Getr += ", 1)"; 839 } 840 else 841 Getr += "return " + getIvarAccessString(OID); 842 Getr += "; }"; 843 InsertText(onePastSemiLoc, Getr); 844 } 845 846 if (PD->isReadOnly() || PD->getSetterMethodDecl()->isDefined()) 847 return; 848 849 // Generate the 'setter' function. 850 std::string Setr; 851 bool GenSetProperty = Attributes & (ObjCPropertyDecl::OBJC_PR_retain | 852 ObjCPropertyDecl::OBJC_PR_copy); 853 if (GenSetProperty && !objcSetPropertyDefined) { 854 objcSetPropertyDefined = true; 855 // FIXME. Is this attribute correct in all cases? 856 Setr = "\nextern \"C\" __declspec(dllimport) " 857 "void objc_setProperty (id, SEL, long, id, bool, bool);\n"; 858 } 859 860 RewriteObjCMethodDecl(OID->getContainingInterface(), 861 PD->getSetterMethodDecl(), Setr); 862 Setr += "{ "; 863 // Synthesize an explicit cast to initialize the ivar. 864 // See objc-act.c:objc_synthesize_new_setter() for details. 865 if (GenSetProperty) { 866 Setr += "objc_setProperty (self, _cmd, "; 867 RewriteIvarOffsetComputation(OID, Setr); 868 Setr += ", (id)"; 869 Setr += PD->getName(); 870 Setr += ", "; 871 if (Attributes & ObjCPropertyDecl::OBJC_PR_nonatomic) 872 Setr += "0, "; 873 else 874 Setr += "1, "; 875 if (Attributes & ObjCPropertyDecl::OBJC_PR_copy) 876 Setr += "1)"; 877 else 878 Setr += "0)"; 879 } 880 else { 881 Setr += getIvarAccessString(OID) + " = "; 882 Setr += PD->getName(); 883 } 884 Setr += "; }"; 885 InsertText(onePastSemiLoc, Setr); 886} 887 888static void RewriteOneForwardClassDecl(ObjCInterfaceDecl *ForwardDecl, 889 std::string &typedefString) { 890 typedefString += "#ifndef _REWRITER_typedef_"; 891 typedefString += ForwardDecl->getNameAsString(); 892 typedefString += "\n"; 893 typedefString += "#define _REWRITER_typedef_"; 894 typedefString += ForwardDecl->getNameAsString(); 895 typedefString += "\n"; 896 typedefString += "typedef struct objc_object "; 897 typedefString += ForwardDecl->getNameAsString(); 898 typedefString += ";\n#endif\n"; 899} 900 901void RewriteObjC::RewriteForwardClassEpilogue(ObjCInterfaceDecl *ClassDecl, 902 const std::string &typedefString) { 903 SourceLocation startLoc = ClassDecl->getLocStart(); 904 const char *startBuf = SM->getCharacterData(startLoc); 905 const char *semiPtr = strchr(startBuf, ';'); 906 // Replace the @class with typedefs corresponding to the classes. 907 ReplaceText(startLoc, semiPtr-startBuf+1, typedefString); 908} 909 910void RewriteObjC::RewriteForwardClassDecl(DeclGroupRef D) { 911 std::string typedefString; 912 for (DeclGroupRef::iterator I = D.begin(), E = D.end(); I != E; ++I) { 913 ObjCInterfaceDecl *ForwardDecl = cast<ObjCInterfaceDecl>(*I); 914 if (I == D.begin()) { 915 // Translate to typedef's that forward reference structs with the same name 916 // as the class. As a convenience, we include the original declaration 917 // as a comment. 918 typedefString += "// @class "; 919 typedefString += ForwardDecl->getNameAsString(); 920 typedefString += ";\n"; 921 } 922 RewriteOneForwardClassDecl(ForwardDecl, typedefString); 923 } 924 DeclGroupRef::iterator I = D.begin(); 925 RewriteForwardClassEpilogue(cast<ObjCInterfaceDecl>(*I), typedefString); 926} 927 928void RewriteObjC::RewriteForwardClassDecl(const SmallVectorImpl<Decl *> &D) { 929 std::string typedefString; 930 for (unsigned i = 0; i < D.size(); i++) { 931 ObjCInterfaceDecl *ForwardDecl = cast<ObjCInterfaceDecl>(D[i]); 932 if (i == 0) { 933 typedefString += "// @class "; 934 typedefString += ForwardDecl->getNameAsString(); 935 typedefString += ";\n"; 936 } 937 RewriteOneForwardClassDecl(ForwardDecl, typedefString); 938 } 939 RewriteForwardClassEpilogue(cast<ObjCInterfaceDecl>(D[0]), typedefString); 940} 941 942void RewriteObjC::RewriteMethodDeclaration(ObjCMethodDecl *Method) { 943 // When method is a synthesized one, such as a getter/setter there is 944 // nothing to rewrite. 945 if (Method->isImplicit()) 946 return; 947 SourceLocation LocStart = Method->getLocStart(); 948 SourceLocation LocEnd = Method->getLocEnd(); 949 950 if (SM->getExpansionLineNumber(LocEnd) > 951 SM->getExpansionLineNumber(LocStart)) { 952 InsertText(LocStart, "#if 0\n"); 953 ReplaceText(LocEnd, 1, ";\n#endif\n"); 954 } else { 955 InsertText(LocStart, "// "); 956 } 957} 958 959void RewriteObjC::RewriteProperty(ObjCPropertyDecl *prop) { 960 SourceLocation Loc = prop->getAtLoc(); 961 962 ReplaceText(Loc, 0, "// "); 963 // FIXME: handle properties that are declared across multiple lines. 964} 965 966void RewriteObjC::RewriteCategoryDecl(ObjCCategoryDecl *CatDecl) { 967 SourceLocation LocStart = CatDecl->getLocStart(); 968 969 // FIXME: handle category headers that are declared across multiple lines. 970 ReplaceText(LocStart, 0, "// "); 971 972 for (auto *I : CatDecl->properties()) 973 RewriteProperty(I); 974 for (auto *I : CatDecl->instance_methods()) 975 RewriteMethodDeclaration(I); 976 for (auto *I : CatDecl->class_methods()) 977 RewriteMethodDeclaration(I); 978 979 // Lastly, comment out the @end. 980 ReplaceText(CatDecl->getAtEndRange().getBegin(), 981 strlen("@end"), "/* @end */"); 982} 983 984void RewriteObjC::RewriteProtocolDecl(ObjCProtocolDecl *PDecl) { 985 SourceLocation LocStart = PDecl->getLocStart(); 986 assert(PDecl->isThisDeclarationADefinition()); 987 988 // FIXME: handle protocol headers that are declared across multiple lines. 989 ReplaceText(LocStart, 0, "// "); 990 991 for (auto *I : PDecl->instance_methods()) 992 RewriteMethodDeclaration(I); 993 for (auto *I : PDecl->class_methods()) 994 RewriteMethodDeclaration(I); 995 for (auto *I : PDecl->properties()) 996 RewriteProperty(I); 997 998 // Lastly, comment out the @end. 999 SourceLocation LocEnd = PDecl->getAtEndRange().getBegin(); 1000 ReplaceText(LocEnd, strlen("@end"), "/* @end */"); 1001 1002 // Must comment out @optional/@required 1003 const char *startBuf = SM->getCharacterData(LocStart); 1004 const char *endBuf = SM->getCharacterData(LocEnd); 1005 for (const char *p = startBuf; p < endBuf; p++) { 1006 if (*p == '@' && !strncmp(p+1, "optional", strlen("optional"))) { 1007 SourceLocation OptionalLoc = LocStart.getLocWithOffset(p-startBuf); 1008 ReplaceText(OptionalLoc, strlen("@optional"), "/* @optional */"); 1009 1010 } 1011 else if (*p == '@' && !strncmp(p+1, "required", strlen("required"))) { 1012 SourceLocation OptionalLoc = LocStart.getLocWithOffset(p-startBuf); 1013 ReplaceText(OptionalLoc, strlen("@required"), "/* @required */"); 1014 1015 } 1016 } 1017} 1018 1019void RewriteObjC::RewriteForwardProtocolDecl(DeclGroupRef D) { 1020 SourceLocation LocStart = (*D.begin())->getLocStart(); 1021 if (LocStart.isInvalid()) 1022 llvm_unreachable("Invalid SourceLocation"); 1023 // FIXME: handle forward protocol that are declared across multiple lines. 1024 ReplaceText(LocStart, 0, "// "); 1025} 1026 1027void 1028RewriteObjC::RewriteForwardProtocolDecl(const SmallVectorImpl<Decl *> &DG) { 1029 SourceLocation LocStart = DG[0]->getLocStart(); 1030 if (LocStart.isInvalid()) 1031 llvm_unreachable("Invalid SourceLocation"); 1032 // FIXME: handle forward protocol that are declared across multiple lines. 1033 ReplaceText(LocStart, 0, "// "); 1034} 1035 1036void RewriteObjC::RewriteTypeIntoString(QualType T, std::string &ResultStr, 1037 const FunctionType *&FPRetType) { 1038 if (T->isObjCQualifiedIdType()) 1039 ResultStr += "id"; 1040 else if (T->isFunctionPointerType() || 1041 T->isBlockPointerType()) { 1042 // needs special handling, since pointer-to-functions have special 1043 // syntax (where a decaration models use). 1044 QualType retType = T; 1045 QualType PointeeTy; 1046 if (const PointerType* PT = retType->getAs<PointerType>()) 1047 PointeeTy = PT->getPointeeType(); 1048 else if (const BlockPointerType *BPT = retType->getAs<BlockPointerType>()) 1049 PointeeTy = BPT->getPointeeType(); 1050 if ((FPRetType = PointeeTy->getAs<FunctionType>())) { 1051 ResultStr += 1052 FPRetType->getReturnType().getAsString(Context->getPrintingPolicy()); 1053 ResultStr += "(*"; 1054 } 1055 } else 1056 ResultStr += T.getAsString(Context->getPrintingPolicy()); 1057} 1058 1059void RewriteObjC::RewriteObjCMethodDecl(const ObjCInterfaceDecl *IDecl, 1060 ObjCMethodDecl *OMD, 1061 std::string &ResultStr) { 1062 //fprintf(stderr,"In RewriteObjCMethodDecl\n"); 1063 const FunctionType *FPRetType = nullptr; 1064 ResultStr += "\nstatic "; 1065 RewriteTypeIntoString(OMD->getReturnType(), ResultStr, FPRetType); 1066 ResultStr += " "; 1067 1068 // Unique method name 1069 std::string NameStr; 1070 1071 if (OMD->isInstanceMethod()) 1072 NameStr += "_I_"; 1073 else 1074 NameStr += "_C_"; 1075 1076 NameStr += IDecl->getNameAsString(); 1077 NameStr += "_"; 1078 1079 if (ObjCCategoryImplDecl *CID = 1080 dyn_cast<ObjCCategoryImplDecl>(OMD->getDeclContext())) { 1081 NameStr += CID->getNameAsString(); 1082 NameStr += "_"; 1083 } 1084 // Append selector names, replacing ':' with '_' 1085 { 1086 std::string selString = OMD->getSelector().getAsString(); 1087 int len = selString.size(); 1088 for (int i = 0; i < len; i++) 1089 if (selString[i] == ':') 1090 selString[i] = '_'; 1091 NameStr += selString; 1092 } 1093 // Remember this name for metadata emission 1094 MethodInternalNames[OMD] = NameStr; 1095 ResultStr += NameStr; 1096 1097 // Rewrite arguments 1098 ResultStr += "("; 1099 1100 // invisible arguments 1101 if (OMD->isInstanceMethod()) { 1102 QualType selfTy = Context->getObjCInterfaceType(IDecl); 1103 selfTy = Context->getPointerType(selfTy); 1104 if (!LangOpts.MicrosoftExt) { 1105 if (ObjCSynthesizedStructs.count(const_cast<ObjCInterfaceDecl*>(IDecl))) 1106 ResultStr += "struct "; 1107 } 1108 // When rewriting for Microsoft, explicitly omit the structure name. 1109 ResultStr += IDecl->getNameAsString(); 1110 ResultStr += " *"; 1111 } 1112 else 1113 ResultStr += Context->getObjCClassType().getAsString( 1114 Context->getPrintingPolicy()); 1115 1116 ResultStr += " self, "; 1117 ResultStr += Context->getObjCSelType().getAsString(Context->getPrintingPolicy()); 1118 ResultStr += " _cmd"; 1119 1120 // Method arguments. 1121 for (const auto *PDecl : OMD->params()) { 1122 ResultStr += ", "; 1123 if (PDecl->getType()->isObjCQualifiedIdType()) { 1124 ResultStr += "id "; 1125 ResultStr += PDecl->getNameAsString(); 1126 } else { 1127 std::string Name = PDecl->getNameAsString(); 1128 QualType QT = PDecl->getType(); 1129 // Make sure we convert "t (^)(...)" to "t (*)(...)". 1130 (void)convertBlockPointerToFunctionPointer(QT); 1131 QT.getAsStringInternal(Name, Context->getPrintingPolicy()); 1132 ResultStr += Name; 1133 } 1134 } 1135 if (OMD->isVariadic()) 1136 ResultStr += ", ..."; 1137 ResultStr += ") "; 1138 1139 if (FPRetType) { 1140 ResultStr += ")"; // close the precedence "scope" for "*". 1141 1142 // Now, emit the argument types (if any). 1143 if (const FunctionProtoType *FT = dyn_cast<FunctionProtoType>(FPRetType)) { 1144 ResultStr += "("; 1145 for (unsigned i = 0, e = FT->getNumParams(); i != e; ++i) { 1146 if (i) ResultStr += ", "; 1147 std::string ParamStr = 1148 FT->getParamType(i).getAsString(Context->getPrintingPolicy()); 1149 ResultStr += ParamStr; 1150 } 1151 if (FT->isVariadic()) { 1152 if (FT->getNumParams()) 1153 ResultStr += ", "; 1154 ResultStr += "..."; 1155 } 1156 ResultStr += ")"; 1157 } else { 1158 ResultStr += "()"; 1159 } 1160 } 1161} 1162void RewriteObjC::RewriteImplementationDecl(Decl *OID) { 1163 ObjCImplementationDecl *IMD = dyn_cast<ObjCImplementationDecl>(OID); 1164 ObjCCategoryImplDecl *CID = dyn_cast<ObjCCategoryImplDecl>(OID); 1165 1166 InsertText(IMD ? IMD->getLocStart() : CID->getLocStart(), "// "); 1167 1168 for (auto *OMD : IMD ? IMD->instance_methods() : CID->instance_methods()) { 1169 std::string ResultStr; 1170 RewriteObjCMethodDecl(OMD->getClassInterface(), OMD, ResultStr); 1171 SourceLocation LocStart = OMD->getLocStart(); 1172 SourceLocation LocEnd = OMD->getCompoundBody()->getLocStart(); 1173 1174 const char *startBuf = SM->getCharacterData(LocStart); 1175 const char *endBuf = SM->getCharacterData(LocEnd); 1176 ReplaceText(LocStart, endBuf-startBuf, ResultStr); 1177 } 1178 1179 for (auto *OMD : IMD ? IMD->class_methods() : CID->class_methods()) { 1180 std::string ResultStr; 1181 RewriteObjCMethodDecl(OMD->getClassInterface(), OMD, ResultStr); 1182 SourceLocation LocStart = OMD->getLocStart(); 1183 SourceLocation LocEnd = OMD->getCompoundBody()->getLocStart(); 1184 1185 const char *startBuf = SM->getCharacterData(LocStart); 1186 const char *endBuf = SM->getCharacterData(LocEnd); 1187 ReplaceText(LocStart, endBuf-startBuf, ResultStr); 1188 } 1189 for (auto *I : IMD ? IMD->property_impls() : CID->property_impls()) 1190 RewritePropertyImplDecl(I, IMD, CID); 1191 1192 InsertText(IMD ? IMD->getLocEnd() : CID->getLocEnd(), "// "); 1193} 1194 1195void RewriteObjC::RewriteInterfaceDecl(ObjCInterfaceDecl *ClassDecl) { 1196 std::string ResultStr; 1197 if (!ObjCForwardDecls.count(ClassDecl->getCanonicalDecl())) { 1198 // we haven't seen a forward decl - generate a typedef. 1199 ResultStr = "#ifndef _REWRITER_typedef_"; 1200 ResultStr += ClassDecl->getNameAsString(); 1201 ResultStr += "\n"; 1202 ResultStr += "#define _REWRITER_typedef_"; 1203 ResultStr += ClassDecl->getNameAsString(); 1204 ResultStr += "\n"; 1205 ResultStr += "typedef struct objc_object "; 1206 ResultStr += ClassDecl->getNameAsString(); 1207 ResultStr += ";\n#endif\n"; 1208 // Mark this typedef as having been generated. 1209 ObjCForwardDecls.insert(ClassDecl->getCanonicalDecl()); 1210 } 1211 RewriteObjCInternalStruct(ClassDecl, ResultStr); 1212 1213 for (auto *I : ClassDecl->properties()) 1214 RewriteProperty(I); 1215 for (auto *I : ClassDecl->instance_methods()) 1216 RewriteMethodDeclaration(I); 1217 for (auto *I : ClassDecl->class_methods()) 1218 RewriteMethodDeclaration(I); 1219 1220 // Lastly, comment out the @end. 1221 ReplaceText(ClassDecl->getAtEndRange().getBegin(), strlen("@end"), 1222 "/* @end */"); 1223} 1224 1225Stmt *RewriteObjC::RewritePropertyOrImplicitSetter(PseudoObjectExpr *PseudoOp) { 1226 SourceRange OldRange = PseudoOp->getSourceRange(); 1227 1228 // We just magically know some things about the structure of this 1229 // expression. 1230 ObjCMessageExpr *OldMsg = 1231 cast<ObjCMessageExpr>(PseudoOp->getSemanticExpr( 1232 PseudoOp->getNumSemanticExprs() - 1)); 1233 1234 // Because the rewriter doesn't allow us to rewrite rewritten code, 1235 // we need to suppress rewriting the sub-statements. 1236 Expr *Base, *RHS; 1237 { 1238 DisableReplaceStmtScope S(*this); 1239 1240 // Rebuild the base expression if we have one. 1241 Base = nullptr; 1242 if (OldMsg->getReceiverKind() == ObjCMessageExpr::Instance) { 1243 Base = OldMsg->getInstanceReceiver(); 1244 Base = cast<OpaqueValueExpr>(Base)->getSourceExpr(); 1245 Base = cast<Expr>(RewriteFunctionBodyOrGlobalInitializer(Base)); 1246 } 1247 1248 // Rebuild the RHS. 1249 RHS = cast<BinaryOperator>(PseudoOp->getSyntacticForm())->getRHS(); 1250 RHS = cast<OpaqueValueExpr>(RHS)->getSourceExpr(); 1251 RHS = cast<Expr>(RewriteFunctionBodyOrGlobalInitializer(RHS)); 1252 } 1253 1254 // TODO: avoid this copy. 1255 SmallVector<SourceLocation, 1> SelLocs; 1256 OldMsg->getSelectorLocs(SelLocs); 1257 1258 ObjCMessageExpr *NewMsg = nullptr; 1259 switch (OldMsg->getReceiverKind()) { 1260 case ObjCMessageExpr::Class: 1261 NewMsg = ObjCMessageExpr::Create(*Context, OldMsg->getType(), 1262 OldMsg->getValueKind(), 1263 OldMsg->getLeftLoc(), 1264 OldMsg->getClassReceiverTypeInfo(), 1265 OldMsg->getSelector(), 1266 SelLocs, 1267 OldMsg->getMethodDecl(), 1268 RHS, 1269 OldMsg->getRightLoc(), 1270 OldMsg->isImplicit()); 1271 break; 1272 1273 case ObjCMessageExpr::Instance: 1274 NewMsg = ObjCMessageExpr::Create(*Context, OldMsg->getType(), 1275 OldMsg->getValueKind(), 1276 OldMsg->getLeftLoc(), 1277 Base, 1278 OldMsg->getSelector(), 1279 SelLocs, 1280 OldMsg->getMethodDecl(), 1281 RHS, 1282 OldMsg->getRightLoc(), 1283 OldMsg->isImplicit()); 1284 break; 1285 1286 case ObjCMessageExpr::SuperClass: 1287 case ObjCMessageExpr::SuperInstance: 1288 NewMsg = ObjCMessageExpr::Create(*Context, OldMsg->getType(), 1289 OldMsg->getValueKind(), 1290 OldMsg->getLeftLoc(), 1291 OldMsg->getSuperLoc(), 1292 OldMsg->getReceiverKind() == ObjCMessageExpr::SuperInstance, 1293 OldMsg->getSuperType(), 1294 OldMsg->getSelector(), 1295 SelLocs, 1296 OldMsg->getMethodDecl(), 1297 RHS, 1298 OldMsg->getRightLoc(), 1299 OldMsg->isImplicit()); 1300 break; 1301 } 1302 1303 Stmt *Replacement = SynthMessageExpr(NewMsg); 1304 ReplaceStmtWithRange(PseudoOp, Replacement, OldRange); 1305 return Replacement; 1306} 1307 1308Stmt *RewriteObjC::RewritePropertyOrImplicitGetter(PseudoObjectExpr *PseudoOp) { 1309 SourceRange OldRange = PseudoOp->getSourceRange(); 1310 1311 // We just magically know some things about the structure of this 1312 // expression. 1313 ObjCMessageExpr *OldMsg = 1314 cast<ObjCMessageExpr>(PseudoOp->getResultExpr()->IgnoreImplicit()); 1315 1316 // Because the rewriter doesn't allow us to rewrite rewritten code, 1317 // we need to suppress rewriting the sub-statements. 1318 Expr *Base = nullptr; 1319 { 1320 DisableReplaceStmtScope S(*this); 1321 1322 // Rebuild the base expression if we have one. 1323 if (OldMsg->getReceiverKind() == ObjCMessageExpr::Instance) { 1324 Base = OldMsg->getInstanceReceiver(); 1325 Base = cast<OpaqueValueExpr>(Base)->getSourceExpr(); 1326 Base = cast<Expr>(RewriteFunctionBodyOrGlobalInitializer(Base)); 1327 } 1328 } 1329 1330 // Intentionally empty. 1331 SmallVector<SourceLocation, 1> SelLocs; 1332 SmallVector<Expr*, 1> Args; 1333 1334 ObjCMessageExpr *NewMsg = nullptr; 1335 switch (OldMsg->getReceiverKind()) { 1336 case ObjCMessageExpr::Class: 1337 NewMsg = ObjCMessageExpr::Create(*Context, OldMsg->getType(), 1338 OldMsg->getValueKind(), 1339 OldMsg->getLeftLoc(), 1340 OldMsg->getClassReceiverTypeInfo(), 1341 OldMsg->getSelector(), 1342 SelLocs, 1343 OldMsg->getMethodDecl(), 1344 Args, 1345 OldMsg->getRightLoc(), 1346 OldMsg->isImplicit()); 1347 break; 1348 1349 case ObjCMessageExpr::Instance: 1350 NewMsg = ObjCMessageExpr::Create(*Context, OldMsg->getType(), 1351 OldMsg->getValueKind(), 1352 OldMsg->getLeftLoc(), 1353 Base, 1354 OldMsg->getSelector(), 1355 SelLocs, 1356 OldMsg->getMethodDecl(), 1357 Args, 1358 OldMsg->getRightLoc(), 1359 OldMsg->isImplicit()); 1360 break; 1361 1362 case ObjCMessageExpr::SuperClass: 1363 case ObjCMessageExpr::SuperInstance: 1364 NewMsg = ObjCMessageExpr::Create(*Context, OldMsg->getType(), 1365 OldMsg->getValueKind(), 1366 OldMsg->getLeftLoc(), 1367 OldMsg->getSuperLoc(), 1368 OldMsg->getReceiverKind() == ObjCMessageExpr::SuperInstance, 1369 OldMsg->getSuperType(), 1370 OldMsg->getSelector(), 1371 SelLocs, 1372 OldMsg->getMethodDecl(), 1373 Args, 1374 OldMsg->getRightLoc(), 1375 OldMsg->isImplicit()); 1376 break; 1377 } 1378 1379 Stmt *Replacement = SynthMessageExpr(NewMsg); 1380 ReplaceStmtWithRange(PseudoOp, Replacement, OldRange); 1381 return Replacement; 1382} 1383 1384/// SynthCountByEnumWithState - To print: 1385/// ((unsigned int (*) 1386/// (id, SEL, struct __objcFastEnumerationState *, id *, unsigned int)) 1387/// (void *)objc_msgSend)((id)l_collection, 1388/// sel_registerName( 1389/// "countByEnumeratingWithState:objects:count:"), 1390/// &enumState, 1391/// (id *)__rw_items, (unsigned int)16) 1392/// 1393void RewriteObjC::SynthCountByEnumWithState(std::string &buf) { 1394 buf += "((unsigned int (*) (id, SEL, struct __objcFastEnumerationState *, " 1395 "id *, unsigned int))(void *)objc_msgSend)"; 1396 buf += "\n\t\t"; 1397 buf += "((id)l_collection,\n\t\t"; 1398 buf += "sel_registerName(\"countByEnumeratingWithState:objects:count:\"),"; 1399 buf += "\n\t\t"; 1400 buf += "&enumState, " 1401 "(id *)__rw_items, (unsigned int)16)"; 1402} 1403 1404/// RewriteBreakStmt - Rewrite for a break-stmt inside an ObjC2's foreach 1405/// statement to exit to its outer synthesized loop. 1406/// 1407Stmt *RewriteObjC::RewriteBreakStmt(BreakStmt *S) { 1408 if (Stmts.empty() || !isa<ObjCForCollectionStmt>(Stmts.back())) 1409 return S; 1410 // replace break with goto __break_label 1411 std::string buf; 1412 1413 SourceLocation startLoc = S->getLocStart(); 1414 buf = "goto __break_label_"; 1415 buf += utostr(ObjCBcLabelNo.back()); 1416 ReplaceText(startLoc, strlen("break"), buf); 1417 1418 return nullptr; 1419} 1420 1421/// RewriteContinueStmt - Rewrite for a continue-stmt inside an ObjC2's foreach 1422/// statement to continue with its inner synthesized loop. 1423/// 1424Stmt *RewriteObjC::RewriteContinueStmt(ContinueStmt *S) { 1425 if (Stmts.empty() || !isa<ObjCForCollectionStmt>(Stmts.back())) 1426 return S; 1427 // replace continue with goto __continue_label 1428 std::string buf; 1429 1430 SourceLocation startLoc = S->getLocStart(); 1431 buf = "goto __continue_label_"; 1432 buf += utostr(ObjCBcLabelNo.back()); 1433 ReplaceText(startLoc, strlen("continue"), buf); 1434 1435 return nullptr; 1436} 1437 1438/// RewriteObjCForCollectionStmt - Rewriter for ObjC2's foreach statement. 1439/// It rewrites: 1440/// for ( type elem in collection) { stmts; } 1441 1442/// Into: 1443/// { 1444/// type elem; 1445/// struct __objcFastEnumerationState enumState = { 0 }; 1446/// id __rw_items[16]; 1447/// id l_collection = (id)collection; 1448/// unsigned long limit = [l_collection countByEnumeratingWithState:&enumState 1449/// objects:__rw_items count:16]; 1450/// if (limit) { 1451/// unsigned long startMutations = *enumState.mutationsPtr; 1452/// do { 1453/// unsigned long counter = 0; 1454/// do { 1455/// if (startMutations != *enumState.mutationsPtr) 1456/// objc_enumerationMutation(l_collection); 1457/// elem = (type)enumState.itemsPtr[counter++]; 1458/// stmts; 1459/// __continue_label: ; 1460/// } while (counter < limit); 1461/// } while (limit = [l_collection countByEnumeratingWithState:&enumState 1462/// objects:__rw_items count:16]); 1463/// elem = nil; 1464/// __break_label: ; 1465/// } 1466/// else 1467/// elem = nil; 1468/// } 1469/// 1470Stmt *RewriteObjC::RewriteObjCForCollectionStmt(ObjCForCollectionStmt *S, 1471 SourceLocation OrigEnd) { 1472 assert(!Stmts.empty() && "ObjCForCollectionStmt - Statement stack empty"); 1473 assert(isa<ObjCForCollectionStmt>(Stmts.back()) && 1474 "ObjCForCollectionStmt Statement stack mismatch"); 1475 assert(!ObjCBcLabelNo.empty() && 1476 "ObjCForCollectionStmt - Label No stack empty"); 1477 1478 SourceLocation startLoc = S->getLocStart(); 1479 const char *startBuf = SM->getCharacterData(startLoc); 1480 StringRef elementName; 1481 std::string elementTypeAsString; 1482 std::string buf; 1483 buf = "\n{\n\t"; 1484 if (DeclStmt *DS = dyn_cast<DeclStmt>(S->getElement())) { 1485 // type elem; 1486 NamedDecl* D = cast<NamedDecl>(DS->getSingleDecl()); 1487 QualType ElementType = cast<ValueDecl>(D)->getType(); 1488 if (ElementType->isObjCQualifiedIdType() || 1489 ElementType->isObjCQualifiedInterfaceType()) 1490 // Simply use 'id' for all qualified types. 1491 elementTypeAsString = "id"; 1492 else 1493 elementTypeAsString = ElementType.getAsString(Context->getPrintingPolicy()); 1494 buf += elementTypeAsString; 1495 buf += " "; 1496 elementName = D->getName(); 1497 buf += elementName; 1498 buf += ";\n\t"; 1499 } 1500 else { 1501 DeclRefExpr *DR = cast<DeclRefExpr>(S->getElement()); 1502 elementName = DR->getDecl()->getName(); 1503 ValueDecl *VD = cast<ValueDecl>(DR->getDecl()); 1504 if (VD->getType()->isObjCQualifiedIdType() || 1505 VD->getType()->isObjCQualifiedInterfaceType()) 1506 // Simply use 'id' for all qualified types. 1507 elementTypeAsString = "id"; 1508 else 1509 elementTypeAsString = VD->getType().getAsString(Context->getPrintingPolicy()); 1510 } 1511 1512 // struct __objcFastEnumerationState enumState = { 0 }; 1513 buf += "struct __objcFastEnumerationState enumState = { 0 };\n\t"; 1514 // id __rw_items[16]; 1515 buf += "id __rw_items[16];\n\t"; 1516 // id l_collection = (id) 1517 buf += "id l_collection = (id)"; 1518 // Find start location of 'collection' the hard way! 1519 const char *startCollectionBuf = startBuf; 1520 startCollectionBuf += 3; // skip 'for' 1521 startCollectionBuf = strchr(startCollectionBuf, '('); 1522 startCollectionBuf++; // skip '(' 1523 // find 'in' and skip it. 1524 while (*startCollectionBuf != ' ' || 1525 *(startCollectionBuf+1) != 'i' || *(startCollectionBuf+2) != 'n' || 1526 (*(startCollectionBuf+3) != ' ' && 1527 *(startCollectionBuf+3) != '[' && *(startCollectionBuf+3) != '(')) 1528 startCollectionBuf++; 1529 startCollectionBuf += 3; 1530 1531 // Replace: "for (type element in" with string constructed thus far. 1532 ReplaceText(startLoc, startCollectionBuf - startBuf, buf); 1533 // Replace ')' in for '(' type elem in collection ')' with ';' 1534 SourceLocation rightParenLoc = S->getRParenLoc(); 1535 const char *rparenBuf = SM->getCharacterData(rightParenLoc); 1536 SourceLocation lparenLoc = startLoc.getLocWithOffset(rparenBuf-startBuf); 1537 buf = ";\n\t"; 1538 1539 // unsigned long limit = [l_collection countByEnumeratingWithState:&enumState 1540 // objects:__rw_items count:16]; 1541 // which is synthesized into: 1542 // unsigned int limit = 1543 // ((unsigned int (*) 1544 // (id, SEL, struct __objcFastEnumerationState *, id *, unsigned int)) 1545 // (void *)objc_msgSend)((id)l_collection, 1546 // sel_registerName( 1547 // "countByEnumeratingWithState:objects:count:"), 1548 // (struct __objcFastEnumerationState *)&state, 1549 // (id *)__rw_items, (unsigned int)16); 1550 buf += "unsigned long limit =\n\t\t"; 1551 SynthCountByEnumWithState(buf); 1552 buf += ";\n\t"; 1553 /// if (limit) { 1554 /// unsigned long startMutations = *enumState.mutationsPtr; 1555 /// do { 1556 /// unsigned long counter = 0; 1557 /// do { 1558 /// if (startMutations != *enumState.mutationsPtr) 1559 /// objc_enumerationMutation(l_collection); 1560 /// elem = (type)enumState.itemsPtr[counter++]; 1561 buf += "if (limit) {\n\t"; 1562 buf += "unsigned long startMutations = *enumState.mutationsPtr;\n\t"; 1563 buf += "do {\n\t\t"; 1564 buf += "unsigned long counter = 0;\n\t\t"; 1565 buf += "do {\n\t\t\t"; 1566 buf += "if (startMutations != *enumState.mutationsPtr)\n\t\t\t\t"; 1567 buf += "objc_enumerationMutation(l_collection);\n\t\t\t"; 1568 buf += elementName; 1569 buf += " = ("; 1570 buf += elementTypeAsString; 1571 buf += ")enumState.itemsPtr[counter++];"; 1572 // Replace ')' in for '(' type elem in collection ')' with all of these. 1573 ReplaceText(lparenLoc, 1, buf); 1574 1575 /// __continue_label: ; 1576 /// } while (counter < limit); 1577 /// } while (limit = [l_collection countByEnumeratingWithState:&enumState 1578 /// objects:__rw_items count:16]); 1579 /// elem = nil; 1580 /// __break_label: ; 1581 /// } 1582 /// else 1583 /// elem = nil; 1584 /// } 1585 /// 1586 buf = ";\n\t"; 1587 buf += "__continue_label_"; 1588 buf += utostr(ObjCBcLabelNo.back()); 1589 buf += ": ;"; 1590 buf += "\n\t\t"; 1591 buf += "} while (counter < limit);\n\t"; 1592 buf += "} while (limit = "; 1593 SynthCountByEnumWithState(buf); 1594 buf += ");\n\t"; 1595 buf += elementName; 1596 buf += " = (("; 1597 buf += elementTypeAsString; 1598 buf += ")0);\n\t"; 1599 buf += "__break_label_"; 1600 buf += utostr(ObjCBcLabelNo.back()); 1601 buf += ": ;\n\t"; 1602 buf += "}\n\t"; 1603 buf += "else\n\t\t"; 1604 buf += elementName; 1605 buf += " = (("; 1606 buf += elementTypeAsString; 1607 buf += ")0);\n\t"; 1608 buf += "}\n"; 1609 1610 // Insert all these *after* the statement body. 1611 // FIXME: If this should support Obj-C++, support CXXTryStmt 1612 if (isa<CompoundStmt>(S->getBody())) { 1613 SourceLocation endBodyLoc = OrigEnd.getLocWithOffset(1); 1614 InsertText(endBodyLoc, buf); 1615 } else { 1616 /* Need to treat single statements specially. For example: 1617 * 1618 * for (A *a in b) if (stuff()) break; 1619 * for (A *a in b) xxxyy; 1620 * 1621 * The following code simply scans ahead to the semi to find the actual end. 1622 */ 1623 const char *stmtBuf = SM->getCharacterData(OrigEnd); 1624 const char *semiBuf = strchr(stmtBuf, ';'); 1625 assert(semiBuf && "Can't find ';'"); 1626 SourceLocation endBodyLoc = OrigEnd.getLocWithOffset(semiBuf-stmtBuf+1); 1627 InsertText(endBodyLoc, buf); 1628 } 1629 Stmts.pop_back(); 1630 ObjCBcLabelNo.pop_back(); 1631 return nullptr; 1632} 1633 1634/// RewriteObjCSynchronizedStmt - 1635/// This routine rewrites @synchronized(expr) stmt; 1636/// into: 1637/// objc_sync_enter(expr); 1638/// @try stmt @finally { objc_sync_exit(expr); } 1639/// 1640Stmt *RewriteObjC::RewriteObjCSynchronizedStmt(ObjCAtSynchronizedStmt *S) { 1641 // Get the start location and compute the semi location. 1642 SourceLocation startLoc = S->getLocStart(); 1643 const char *startBuf = SM->getCharacterData(startLoc); 1644 1645 assert((*startBuf == '@') && "bogus @synchronized location"); 1646 1647 std::string buf; 1648 buf = "objc_sync_enter((id)"; 1649 const char *lparenBuf = startBuf; 1650 while (*lparenBuf != '(') lparenBuf++; 1651 ReplaceText(startLoc, lparenBuf-startBuf+1, buf); 1652 // We can't use S->getSynchExpr()->getLocEnd() to find the end location, since 1653 // the sync expression is typically a message expression that's already 1654 // been rewritten! (which implies the SourceLocation's are invalid). 1655 SourceLocation endLoc = S->getSynchBody()->getLocStart(); 1656 const char *endBuf = SM->getCharacterData(endLoc); 1657 while (*endBuf != ')') endBuf--; 1658 SourceLocation rparenLoc = startLoc.getLocWithOffset(endBuf-startBuf); 1659 buf = ");\n"; 1660 // declare a new scope with two variables, _stack and _rethrow. 1661 buf += "/* @try scope begin */ \n{ struct _objc_exception_data {\n"; 1662 buf += "int buf[18/*32-bit i386*/];\n"; 1663 buf += "char *pointers[4];} _stack;\n"; 1664 buf += "id volatile _rethrow = 0;\n"; 1665 buf += "objc_exception_try_enter(&_stack);\n"; 1666 buf += "if (!_setjmp(_stack.buf)) /* @try block continue */\n"; 1667 ReplaceText(rparenLoc, 1, buf); 1668 startLoc = S->getSynchBody()->getLocEnd(); 1669 startBuf = SM->getCharacterData(startLoc); 1670 1671 assert((*startBuf == '}') && "bogus @synchronized block"); 1672 SourceLocation lastCurlyLoc = startLoc; 1673 buf = "}\nelse {\n"; 1674 buf += " _rethrow = objc_exception_extract(&_stack);\n"; 1675 buf += "}\n"; 1676 buf += "{ /* implicit finally clause */\n"; 1677 buf += " if (!_rethrow) objc_exception_try_exit(&_stack);\n"; 1678 1679 std::string syncBuf; 1680 syncBuf += " objc_sync_exit("; 1681 1682 Expr *syncExpr = S->getSynchExpr(); 1683 CastKind CK = syncExpr->getType()->isObjCObjectPointerType() 1684 ? CK_BitCast : 1685 syncExpr->getType()->isBlockPointerType() 1686 ? CK_BlockPointerToObjCPointerCast 1687 : CK_CPointerToObjCPointerCast; 1688 syncExpr = NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(), 1689 CK, syncExpr); 1690 std::string syncExprBufS; 1691 llvm::raw_string_ostream syncExprBuf(syncExprBufS); 1692 assert(syncExpr != nullptr && "Expected non-null Expr"); 1693 syncExpr->printPretty(syncExprBuf, nullptr, PrintingPolicy(LangOpts)); 1694 syncBuf += syncExprBuf.str(); 1695 syncBuf += ");"; 1696 1697 buf += syncBuf; 1698 buf += "\n if (_rethrow) objc_exception_throw(_rethrow);\n"; 1699 buf += "}\n"; 1700 buf += "}"; 1701 1702 ReplaceText(lastCurlyLoc, 1, buf); 1703 1704 bool hasReturns = false; 1705 HasReturnStmts(S->getSynchBody(), hasReturns); 1706 if (hasReturns) 1707 RewriteSyncReturnStmts(S->getSynchBody(), syncBuf); 1708 1709 return nullptr; 1710} 1711 1712void RewriteObjC::WarnAboutReturnGotoStmts(Stmt *S) 1713{ 1714 // Perform a bottom up traversal of all children. 1715 for (Stmt::child_range CI = S->children(); CI; ++CI) 1716 if (*CI) 1717 WarnAboutReturnGotoStmts(*CI); 1718 1719 if (isa<ReturnStmt>(S) || isa<GotoStmt>(S)) { 1720 Diags.Report(Context->getFullLoc(S->getLocStart()), 1721 TryFinallyContainsReturnDiag); 1722 } 1723 return; 1724} 1725 1726void RewriteObjC::HasReturnStmts(Stmt *S, bool &hasReturns) 1727{ 1728 // Perform a bottom up traversal of all children. 1729 for (Stmt::child_range CI = S->children(); CI; ++CI) 1730 if (*CI) 1731 HasReturnStmts(*CI, hasReturns); 1732 1733 if (isa<ReturnStmt>(S)) 1734 hasReturns = true; 1735 return; 1736} 1737 1738void RewriteObjC::RewriteTryReturnStmts(Stmt *S) { 1739 // Perform a bottom up traversal of all children. 1740 for (Stmt::child_range CI = S->children(); CI; ++CI) 1741 if (*CI) { 1742 RewriteTryReturnStmts(*CI); 1743 } 1744 if (isa<ReturnStmt>(S)) { 1745 SourceLocation startLoc = S->getLocStart(); 1746 const char *startBuf = SM->getCharacterData(startLoc); 1747 1748 const char *semiBuf = strchr(startBuf, ';'); 1749 assert((*semiBuf == ';') && "RewriteTryReturnStmts: can't find ';'"); 1750 SourceLocation onePastSemiLoc = startLoc.getLocWithOffset(semiBuf-startBuf+1); 1751 1752 std::string buf; 1753 buf = "{ objc_exception_try_exit(&_stack); return"; 1754 1755 ReplaceText(startLoc, 6, buf); 1756 InsertText(onePastSemiLoc, "}"); 1757 } 1758 return; 1759} 1760 1761void RewriteObjC::RewriteSyncReturnStmts(Stmt *S, std::string syncExitBuf) { 1762 // Perform a bottom up traversal of all children. 1763 for (Stmt::child_range CI = S->children(); CI; ++CI) 1764 if (*CI) { 1765 RewriteSyncReturnStmts(*CI, syncExitBuf); 1766 } 1767 if (isa<ReturnStmt>(S)) { 1768 SourceLocation startLoc = S->getLocStart(); 1769 const char *startBuf = SM->getCharacterData(startLoc); 1770 1771 const char *semiBuf = strchr(startBuf, ';'); 1772 assert((*semiBuf == ';') && "RewriteSyncReturnStmts: can't find ';'"); 1773 SourceLocation onePastSemiLoc = startLoc.getLocWithOffset(semiBuf-startBuf+1); 1774 1775 std::string buf; 1776 buf = "{ objc_exception_try_exit(&_stack);"; 1777 buf += syncExitBuf; 1778 buf += " return"; 1779 1780 ReplaceText(startLoc, 6, buf); 1781 InsertText(onePastSemiLoc, "}"); 1782 } 1783 return; 1784} 1785 1786Stmt *RewriteObjC::RewriteObjCTryStmt(ObjCAtTryStmt *S) { 1787 // Get the start location and compute the semi location. 1788 SourceLocation startLoc = S->getLocStart(); 1789 const char *startBuf = SM->getCharacterData(startLoc); 1790 1791 assert((*startBuf == '@') && "bogus @try location"); 1792 1793 std::string buf; 1794 // declare a new scope with two variables, _stack and _rethrow. 1795 buf = "/* @try scope begin */ { struct _objc_exception_data {\n"; 1796 buf += "int buf[18/*32-bit i386*/];\n"; 1797 buf += "char *pointers[4];} _stack;\n"; 1798 buf += "id volatile _rethrow = 0;\n"; 1799 buf += "objc_exception_try_enter(&_stack);\n"; 1800 buf += "if (!_setjmp(_stack.buf)) /* @try block continue */\n"; 1801 1802 ReplaceText(startLoc, 4, buf); 1803 1804 startLoc = S->getTryBody()->getLocEnd(); 1805 startBuf = SM->getCharacterData(startLoc); 1806 1807 assert((*startBuf == '}') && "bogus @try block"); 1808 1809 SourceLocation lastCurlyLoc = startLoc; 1810 if (S->getNumCatchStmts()) { 1811 startLoc = startLoc.getLocWithOffset(1); 1812 buf = " /* @catch begin */ else {\n"; 1813 buf += " id _caught = objc_exception_extract(&_stack);\n"; 1814 buf += " objc_exception_try_enter (&_stack);\n"; 1815 buf += " if (_setjmp(_stack.buf))\n"; 1816 buf += " _rethrow = objc_exception_extract(&_stack);\n"; 1817 buf += " else { /* @catch continue */"; 1818 1819 InsertText(startLoc, buf); 1820 } else { /* no catch list */ 1821 buf = "}\nelse {\n"; 1822 buf += " _rethrow = objc_exception_extract(&_stack);\n"; 1823 buf += "}"; 1824 ReplaceText(lastCurlyLoc, 1, buf); 1825 } 1826 Stmt *lastCatchBody = nullptr; 1827 for (unsigned I = 0, N = S->getNumCatchStmts(); I != N; ++I) { 1828 ObjCAtCatchStmt *Catch = S->getCatchStmt(I); 1829 VarDecl *catchDecl = Catch->getCatchParamDecl(); 1830 1831 if (I == 0) 1832 buf = "if ("; // we are generating code for the first catch clause 1833 else 1834 buf = "else if ("; 1835 startLoc = Catch->getLocStart(); 1836 startBuf = SM->getCharacterData(startLoc); 1837 1838 assert((*startBuf == '@') && "bogus @catch location"); 1839 1840 const char *lParenLoc = strchr(startBuf, '('); 1841 1842 if (Catch->hasEllipsis()) { 1843 // Now rewrite the body... 1844 lastCatchBody = Catch->getCatchBody(); 1845 SourceLocation bodyLoc = lastCatchBody->getLocStart(); 1846 const char *bodyBuf = SM->getCharacterData(bodyLoc); 1847 assert(*SM->getCharacterData(Catch->getRParenLoc()) == ')' && 1848 "bogus @catch paren location"); 1849 assert((*bodyBuf == '{') && "bogus @catch body location"); 1850 1851 buf += "1) { id _tmp = _caught;"; 1852 Rewrite.ReplaceText(startLoc, bodyBuf-startBuf+1, buf); 1853 } else if (catchDecl) { 1854 QualType t = catchDecl->getType(); 1855 if (t == Context->getObjCIdType()) { 1856 buf += "1) { "; 1857 ReplaceText(startLoc, lParenLoc-startBuf+1, buf); 1858 } else if (const ObjCObjectPointerType *Ptr = 1859 t->getAs<ObjCObjectPointerType>()) { 1860 // Should be a pointer to a class. 1861 ObjCInterfaceDecl *IDecl = Ptr->getObjectType()->getInterface(); 1862 if (IDecl) { 1863 buf += "objc_exception_match((struct objc_class *)objc_getClass(\""; 1864 buf += IDecl->getNameAsString(); 1865 buf += "\"), (struct objc_object *)_caught)) { "; 1866 ReplaceText(startLoc, lParenLoc-startBuf+1, buf); 1867 } 1868 } 1869 // Now rewrite the body... 1870 lastCatchBody = Catch->getCatchBody(); 1871 SourceLocation rParenLoc = Catch->getRParenLoc(); 1872 SourceLocation bodyLoc = lastCatchBody->getLocStart(); 1873 const char *bodyBuf = SM->getCharacterData(bodyLoc); 1874 const char *rParenBuf = SM->getCharacterData(rParenLoc); 1875 assert((*rParenBuf == ')') && "bogus @catch paren location"); 1876 assert((*bodyBuf == '{') && "bogus @catch body location"); 1877 1878 // Here we replace ") {" with "= _caught;" (which initializes and 1879 // declares the @catch parameter). 1880 ReplaceText(rParenLoc, bodyBuf-rParenBuf+1, " = _caught;"); 1881 } else { 1882 llvm_unreachable("@catch rewrite bug"); 1883 } 1884 } 1885 // Complete the catch list... 1886 if (lastCatchBody) { 1887 SourceLocation bodyLoc = lastCatchBody->getLocEnd(); 1888 assert(*SM->getCharacterData(bodyLoc) == '}' && 1889 "bogus @catch body location"); 1890 1891 // Insert the last (implicit) else clause *before* the right curly brace. 1892 bodyLoc = bodyLoc.getLocWithOffset(-1); 1893 buf = "} /* last catch end */\n"; 1894 buf += "else {\n"; 1895 buf += " _rethrow = _caught;\n"; 1896 buf += " objc_exception_try_exit(&_stack);\n"; 1897 buf += "} } /* @catch end */\n"; 1898 if (!S->getFinallyStmt()) 1899 buf += "}\n"; 1900 InsertText(bodyLoc, buf); 1901 1902 // Set lastCurlyLoc 1903 lastCurlyLoc = lastCatchBody->getLocEnd(); 1904 } 1905 if (ObjCAtFinallyStmt *finalStmt = S->getFinallyStmt()) { 1906 startLoc = finalStmt->getLocStart(); 1907 startBuf = SM->getCharacterData(startLoc); 1908 assert((*startBuf == '@') && "bogus @finally start"); 1909 1910 ReplaceText(startLoc, 8, "/* @finally */"); 1911 1912 Stmt *body = finalStmt->getFinallyBody(); 1913 SourceLocation startLoc = body->getLocStart(); 1914 SourceLocation endLoc = body->getLocEnd(); 1915 assert(*SM->getCharacterData(startLoc) == '{' && 1916 "bogus @finally body location"); 1917 assert(*SM->getCharacterData(endLoc) == '}' && 1918 "bogus @finally body location"); 1919 1920 startLoc = startLoc.getLocWithOffset(1); 1921 InsertText(startLoc, " if (!_rethrow) objc_exception_try_exit(&_stack);\n"); 1922 endLoc = endLoc.getLocWithOffset(-1); 1923 InsertText(endLoc, " if (_rethrow) objc_exception_throw(_rethrow);\n"); 1924 1925 // Set lastCurlyLoc 1926 lastCurlyLoc = body->getLocEnd(); 1927 1928 // Now check for any return/continue/go statements within the @try. 1929 WarnAboutReturnGotoStmts(S->getTryBody()); 1930 } else { /* no finally clause - make sure we synthesize an implicit one */ 1931 buf = "{ /* implicit finally clause */\n"; 1932 buf += " if (!_rethrow) objc_exception_try_exit(&_stack);\n"; 1933 buf += " if (_rethrow) objc_exception_throw(_rethrow);\n"; 1934 buf += "}"; 1935 ReplaceText(lastCurlyLoc, 1, buf); 1936 1937 // Now check for any return/continue/go statements within the @try. 1938 // The implicit finally clause won't called if the @try contains any 1939 // jump statements. 1940 bool hasReturns = false; 1941 HasReturnStmts(S->getTryBody(), hasReturns); 1942 if (hasReturns) 1943 RewriteTryReturnStmts(S->getTryBody()); 1944 } 1945 // Now emit the final closing curly brace... 1946 lastCurlyLoc = lastCurlyLoc.getLocWithOffset(1); 1947 InsertText(lastCurlyLoc, " } /* @try scope end */\n"); 1948 return nullptr; 1949} 1950 1951// This can't be done with ReplaceStmt(S, ThrowExpr), since 1952// the throw expression is typically a message expression that's already 1953// been rewritten! (which implies the SourceLocation's are invalid). 1954Stmt *RewriteObjC::RewriteObjCThrowStmt(ObjCAtThrowStmt *S) { 1955 // Get the start location and compute the semi location. 1956 SourceLocation startLoc = S->getLocStart(); 1957 const char *startBuf = SM->getCharacterData(startLoc); 1958 1959 assert((*startBuf == '@') && "bogus @throw location"); 1960 1961 std::string buf; 1962 /* void objc_exception_throw(id) __attribute__((noreturn)); */ 1963 if (S->getThrowExpr()) 1964 buf = "objc_exception_throw("; 1965 else // add an implicit argument 1966 buf = "objc_exception_throw(_caught"; 1967 1968 // handle "@ throw" correctly. 1969 const char *wBuf = strchr(startBuf, 'w'); 1970 assert((*wBuf == 'w') && "@throw: can't find 'w'"); 1971 ReplaceText(startLoc, wBuf-startBuf+1, buf); 1972 1973 const char *semiBuf = strchr(startBuf, ';'); 1974 assert((*semiBuf == ';') && "@throw: can't find ';'"); 1975 SourceLocation semiLoc = startLoc.getLocWithOffset(semiBuf-startBuf); 1976 ReplaceText(semiLoc, 1, ");"); 1977 return nullptr; 1978} 1979 1980Stmt *RewriteObjC::RewriteAtEncode(ObjCEncodeExpr *Exp) { 1981 // Create a new string expression. 1982 std::string StrEncoding; 1983 Context->getObjCEncodingForType(Exp->getEncodedType(), StrEncoding); 1984 Expr *Replacement = getStringLiteral(StrEncoding); 1985 ReplaceStmt(Exp, Replacement); 1986 1987 // Replace this subexpr in the parent. 1988 // delete Exp; leak for now, see RewritePropertyOrImplicitSetter() usage for more info. 1989 return Replacement; 1990} 1991 1992Stmt *RewriteObjC::RewriteAtSelector(ObjCSelectorExpr *Exp) { 1993 if (!SelGetUidFunctionDecl) 1994 SynthSelGetUidFunctionDecl(); 1995 assert(SelGetUidFunctionDecl && "Can't find sel_registerName() decl"); 1996 // Create a call to sel_registerName("selName"). 1997 SmallVector<Expr*, 8> SelExprs; 1998 SelExprs.push_back(getStringLiteral(Exp->getSelector().getAsString())); 1999 CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl, 2000 &SelExprs[0], SelExprs.size()); 2001 ReplaceStmt(Exp, SelExp); 2002 // delete Exp; leak for now, see RewritePropertyOrImplicitSetter() usage for more info. 2003 return SelExp; 2004} 2005 2006CallExpr *RewriteObjC::SynthesizeCallToFunctionDecl( 2007 FunctionDecl *FD, Expr **args, unsigned nargs, SourceLocation StartLoc, 2008 SourceLocation EndLoc) { 2009 // Get the type, we will need to reference it in a couple spots. 2010 QualType msgSendType = FD->getType(); 2011 2012 // Create a reference to the objc_msgSend() declaration. 2013 DeclRefExpr *DRE = new (Context) DeclRefExpr(FD, false, msgSendType, 2014 VK_LValue, SourceLocation()); 2015 2016 // Now, we cast the reference to a pointer to the objc_msgSend type. 2017 QualType pToFunc = Context->getPointerType(msgSendType); 2018 ImplicitCastExpr *ICE = 2019 ImplicitCastExpr::Create(*Context, pToFunc, CK_FunctionToPointerDecay, 2020 DRE, nullptr, VK_RValue); 2021 2022 const FunctionType *FT = msgSendType->getAs<FunctionType>(); 2023 2024 CallExpr *Exp = 2025 new (Context) CallExpr(*Context, ICE, llvm::makeArrayRef(args, nargs), 2026 FT->getCallResultType(*Context), 2027 VK_RValue, EndLoc); 2028 return Exp; 2029} 2030 2031static bool scanForProtocolRefs(const char *startBuf, const char *endBuf, 2032 const char *&startRef, const char *&endRef) { 2033 while (startBuf < endBuf) { 2034 if (*startBuf == '<') 2035 startRef = startBuf; // mark the start. 2036 if (*startBuf == '>') { 2037 if (startRef && *startRef == '<') { 2038 endRef = startBuf; // mark the end. 2039 return true; 2040 } 2041 return false; 2042 } 2043 startBuf++; 2044 } 2045 return false; 2046} 2047 2048static void scanToNextArgument(const char *&argRef) { 2049 int angle = 0; 2050 while (*argRef != ')' && (*argRef != ',' || angle > 0)) { 2051 if (*argRef == '<') 2052 angle++; 2053 else if (*argRef == '>') 2054 angle--; 2055 argRef++; 2056 } 2057 assert(angle == 0 && "scanToNextArgument - bad protocol type syntax"); 2058} 2059 2060bool RewriteObjC::needToScanForQualifiers(QualType T) { 2061 if (T->isObjCQualifiedIdType()) 2062 return true; 2063 if (const PointerType *PT = T->getAs<PointerType>()) { 2064 if (PT->getPointeeType()->isObjCQualifiedIdType()) 2065 return true; 2066 } 2067 if (T->isObjCObjectPointerType()) { 2068 T = T->getPointeeType(); 2069 return T->isObjCQualifiedInterfaceType(); 2070 } 2071 if (T->isArrayType()) { 2072 QualType ElemTy = Context->getBaseElementType(T); 2073 return needToScanForQualifiers(ElemTy); 2074 } 2075 return false; 2076} 2077 2078void RewriteObjC::RewriteObjCQualifiedInterfaceTypes(Expr *E) { 2079 QualType Type = E->getType(); 2080 if (needToScanForQualifiers(Type)) { 2081 SourceLocation Loc, EndLoc; 2082 2083 if (const CStyleCastExpr *ECE = dyn_cast<CStyleCastExpr>(E)) { 2084 Loc = ECE->getLParenLoc(); 2085 EndLoc = ECE->getRParenLoc(); 2086 } else { 2087 Loc = E->getLocStart(); 2088 EndLoc = E->getLocEnd(); 2089 } 2090 // This will defend against trying to rewrite synthesized expressions. 2091 if (Loc.isInvalid() || EndLoc.isInvalid()) 2092 return; 2093 2094 const char *startBuf = SM->getCharacterData(Loc); 2095 const char *endBuf = SM->getCharacterData(EndLoc); 2096 const char *startRef = nullptr, *endRef = nullptr; 2097 if (scanForProtocolRefs(startBuf, endBuf, startRef, endRef)) { 2098 // Get the locations of the startRef, endRef. 2099 SourceLocation LessLoc = Loc.getLocWithOffset(startRef-startBuf); 2100 SourceLocation GreaterLoc = Loc.getLocWithOffset(endRef-startBuf+1); 2101 // Comment out the protocol references. 2102 InsertText(LessLoc, "/*"); 2103 InsertText(GreaterLoc, "*/"); 2104 } 2105 } 2106} 2107 2108void RewriteObjC::RewriteObjCQualifiedInterfaceTypes(Decl *Dcl) { 2109 SourceLocation Loc; 2110 QualType Type; 2111 const FunctionProtoType *proto = nullptr; 2112 if (VarDecl *VD = dyn_cast<VarDecl>(Dcl)) { 2113 Loc = VD->getLocation(); 2114 Type = VD->getType(); 2115 } 2116 else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(Dcl)) { 2117 Loc = FD->getLocation(); 2118 // Check for ObjC 'id' and class types that have been adorned with protocol 2119 // information (id<p>, C<p>*). The protocol references need to be rewritten! 2120 const FunctionType *funcType = FD->getType()->getAs<FunctionType>(); 2121 assert(funcType && "missing function type"); 2122 proto = dyn_cast<FunctionProtoType>(funcType); 2123 if (!proto) 2124 return; 2125 Type = proto->getReturnType(); 2126 } 2127 else if (FieldDecl *FD = dyn_cast<FieldDecl>(Dcl)) { 2128 Loc = FD->getLocation(); 2129 Type = FD->getType(); 2130 } 2131 else 2132 return; 2133 2134 if (needToScanForQualifiers(Type)) { 2135 // Since types are unique, we need to scan the buffer. 2136 2137 const char *endBuf = SM->getCharacterData(Loc); 2138 const char *startBuf = endBuf; 2139 while (*startBuf != ';' && *startBuf != '<' && startBuf != MainFileStart) 2140 startBuf--; // scan backward (from the decl location) for return type. 2141 const char *startRef = nullptr, *endRef = nullptr; 2142 if (scanForProtocolRefs(startBuf, endBuf, startRef, endRef)) { 2143 // Get the locations of the startRef, endRef. 2144 SourceLocation LessLoc = Loc.getLocWithOffset(startRef-endBuf); 2145 SourceLocation GreaterLoc = Loc.getLocWithOffset(endRef-endBuf+1); 2146 // Comment out the protocol references. 2147 InsertText(LessLoc, "/*"); 2148 InsertText(GreaterLoc, "*/"); 2149 } 2150 } 2151 if (!proto) 2152 return; // most likely, was a variable 2153 // Now check arguments. 2154 const char *startBuf = SM->getCharacterData(Loc); 2155 const char *startFuncBuf = startBuf; 2156 for (unsigned i = 0; i < proto->getNumParams(); i++) { 2157 if (needToScanForQualifiers(proto->getParamType(i))) { 2158 // Since types are unique, we need to scan the buffer. 2159 2160 const char *endBuf = startBuf; 2161 // scan forward (from the decl location) for argument types. 2162 scanToNextArgument(endBuf); 2163 const char *startRef = nullptr, *endRef = nullptr; 2164 if (scanForProtocolRefs(startBuf, endBuf, startRef, endRef)) { 2165 // Get the locations of the startRef, endRef. 2166 SourceLocation LessLoc = 2167 Loc.getLocWithOffset(startRef-startFuncBuf); 2168 SourceLocation GreaterLoc = 2169 Loc.getLocWithOffset(endRef-startFuncBuf+1); 2170 // Comment out the protocol references. 2171 InsertText(LessLoc, "/*"); 2172 InsertText(GreaterLoc, "*/"); 2173 } 2174 startBuf = ++endBuf; 2175 } 2176 else { 2177 // If the function name is derived from a macro expansion, then the 2178 // argument buffer will not follow the name. Need to speak with Chris. 2179 while (*startBuf && *startBuf != ')' && *startBuf != ',') 2180 startBuf++; // scan forward (from the decl location) for argument types. 2181 startBuf++; 2182 } 2183 } 2184} 2185 2186void RewriteObjC::RewriteTypeOfDecl(VarDecl *ND) { 2187 QualType QT = ND->getType(); 2188 const Type* TypePtr = QT->getAs<Type>(); 2189 if (!isa<TypeOfExprType>(TypePtr)) 2190 return; 2191 while (isa<TypeOfExprType>(TypePtr)) { 2192 const TypeOfExprType *TypeOfExprTypePtr = cast<TypeOfExprType>(TypePtr); 2193 QT = TypeOfExprTypePtr->getUnderlyingExpr()->getType(); 2194 TypePtr = QT->getAs<Type>(); 2195 } 2196 // FIXME. This will not work for multiple declarators; as in: 2197 // __typeof__(a) b,c,d; 2198 std::string TypeAsString(QT.getAsString(Context->getPrintingPolicy())); 2199 SourceLocation DeclLoc = ND->getTypeSpecStartLoc(); 2200 const char *startBuf = SM->getCharacterData(DeclLoc); 2201 if (ND->getInit()) { 2202 std::string Name(ND->getNameAsString()); 2203 TypeAsString += " " + Name + " = "; 2204 Expr *E = ND->getInit(); 2205 SourceLocation startLoc; 2206 if (const CStyleCastExpr *ECE = dyn_cast<CStyleCastExpr>(E)) 2207 startLoc = ECE->getLParenLoc(); 2208 else 2209 startLoc = E->getLocStart(); 2210 startLoc = SM->getExpansionLoc(startLoc); 2211 const char *endBuf = SM->getCharacterData(startLoc); 2212 ReplaceText(DeclLoc, endBuf-startBuf-1, TypeAsString); 2213 } 2214 else { 2215 SourceLocation X = ND->getLocEnd(); 2216 X = SM->getExpansionLoc(X); 2217 const char *endBuf = SM->getCharacterData(X); 2218 ReplaceText(DeclLoc, endBuf-startBuf-1, TypeAsString); 2219 } 2220} 2221 2222// SynthSelGetUidFunctionDecl - SEL sel_registerName(const char *str); 2223void RewriteObjC::SynthSelGetUidFunctionDecl() { 2224 IdentifierInfo *SelGetUidIdent = &Context->Idents.get("sel_registerName"); 2225 SmallVector<QualType, 16> ArgTys; 2226 ArgTys.push_back(Context->getPointerType(Context->CharTy.withConst())); 2227 QualType getFuncType = 2228 getSimpleFunctionType(Context->getObjCSelType(), ArgTys); 2229 SelGetUidFunctionDecl = FunctionDecl::Create(*Context, TUDecl, 2230 SourceLocation(), 2231 SourceLocation(), 2232 SelGetUidIdent, getFuncType, 2233 nullptr, SC_Extern); 2234} 2235 2236void RewriteObjC::RewriteFunctionDecl(FunctionDecl *FD) { 2237 // declared in <objc/objc.h> 2238 if (FD->getIdentifier() && 2239 FD->getName() == "sel_registerName") { 2240 SelGetUidFunctionDecl = FD; 2241 return; 2242 } 2243 RewriteObjCQualifiedInterfaceTypes(FD); 2244} 2245 2246void RewriteObjC::RewriteBlockPointerType(std::string& Str, QualType Type) { 2247 std::string TypeString(Type.getAsString(Context->getPrintingPolicy())); 2248 const char *argPtr = TypeString.c_str(); 2249 if (!strchr(argPtr, '^')) { 2250 Str += TypeString; 2251 return; 2252 } 2253 while (*argPtr) { 2254 Str += (*argPtr == '^' ? '*' : *argPtr); 2255 argPtr++; 2256 } 2257} 2258 2259// FIXME. Consolidate this routine with RewriteBlockPointerType. 2260void RewriteObjC::RewriteBlockPointerTypeVariable(std::string& Str, 2261 ValueDecl *VD) { 2262 QualType Type = VD->getType(); 2263 std::string TypeString(Type.getAsString(Context->getPrintingPolicy())); 2264 const char *argPtr = TypeString.c_str(); 2265 int paren = 0; 2266 while (*argPtr) { 2267 switch (*argPtr) { 2268 case '(': 2269 Str += *argPtr; 2270 paren++; 2271 break; 2272 case ')': 2273 Str += *argPtr; 2274 paren--; 2275 break; 2276 case '^': 2277 Str += '*'; 2278 if (paren == 1) 2279 Str += VD->getNameAsString(); 2280 break; 2281 default: 2282 Str += *argPtr; 2283 break; 2284 } 2285 argPtr++; 2286 } 2287} 2288 2289 2290void RewriteObjC::RewriteBlockLiteralFunctionDecl(FunctionDecl *FD) { 2291 SourceLocation FunLocStart = FD->getTypeSpecStartLoc(); 2292 const FunctionType *funcType = FD->getType()->getAs<FunctionType>(); 2293 const FunctionProtoType *proto = dyn_cast<FunctionProtoType>(funcType); 2294 if (!proto) 2295 return; 2296 QualType Type = proto->getReturnType(); 2297 std::string FdStr = Type.getAsString(Context->getPrintingPolicy()); 2298 FdStr += " "; 2299 FdStr += FD->getName(); 2300 FdStr += "("; 2301 unsigned numArgs = proto->getNumParams(); 2302 for (unsigned i = 0; i < numArgs; i++) { 2303 QualType ArgType = proto->getParamType(i); 2304 RewriteBlockPointerType(FdStr, ArgType); 2305 if (i+1 < numArgs) 2306 FdStr += ", "; 2307 } 2308 FdStr += ");\n"; 2309 InsertText(FunLocStart, FdStr); 2310 CurFunctionDeclToDeclareForBlock = nullptr; 2311} 2312 2313// SynthSuperConstructorFunctionDecl - id objc_super(id obj, id super); 2314void RewriteObjC::SynthSuperConstructorFunctionDecl() { 2315 if (SuperConstructorFunctionDecl) 2316 return; 2317 IdentifierInfo *msgSendIdent = &Context->Idents.get("__rw_objc_super"); 2318 SmallVector<QualType, 16> ArgTys; 2319 QualType argT = Context->getObjCIdType(); 2320 assert(!argT.isNull() && "Can't find 'id' type"); 2321 ArgTys.push_back(argT); 2322 ArgTys.push_back(argT); 2323 QualType msgSendType = getSimpleFunctionType(Context->getObjCIdType(), 2324 ArgTys); 2325 SuperConstructorFunctionDecl = FunctionDecl::Create(*Context, TUDecl, 2326 SourceLocation(), 2327 SourceLocation(), 2328 msgSendIdent, msgSendType, 2329 nullptr, SC_Extern); 2330} 2331 2332// SynthMsgSendFunctionDecl - id objc_msgSend(id self, SEL op, ...); 2333void RewriteObjC::SynthMsgSendFunctionDecl() { 2334 IdentifierInfo *msgSendIdent = &Context->Idents.get("objc_msgSend"); 2335 SmallVector<QualType, 16> ArgTys; 2336 QualType argT = Context->getObjCIdType(); 2337 assert(!argT.isNull() && "Can't find 'id' type"); 2338 ArgTys.push_back(argT); 2339 argT = Context->getObjCSelType(); 2340 assert(!argT.isNull() && "Can't find 'SEL' type"); 2341 ArgTys.push_back(argT); 2342 QualType msgSendType = getSimpleFunctionType(Context->getObjCIdType(), 2343 ArgTys, /*isVariadic=*/true); 2344 MsgSendFunctionDecl = FunctionDecl::Create(*Context, TUDecl, 2345 SourceLocation(), 2346 SourceLocation(), 2347 msgSendIdent, msgSendType, 2348 nullptr, SC_Extern); 2349} 2350 2351// SynthMsgSendSuperFunctionDecl - id objc_msgSendSuper(struct objc_super *, SEL op, ...); 2352void RewriteObjC::SynthMsgSendSuperFunctionDecl() { 2353 IdentifierInfo *msgSendIdent = &Context->Idents.get("objc_msgSendSuper"); 2354 SmallVector<QualType, 16> ArgTys; 2355 RecordDecl *RD = RecordDecl::Create(*Context, TTK_Struct, TUDecl, 2356 SourceLocation(), SourceLocation(), 2357 &Context->Idents.get("objc_super")); 2358 QualType argT = Context->getPointerType(Context->getTagDeclType(RD)); 2359 assert(!argT.isNull() && "Can't build 'struct objc_super *' type"); 2360 ArgTys.push_back(argT); 2361 argT = Context->getObjCSelType(); 2362 assert(!argT.isNull() && "Can't find 'SEL' type"); 2363 ArgTys.push_back(argT); 2364 QualType msgSendType = getSimpleFunctionType(Context->getObjCIdType(), 2365 ArgTys, /*isVariadic=*/true); 2366 MsgSendSuperFunctionDecl = FunctionDecl::Create(*Context, TUDecl, 2367 SourceLocation(), 2368 SourceLocation(), 2369 msgSendIdent, msgSendType, 2370 nullptr, SC_Extern); 2371} 2372 2373// SynthMsgSendStretFunctionDecl - id objc_msgSend_stret(id self, SEL op, ...); 2374void RewriteObjC::SynthMsgSendStretFunctionDecl() { 2375 IdentifierInfo *msgSendIdent = &Context->Idents.get("objc_msgSend_stret"); 2376 SmallVector<QualType, 16> ArgTys; 2377 QualType argT = Context->getObjCIdType(); 2378 assert(!argT.isNull() && "Can't find 'id' type"); 2379 ArgTys.push_back(argT); 2380 argT = Context->getObjCSelType(); 2381 assert(!argT.isNull() && "Can't find 'SEL' type"); 2382 ArgTys.push_back(argT); 2383 QualType msgSendType = getSimpleFunctionType(Context->getObjCIdType(), 2384 ArgTys, /*isVariadic=*/true); 2385 MsgSendStretFunctionDecl = FunctionDecl::Create(*Context, TUDecl, 2386 SourceLocation(), 2387 SourceLocation(), 2388 msgSendIdent, msgSendType, 2389 nullptr, SC_Extern); 2390} 2391 2392// SynthMsgSendSuperStretFunctionDecl - 2393// id objc_msgSendSuper_stret(struct objc_super *, SEL op, ...); 2394void RewriteObjC::SynthMsgSendSuperStretFunctionDecl() { 2395 IdentifierInfo *msgSendIdent = 2396 &Context->Idents.get("objc_msgSendSuper_stret"); 2397 SmallVector<QualType, 16> ArgTys; 2398 RecordDecl *RD = RecordDecl::Create(*Context, TTK_Struct, TUDecl, 2399 SourceLocation(), SourceLocation(), 2400 &Context->Idents.get("objc_super")); 2401 QualType argT = Context->getPointerType(Context->getTagDeclType(RD)); 2402 assert(!argT.isNull() && "Can't build 'struct objc_super *' type"); 2403 ArgTys.push_back(argT); 2404 argT = Context->getObjCSelType(); 2405 assert(!argT.isNull() && "Can't find 'SEL' type"); 2406 ArgTys.push_back(argT); 2407 QualType msgSendType = getSimpleFunctionType(Context->getObjCIdType(), 2408 ArgTys, /*isVariadic=*/true); 2409 MsgSendSuperStretFunctionDecl = FunctionDecl::Create(*Context, TUDecl, 2410 SourceLocation(), 2411 SourceLocation(), 2412 msgSendIdent, 2413 msgSendType, nullptr, 2414 SC_Extern); 2415} 2416 2417// SynthMsgSendFpretFunctionDecl - double objc_msgSend_fpret(id self, SEL op, ...); 2418void RewriteObjC::SynthMsgSendFpretFunctionDecl() { 2419 IdentifierInfo *msgSendIdent = &Context->Idents.get("objc_msgSend_fpret"); 2420 SmallVector<QualType, 16> ArgTys; 2421 QualType argT = Context->getObjCIdType(); 2422 assert(!argT.isNull() && "Can't find 'id' type"); 2423 ArgTys.push_back(argT); 2424 argT = Context->getObjCSelType(); 2425 assert(!argT.isNull() && "Can't find 'SEL' type"); 2426 ArgTys.push_back(argT); 2427 QualType msgSendType = getSimpleFunctionType(Context->DoubleTy, 2428 ArgTys, /*isVariadic=*/true); 2429 MsgSendFpretFunctionDecl = FunctionDecl::Create(*Context, TUDecl, 2430 SourceLocation(), 2431 SourceLocation(), 2432 msgSendIdent, msgSendType, 2433 nullptr, SC_Extern); 2434} 2435 2436// SynthGetClassFunctionDecl - id objc_getClass(const char *name); 2437void RewriteObjC::SynthGetClassFunctionDecl() { 2438 IdentifierInfo *getClassIdent = &Context->Idents.get("objc_getClass"); 2439 SmallVector<QualType, 16> ArgTys; 2440 ArgTys.push_back(Context->getPointerType(Context->CharTy.withConst())); 2441 QualType getClassType = getSimpleFunctionType(Context->getObjCIdType(), 2442 ArgTys); 2443 GetClassFunctionDecl = FunctionDecl::Create(*Context, TUDecl, 2444 SourceLocation(), 2445 SourceLocation(), 2446 getClassIdent, getClassType, 2447 nullptr, SC_Extern); 2448} 2449 2450// SynthGetSuperClassFunctionDecl - Class class_getSuperclass(Class cls); 2451void RewriteObjC::SynthGetSuperClassFunctionDecl() { 2452 IdentifierInfo *getSuperClassIdent = 2453 &Context->Idents.get("class_getSuperclass"); 2454 SmallVector<QualType, 16> ArgTys; 2455 ArgTys.push_back(Context->getObjCClassType()); 2456 QualType getClassType = getSimpleFunctionType(Context->getObjCClassType(), 2457 ArgTys); 2458 GetSuperClassFunctionDecl = FunctionDecl::Create(*Context, TUDecl, 2459 SourceLocation(), 2460 SourceLocation(), 2461 getSuperClassIdent, 2462 getClassType, nullptr, 2463 SC_Extern); 2464} 2465 2466// SynthGetMetaClassFunctionDecl - id objc_getMetaClass(const char *name); 2467void RewriteObjC::SynthGetMetaClassFunctionDecl() { 2468 IdentifierInfo *getClassIdent = &Context->Idents.get("objc_getMetaClass"); 2469 SmallVector<QualType, 16> ArgTys; 2470 ArgTys.push_back(Context->getPointerType(Context->CharTy.withConst())); 2471 QualType getClassType = getSimpleFunctionType(Context->getObjCIdType(), 2472 ArgTys); 2473 GetMetaClassFunctionDecl = FunctionDecl::Create(*Context, TUDecl, 2474 SourceLocation(), 2475 SourceLocation(), 2476 getClassIdent, getClassType, 2477 nullptr, SC_Extern); 2478} 2479 2480Stmt *RewriteObjC::RewriteObjCStringLiteral(ObjCStringLiteral *Exp) { 2481 assert(Exp != nullptr && "Expected non-null ObjCStringLiteral"); 2482 QualType strType = getConstantStringStructType(); 2483 2484 std::string S = "__NSConstantStringImpl_"; 2485 2486 std::string tmpName = InFileName; 2487 unsigned i; 2488 for (i=0; i < tmpName.length(); i++) { 2489 char c = tmpName.at(i); 2490 // replace any non-alphanumeric characters with '_'. 2491 if (!isAlphanumeric(c)) 2492 tmpName[i] = '_'; 2493 } 2494 S += tmpName; 2495 S += "_"; 2496 S += utostr(NumObjCStringLiterals++); 2497 2498 Preamble += "static __NSConstantStringImpl " + S; 2499 Preamble += " __attribute__ ((section (\"__DATA, __cfstring\"))) = {__CFConstantStringClassReference,"; 2500 Preamble += "0x000007c8,"; // utf8_str 2501 // The pretty printer for StringLiteral handles escape characters properly. 2502 std::string prettyBufS; 2503 llvm::raw_string_ostream prettyBuf(prettyBufS); 2504 Exp->getString()->printPretty(prettyBuf, nullptr, PrintingPolicy(LangOpts)); 2505 Preamble += prettyBuf.str(); 2506 Preamble += ","; 2507 Preamble += utostr(Exp->getString()->getByteLength()) + "};\n"; 2508 2509 VarDecl *NewVD = VarDecl::Create(*Context, TUDecl, SourceLocation(), 2510 SourceLocation(), &Context->Idents.get(S), 2511 strType, nullptr, SC_Static); 2512 DeclRefExpr *DRE = new (Context) DeclRefExpr(NewVD, false, strType, VK_LValue, 2513 SourceLocation()); 2514 Expr *Unop = new (Context) UnaryOperator(DRE, UO_AddrOf, 2515 Context->getPointerType(DRE->getType()), 2516 VK_RValue, OK_Ordinary, 2517 SourceLocation()); 2518 // cast to NSConstantString * 2519 CastExpr *cast = NoTypeInfoCStyleCastExpr(Context, Exp->getType(), 2520 CK_CPointerToObjCPointerCast, Unop); 2521 ReplaceStmt(Exp, cast); 2522 // delete Exp; leak for now, see RewritePropertyOrImplicitSetter() usage for more info. 2523 return cast; 2524} 2525 2526// struct objc_super { struct objc_object *receiver; struct objc_class *super; }; 2527QualType RewriteObjC::getSuperStructType() { 2528 if (!SuperStructDecl) { 2529 SuperStructDecl = RecordDecl::Create(*Context, TTK_Struct, TUDecl, 2530 SourceLocation(), SourceLocation(), 2531 &Context->Idents.get("objc_super")); 2532 QualType FieldTypes[2]; 2533 2534 // struct objc_object *receiver; 2535 FieldTypes[0] = Context->getObjCIdType(); 2536 // struct objc_class *super; 2537 FieldTypes[1] = Context->getObjCClassType(); 2538 2539 // Create fields 2540 for (unsigned i = 0; i < 2; ++i) { 2541 SuperStructDecl->addDecl(FieldDecl::Create(*Context, SuperStructDecl, 2542 SourceLocation(), 2543 SourceLocation(), nullptr, 2544 FieldTypes[i], nullptr, 2545 /*BitWidth=*/nullptr, 2546 /*Mutable=*/false, 2547 ICIS_NoInit)); 2548 } 2549 2550 SuperStructDecl->completeDefinition(); 2551 } 2552 return Context->getTagDeclType(SuperStructDecl); 2553} 2554 2555QualType RewriteObjC::getConstantStringStructType() { 2556 if (!ConstantStringDecl) { 2557 ConstantStringDecl = RecordDecl::Create(*Context, TTK_Struct, TUDecl, 2558 SourceLocation(), SourceLocation(), 2559 &Context->Idents.get("__NSConstantStringImpl")); 2560 QualType FieldTypes[4]; 2561 2562 // struct objc_object *receiver; 2563 FieldTypes[0] = Context->getObjCIdType(); 2564 // int flags; 2565 FieldTypes[1] = Context->IntTy; 2566 // char *str; 2567 FieldTypes[2] = Context->getPointerType(Context->CharTy); 2568 // long length; 2569 FieldTypes[3] = Context->LongTy; 2570 2571 // Create fields 2572 for (unsigned i = 0; i < 4; ++i) { 2573 ConstantStringDecl->addDecl(FieldDecl::Create(*Context, 2574 ConstantStringDecl, 2575 SourceLocation(), 2576 SourceLocation(), nullptr, 2577 FieldTypes[i], nullptr, 2578 /*BitWidth=*/nullptr, 2579 /*Mutable=*/true, 2580 ICIS_NoInit)); 2581 } 2582 2583 ConstantStringDecl->completeDefinition(); 2584 } 2585 return Context->getTagDeclType(ConstantStringDecl); 2586} 2587 2588CallExpr *RewriteObjC::SynthMsgSendStretCallExpr(FunctionDecl *MsgSendStretFlavor, 2589 QualType msgSendType, 2590 QualType returnType, 2591 SmallVectorImpl<QualType> &ArgTypes, 2592 SmallVectorImpl<Expr*> &MsgExprs, 2593 ObjCMethodDecl *Method) { 2594 // Create a reference to the objc_msgSend_stret() declaration. 2595 DeclRefExpr *STDRE = new (Context) DeclRefExpr(MsgSendStretFlavor, 2596 false, msgSendType, 2597 VK_LValue, SourceLocation()); 2598 // Need to cast objc_msgSend_stret to "void *" (see above comment). 2599 CastExpr *cast = NoTypeInfoCStyleCastExpr(Context, 2600 Context->getPointerType(Context->VoidTy), 2601 CK_BitCast, STDRE); 2602 // Now do the "normal" pointer to function cast. 2603 QualType castType = getSimpleFunctionType(returnType, ArgTypes, 2604 Method ? Method->isVariadic() 2605 : false); 2606 castType = Context->getPointerType(castType); 2607 cast = NoTypeInfoCStyleCastExpr(Context, castType, CK_BitCast, 2608 cast); 2609 2610 // Don't forget the parens to enforce the proper binding. 2611 ParenExpr *PE = new (Context) ParenExpr(SourceLocation(), SourceLocation(), cast); 2612 2613 const FunctionType *FT = msgSendType->getAs<FunctionType>(); 2614 CallExpr *STCE = new (Context) CallExpr( 2615 *Context, PE, MsgExprs, FT->getReturnType(), VK_RValue, SourceLocation()); 2616 return STCE; 2617 2618} 2619 2620 2621Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp, 2622 SourceLocation StartLoc, 2623 SourceLocation EndLoc) { 2624 if (!SelGetUidFunctionDecl) 2625 SynthSelGetUidFunctionDecl(); 2626 if (!MsgSendFunctionDecl) 2627 SynthMsgSendFunctionDecl(); 2628 if (!MsgSendSuperFunctionDecl) 2629 SynthMsgSendSuperFunctionDecl(); 2630 if (!MsgSendStretFunctionDecl) 2631 SynthMsgSendStretFunctionDecl(); 2632 if (!MsgSendSuperStretFunctionDecl) 2633 SynthMsgSendSuperStretFunctionDecl(); 2634 if (!MsgSendFpretFunctionDecl) 2635 SynthMsgSendFpretFunctionDecl(); 2636 if (!GetClassFunctionDecl) 2637 SynthGetClassFunctionDecl(); 2638 if (!GetSuperClassFunctionDecl) 2639 SynthGetSuperClassFunctionDecl(); 2640 if (!GetMetaClassFunctionDecl) 2641 SynthGetMetaClassFunctionDecl(); 2642 2643 // default to objc_msgSend(). 2644 FunctionDecl *MsgSendFlavor = MsgSendFunctionDecl; 2645 // May need to use objc_msgSend_stret() as well. 2646 FunctionDecl *MsgSendStretFlavor = nullptr; 2647 if (ObjCMethodDecl *mDecl = Exp->getMethodDecl()) { 2648 QualType resultType = mDecl->getReturnType(); 2649 if (resultType->isRecordType()) 2650 MsgSendStretFlavor = MsgSendStretFunctionDecl; 2651 else if (resultType->isRealFloatingType()) 2652 MsgSendFlavor = MsgSendFpretFunctionDecl; 2653 } 2654 2655 // Synthesize a call to objc_msgSend(). 2656 SmallVector<Expr*, 8> MsgExprs; 2657 switch (Exp->getReceiverKind()) { 2658 case ObjCMessageExpr::SuperClass: { 2659 MsgSendFlavor = MsgSendSuperFunctionDecl; 2660 if (MsgSendStretFlavor) 2661 MsgSendStretFlavor = MsgSendSuperStretFunctionDecl; 2662 assert(MsgSendFlavor && "MsgSendFlavor is NULL!"); 2663 2664 ObjCInterfaceDecl *ClassDecl = CurMethodDef->getClassInterface(); 2665 2666 SmallVector<Expr*, 4> InitExprs; 2667 2668 // set the receiver to self, the first argument to all methods. 2669 InitExprs.push_back( 2670 NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(), 2671 CK_BitCast, 2672 new (Context) DeclRefExpr(CurMethodDef->getSelfDecl(), 2673 false, 2674 Context->getObjCIdType(), 2675 VK_RValue, 2676 SourceLocation())) 2677 ); // set the 'receiver'. 2678 2679 // (id)class_getSuperclass((Class)objc_getClass("CurrentClass")) 2680 SmallVector<Expr*, 8> ClsExprs; 2681 ClsExprs.push_back(getStringLiteral(ClassDecl->getIdentifier()->getName())); 2682 CallExpr *Cls = SynthesizeCallToFunctionDecl(GetMetaClassFunctionDecl, 2683 &ClsExprs[0], 2684 ClsExprs.size(), 2685 StartLoc, 2686 EndLoc); 2687 // (Class)objc_getClass("CurrentClass") 2688 CastExpr *ArgExpr = NoTypeInfoCStyleCastExpr(Context, 2689 Context->getObjCClassType(), 2690 CK_BitCast, Cls); 2691 ClsExprs.clear(); 2692 ClsExprs.push_back(ArgExpr); 2693 Cls = SynthesizeCallToFunctionDecl(GetSuperClassFunctionDecl, 2694 &ClsExprs[0], ClsExprs.size(), 2695 StartLoc, EndLoc); 2696 2697 // (id)class_getSuperclass((Class)objc_getClass("CurrentClass")) 2698 // To turn off a warning, type-cast to 'id' 2699 InitExprs.push_back( // set 'super class', using class_getSuperclass(). 2700 NoTypeInfoCStyleCastExpr(Context, 2701 Context->getObjCIdType(), 2702 CK_BitCast, Cls)); 2703 // struct objc_super 2704 QualType superType = getSuperStructType(); 2705 Expr *SuperRep; 2706 2707 if (LangOpts.MicrosoftExt) { 2708 SynthSuperConstructorFunctionDecl(); 2709 // Simulate a constructor call... 2710 DeclRefExpr *DRE = new (Context) DeclRefExpr(SuperConstructorFunctionDecl, 2711 false, superType, VK_LValue, 2712 SourceLocation()); 2713 SuperRep = new (Context) CallExpr(*Context, DRE, InitExprs, 2714 superType, VK_LValue, 2715 SourceLocation()); 2716 // The code for super is a little tricky to prevent collision with 2717 // the structure definition in the header. The rewriter has it's own 2718 // internal definition (__rw_objc_super) that is uses. This is why 2719 // we need the cast below. For example: 2720 // (struct objc_super *)&__rw_objc_super((id)self, (id)objc_getClass("SUPER")) 2721 // 2722 SuperRep = new (Context) UnaryOperator(SuperRep, UO_AddrOf, 2723 Context->getPointerType(SuperRep->getType()), 2724 VK_RValue, OK_Ordinary, 2725 SourceLocation()); 2726 SuperRep = NoTypeInfoCStyleCastExpr(Context, 2727 Context->getPointerType(superType), 2728 CK_BitCast, SuperRep); 2729 } else { 2730 // (struct objc_super) { <exprs from above> } 2731 InitListExpr *ILE = 2732 new (Context) InitListExpr(*Context, SourceLocation(), InitExprs, 2733 SourceLocation()); 2734 TypeSourceInfo *superTInfo 2735 = Context->getTrivialTypeSourceInfo(superType); 2736 SuperRep = new (Context) CompoundLiteralExpr(SourceLocation(), superTInfo, 2737 superType, VK_LValue, 2738 ILE, false); 2739 // struct objc_super * 2740 SuperRep = new (Context) UnaryOperator(SuperRep, UO_AddrOf, 2741 Context->getPointerType(SuperRep->getType()), 2742 VK_RValue, OK_Ordinary, 2743 SourceLocation()); 2744 } 2745 MsgExprs.push_back(SuperRep); 2746 break; 2747 } 2748 2749 case ObjCMessageExpr::Class: { 2750 SmallVector<Expr*, 8> ClsExprs; 2751 ObjCInterfaceDecl *Class 2752 = Exp->getClassReceiver()->getAs<ObjCObjectType>()->getInterface(); 2753 IdentifierInfo *clsName = Class->getIdentifier(); 2754 ClsExprs.push_back(getStringLiteral(clsName->getName())); 2755 CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl, 2756 &ClsExprs[0], 2757 ClsExprs.size(), 2758 StartLoc, EndLoc); 2759 MsgExprs.push_back(Cls); 2760 break; 2761 } 2762 2763 case ObjCMessageExpr::SuperInstance:{ 2764 MsgSendFlavor = MsgSendSuperFunctionDecl; 2765 if (MsgSendStretFlavor) 2766 MsgSendStretFlavor = MsgSendSuperStretFunctionDecl; 2767 assert(MsgSendFlavor && "MsgSendFlavor is NULL!"); 2768 ObjCInterfaceDecl *ClassDecl = CurMethodDef->getClassInterface(); 2769 SmallVector<Expr*, 4> InitExprs; 2770 2771 InitExprs.push_back( 2772 NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(), 2773 CK_BitCast, 2774 new (Context) DeclRefExpr(CurMethodDef->getSelfDecl(), 2775 false, 2776 Context->getObjCIdType(), 2777 VK_RValue, SourceLocation())) 2778 ); // set the 'receiver'. 2779 2780 // (id)class_getSuperclass((Class)objc_getClass("CurrentClass")) 2781 SmallVector<Expr*, 8> ClsExprs; 2782 ClsExprs.push_back(getStringLiteral(ClassDecl->getIdentifier()->getName())); 2783 CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl, 2784 &ClsExprs[0], 2785 ClsExprs.size(), 2786 StartLoc, EndLoc); 2787 // (Class)objc_getClass("CurrentClass") 2788 CastExpr *ArgExpr = NoTypeInfoCStyleCastExpr(Context, 2789 Context->getObjCClassType(), 2790 CK_BitCast, Cls); 2791 ClsExprs.clear(); 2792 ClsExprs.push_back(ArgExpr); 2793 Cls = SynthesizeCallToFunctionDecl(GetSuperClassFunctionDecl, 2794 &ClsExprs[0], ClsExprs.size(), 2795 StartLoc, EndLoc); 2796 2797 // (id)class_getSuperclass((Class)objc_getClass("CurrentClass")) 2798 // To turn off a warning, type-cast to 'id' 2799 InitExprs.push_back( 2800 // set 'super class', using class_getSuperclass(). 2801 NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(), 2802 CK_BitCast, Cls)); 2803 // struct objc_super 2804 QualType superType = getSuperStructType(); 2805 Expr *SuperRep; 2806 2807 if (LangOpts.MicrosoftExt) { 2808 SynthSuperConstructorFunctionDecl(); 2809 // Simulate a constructor call... 2810 DeclRefExpr *DRE = new (Context) DeclRefExpr(SuperConstructorFunctionDecl, 2811 false, superType, VK_LValue, 2812 SourceLocation()); 2813 SuperRep = new (Context) CallExpr(*Context, DRE, InitExprs, 2814 superType, VK_LValue, SourceLocation()); 2815 // The code for super is a little tricky to prevent collision with 2816 // the structure definition in the header. The rewriter has it's own 2817 // internal definition (__rw_objc_super) that is uses. This is why 2818 // we need the cast below. For example: 2819 // (struct objc_super *)&__rw_objc_super((id)self, (id)objc_getClass("SUPER")) 2820 // 2821 SuperRep = new (Context) UnaryOperator(SuperRep, UO_AddrOf, 2822 Context->getPointerType(SuperRep->getType()), 2823 VK_RValue, OK_Ordinary, 2824 SourceLocation()); 2825 SuperRep = NoTypeInfoCStyleCastExpr(Context, 2826 Context->getPointerType(superType), 2827 CK_BitCast, SuperRep); 2828 } else { 2829 // (struct objc_super) { <exprs from above> } 2830 InitListExpr *ILE = 2831 new (Context) InitListExpr(*Context, SourceLocation(), InitExprs, 2832 SourceLocation()); 2833 TypeSourceInfo *superTInfo 2834 = Context->getTrivialTypeSourceInfo(superType); 2835 SuperRep = new (Context) CompoundLiteralExpr(SourceLocation(), superTInfo, 2836 superType, VK_RValue, ILE, 2837 false); 2838 } 2839 MsgExprs.push_back(SuperRep); 2840 break; 2841 } 2842 2843 case ObjCMessageExpr::Instance: { 2844 // Remove all type-casts because it may contain objc-style types; e.g. 2845 // Foo<Proto> *. 2846 Expr *recExpr = Exp->getInstanceReceiver(); 2847 while (CStyleCastExpr *CE = dyn_cast<CStyleCastExpr>(recExpr)) 2848 recExpr = CE->getSubExpr(); 2849 CastKind CK = recExpr->getType()->isObjCObjectPointerType() 2850 ? CK_BitCast : recExpr->getType()->isBlockPointerType() 2851 ? CK_BlockPointerToObjCPointerCast 2852 : CK_CPointerToObjCPointerCast; 2853 2854 recExpr = NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(), 2855 CK, recExpr); 2856 MsgExprs.push_back(recExpr); 2857 break; 2858 } 2859 } 2860 2861 // Create a call to sel_registerName("selName"), it will be the 2nd argument. 2862 SmallVector<Expr*, 8> SelExprs; 2863 SelExprs.push_back(getStringLiteral(Exp->getSelector().getAsString())); 2864 CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl, 2865 &SelExprs[0], SelExprs.size(), 2866 StartLoc, 2867 EndLoc); 2868 MsgExprs.push_back(SelExp); 2869 2870 // Now push any user supplied arguments. 2871 for (unsigned i = 0; i < Exp->getNumArgs(); i++) { 2872 Expr *userExpr = Exp->getArg(i); 2873 // Make all implicit casts explicit...ICE comes in handy:-) 2874 if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(userExpr)) { 2875 // Reuse the ICE type, it is exactly what the doctor ordered. 2876 QualType type = ICE->getType(); 2877 if (needToScanForQualifiers(type)) 2878 type = Context->getObjCIdType(); 2879 // Make sure we convert "type (^)(...)" to "type (*)(...)". 2880 (void)convertBlockPointerToFunctionPointer(type); 2881 const Expr *SubExpr = ICE->IgnoreParenImpCasts(); 2882 CastKind CK; 2883 if (SubExpr->getType()->isIntegralType(*Context) && 2884 type->isBooleanType()) { 2885 CK = CK_IntegralToBoolean; 2886 } else if (type->isObjCObjectPointerType()) { 2887 if (SubExpr->getType()->isBlockPointerType()) { 2888 CK = CK_BlockPointerToObjCPointerCast; 2889 } else if (SubExpr->getType()->isPointerType()) { 2890 CK = CK_CPointerToObjCPointerCast; 2891 } else { 2892 CK = CK_BitCast; 2893 } 2894 } else { 2895 CK = CK_BitCast; 2896 } 2897 2898 userExpr = NoTypeInfoCStyleCastExpr(Context, type, CK, userExpr); 2899 } 2900 // Make id<P...> cast into an 'id' cast. 2901 else if (CStyleCastExpr *CE = dyn_cast<CStyleCastExpr>(userExpr)) { 2902 if (CE->getType()->isObjCQualifiedIdType()) { 2903 while ((CE = dyn_cast<CStyleCastExpr>(userExpr))) 2904 userExpr = CE->getSubExpr(); 2905 CastKind CK; 2906 if (userExpr->getType()->isIntegralType(*Context)) { 2907 CK = CK_IntegralToPointer; 2908 } else if (userExpr->getType()->isBlockPointerType()) { 2909 CK = CK_BlockPointerToObjCPointerCast; 2910 } else if (userExpr->getType()->isPointerType()) { 2911 CK = CK_CPointerToObjCPointerCast; 2912 } else { 2913 CK = CK_BitCast; 2914 } 2915 userExpr = NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(), 2916 CK, userExpr); 2917 } 2918 } 2919 MsgExprs.push_back(userExpr); 2920 // We've transferred the ownership to MsgExprs. For now, we *don't* null 2921 // out the argument in the original expression (since we aren't deleting 2922 // the ObjCMessageExpr). See RewritePropertyOrImplicitSetter() usage for more info. 2923 //Exp->setArg(i, 0); 2924 } 2925 // Generate the funky cast. 2926 CastExpr *cast; 2927 SmallVector<QualType, 8> ArgTypes; 2928 QualType returnType; 2929 2930 // Push 'id' and 'SEL', the 2 implicit arguments. 2931 if (MsgSendFlavor == MsgSendSuperFunctionDecl) 2932 ArgTypes.push_back(Context->getPointerType(getSuperStructType())); 2933 else 2934 ArgTypes.push_back(Context->getObjCIdType()); 2935 ArgTypes.push_back(Context->getObjCSelType()); 2936 if (ObjCMethodDecl *OMD = Exp->getMethodDecl()) { 2937 // Push any user argument types. 2938 for (const auto *PI : OMD->params()) { 2939 QualType t = PI->getType()->isObjCQualifiedIdType() 2940 ? Context->getObjCIdType() 2941 : PI->getType(); 2942 // Make sure we convert "t (^)(...)" to "t (*)(...)". 2943 (void)convertBlockPointerToFunctionPointer(t); 2944 ArgTypes.push_back(t); 2945 } 2946 returnType = Exp->getType(); 2947 convertToUnqualifiedObjCType(returnType); 2948 (void)convertBlockPointerToFunctionPointer(returnType); 2949 } else { 2950 returnType = Context->getObjCIdType(); 2951 } 2952 // Get the type, we will need to reference it in a couple spots. 2953 QualType msgSendType = MsgSendFlavor->getType(); 2954 2955 // Create a reference to the objc_msgSend() declaration. 2956 DeclRefExpr *DRE = new (Context) DeclRefExpr(MsgSendFlavor, false, msgSendType, 2957 VK_LValue, SourceLocation()); 2958 2959 // Need to cast objc_msgSend to "void *" (to workaround a GCC bandaid). 2960 // If we don't do this cast, we get the following bizarre warning/note: 2961 // xx.m:13: warning: function called through a non-compatible type 2962 // xx.m:13: note: if this code is reached, the program will abort 2963 cast = NoTypeInfoCStyleCastExpr(Context, 2964 Context->getPointerType(Context->VoidTy), 2965 CK_BitCast, DRE); 2966 2967 // Now do the "normal" pointer to function cast. 2968 // If we don't have a method decl, force a variadic cast. 2969 const ObjCMethodDecl *MD = Exp->getMethodDecl(); 2970 QualType castType = 2971 getSimpleFunctionType(returnType, ArgTypes, MD ? MD->isVariadic() : true); 2972 castType = Context->getPointerType(castType); 2973 cast = NoTypeInfoCStyleCastExpr(Context, castType, CK_BitCast, 2974 cast); 2975 2976 // Don't forget the parens to enforce the proper binding. 2977 ParenExpr *PE = new (Context) ParenExpr(StartLoc, EndLoc, cast); 2978 2979 const FunctionType *FT = msgSendType->getAs<FunctionType>(); 2980 CallExpr *CE = new (Context) 2981 CallExpr(*Context, PE, MsgExprs, FT->getReturnType(), VK_RValue, EndLoc); 2982 Stmt *ReplacingStmt = CE; 2983 if (MsgSendStretFlavor) { 2984 // We have the method which returns a struct/union. Must also generate 2985 // call to objc_msgSend_stret and hang both varieties on a conditional 2986 // expression which dictate which one to envoke depending on size of 2987 // method's return type. 2988 2989 CallExpr *STCE = SynthMsgSendStretCallExpr(MsgSendStretFlavor, 2990 msgSendType, returnType, 2991 ArgTypes, MsgExprs, 2992 Exp->getMethodDecl()); 2993 2994 // Build sizeof(returnType) 2995 UnaryExprOrTypeTraitExpr *sizeofExpr = 2996 new (Context) UnaryExprOrTypeTraitExpr(UETT_SizeOf, 2997 Context->getTrivialTypeSourceInfo(returnType), 2998 Context->getSizeType(), SourceLocation(), 2999 SourceLocation()); 3000 // (sizeof(returnType) <= 8 ? objc_msgSend(...) : objc_msgSend_stret(...)) 3001 // FIXME: Value of 8 is base on ppc32/x86 ABI for the most common cases. 3002 // For X86 it is more complicated and some kind of target specific routine 3003 // is needed to decide what to do. 3004 unsigned IntSize = 3005 static_cast<unsigned>(Context->getTypeSize(Context->IntTy)); 3006 IntegerLiteral *limit = IntegerLiteral::Create(*Context, 3007 llvm::APInt(IntSize, 8), 3008 Context->IntTy, 3009 SourceLocation()); 3010 BinaryOperator *lessThanExpr = 3011 new (Context) BinaryOperator(sizeofExpr, limit, BO_LE, Context->IntTy, 3012 VK_RValue, OK_Ordinary, SourceLocation(), 3013 false); 3014 // (sizeof(returnType) <= 8 ? objc_msgSend(...) : objc_msgSend_stret(...)) 3015 ConditionalOperator *CondExpr = 3016 new (Context) ConditionalOperator(lessThanExpr, 3017 SourceLocation(), CE, 3018 SourceLocation(), STCE, 3019 returnType, VK_RValue, OK_Ordinary); 3020 ReplacingStmt = new (Context) ParenExpr(SourceLocation(), SourceLocation(), 3021 CondExpr); 3022 } 3023 // delete Exp; leak for now, see RewritePropertyOrImplicitSetter() usage for more info. 3024 return ReplacingStmt; 3025} 3026 3027Stmt *RewriteObjC::RewriteMessageExpr(ObjCMessageExpr *Exp) { 3028 Stmt *ReplacingStmt = SynthMessageExpr(Exp, Exp->getLocStart(), 3029 Exp->getLocEnd()); 3030 3031 // Now do the actual rewrite. 3032 ReplaceStmt(Exp, ReplacingStmt); 3033 3034 // delete Exp; leak for now, see RewritePropertyOrImplicitSetter() usage for more info. 3035 return ReplacingStmt; 3036} 3037 3038// typedef struct objc_object Protocol; 3039QualType RewriteObjC::getProtocolType() { 3040 if (!ProtocolTypeDecl) { 3041 TypeSourceInfo *TInfo 3042 = Context->getTrivialTypeSourceInfo(Context->getObjCIdType()); 3043 ProtocolTypeDecl = TypedefDecl::Create(*Context, TUDecl, 3044 SourceLocation(), SourceLocation(), 3045 &Context->Idents.get("Protocol"), 3046 TInfo); 3047 } 3048 return Context->getTypeDeclType(ProtocolTypeDecl); 3049} 3050 3051/// RewriteObjCProtocolExpr - Rewrite a protocol expression into 3052/// a synthesized/forward data reference (to the protocol's metadata). 3053/// The forward references (and metadata) are generated in 3054/// RewriteObjC::HandleTranslationUnit(). 3055Stmt *RewriteObjC::RewriteObjCProtocolExpr(ObjCProtocolExpr *Exp) { 3056 std::string Name = "_OBJC_PROTOCOL_" + Exp->getProtocol()->getNameAsString(); 3057 IdentifierInfo *ID = &Context->Idents.get(Name); 3058 VarDecl *VD = VarDecl::Create(*Context, TUDecl, SourceLocation(), 3059 SourceLocation(), ID, getProtocolType(), 3060 nullptr, SC_Extern); 3061 DeclRefExpr *DRE = new (Context) DeclRefExpr(VD, false, getProtocolType(), 3062 VK_LValue, SourceLocation()); 3063 Expr *DerefExpr = new (Context) UnaryOperator(DRE, UO_AddrOf, 3064 Context->getPointerType(DRE->getType()), 3065 VK_RValue, OK_Ordinary, SourceLocation()); 3066 CastExpr *castExpr = NoTypeInfoCStyleCastExpr(Context, DerefExpr->getType(), 3067 CK_BitCast, 3068 DerefExpr); 3069 ReplaceStmt(Exp, castExpr); 3070 ProtocolExprDecls.insert(Exp->getProtocol()->getCanonicalDecl()); 3071 // delete Exp; leak for now, see RewritePropertyOrImplicitSetter() usage for more info. 3072 return castExpr; 3073 3074} 3075 3076bool RewriteObjC::BufferContainsPPDirectives(const char *startBuf, 3077 const char *endBuf) { 3078 while (startBuf < endBuf) { 3079 if (*startBuf == '#') { 3080 // Skip whitespace. 3081 for (++startBuf; startBuf[0] == ' ' || startBuf[0] == '\t'; ++startBuf) 3082 ; 3083 if (!strncmp(startBuf, "if", strlen("if")) || 3084 !strncmp(startBuf, "ifdef", strlen("ifdef")) || 3085 !strncmp(startBuf, "ifndef", strlen("ifndef")) || 3086 !strncmp(startBuf, "define", strlen("define")) || 3087 !strncmp(startBuf, "undef", strlen("undef")) || 3088 !strncmp(startBuf, "else", strlen("else")) || 3089 !strncmp(startBuf, "elif", strlen("elif")) || 3090 !strncmp(startBuf, "endif", strlen("endif")) || 3091 !strncmp(startBuf, "pragma", strlen("pragma")) || 3092 !strncmp(startBuf, "include", strlen("include")) || 3093 !strncmp(startBuf, "import", strlen("import")) || 3094 !strncmp(startBuf, "include_next", strlen("include_next"))) 3095 return true; 3096 } 3097 startBuf++; 3098 } 3099 return false; 3100} 3101 3102/// RewriteObjCInternalStruct - Rewrite one internal struct corresponding to 3103/// an objective-c class with ivars. 3104void RewriteObjC::RewriteObjCInternalStruct(ObjCInterfaceDecl *CDecl, 3105 std::string &Result) { 3106 assert(CDecl && "Class missing in SynthesizeObjCInternalStruct"); 3107 assert(CDecl->getName() != "" && 3108 "Name missing in SynthesizeObjCInternalStruct"); 3109 // Do not synthesize more than once. 3110 if (ObjCSynthesizedStructs.count(CDecl)) 3111 return; 3112 ObjCInterfaceDecl *RCDecl = CDecl->getSuperClass(); 3113 int NumIvars = CDecl->ivar_size(); 3114 SourceLocation LocStart = CDecl->getLocStart(); 3115 SourceLocation LocEnd = CDecl->getEndOfDefinitionLoc(); 3116 3117 const char *startBuf = SM->getCharacterData(LocStart); 3118 const char *endBuf = SM->getCharacterData(LocEnd); 3119 3120 // If no ivars and no root or if its root, directly or indirectly, 3121 // have no ivars (thus not synthesized) then no need to synthesize this class. 3122 if ((!CDecl->isThisDeclarationADefinition() || NumIvars == 0) && 3123 (!RCDecl || !ObjCSynthesizedStructs.count(RCDecl))) { 3124 endBuf += Lexer::MeasureTokenLength(LocEnd, *SM, LangOpts); 3125 ReplaceText(LocStart, endBuf-startBuf, Result); 3126 return; 3127 } 3128 3129 // FIXME: This has potential of causing problem. If 3130 // SynthesizeObjCInternalStruct is ever called recursively. 3131 Result += "\nstruct "; 3132 Result += CDecl->getNameAsString(); 3133 if (LangOpts.MicrosoftExt) 3134 Result += "_IMPL"; 3135 3136 if (NumIvars > 0) { 3137 const char *cursor = strchr(startBuf, '{'); 3138 assert((cursor && endBuf) 3139 && "SynthesizeObjCInternalStruct - malformed @interface"); 3140 // If the buffer contains preprocessor directives, we do more fine-grained 3141 // rewrites. This is intended to fix code that looks like (which occurs in 3142 // NSURL.h, for example): 3143 // 3144 // #ifdef XYZ 3145 // @interface Foo : NSObject 3146 // #else 3147 // @interface FooBar : NSObject 3148 // #endif 3149 // { 3150 // int i; 3151 // } 3152 // @end 3153 // 3154 // This clause is segregated to avoid breaking the common case. 3155 if (BufferContainsPPDirectives(startBuf, cursor)) { 3156 SourceLocation L = RCDecl ? CDecl->getSuperClassLoc() : 3157 CDecl->getAtStartLoc(); 3158 const char *endHeader = SM->getCharacterData(L); 3159 endHeader += Lexer::MeasureTokenLength(L, *SM, LangOpts); 3160 3161 if (CDecl->protocol_begin() != CDecl->protocol_end()) { 3162 // advance to the end of the referenced protocols. 3163 while (endHeader < cursor && *endHeader != '>') endHeader++; 3164 endHeader++; 3165 } 3166 // rewrite the original header 3167 ReplaceText(LocStart, endHeader-startBuf, Result); 3168 } else { 3169 // rewrite the original header *without* disturbing the '{' 3170 ReplaceText(LocStart, cursor-startBuf, Result); 3171 } 3172 if (RCDecl && ObjCSynthesizedStructs.count(RCDecl)) { 3173 Result = "\n struct "; 3174 Result += RCDecl->getNameAsString(); 3175 Result += "_IMPL "; 3176 Result += RCDecl->getNameAsString(); 3177 Result += "_IVARS;\n"; 3178 3179 // insert the super class structure definition. 3180 SourceLocation OnePastCurly = 3181 LocStart.getLocWithOffset(cursor-startBuf+1); 3182 InsertText(OnePastCurly, Result); 3183 } 3184 cursor++; // past '{' 3185 3186 // Now comment out any visibility specifiers. 3187 while (cursor < endBuf) { 3188 if (*cursor == '@') { 3189 SourceLocation atLoc = LocStart.getLocWithOffset(cursor-startBuf); 3190 // Skip whitespace. 3191 for (++cursor; cursor[0] == ' ' || cursor[0] == '\t'; ++cursor) 3192 /*scan*/; 3193 3194 // FIXME: presence of @public, etc. inside comment results in 3195 // this transformation as well, which is still correct c-code. 3196 if (!strncmp(cursor, "public", strlen("public")) || 3197 !strncmp(cursor, "private", strlen("private")) || 3198 !strncmp(cursor, "package", strlen("package")) || 3199 !strncmp(cursor, "protected", strlen("protected"))) 3200 InsertText(atLoc, "// "); 3201 } 3202 // FIXME: If there are cases where '<' is used in ivar declaration part 3203 // of user code, then scan the ivar list and use needToScanForQualifiers 3204 // for type checking. 3205 else if (*cursor == '<') { 3206 SourceLocation atLoc = LocStart.getLocWithOffset(cursor-startBuf); 3207 InsertText(atLoc, "/* "); 3208 cursor = strchr(cursor, '>'); 3209 cursor++; 3210 atLoc = LocStart.getLocWithOffset(cursor-startBuf); 3211 InsertText(atLoc, " */"); 3212 } else if (*cursor == '^') { // rewrite block specifier. 3213 SourceLocation caretLoc = LocStart.getLocWithOffset(cursor-startBuf); 3214 ReplaceText(caretLoc, 1, "*"); 3215 } 3216 cursor++; 3217 } 3218 // Don't forget to add a ';'!! 3219 InsertText(LocEnd.getLocWithOffset(1), ";"); 3220 } else { // we don't have any instance variables - insert super struct. 3221 endBuf += Lexer::MeasureTokenLength(LocEnd, *SM, LangOpts); 3222 Result += " {\n struct "; 3223 Result += RCDecl->getNameAsString(); 3224 Result += "_IMPL "; 3225 Result += RCDecl->getNameAsString(); 3226 Result += "_IVARS;\n};\n"; 3227 ReplaceText(LocStart, endBuf-startBuf, Result); 3228 } 3229 // Mark this struct as having been generated. 3230 if (!ObjCSynthesizedStructs.insert(CDecl).second) 3231 llvm_unreachable("struct already synthesize- SynthesizeObjCInternalStruct"); 3232} 3233 3234//===----------------------------------------------------------------------===// 3235// Meta Data Emission 3236//===----------------------------------------------------------------------===// 3237 3238 3239/// RewriteImplementations - This routine rewrites all method implementations 3240/// and emits meta-data. 3241 3242void RewriteObjC::RewriteImplementations() { 3243 int ClsDefCount = ClassImplementation.size(); 3244 int CatDefCount = CategoryImplementation.size(); 3245 3246 // Rewrite implemented methods 3247 for (int i = 0; i < ClsDefCount; i++) 3248 RewriteImplementationDecl(ClassImplementation[i]); 3249 3250 for (int i = 0; i < CatDefCount; i++) 3251 RewriteImplementationDecl(CategoryImplementation[i]); 3252} 3253 3254void RewriteObjC::RewriteByRefString(std::string &ResultStr, 3255 const std::string &Name, 3256 ValueDecl *VD, bool def) { 3257 assert(BlockByRefDeclNo.count(VD) && 3258 "RewriteByRefString: ByRef decl missing"); 3259 if (def) 3260 ResultStr += "struct "; 3261 ResultStr += "__Block_byref_" + Name + 3262 "_" + utostr(BlockByRefDeclNo[VD]) ; 3263} 3264 3265static bool HasLocalVariableExternalStorage(ValueDecl *VD) { 3266 if (VarDecl *Var = dyn_cast<VarDecl>(VD)) 3267 return (Var->isFunctionOrMethodVarDecl() && !Var->hasLocalStorage()); 3268 return false; 3269} 3270 3271std::string RewriteObjC::SynthesizeBlockFunc(BlockExpr *CE, int i, 3272 StringRef funcName, 3273 std::string Tag) { 3274 const FunctionType *AFT = CE->getFunctionType(); 3275 QualType RT = AFT->getReturnType(); 3276 std::string StructRef = "struct " + Tag; 3277 std::string S = "static " + RT.getAsString(Context->getPrintingPolicy()) + " __" + 3278 funcName.str() + "_" + "block_func_" + utostr(i); 3279 3280 BlockDecl *BD = CE->getBlockDecl(); 3281 3282 if (isa<FunctionNoProtoType>(AFT)) { 3283 // No user-supplied arguments. Still need to pass in a pointer to the 3284 // block (to reference imported block decl refs). 3285 S += "(" + StructRef + " *__cself)"; 3286 } else if (BD->param_empty()) { 3287 S += "(" + StructRef + " *__cself)"; 3288 } else { 3289 const FunctionProtoType *FT = cast<FunctionProtoType>(AFT); 3290 assert(FT && "SynthesizeBlockFunc: No function proto"); 3291 S += '('; 3292 // first add the implicit argument. 3293 S += StructRef + " *__cself, "; 3294 std::string ParamStr; 3295 for (BlockDecl::param_iterator AI = BD->param_begin(), 3296 E = BD->param_end(); AI != E; ++AI) { 3297 if (AI != BD->param_begin()) S += ", "; 3298 ParamStr = (*AI)->getNameAsString(); 3299 QualType QT = (*AI)->getType(); 3300 (void)convertBlockPointerToFunctionPointer(QT); 3301 QT.getAsStringInternal(ParamStr, Context->getPrintingPolicy()); 3302 S += ParamStr; 3303 } 3304 if (FT->isVariadic()) { 3305 if (!BD->param_empty()) S += ", "; 3306 S += "..."; 3307 } 3308 S += ')'; 3309 } 3310 S += " {\n"; 3311 3312 // Create local declarations to avoid rewriting all closure decl ref exprs. 3313 // First, emit a declaration for all "by ref" decls. 3314 for (SmallVectorImpl<ValueDecl *>::iterator I = BlockByRefDecls.begin(), 3315 E = BlockByRefDecls.end(); I != E; ++I) { 3316 S += " "; 3317 std::string Name = (*I)->getNameAsString(); 3318 std::string TypeString; 3319 RewriteByRefString(TypeString, Name, (*I)); 3320 TypeString += " *"; 3321 Name = TypeString + Name; 3322 S += Name + " = __cself->" + (*I)->getNameAsString() + "; // bound by ref\n"; 3323 } 3324 // Next, emit a declaration for all "by copy" declarations. 3325 for (SmallVectorImpl<ValueDecl *>::iterator I = BlockByCopyDecls.begin(), 3326 E = BlockByCopyDecls.end(); I != E; ++I) { 3327 S += " "; 3328 // Handle nested closure invocation. For example: 3329 // 3330 // void (^myImportedClosure)(void); 3331 // myImportedClosure = ^(void) { setGlobalInt(x + y); }; 3332 // 3333 // void (^anotherClosure)(void); 3334 // anotherClosure = ^(void) { 3335 // myImportedClosure(); // import and invoke the closure 3336 // }; 3337 // 3338 if (isTopLevelBlockPointerType((*I)->getType())) { 3339 RewriteBlockPointerTypeVariable(S, (*I)); 3340 S += " = ("; 3341 RewriteBlockPointerType(S, (*I)->getType()); 3342 S += ")"; 3343 S += "__cself->" + (*I)->getNameAsString() + "; // bound by copy\n"; 3344 } 3345 else { 3346 std::string Name = (*I)->getNameAsString(); 3347 QualType QT = (*I)->getType(); 3348 if (HasLocalVariableExternalStorage(*I)) 3349 QT = Context->getPointerType(QT); 3350 QT.getAsStringInternal(Name, Context->getPrintingPolicy()); 3351 S += Name + " = __cself->" + 3352 (*I)->getNameAsString() + "; // bound by copy\n"; 3353 } 3354 } 3355 std::string RewrittenStr = RewrittenBlockExprs[CE]; 3356 const char *cstr = RewrittenStr.c_str(); 3357 while (*cstr++ != '{') ; 3358 S += cstr; 3359 S += "\n"; 3360 return S; 3361} 3362 3363std::string RewriteObjC::SynthesizeBlockHelperFuncs(BlockExpr *CE, int i, 3364 StringRef funcName, 3365 std::string Tag) { 3366 std::string StructRef = "struct " + Tag; 3367 std::string S = "static void __"; 3368 3369 S += funcName; 3370 S += "_block_copy_" + utostr(i); 3371 S += "(" + StructRef; 3372 S += "*dst, " + StructRef; 3373 S += "*src) {"; 3374 for (ValueDecl *VD : ImportedBlockDecls) { 3375 S += "_Block_object_assign((void*)&dst->"; 3376 S += VD->getNameAsString(); 3377 S += ", (void*)src->"; 3378 S += VD->getNameAsString(); 3379 if (BlockByRefDeclsPtrSet.count(VD)) 3380 S += ", " + utostr(BLOCK_FIELD_IS_BYREF) + "/*BLOCK_FIELD_IS_BYREF*/);"; 3381 else if (VD->getType()->isBlockPointerType()) 3382 S += ", " + utostr(BLOCK_FIELD_IS_BLOCK) + "/*BLOCK_FIELD_IS_BLOCK*/);"; 3383 else 3384 S += ", " + utostr(BLOCK_FIELD_IS_OBJECT) + "/*BLOCK_FIELD_IS_OBJECT*/);"; 3385 } 3386 S += "}\n"; 3387 3388 S += "\nstatic void __"; 3389 S += funcName; 3390 S += "_block_dispose_" + utostr(i); 3391 S += "(" + StructRef; 3392 S += "*src) {"; 3393 for (ValueDecl *VD : ImportedBlockDecls) { 3394 S += "_Block_object_dispose((void*)src->"; 3395 S += VD->getNameAsString(); 3396 if (BlockByRefDeclsPtrSet.count(VD)) 3397 S += ", " + utostr(BLOCK_FIELD_IS_BYREF) + "/*BLOCK_FIELD_IS_BYREF*/);"; 3398 else if (VD->getType()->isBlockPointerType()) 3399 S += ", " + utostr(BLOCK_FIELD_IS_BLOCK) + "/*BLOCK_FIELD_IS_BLOCK*/);"; 3400 else 3401 S += ", " + utostr(BLOCK_FIELD_IS_OBJECT) + "/*BLOCK_FIELD_IS_OBJECT*/);"; 3402 } 3403 S += "}\n"; 3404 return S; 3405} 3406 3407std::string RewriteObjC::SynthesizeBlockImpl(BlockExpr *CE, std::string Tag, 3408 std::string Desc) { 3409 std::string S = "\nstruct " + Tag; 3410 std::string Constructor = " " + Tag; 3411 3412 S += " {\n struct __block_impl impl;\n"; 3413 S += " struct " + Desc; 3414 S += "* Desc;\n"; 3415 3416 Constructor += "(void *fp, "; // Invoke function pointer. 3417 Constructor += "struct " + Desc; // Descriptor pointer. 3418 Constructor += " *desc"; 3419 3420 if (BlockDeclRefs.size()) { 3421 // Output all "by copy" declarations. 3422 for (SmallVectorImpl<ValueDecl *>::iterator I = BlockByCopyDecls.begin(), 3423 E = BlockByCopyDecls.end(); I != E; ++I) { 3424 S += " "; 3425 std::string FieldName = (*I)->getNameAsString(); 3426 std::string ArgName = "_" + FieldName; 3427 // Handle nested closure invocation. For example: 3428 // 3429 // void (^myImportedBlock)(void); 3430 // myImportedBlock = ^(void) { setGlobalInt(x + y); }; 3431 // 3432 // void (^anotherBlock)(void); 3433 // anotherBlock = ^(void) { 3434 // myImportedBlock(); // import and invoke the closure 3435 // }; 3436 // 3437 if (isTopLevelBlockPointerType((*I)->getType())) { 3438 S += "struct __block_impl *"; 3439 Constructor += ", void *" + ArgName; 3440 } else { 3441 QualType QT = (*I)->getType(); 3442 if (HasLocalVariableExternalStorage(*I)) 3443 QT = Context->getPointerType(QT); 3444 QT.getAsStringInternal(FieldName, Context->getPrintingPolicy()); 3445 QT.getAsStringInternal(ArgName, Context->getPrintingPolicy()); 3446 Constructor += ", " + ArgName; 3447 } 3448 S += FieldName + ";\n"; 3449 } 3450 // Output all "by ref" declarations. 3451 for (SmallVectorImpl<ValueDecl *>::iterator I = BlockByRefDecls.begin(), 3452 E = BlockByRefDecls.end(); I != E; ++I) { 3453 S += " "; 3454 std::string FieldName = (*I)->getNameAsString(); 3455 std::string ArgName = "_" + FieldName; 3456 { 3457 std::string TypeString; 3458 RewriteByRefString(TypeString, FieldName, (*I)); 3459 TypeString += " *"; 3460 FieldName = TypeString + FieldName; 3461 ArgName = TypeString + ArgName; 3462 Constructor += ", " + ArgName; 3463 } 3464 S += FieldName + "; // by ref\n"; 3465 } 3466 // Finish writing the constructor. 3467 Constructor += ", int flags=0)"; 3468 // Initialize all "by copy" arguments. 3469 bool firsTime = true; 3470 for (SmallVectorImpl<ValueDecl *>::iterator I = BlockByCopyDecls.begin(), 3471 E = BlockByCopyDecls.end(); I != E; ++I) { 3472 std::string Name = (*I)->getNameAsString(); 3473 if (firsTime) { 3474 Constructor += " : "; 3475 firsTime = false; 3476 } 3477 else 3478 Constructor += ", "; 3479 if (isTopLevelBlockPointerType((*I)->getType())) 3480 Constructor += Name + "((struct __block_impl *)_" + Name + ")"; 3481 else 3482 Constructor += Name + "(_" + Name + ")"; 3483 } 3484 // Initialize all "by ref" arguments. 3485 for (SmallVectorImpl<ValueDecl *>::iterator I = BlockByRefDecls.begin(), 3486 E = BlockByRefDecls.end(); I != E; ++I) { 3487 std::string Name = (*I)->getNameAsString(); 3488 if (firsTime) { 3489 Constructor += " : "; 3490 firsTime = false; 3491 } 3492 else 3493 Constructor += ", "; 3494 Constructor += Name + "(_" + Name + "->__forwarding)"; 3495 } 3496 3497 Constructor += " {\n"; 3498 if (GlobalVarDecl) 3499 Constructor += " impl.isa = &_NSConcreteGlobalBlock;\n"; 3500 else 3501 Constructor += " impl.isa = &_NSConcreteStackBlock;\n"; 3502 Constructor += " impl.Flags = flags;\n impl.FuncPtr = fp;\n"; 3503 3504 Constructor += " Desc = desc;\n"; 3505 } else { 3506 // Finish writing the constructor. 3507 Constructor += ", int flags=0) {\n"; 3508 if (GlobalVarDecl) 3509 Constructor += " impl.isa = &_NSConcreteGlobalBlock;\n"; 3510 else 3511 Constructor += " impl.isa = &_NSConcreteStackBlock;\n"; 3512 Constructor += " impl.Flags = flags;\n impl.FuncPtr = fp;\n"; 3513 Constructor += " Desc = desc;\n"; 3514 } 3515 Constructor += " "; 3516 Constructor += "}\n"; 3517 S += Constructor; 3518 S += "};\n"; 3519 return S; 3520} 3521 3522std::string RewriteObjC::SynthesizeBlockDescriptor(std::string DescTag, 3523 std::string ImplTag, int i, 3524 StringRef FunName, 3525 unsigned hasCopy) { 3526 std::string S = "\nstatic struct " + DescTag; 3527 3528 S += " {\n unsigned long reserved;\n"; 3529 S += " unsigned long Block_size;\n"; 3530 if (hasCopy) { 3531 S += " void (*copy)(struct "; 3532 S += ImplTag; S += "*, struct "; 3533 S += ImplTag; S += "*);\n"; 3534 3535 S += " void (*dispose)(struct "; 3536 S += ImplTag; S += "*);\n"; 3537 } 3538 S += "} "; 3539 3540 S += DescTag + "_DATA = { 0, sizeof(struct "; 3541 S += ImplTag + ")"; 3542 if (hasCopy) { 3543 S += ", __" + FunName.str() + "_block_copy_" + utostr(i); 3544 S += ", __" + FunName.str() + "_block_dispose_" + utostr(i); 3545 } 3546 S += "};\n"; 3547 return S; 3548} 3549 3550void RewriteObjC::SynthesizeBlockLiterals(SourceLocation FunLocStart, 3551 StringRef FunName) { 3552 // Insert declaration for the function in which block literal is used. 3553 if (CurFunctionDeclToDeclareForBlock && !Blocks.empty()) 3554 RewriteBlockLiteralFunctionDecl(CurFunctionDeclToDeclareForBlock); 3555 bool RewriteSC = (GlobalVarDecl && 3556 !Blocks.empty() && 3557 GlobalVarDecl->getStorageClass() == SC_Static && 3558 GlobalVarDecl->getType().getCVRQualifiers()); 3559 if (RewriteSC) { 3560 std::string SC(" void __"); 3561 SC += GlobalVarDecl->getNameAsString(); 3562 SC += "() {}"; 3563 InsertText(FunLocStart, SC); 3564 } 3565 3566 // Insert closures that were part of the function. 3567 for (unsigned i = 0, count=0; i < Blocks.size(); i++) { 3568 CollectBlockDeclRefInfo(Blocks[i]); 3569 // Need to copy-in the inner copied-in variables not actually used in this 3570 // block. 3571 for (int j = 0; j < InnerDeclRefsCount[i]; j++) { 3572 DeclRefExpr *Exp = InnerDeclRefs[count++]; 3573 ValueDecl *VD = Exp->getDecl(); 3574 BlockDeclRefs.push_back(Exp); 3575 if (!VD->hasAttr<BlocksAttr>() && !BlockByCopyDeclsPtrSet.count(VD)) { 3576 BlockByCopyDeclsPtrSet.insert(VD); 3577 BlockByCopyDecls.push_back(VD); 3578 } 3579 if (VD->hasAttr<BlocksAttr>() && !BlockByRefDeclsPtrSet.count(VD)) { 3580 BlockByRefDeclsPtrSet.insert(VD); 3581 BlockByRefDecls.push_back(VD); 3582 } 3583 // imported objects in the inner blocks not used in the outer 3584 // blocks must be copied/disposed in the outer block as well. 3585 if (VD->hasAttr<BlocksAttr>() || 3586 VD->getType()->isObjCObjectPointerType() || 3587 VD->getType()->isBlockPointerType()) 3588 ImportedBlockDecls.insert(VD); 3589 } 3590 3591 std::string ImplTag = "__" + FunName.str() + "_block_impl_" + utostr(i); 3592 std::string DescTag = "__" + FunName.str() + "_block_desc_" + utostr(i); 3593 3594 std::string CI = SynthesizeBlockImpl(Blocks[i], ImplTag, DescTag); 3595 3596 InsertText(FunLocStart, CI); 3597 3598 std::string CF = SynthesizeBlockFunc(Blocks[i], i, FunName, ImplTag); 3599 3600 InsertText(FunLocStart, CF); 3601 3602 if (ImportedBlockDecls.size()) { 3603 std::string HF = SynthesizeBlockHelperFuncs(Blocks[i], i, FunName, ImplTag); 3604 InsertText(FunLocStart, HF); 3605 } 3606 std::string BD = SynthesizeBlockDescriptor(DescTag, ImplTag, i, FunName, 3607 ImportedBlockDecls.size() > 0); 3608 InsertText(FunLocStart, BD); 3609 3610 BlockDeclRefs.clear(); 3611 BlockByRefDecls.clear(); 3612 BlockByRefDeclsPtrSet.clear(); 3613 BlockByCopyDecls.clear(); 3614 BlockByCopyDeclsPtrSet.clear(); 3615 ImportedBlockDecls.clear(); 3616 } 3617 if (RewriteSC) { 3618 // Must insert any 'const/volatile/static here. Since it has been 3619 // removed as result of rewriting of block literals. 3620 std::string SC; 3621 if (GlobalVarDecl->getStorageClass() == SC_Static) 3622 SC = "static "; 3623 if (GlobalVarDecl->getType().isConstQualified()) 3624 SC += "const "; 3625 if (GlobalVarDecl->getType().isVolatileQualified()) 3626 SC += "volatile "; 3627 if (GlobalVarDecl->getType().isRestrictQualified()) 3628 SC += "restrict "; 3629 InsertText(FunLocStart, SC); 3630 } 3631 3632 Blocks.clear(); 3633 InnerDeclRefsCount.clear(); 3634 InnerDeclRefs.clear(); 3635 RewrittenBlockExprs.clear(); 3636} 3637 3638void RewriteObjC::InsertBlockLiteralsWithinFunction(FunctionDecl *FD) { 3639 SourceLocation FunLocStart = FD->getTypeSpecStartLoc(); 3640 StringRef FuncName = FD->getName(); 3641 3642 SynthesizeBlockLiterals(FunLocStart, FuncName); 3643} 3644 3645static void BuildUniqueMethodName(std::string &Name, 3646 ObjCMethodDecl *MD) { 3647 ObjCInterfaceDecl *IFace = MD->getClassInterface(); 3648 Name = IFace->getName(); 3649 Name += "__" + MD->getSelector().getAsString(); 3650 // Convert colons to underscores. 3651 std::string::size_type loc = 0; 3652 while ((loc = Name.find(":", loc)) != std::string::npos) 3653 Name.replace(loc, 1, "_"); 3654} 3655 3656void RewriteObjC::InsertBlockLiteralsWithinMethod(ObjCMethodDecl *MD) { 3657 //fprintf(stderr,"In InsertBlockLiteralsWitinMethod\n"); 3658 //SourceLocation FunLocStart = MD->getLocStart(); 3659 SourceLocation FunLocStart = MD->getLocStart(); 3660 std::string FuncName; 3661 BuildUniqueMethodName(FuncName, MD); 3662 SynthesizeBlockLiterals(FunLocStart, FuncName); 3663} 3664 3665void RewriteObjC::GetBlockDeclRefExprs(Stmt *S) { 3666 for (Stmt::child_range CI = S->children(); CI; ++CI) 3667 if (*CI) { 3668 if (BlockExpr *CBE = dyn_cast<BlockExpr>(*CI)) 3669 GetBlockDeclRefExprs(CBE->getBody()); 3670 else 3671 GetBlockDeclRefExprs(*CI); 3672 } 3673 // Handle specific things. 3674 if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(S)) 3675 if (DRE->refersToEnclosingVariableOrCapture() || 3676 HasLocalVariableExternalStorage(DRE->getDecl())) 3677 // FIXME: Handle enums. 3678 BlockDeclRefs.push_back(DRE); 3679 3680 return; 3681} 3682 3683void RewriteObjC::GetInnerBlockDeclRefExprs(Stmt *S, 3684 SmallVectorImpl<DeclRefExpr *> &InnerBlockDeclRefs, 3685 llvm::SmallPtrSetImpl<const DeclContext *> &InnerContexts) { 3686 for (Stmt::child_range CI = S->children(); CI; ++CI) 3687 if (*CI) { 3688 if (BlockExpr *CBE = dyn_cast<BlockExpr>(*CI)) { 3689 InnerContexts.insert(cast<DeclContext>(CBE->getBlockDecl())); 3690 GetInnerBlockDeclRefExprs(CBE->getBody(), 3691 InnerBlockDeclRefs, 3692 InnerContexts); 3693 } 3694 else 3695 GetInnerBlockDeclRefExprs(*CI, 3696 InnerBlockDeclRefs, 3697 InnerContexts); 3698 3699 } 3700 // Handle specific things. 3701 if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(S)) { 3702 if (DRE->refersToEnclosingVariableOrCapture() || 3703 HasLocalVariableExternalStorage(DRE->getDecl())) { 3704 if (!InnerContexts.count(DRE->getDecl()->getDeclContext())) 3705 InnerBlockDeclRefs.push_back(DRE); 3706 if (VarDecl *Var = cast<VarDecl>(DRE->getDecl())) 3707 if (Var->isFunctionOrMethodVarDecl()) 3708 ImportedLocalExternalDecls.insert(Var); 3709 } 3710 } 3711 3712 return; 3713} 3714 3715/// convertFunctionTypeOfBlocks - This routine converts a function type 3716/// whose result type may be a block pointer or whose argument type(s) 3717/// might be block pointers to an equivalent function type replacing 3718/// all block pointers to function pointers. 3719QualType RewriteObjC::convertFunctionTypeOfBlocks(const FunctionType *FT) { 3720 const FunctionProtoType *FTP = dyn_cast<FunctionProtoType>(FT); 3721 // FTP will be null for closures that don't take arguments. 3722 // Generate a funky cast. 3723 SmallVector<QualType, 8> ArgTypes; 3724 QualType Res = FT->getReturnType(); 3725 bool HasBlockType = convertBlockPointerToFunctionPointer(Res); 3726 3727 if (FTP) { 3728 for (auto &I : FTP->param_types()) { 3729 QualType t = I; 3730 // Make sure we convert "t (^)(...)" to "t (*)(...)". 3731 if (convertBlockPointerToFunctionPointer(t)) 3732 HasBlockType = true; 3733 ArgTypes.push_back(t); 3734 } 3735 } 3736 QualType FuncType; 3737 // FIXME. Does this work if block takes no argument but has a return type 3738 // which is of block type? 3739 if (HasBlockType) 3740 FuncType = getSimpleFunctionType(Res, ArgTypes); 3741 else FuncType = QualType(FT, 0); 3742 return FuncType; 3743} 3744 3745Stmt *RewriteObjC::SynthesizeBlockCall(CallExpr *Exp, const Expr *BlockExp) { 3746 // Navigate to relevant type information. 3747 const BlockPointerType *CPT = nullptr; 3748 3749 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(BlockExp)) { 3750 CPT = DRE->getType()->getAs<BlockPointerType>(); 3751 } else if (const MemberExpr *MExpr = dyn_cast<MemberExpr>(BlockExp)) { 3752 CPT = MExpr->getType()->getAs<BlockPointerType>(); 3753 } 3754 else if (const ParenExpr *PRE = dyn_cast<ParenExpr>(BlockExp)) { 3755 return SynthesizeBlockCall(Exp, PRE->getSubExpr()); 3756 } 3757 else if (const ImplicitCastExpr *IEXPR = dyn_cast<ImplicitCastExpr>(BlockExp)) 3758 CPT = IEXPR->getType()->getAs<BlockPointerType>(); 3759 else if (const ConditionalOperator *CEXPR = 3760 dyn_cast<ConditionalOperator>(BlockExp)) { 3761 Expr *LHSExp = CEXPR->getLHS(); 3762 Stmt *LHSStmt = SynthesizeBlockCall(Exp, LHSExp); 3763 Expr *RHSExp = CEXPR->getRHS(); 3764 Stmt *RHSStmt = SynthesizeBlockCall(Exp, RHSExp); 3765 Expr *CONDExp = CEXPR->getCond(); 3766 ConditionalOperator *CondExpr = 3767 new (Context) ConditionalOperator(CONDExp, 3768 SourceLocation(), cast<Expr>(LHSStmt), 3769 SourceLocation(), cast<Expr>(RHSStmt), 3770 Exp->getType(), VK_RValue, OK_Ordinary); 3771 return CondExpr; 3772 } else if (const ObjCIvarRefExpr *IRE = dyn_cast<ObjCIvarRefExpr>(BlockExp)) { 3773 CPT = IRE->getType()->getAs<BlockPointerType>(); 3774 } else if (const PseudoObjectExpr *POE 3775 = dyn_cast<PseudoObjectExpr>(BlockExp)) { 3776 CPT = POE->getType()->castAs<BlockPointerType>(); 3777 } else { 3778 assert(1 && "RewriteBlockClass: Bad type"); 3779 } 3780 assert(CPT && "RewriteBlockClass: Bad type"); 3781 const FunctionType *FT = CPT->getPointeeType()->getAs<FunctionType>(); 3782 assert(FT && "RewriteBlockClass: Bad type"); 3783 const FunctionProtoType *FTP = dyn_cast<FunctionProtoType>(FT); 3784 // FTP will be null for closures that don't take arguments. 3785 3786 RecordDecl *RD = RecordDecl::Create(*Context, TTK_Struct, TUDecl, 3787 SourceLocation(), SourceLocation(), 3788 &Context->Idents.get("__block_impl")); 3789 QualType PtrBlock = Context->getPointerType(Context->getTagDeclType(RD)); 3790 3791 // Generate a funky cast. 3792 SmallVector<QualType, 8> ArgTypes; 3793 3794 // Push the block argument type. 3795 ArgTypes.push_back(PtrBlock); 3796 if (FTP) { 3797 for (auto &I : FTP->param_types()) { 3798 QualType t = I; 3799 // Make sure we convert "t (^)(...)" to "t (*)(...)". 3800 if (!convertBlockPointerToFunctionPointer(t)) 3801 convertToUnqualifiedObjCType(t); 3802 ArgTypes.push_back(t); 3803 } 3804 } 3805 // Now do the pointer to function cast. 3806 QualType PtrToFuncCastType = getSimpleFunctionType(Exp->getType(), ArgTypes); 3807 3808 PtrToFuncCastType = Context->getPointerType(PtrToFuncCastType); 3809 3810 CastExpr *BlkCast = NoTypeInfoCStyleCastExpr(Context, PtrBlock, 3811 CK_BitCast, 3812 const_cast<Expr*>(BlockExp)); 3813 // Don't forget the parens to enforce the proper binding. 3814 ParenExpr *PE = new (Context) ParenExpr(SourceLocation(), SourceLocation(), 3815 BlkCast); 3816 //PE->dump(); 3817 3818 FieldDecl *FD = FieldDecl::Create(*Context, nullptr, SourceLocation(), 3819 SourceLocation(), 3820 &Context->Idents.get("FuncPtr"), 3821 Context->VoidPtrTy, nullptr, 3822 /*BitWidth=*/nullptr, /*Mutable=*/true, 3823 ICIS_NoInit); 3824 MemberExpr *ME = 3825 new (Context) MemberExpr(PE, true, SourceLocation(), FD, SourceLocation(), 3826 FD->getType(), VK_LValue, OK_Ordinary); 3827 3828 CastExpr *FunkCast = NoTypeInfoCStyleCastExpr(Context, PtrToFuncCastType, 3829 CK_BitCast, ME); 3830 PE = new (Context) ParenExpr(SourceLocation(), SourceLocation(), FunkCast); 3831 3832 SmallVector<Expr*, 8> BlkExprs; 3833 // Add the implicit argument. 3834 BlkExprs.push_back(BlkCast); 3835 // Add the user arguments. 3836 for (CallExpr::arg_iterator I = Exp->arg_begin(), 3837 E = Exp->arg_end(); I != E; ++I) { 3838 BlkExprs.push_back(*I); 3839 } 3840 CallExpr *CE = new (Context) CallExpr(*Context, PE, BlkExprs, 3841 Exp->getType(), VK_RValue, 3842 SourceLocation()); 3843 return CE; 3844} 3845 3846// We need to return the rewritten expression to handle cases where the 3847// BlockDeclRefExpr is embedded in another expression being rewritten. 3848// For example: 3849// 3850// int main() { 3851// __block Foo *f; 3852// __block int i; 3853// 3854// void (^myblock)() = ^() { 3855// [f test]; // f is a BlockDeclRefExpr embedded in a message (which is being rewritten). 3856// i = 77; 3857// }; 3858//} 3859Stmt *RewriteObjC::RewriteBlockDeclRefExpr(DeclRefExpr *DeclRefExp) { 3860 // Rewrite the byref variable into BYREFVAR->__forwarding->BYREFVAR 3861 // for each DeclRefExp where BYREFVAR is name of the variable. 3862 ValueDecl *VD = DeclRefExp->getDecl(); 3863 bool isArrow = DeclRefExp->refersToEnclosingVariableOrCapture() || 3864 HasLocalVariableExternalStorage(DeclRefExp->getDecl()); 3865 3866 FieldDecl *FD = FieldDecl::Create(*Context, nullptr, SourceLocation(), 3867 SourceLocation(), 3868 &Context->Idents.get("__forwarding"), 3869 Context->VoidPtrTy, nullptr, 3870 /*BitWidth=*/nullptr, /*Mutable=*/true, 3871 ICIS_NoInit); 3872 MemberExpr *ME = new (Context) 3873 MemberExpr(DeclRefExp, isArrow, SourceLocation(), FD, SourceLocation(), 3874 FD->getType(), VK_LValue, OK_Ordinary); 3875 3876 StringRef Name = VD->getName(); 3877 FD = FieldDecl::Create(*Context, nullptr, SourceLocation(), SourceLocation(), 3878 &Context->Idents.get(Name), 3879 Context->VoidPtrTy, nullptr, 3880 /*BitWidth=*/nullptr, /*Mutable=*/true, 3881 ICIS_NoInit); 3882 ME = 3883 new (Context) MemberExpr(ME, true, SourceLocation(), FD, SourceLocation(), 3884 DeclRefExp->getType(), VK_LValue, OK_Ordinary); 3885 3886 // Need parens to enforce precedence. 3887 ParenExpr *PE = new (Context) ParenExpr(DeclRefExp->getExprLoc(), 3888 DeclRefExp->getExprLoc(), 3889 ME); 3890 ReplaceStmt(DeclRefExp, PE); 3891 return PE; 3892} 3893 3894// Rewrites the imported local variable V with external storage 3895// (static, extern, etc.) as *V 3896// 3897Stmt *RewriteObjC::RewriteLocalVariableExternalStorage(DeclRefExpr *DRE) { 3898 ValueDecl *VD = DRE->getDecl(); 3899 if (VarDecl *Var = dyn_cast<VarDecl>(VD)) 3900 if (!ImportedLocalExternalDecls.count(Var)) 3901 return DRE; 3902 Expr *Exp = new (Context) UnaryOperator(DRE, UO_Deref, DRE->getType(), 3903 VK_LValue, OK_Ordinary, 3904 DRE->getLocation()); 3905 // Need parens to enforce precedence. 3906 ParenExpr *PE = new (Context) ParenExpr(SourceLocation(), SourceLocation(), 3907 Exp); 3908 ReplaceStmt(DRE, PE); 3909 return PE; 3910} 3911 3912void RewriteObjC::RewriteCastExpr(CStyleCastExpr *CE) { 3913 SourceLocation LocStart = CE->getLParenLoc(); 3914 SourceLocation LocEnd = CE->getRParenLoc(); 3915 3916 // Need to avoid trying to rewrite synthesized casts. 3917 if (LocStart.isInvalid()) 3918 return; 3919 // Need to avoid trying to rewrite casts contained in macros. 3920 if (!Rewriter::isRewritable(LocStart) || !Rewriter::isRewritable(LocEnd)) 3921 return; 3922 3923 const char *startBuf = SM->getCharacterData(LocStart); 3924 const char *endBuf = SM->getCharacterData(LocEnd); 3925 QualType QT = CE->getType(); 3926 const Type* TypePtr = QT->getAs<Type>(); 3927 if (isa<TypeOfExprType>(TypePtr)) { 3928 const TypeOfExprType *TypeOfExprTypePtr = cast<TypeOfExprType>(TypePtr); 3929 QT = TypeOfExprTypePtr->getUnderlyingExpr()->getType(); 3930 std::string TypeAsString = "("; 3931 RewriteBlockPointerType(TypeAsString, QT); 3932 TypeAsString += ")"; 3933 ReplaceText(LocStart, endBuf-startBuf+1, TypeAsString); 3934 return; 3935 } 3936 // advance the location to startArgList. 3937 const char *argPtr = startBuf; 3938 3939 while (*argPtr++ && (argPtr < endBuf)) { 3940 switch (*argPtr) { 3941 case '^': 3942 // Replace the '^' with '*'. 3943 LocStart = LocStart.getLocWithOffset(argPtr-startBuf); 3944 ReplaceText(LocStart, 1, "*"); 3945 break; 3946 } 3947 } 3948 return; 3949} 3950 3951void RewriteObjC::RewriteBlockPointerFunctionArgs(FunctionDecl *FD) { 3952 SourceLocation DeclLoc = FD->getLocation(); 3953 unsigned parenCount = 0; 3954 3955 // We have 1 or more arguments that have closure pointers. 3956 const char *startBuf = SM->getCharacterData(DeclLoc); 3957 const char *startArgList = strchr(startBuf, '('); 3958 3959 assert((*startArgList == '(') && "Rewriter fuzzy parser confused"); 3960 3961 parenCount++; 3962 // advance the location to startArgList. 3963 DeclLoc = DeclLoc.getLocWithOffset(startArgList-startBuf); 3964 assert((DeclLoc.isValid()) && "Invalid DeclLoc"); 3965 3966 const char *argPtr = startArgList; 3967 3968 while (*argPtr++ && parenCount) { 3969 switch (*argPtr) { 3970 case '^': 3971 // Replace the '^' with '*'. 3972 DeclLoc = DeclLoc.getLocWithOffset(argPtr-startArgList); 3973 ReplaceText(DeclLoc, 1, "*"); 3974 break; 3975 case '(': 3976 parenCount++; 3977 break; 3978 case ')': 3979 parenCount--; 3980 break; 3981 } 3982 } 3983 return; 3984} 3985 3986bool RewriteObjC::PointerTypeTakesAnyBlockArguments(QualType QT) { 3987 const FunctionProtoType *FTP; 3988 const PointerType *PT = QT->getAs<PointerType>(); 3989 if (PT) { 3990 FTP = PT->getPointeeType()->getAs<FunctionProtoType>(); 3991 } else { 3992 const BlockPointerType *BPT = QT->getAs<BlockPointerType>(); 3993 assert(BPT && "BlockPointerTypeTakeAnyBlockArguments(): not a block pointer type"); 3994 FTP = BPT->getPointeeType()->getAs<FunctionProtoType>(); 3995 } 3996 if (FTP) { 3997 for (const auto &I : FTP->param_types()) 3998 if (isTopLevelBlockPointerType(I)) 3999 return true; 4000 } 4001 return false; 4002} 4003 4004bool RewriteObjC::PointerTypeTakesAnyObjCQualifiedType(QualType QT) { 4005 const FunctionProtoType *FTP; 4006 const PointerType *PT = QT->getAs<PointerType>(); 4007 if (PT) { 4008 FTP = PT->getPointeeType()->getAs<FunctionProtoType>(); 4009 } else { 4010 const BlockPointerType *BPT = QT->getAs<BlockPointerType>(); 4011 assert(BPT && "BlockPointerTypeTakeAnyBlockArguments(): not a block pointer type"); 4012 FTP = BPT->getPointeeType()->getAs<FunctionProtoType>(); 4013 } 4014 if (FTP) { 4015 for (const auto &I : FTP->param_types()) { 4016 if (I->isObjCQualifiedIdType()) 4017 return true; 4018 if (I->isObjCObjectPointerType() && 4019 I->getPointeeType()->isObjCQualifiedInterfaceType()) 4020 return true; 4021 } 4022 4023 } 4024 return false; 4025} 4026 4027void RewriteObjC::GetExtentOfArgList(const char *Name, const char *&LParen, 4028 const char *&RParen) { 4029 const char *argPtr = strchr(Name, '('); 4030 assert((*argPtr == '(') && "Rewriter fuzzy parser confused"); 4031 4032 LParen = argPtr; // output the start. 4033 argPtr++; // skip past the left paren. 4034 unsigned parenCount = 1; 4035 4036 while (*argPtr && parenCount) { 4037 switch (*argPtr) { 4038 case '(': parenCount++; break; 4039 case ')': parenCount--; break; 4040 default: break; 4041 } 4042 if (parenCount) argPtr++; 4043 } 4044 assert((*argPtr == ')') && "Rewriter fuzzy parser confused"); 4045 RParen = argPtr; // output the end 4046} 4047 4048void RewriteObjC::RewriteBlockPointerDecl(NamedDecl *ND) { 4049 if (FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) { 4050 RewriteBlockPointerFunctionArgs(FD); 4051 return; 4052 } 4053 // Handle Variables and Typedefs. 4054 SourceLocation DeclLoc = ND->getLocation(); 4055 QualType DeclT; 4056 if (VarDecl *VD = dyn_cast<VarDecl>(ND)) 4057 DeclT = VD->getType(); 4058 else if (TypedefNameDecl *TDD = dyn_cast<TypedefNameDecl>(ND)) 4059 DeclT = TDD->getUnderlyingType(); 4060 else if (FieldDecl *FD = dyn_cast<FieldDecl>(ND)) 4061 DeclT = FD->getType(); 4062 else 4063 llvm_unreachable("RewriteBlockPointerDecl(): Decl type not yet handled"); 4064 4065 const char *startBuf = SM->getCharacterData(DeclLoc); 4066 const char *endBuf = startBuf; 4067 // scan backward (from the decl location) for the end of the previous decl. 4068 while (*startBuf != '^' && *startBuf != ';' && startBuf != MainFileStart) 4069 startBuf--; 4070 SourceLocation Start = DeclLoc.getLocWithOffset(startBuf-endBuf); 4071 std::string buf; 4072 unsigned OrigLength=0; 4073 // *startBuf != '^' if we are dealing with a pointer to function that 4074 // may take block argument types (which will be handled below). 4075 if (*startBuf == '^') { 4076 // Replace the '^' with '*', computing a negative offset. 4077 buf = '*'; 4078 startBuf++; 4079 OrigLength++; 4080 } 4081 while (*startBuf != ')') { 4082 buf += *startBuf; 4083 startBuf++; 4084 OrigLength++; 4085 } 4086 buf += ')'; 4087 OrigLength++; 4088 4089 if (PointerTypeTakesAnyBlockArguments(DeclT) || 4090 PointerTypeTakesAnyObjCQualifiedType(DeclT)) { 4091 // Replace the '^' with '*' for arguments. 4092 // Replace id<P> with id/*<>*/ 4093 DeclLoc = ND->getLocation(); 4094 startBuf = SM->getCharacterData(DeclLoc); 4095 const char *argListBegin, *argListEnd; 4096 GetExtentOfArgList(startBuf, argListBegin, argListEnd); 4097 while (argListBegin < argListEnd) { 4098 if (*argListBegin == '^') 4099 buf += '*'; 4100 else if (*argListBegin == '<') { 4101 buf += "/*"; 4102 buf += *argListBegin++; 4103 OrigLength++; 4104 while (*argListBegin != '>') { 4105 buf += *argListBegin++; 4106 OrigLength++; 4107 } 4108 buf += *argListBegin; 4109 buf += "*/"; 4110 } 4111 else 4112 buf += *argListBegin; 4113 argListBegin++; 4114 OrigLength++; 4115 } 4116 buf += ')'; 4117 OrigLength++; 4118 } 4119 ReplaceText(Start, OrigLength, buf); 4120 4121 return; 4122} 4123 4124 4125/// SynthesizeByrefCopyDestroyHelper - This routine synthesizes: 4126/// void __Block_byref_id_object_copy(struct Block_byref_id_object *dst, 4127/// struct Block_byref_id_object *src) { 4128/// _Block_object_assign (&_dest->object, _src->object, 4129/// BLOCK_BYREF_CALLER | BLOCK_FIELD_IS_OBJECT 4130/// [|BLOCK_FIELD_IS_WEAK]) // object 4131/// _Block_object_assign(&_dest->object, _src->object, 4132/// BLOCK_BYREF_CALLER | BLOCK_FIELD_IS_BLOCK 4133/// [|BLOCK_FIELD_IS_WEAK]) // block 4134/// } 4135/// And: 4136/// void __Block_byref_id_object_dispose(struct Block_byref_id_object *_src) { 4137/// _Block_object_dispose(_src->object, 4138/// BLOCK_BYREF_CALLER | BLOCK_FIELD_IS_OBJECT 4139/// [|BLOCK_FIELD_IS_WEAK]) // object 4140/// _Block_object_dispose(_src->object, 4141/// BLOCK_BYREF_CALLER | BLOCK_FIELD_IS_BLOCK 4142/// [|BLOCK_FIELD_IS_WEAK]) // block 4143/// } 4144 4145std::string RewriteObjC::SynthesizeByrefCopyDestroyHelper(VarDecl *VD, 4146 int flag) { 4147 std::string S; 4148 if (CopyDestroyCache.count(flag)) 4149 return S; 4150 CopyDestroyCache.insert(flag); 4151 S = "static void __Block_byref_id_object_copy_"; 4152 S += utostr(flag); 4153 S += "(void *dst, void *src) {\n"; 4154 4155 // offset into the object pointer is computed as: 4156 // void * + void* + int + int + void* + void * 4157 unsigned IntSize = 4158 static_cast<unsigned>(Context->getTypeSize(Context->IntTy)); 4159 unsigned VoidPtrSize = 4160 static_cast<unsigned>(Context->getTypeSize(Context->VoidPtrTy)); 4161 4162 unsigned offset = (VoidPtrSize*4 + IntSize + IntSize)/Context->getCharWidth(); 4163 S += " _Block_object_assign((char*)dst + "; 4164 S += utostr(offset); 4165 S += ", *(void * *) ((char*)src + "; 4166 S += utostr(offset); 4167 S += "), "; 4168 S += utostr(flag); 4169 S += ");\n}\n"; 4170 4171 S += "static void __Block_byref_id_object_dispose_"; 4172 S += utostr(flag); 4173 S += "(void *src) {\n"; 4174 S += " _Block_object_dispose(*(void * *) ((char*)src + "; 4175 S += utostr(offset); 4176 S += "), "; 4177 S += utostr(flag); 4178 S += ");\n}\n"; 4179 return S; 4180} 4181 4182/// RewriteByRefVar - For each __block typex ND variable this routine transforms 4183/// the declaration into: 4184/// struct __Block_byref_ND { 4185/// void *__isa; // NULL for everything except __weak pointers 4186/// struct __Block_byref_ND *__forwarding; 4187/// int32_t __flags; 4188/// int32_t __size; 4189/// void *__Block_byref_id_object_copy; // If variable is __block ObjC object 4190/// void *__Block_byref_id_object_dispose; // If variable is __block ObjC object 4191/// typex ND; 4192/// }; 4193/// 4194/// It then replaces declaration of ND variable with: 4195/// struct __Block_byref_ND ND = {__isa=0B, __forwarding=&ND, __flags=some_flag, 4196/// __size=sizeof(struct __Block_byref_ND), 4197/// ND=initializer-if-any}; 4198/// 4199/// 4200void RewriteObjC::RewriteByRefVar(VarDecl *ND) { 4201 // Insert declaration for the function in which block literal is 4202 // used. 4203 if (CurFunctionDeclToDeclareForBlock) 4204 RewriteBlockLiteralFunctionDecl(CurFunctionDeclToDeclareForBlock); 4205 int flag = 0; 4206 int isa = 0; 4207 SourceLocation DeclLoc = ND->getTypeSpecStartLoc(); 4208 if (DeclLoc.isInvalid()) 4209 // If type location is missing, it is because of missing type (a warning). 4210 // Use variable's location which is good for this case. 4211 DeclLoc = ND->getLocation(); 4212 const char *startBuf = SM->getCharacterData(DeclLoc); 4213 SourceLocation X = ND->getLocEnd(); 4214 X = SM->getExpansionLoc(X); 4215 const char *endBuf = SM->getCharacterData(X); 4216 std::string Name(ND->getNameAsString()); 4217 std::string ByrefType; 4218 RewriteByRefString(ByrefType, Name, ND, true); 4219 ByrefType += " {\n"; 4220 ByrefType += " void *__isa;\n"; 4221 RewriteByRefString(ByrefType, Name, ND); 4222 ByrefType += " *__forwarding;\n"; 4223 ByrefType += " int __flags;\n"; 4224 ByrefType += " int __size;\n"; 4225 // Add void *__Block_byref_id_object_copy; 4226 // void *__Block_byref_id_object_dispose; if needed. 4227 QualType Ty = ND->getType(); 4228 bool HasCopyAndDispose = Context->BlockRequiresCopying(Ty, ND); 4229 if (HasCopyAndDispose) { 4230 ByrefType += " void (*__Block_byref_id_object_copy)(void*, void*);\n"; 4231 ByrefType += " void (*__Block_byref_id_object_dispose)(void*);\n"; 4232 } 4233 4234 QualType T = Ty; 4235 (void)convertBlockPointerToFunctionPointer(T); 4236 T.getAsStringInternal(Name, Context->getPrintingPolicy()); 4237 4238 ByrefType += " " + Name + ";\n"; 4239 ByrefType += "};\n"; 4240 // Insert this type in global scope. It is needed by helper function. 4241 SourceLocation FunLocStart; 4242 if (CurFunctionDef) 4243 FunLocStart = CurFunctionDef->getTypeSpecStartLoc(); 4244 else { 4245 assert(CurMethodDef && "RewriteByRefVar - CurMethodDef is null"); 4246 FunLocStart = CurMethodDef->getLocStart(); 4247 } 4248 InsertText(FunLocStart, ByrefType); 4249 if (Ty.isObjCGCWeak()) { 4250 flag |= BLOCK_FIELD_IS_WEAK; 4251 isa = 1; 4252 } 4253 4254 if (HasCopyAndDispose) { 4255 flag = BLOCK_BYREF_CALLER; 4256 QualType Ty = ND->getType(); 4257 // FIXME. Handle __weak variable (BLOCK_FIELD_IS_WEAK) as well. 4258 if (Ty->isBlockPointerType()) 4259 flag |= BLOCK_FIELD_IS_BLOCK; 4260 else 4261 flag |= BLOCK_FIELD_IS_OBJECT; 4262 std::string HF = SynthesizeByrefCopyDestroyHelper(ND, flag); 4263 if (!HF.empty()) 4264 InsertText(FunLocStart, HF); 4265 } 4266 4267 // struct __Block_byref_ND ND = 4268 // {0, &ND, some_flag, __size=sizeof(struct __Block_byref_ND), 4269 // initializer-if-any}; 4270 bool hasInit = (ND->getInit() != nullptr); 4271 unsigned flags = 0; 4272 if (HasCopyAndDispose) 4273 flags |= BLOCK_HAS_COPY_DISPOSE; 4274 Name = ND->getNameAsString(); 4275 ByrefType.clear(); 4276 RewriteByRefString(ByrefType, Name, ND); 4277 std::string ForwardingCastType("("); 4278 ForwardingCastType += ByrefType + " *)"; 4279 if (!hasInit) { 4280 ByrefType += " " + Name + " = {(void*)"; 4281 ByrefType += utostr(isa); 4282 ByrefType += "," + ForwardingCastType + "&" + Name + ", "; 4283 ByrefType += utostr(flags); 4284 ByrefType += ", "; 4285 ByrefType += "sizeof("; 4286 RewriteByRefString(ByrefType, Name, ND); 4287 ByrefType += ")"; 4288 if (HasCopyAndDispose) { 4289 ByrefType += ", __Block_byref_id_object_copy_"; 4290 ByrefType += utostr(flag); 4291 ByrefType += ", __Block_byref_id_object_dispose_"; 4292 ByrefType += utostr(flag); 4293 } 4294 ByrefType += "};\n"; 4295 unsigned nameSize = Name.size(); 4296 // for block or function pointer declaration. Name is aleady 4297 // part of the declaration. 4298 if (Ty->isBlockPointerType() || Ty->isFunctionPointerType()) 4299 nameSize = 1; 4300 ReplaceText(DeclLoc, endBuf-startBuf+nameSize, ByrefType); 4301 } 4302 else { 4303 SourceLocation startLoc; 4304 Expr *E = ND->getInit(); 4305 if (const CStyleCastExpr *ECE = dyn_cast<CStyleCastExpr>(E)) 4306 startLoc = ECE->getLParenLoc(); 4307 else 4308 startLoc = E->getLocStart(); 4309 startLoc = SM->getExpansionLoc(startLoc); 4310 endBuf = SM->getCharacterData(startLoc); 4311 ByrefType += " " + Name; 4312 ByrefType += " = {(void*)"; 4313 ByrefType += utostr(isa); 4314 ByrefType += "," + ForwardingCastType + "&" + Name + ", "; 4315 ByrefType += utostr(flags); 4316 ByrefType += ", "; 4317 ByrefType += "sizeof("; 4318 RewriteByRefString(ByrefType, Name, ND); 4319 ByrefType += "), "; 4320 if (HasCopyAndDispose) { 4321 ByrefType += "__Block_byref_id_object_copy_"; 4322 ByrefType += utostr(flag); 4323 ByrefType += ", __Block_byref_id_object_dispose_"; 4324 ByrefType += utostr(flag); 4325 ByrefType += ", "; 4326 } 4327 ReplaceText(DeclLoc, endBuf-startBuf, ByrefType); 4328 4329 // Complete the newly synthesized compound expression by inserting a right 4330 // curly brace before the end of the declaration. 4331 // FIXME: This approach avoids rewriting the initializer expression. It 4332 // also assumes there is only one declarator. For example, the following 4333 // isn't currently supported by this routine (in general): 4334 // 4335 // double __block BYREFVAR = 1.34, BYREFVAR2 = 1.37; 4336 // 4337 const char *startInitializerBuf = SM->getCharacterData(startLoc); 4338 const char *semiBuf = strchr(startInitializerBuf, ';'); 4339 assert((*semiBuf == ';') && "RewriteByRefVar: can't find ';'"); 4340 SourceLocation semiLoc = 4341 startLoc.getLocWithOffset(semiBuf-startInitializerBuf); 4342 4343 InsertText(semiLoc, "}"); 4344 } 4345 return; 4346} 4347 4348void RewriteObjC::CollectBlockDeclRefInfo(BlockExpr *Exp) { 4349 // Add initializers for any closure decl refs. 4350 GetBlockDeclRefExprs(Exp->getBody()); 4351 if (BlockDeclRefs.size()) { 4352 // Unique all "by copy" declarations. 4353 for (unsigned i = 0; i < BlockDeclRefs.size(); i++) 4354 if (!BlockDeclRefs[i]->getDecl()->hasAttr<BlocksAttr>()) { 4355 if (!BlockByCopyDeclsPtrSet.count(BlockDeclRefs[i]->getDecl())) { 4356 BlockByCopyDeclsPtrSet.insert(BlockDeclRefs[i]->getDecl()); 4357 BlockByCopyDecls.push_back(BlockDeclRefs[i]->getDecl()); 4358 } 4359 } 4360 // Unique all "by ref" declarations. 4361 for (unsigned i = 0; i < BlockDeclRefs.size(); i++) 4362 if (BlockDeclRefs[i]->getDecl()->hasAttr<BlocksAttr>()) { 4363 if (!BlockByRefDeclsPtrSet.count(BlockDeclRefs[i]->getDecl())) { 4364 BlockByRefDeclsPtrSet.insert(BlockDeclRefs[i]->getDecl()); 4365 BlockByRefDecls.push_back(BlockDeclRefs[i]->getDecl()); 4366 } 4367 } 4368 // Find any imported blocks...they will need special attention. 4369 for (unsigned i = 0; i < BlockDeclRefs.size(); i++) 4370 if (BlockDeclRefs[i]->getDecl()->hasAttr<BlocksAttr>() || 4371 BlockDeclRefs[i]->getType()->isObjCObjectPointerType() || 4372 BlockDeclRefs[i]->getType()->isBlockPointerType()) 4373 ImportedBlockDecls.insert(BlockDeclRefs[i]->getDecl()); 4374 } 4375} 4376 4377FunctionDecl *RewriteObjC::SynthBlockInitFunctionDecl(StringRef name) { 4378 IdentifierInfo *ID = &Context->Idents.get(name); 4379 QualType FType = Context->getFunctionNoProtoType(Context->VoidPtrTy); 4380 return FunctionDecl::Create(*Context, TUDecl, SourceLocation(), 4381 SourceLocation(), ID, FType, nullptr, SC_Extern, 4382 false, false); 4383} 4384 4385Stmt *RewriteObjC::SynthBlockInitExpr(BlockExpr *Exp, 4386 const SmallVectorImpl<DeclRefExpr *> &InnerBlockDeclRefs) { 4387 const BlockDecl *block = Exp->getBlockDecl(); 4388 Blocks.push_back(Exp); 4389 4390 CollectBlockDeclRefInfo(Exp); 4391 4392 // Add inner imported variables now used in current block. 4393 int countOfInnerDecls = 0; 4394 if (!InnerBlockDeclRefs.empty()) { 4395 for (unsigned i = 0; i < InnerBlockDeclRefs.size(); i++) { 4396 DeclRefExpr *Exp = InnerBlockDeclRefs[i]; 4397 ValueDecl *VD = Exp->getDecl(); 4398 if (!VD->hasAttr<BlocksAttr>() && !BlockByCopyDeclsPtrSet.count(VD)) { 4399 // We need to save the copied-in variables in nested 4400 // blocks because it is needed at the end for some of the API generations. 4401 // See SynthesizeBlockLiterals routine. 4402 InnerDeclRefs.push_back(Exp); countOfInnerDecls++; 4403 BlockDeclRefs.push_back(Exp); 4404 BlockByCopyDeclsPtrSet.insert(VD); 4405 BlockByCopyDecls.push_back(VD); 4406 } 4407 if (VD->hasAttr<BlocksAttr>() && !BlockByRefDeclsPtrSet.count(VD)) { 4408 InnerDeclRefs.push_back(Exp); countOfInnerDecls++; 4409 BlockDeclRefs.push_back(Exp); 4410 BlockByRefDeclsPtrSet.insert(VD); 4411 BlockByRefDecls.push_back(VD); 4412 } 4413 } 4414 // Find any imported blocks...they will need special attention. 4415 for (unsigned i = 0; i < InnerBlockDeclRefs.size(); i++) 4416 if (InnerBlockDeclRefs[i]->getDecl()->hasAttr<BlocksAttr>() || 4417 InnerBlockDeclRefs[i]->getType()->isObjCObjectPointerType() || 4418 InnerBlockDeclRefs[i]->getType()->isBlockPointerType()) 4419 ImportedBlockDecls.insert(InnerBlockDeclRefs[i]->getDecl()); 4420 } 4421 InnerDeclRefsCount.push_back(countOfInnerDecls); 4422 4423 std::string FuncName; 4424 4425 if (CurFunctionDef) 4426 FuncName = CurFunctionDef->getNameAsString(); 4427 else if (CurMethodDef) 4428 BuildUniqueMethodName(FuncName, CurMethodDef); 4429 else if (GlobalVarDecl) 4430 FuncName = std::string(GlobalVarDecl->getNameAsString()); 4431 4432 std::string BlockNumber = utostr(Blocks.size()-1); 4433 4434 std::string Tag = "__" + FuncName + "_block_impl_" + BlockNumber; 4435 std::string Func = "__" + FuncName + "_block_func_" + BlockNumber; 4436 4437 // Get a pointer to the function type so we can cast appropriately. 4438 QualType BFT = convertFunctionTypeOfBlocks(Exp->getFunctionType()); 4439 QualType FType = Context->getPointerType(BFT); 4440 4441 FunctionDecl *FD; 4442 Expr *NewRep; 4443 4444 // Simulate a constructor call... 4445 FD = SynthBlockInitFunctionDecl(Tag); 4446 DeclRefExpr *DRE = new (Context) DeclRefExpr(FD, false, FType, VK_RValue, 4447 SourceLocation()); 4448 4449 SmallVector<Expr*, 4> InitExprs; 4450 4451 // Initialize the block function. 4452 FD = SynthBlockInitFunctionDecl(Func); 4453 DeclRefExpr *Arg = new (Context) DeclRefExpr(FD, false, FD->getType(), 4454 VK_LValue, SourceLocation()); 4455 CastExpr *castExpr = NoTypeInfoCStyleCastExpr(Context, Context->VoidPtrTy, 4456 CK_BitCast, Arg); 4457 InitExprs.push_back(castExpr); 4458 4459 // Initialize the block descriptor. 4460 std::string DescData = "__" + FuncName + "_block_desc_" + BlockNumber + "_DATA"; 4461 4462 VarDecl *NewVD = VarDecl::Create(*Context, TUDecl, 4463 SourceLocation(), SourceLocation(), 4464 &Context->Idents.get(DescData.c_str()), 4465 Context->VoidPtrTy, nullptr, 4466 SC_Static); 4467 UnaryOperator *DescRefExpr = 4468 new (Context) UnaryOperator(new (Context) DeclRefExpr(NewVD, false, 4469 Context->VoidPtrTy, 4470 VK_LValue, 4471 SourceLocation()), 4472 UO_AddrOf, 4473 Context->getPointerType(Context->VoidPtrTy), 4474 VK_RValue, OK_Ordinary, 4475 SourceLocation()); 4476 InitExprs.push_back(DescRefExpr); 4477 4478 // Add initializers for any closure decl refs. 4479 if (BlockDeclRefs.size()) { 4480 Expr *Exp; 4481 // Output all "by copy" declarations. 4482 for (SmallVectorImpl<ValueDecl *>::iterator I = BlockByCopyDecls.begin(), 4483 E = BlockByCopyDecls.end(); I != E; ++I) { 4484 if (isObjCType((*I)->getType())) { 4485 // FIXME: Conform to ABI ([[obj retain] autorelease]). 4486 FD = SynthBlockInitFunctionDecl((*I)->getName()); 4487 Exp = new (Context) DeclRefExpr(FD, false, FD->getType(), VK_LValue, 4488 SourceLocation()); 4489 if (HasLocalVariableExternalStorage(*I)) { 4490 QualType QT = (*I)->getType(); 4491 QT = Context->getPointerType(QT); 4492 Exp = new (Context) UnaryOperator(Exp, UO_AddrOf, QT, VK_RValue, 4493 OK_Ordinary, SourceLocation()); 4494 } 4495 } else if (isTopLevelBlockPointerType((*I)->getType())) { 4496 FD = SynthBlockInitFunctionDecl((*I)->getName()); 4497 Arg = new (Context) DeclRefExpr(FD, false, FD->getType(), VK_LValue, 4498 SourceLocation()); 4499 Exp = NoTypeInfoCStyleCastExpr(Context, Context->VoidPtrTy, 4500 CK_BitCast, Arg); 4501 } else { 4502 FD = SynthBlockInitFunctionDecl((*I)->getName()); 4503 Exp = new (Context) DeclRefExpr(FD, false, FD->getType(), VK_LValue, 4504 SourceLocation()); 4505 if (HasLocalVariableExternalStorage(*I)) { 4506 QualType QT = (*I)->getType(); 4507 QT = Context->getPointerType(QT); 4508 Exp = new (Context) UnaryOperator(Exp, UO_AddrOf, QT, VK_RValue, 4509 OK_Ordinary, SourceLocation()); 4510 } 4511 4512 } 4513 InitExprs.push_back(Exp); 4514 } 4515 // Output all "by ref" declarations. 4516 for (SmallVectorImpl<ValueDecl *>::iterator I = BlockByRefDecls.begin(), 4517 E = BlockByRefDecls.end(); I != E; ++I) { 4518 ValueDecl *ND = (*I); 4519 std::string Name(ND->getNameAsString()); 4520 std::string RecName; 4521 RewriteByRefString(RecName, Name, ND, true); 4522 IdentifierInfo *II = &Context->Idents.get(RecName.c_str() 4523 + sizeof("struct")); 4524 RecordDecl *RD = RecordDecl::Create(*Context, TTK_Struct, TUDecl, 4525 SourceLocation(), SourceLocation(), 4526 II); 4527 assert(RD && "SynthBlockInitExpr(): Can't find RecordDecl"); 4528 QualType castT = Context->getPointerType(Context->getTagDeclType(RD)); 4529 4530 FD = SynthBlockInitFunctionDecl((*I)->getName()); 4531 Exp = new (Context) DeclRefExpr(FD, false, FD->getType(), VK_LValue, 4532 SourceLocation()); 4533 bool isNestedCapturedVar = false; 4534 if (block) 4535 for (const auto &CI : block->captures()) { 4536 const VarDecl *variable = CI.getVariable(); 4537 if (variable == ND && CI.isNested()) { 4538 assert (CI.isByRef() && 4539 "SynthBlockInitExpr - captured block variable is not byref"); 4540 isNestedCapturedVar = true; 4541 break; 4542 } 4543 } 4544 // captured nested byref variable has its address passed. Do not take 4545 // its address again. 4546 if (!isNestedCapturedVar) 4547 Exp = new (Context) UnaryOperator(Exp, UO_AddrOf, 4548 Context->getPointerType(Exp->getType()), 4549 VK_RValue, OK_Ordinary, SourceLocation()); 4550 Exp = NoTypeInfoCStyleCastExpr(Context, castT, CK_BitCast, Exp); 4551 InitExprs.push_back(Exp); 4552 } 4553 } 4554 if (ImportedBlockDecls.size()) { 4555 // generate BLOCK_HAS_COPY_DISPOSE(have helper funcs) | BLOCK_HAS_DESCRIPTOR 4556 int flag = (BLOCK_HAS_COPY_DISPOSE | BLOCK_HAS_DESCRIPTOR); 4557 unsigned IntSize = 4558 static_cast<unsigned>(Context->getTypeSize(Context->IntTy)); 4559 Expr *FlagExp = IntegerLiteral::Create(*Context, llvm::APInt(IntSize, flag), 4560 Context->IntTy, SourceLocation()); 4561 InitExprs.push_back(FlagExp); 4562 } 4563 NewRep = new (Context) CallExpr(*Context, DRE, InitExprs, 4564 FType, VK_LValue, SourceLocation()); 4565 NewRep = new (Context) UnaryOperator(NewRep, UO_AddrOf, 4566 Context->getPointerType(NewRep->getType()), 4567 VK_RValue, OK_Ordinary, SourceLocation()); 4568 NewRep = NoTypeInfoCStyleCastExpr(Context, FType, CK_BitCast, 4569 NewRep); 4570 BlockDeclRefs.clear(); 4571 BlockByRefDecls.clear(); 4572 BlockByRefDeclsPtrSet.clear(); 4573 BlockByCopyDecls.clear(); 4574 BlockByCopyDeclsPtrSet.clear(); 4575 ImportedBlockDecls.clear(); 4576 return NewRep; 4577} 4578 4579bool RewriteObjC::IsDeclStmtInForeachHeader(DeclStmt *DS) { 4580 if (const ObjCForCollectionStmt * CS = 4581 dyn_cast<ObjCForCollectionStmt>(Stmts.back())) 4582 return CS->getElement() == DS; 4583 return false; 4584} 4585 4586//===----------------------------------------------------------------------===// 4587// Function Body / Expression rewriting 4588//===----------------------------------------------------------------------===// 4589 4590Stmt *RewriteObjC::RewriteFunctionBodyOrGlobalInitializer(Stmt *S) { 4591 if (isa<SwitchStmt>(S) || isa<WhileStmt>(S) || 4592 isa<DoStmt>(S) || isa<ForStmt>(S)) 4593 Stmts.push_back(S); 4594 else if (isa<ObjCForCollectionStmt>(S)) { 4595 Stmts.push_back(S); 4596 ObjCBcLabelNo.push_back(++BcLabelCount); 4597 } 4598 4599 // Pseudo-object operations and ivar references need special 4600 // treatment because we're going to recursively rewrite them. 4601 if (PseudoObjectExpr *PseudoOp = dyn_cast<PseudoObjectExpr>(S)) { 4602 if (isa<BinaryOperator>(PseudoOp->getSyntacticForm())) { 4603 return RewritePropertyOrImplicitSetter(PseudoOp); 4604 } else { 4605 return RewritePropertyOrImplicitGetter(PseudoOp); 4606 } 4607 } else if (ObjCIvarRefExpr *IvarRefExpr = dyn_cast<ObjCIvarRefExpr>(S)) { 4608 return RewriteObjCIvarRefExpr(IvarRefExpr); 4609 } 4610 4611 SourceRange OrigStmtRange = S->getSourceRange(); 4612 4613 // Perform a bottom up rewrite of all children. 4614 for (Stmt::child_range CI = S->children(); CI; ++CI) 4615 if (*CI) { 4616 Stmt *childStmt = (*CI); 4617 Stmt *newStmt = RewriteFunctionBodyOrGlobalInitializer(childStmt); 4618 if (newStmt) { 4619 *CI = newStmt; 4620 } 4621 } 4622 4623 if (BlockExpr *BE = dyn_cast<BlockExpr>(S)) { 4624 SmallVector<DeclRefExpr *, 8> InnerBlockDeclRefs; 4625 llvm::SmallPtrSet<const DeclContext *, 8> InnerContexts; 4626 InnerContexts.insert(BE->getBlockDecl()); 4627 ImportedLocalExternalDecls.clear(); 4628 GetInnerBlockDeclRefExprs(BE->getBody(), 4629 InnerBlockDeclRefs, InnerContexts); 4630 // Rewrite the block body in place. 4631 Stmt *SaveCurrentBody = CurrentBody; 4632 CurrentBody = BE->getBody(); 4633 PropParentMap = nullptr; 4634 // block literal on rhs of a property-dot-sytax assignment 4635 // must be replaced by its synthesize ast so getRewrittenText 4636 // works as expected. In this case, what actually ends up on RHS 4637 // is the blockTranscribed which is the helper function for the 4638 // block literal; as in: self.c = ^() {[ace ARR];}; 4639 bool saveDisableReplaceStmt = DisableReplaceStmt; 4640 DisableReplaceStmt = false; 4641 RewriteFunctionBodyOrGlobalInitializer(BE->getBody()); 4642 DisableReplaceStmt = saveDisableReplaceStmt; 4643 CurrentBody = SaveCurrentBody; 4644 PropParentMap = nullptr; 4645 ImportedLocalExternalDecls.clear(); 4646 // Now we snarf the rewritten text and stash it away for later use. 4647 std::string Str = Rewrite.getRewrittenText(BE->getSourceRange()); 4648 RewrittenBlockExprs[BE] = Str; 4649 4650 Stmt *blockTranscribed = SynthBlockInitExpr(BE, InnerBlockDeclRefs); 4651 4652 //blockTranscribed->dump(); 4653 ReplaceStmt(S, blockTranscribed); 4654 return blockTranscribed; 4655 } 4656 // Handle specific things. 4657 if (ObjCEncodeExpr *AtEncode = dyn_cast<ObjCEncodeExpr>(S)) 4658 return RewriteAtEncode(AtEncode); 4659 4660 if (ObjCSelectorExpr *AtSelector = dyn_cast<ObjCSelectorExpr>(S)) 4661 return RewriteAtSelector(AtSelector); 4662 4663 if (ObjCStringLiteral *AtString = dyn_cast<ObjCStringLiteral>(S)) 4664 return RewriteObjCStringLiteral(AtString); 4665 4666 if (ObjCMessageExpr *MessExpr = dyn_cast<ObjCMessageExpr>(S)) { 4667#if 0 4668 // Before we rewrite it, put the original message expression in a comment. 4669 SourceLocation startLoc = MessExpr->getLocStart(); 4670 SourceLocation endLoc = MessExpr->getLocEnd(); 4671 4672 const char *startBuf = SM->getCharacterData(startLoc); 4673 const char *endBuf = SM->getCharacterData(endLoc); 4674 4675 std::string messString; 4676 messString += "// "; 4677 messString.append(startBuf, endBuf-startBuf+1); 4678 messString += "\n"; 4679 4680 // FIXME: Missing definition of 4681 // InsertText(clang::SourceLocation, char const*, unsigned int). 4682 // InsertText(startLoc, messString.c_str(), messString.size()); 4683 // Tried this, but it didn't work either... 4684 // ReplaceText(startLoc, 0, messString.c_str(), messString.size()); 4685#endif 4686 return RewriteMessageExpr(MessExpr); 4687 } 4688 4689 if (ObjCAtTryStmt *StmtTry = dyn_cast<ObjCAtTryStmt>(S)) 4690 return RewriteObjCTryStmt(StmtTry); 4691 4692 if (ObjCAtSynchronizedStmt *StmtTry = dyn_cast<ObjCAtSynchronizedStmt>(S)) 4693 return RewriteObjCSynchronizedStmt(StmtTry); 4694 4695 if (ObjCAtThrowStmt *StmtThrow = dyn_cast<ObjCAtThrowStmt>(S)) 4696 return RewriteObjCThrowStmt(StmtThrow); 4697 4698 if (ObjCProtocolExpr *ProtocolExp = dyn_cast<ObjCProtocolExpr>(S)) 4699 return RewriteObjCProtocolExpr(ProtocolExp); 4700 4701 if (ObjCForCollectionStmt *StmtForCollection = 4702 dyn_cast<ObjCForCollectionStmt>(S)) 4703 return RewriteObjCForCollectionStmt(StmtForCollection, 4704 OrigStmtRange.getEnd()); 4705 if (BreakStmt *StmtBreakStmt = 4706 dyn_cast<BreakStmt>(S)) 4707 return RewriteBreakStmt(StmtBreakStmt); 4708 if (ContinueStmt *StmtContinueStmt = 4709 dyn_cast<ContinueStmt>(S)) 4710 return RewriteContinueStmt(StmtContinueStmt); 4711 4712 // Need to check for protocol refs (id <P>, Foo <P> *) in variable decls 4713 // and cast exprs. 4714 if (DeclStmt *DS = dyn_cast<DeclStmt>(S)) { 4715 // FIXME: What we're doing here is modifying the type-specifier that 4716 // precedes the first Decl. In the future the DeclGroup should have 4717 // a separate type-specifier that we can rewrite. 4718 // NOTE: We need to avoid rewriting the DeclStmt if it is within 4719 // the context of an ObjCForCollectionStmt. For example: 4720 // NSArray *someArray; 4721 // for (id <FooProtocol> index in someArray) ; 4722 // This is because RewriteObjCForCollectionStmt() does textual rewriting 4723 // and it depends on the original text locations/positions. 4724 if (Stmts.empty() || !IsDeclStmtInForeachHeader(DS)) 4725 RewriteObjCQualifiedInterfaceTypes(*DS->decl_begin()); 4726 4727 // Blocks rewrite rules. 4728 for (auto *SD : DS->decls()) { 4729 if (ValueDecl *ND = dyn_cast<ValueDecl>(SD)) { 4730 if (isTopLevelBlockPointerType(ND->getType())) 4731 RewriteBlockPointerDecl(ND); 4732 else if (ND->getType()->isFunctionPointerType()) 4733 CheckFunctionPointerDecl(ND->getType(), ND); 4734 if (VarDecl *VD = dyn_cast<VarDecl>(SD)) { 4735 if (VD->hasAttr<BlocksAttr>()) { 4736 static unsigned uniqueByrefDeclCount = 0; 4737 assert(!BlockByRefDeclNo.count(ND) && 4738 "RewriteFunctionBodyOrGlobalInitializer: Duplicate byref decl"); 4739 BlockByRefDeclNo[ND] = uniqueByrefDeclCount++; 4740 RewriteByRefVar(VD); 4741 } 4742 else 4743 RewriteTypeOfDecl(VD); 4744 } 4745 } 4746 if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(SD)) { 4747 if (isTopLevelBlockPointerType(TD->getUnderlyingType())) 4748 RewriteBlockPointerDecl(TD); 4749 else if (TD->getUnderlyingType()->isFunctionPointerType()) 4750 CheckFunctionPointerDecl(TD->getUnderlyingType(), TD); 4751 } 4752 } 4753 } 4754 4755 if (CStyleCastExpr *CE = dyn_cast<CStyleCastExpr>(S)) 4756 RewriteObjCQualifiedInterfaceTypes(CE); 4757 4758 if (isa<SwitchStmt>(S) || isa<WhileStmt>(S) || 4759 isa<DoStmt>(S) || isa<ForStmt>(S)) { 4760 assert(!Stmts.empty() && "Statement stack is empty"); 4761 assert ((isa<SwitchStmt>(Stmts.back()) || isa<WhileStmt>(Stmts.back()) || 4762 isa<DoStmt>(Stmts.back()) || isa<ForStmt>(Stmts.back())) 4763 && "Statement stack mismatch"); 4764 Stmts.pop_back(); 4765 } 4766 // Handle blocks rewriting. 4767 if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(S)) { 4768 ValueDecl *VD = DRE->getDecl(); 4769 if (VD->hasAttr<BlocksAttr>()) 4770 return RewriteBlockDeclRefExpr(DRE); 4771 if (HasLocalVariableExternalStorage(VD)) 4772 return RewriteLocalVariableExternalStorage(DRE); 4773 } 4774 4775 if (CallExpr *CE = dyn_cast<CallExpr>(S)) { 4776 if (CE->getCallee()->getType()->isBlockPointerType()) { 4777 Stmt *BlockCall = SynthesizeBlockCall(CE, CE->getCallee()); 4778 ReplaceStmt(S, BlockCall); 4779 return BlockCall; 4780 } 4781 } 4782 if (CStyleCastExpr *CE = dyn_cast<CStyleCastExpr>(S)) { 4783 RewriteCastExpr(CE); 4784 } 4785#if 0 4786 if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(S)) { 4787 CastExpr *Replacement = new (Context) CastExpr(ICE->getType(), 4788 ICE->getSubExpr(), 4789 SourceLocation()); 4790 // Get the new text. 4791 std::string SStr; 4792 llvm::raw_string_ostream Buf(SStr); 4793 Replacement->printPretty(Buf); 4794 const std::string &Str = Buf.str(); 4795 4796 printf("CAST = %s\n", &Str[0]); 4797 InsertText(ICE->getSubExpr()->getLocStart(), &Str[0], Str.size()); 4798 delete S; 4799 return Replacement; 4800 } 4801#endif 4802 // Return this stmt unmodified. 4803 return S; 4804} 4805 4806void RewriteObjC::RewriteRecordBody(RecordDecl *RD) { 4807 for (auto *FD : RD->fields()) { 4808 if (isTopLevelBlockPointerType(FD->getType())) 4809 RewriteBlockPointerDecl(FD); 4810 if (FD->getType()->isObjCQualifiedIdType() || 4811 FD->getType()->isObjCQualifiedInterfaceType()) 4812 RewriteObjCQualifiedInterfaceTypes(FD); 4813 } 4814} 4815 4816/// HandleDeclInMainFile - This is called for each top-level decl defined in the 4817/// main file of the input. 4818void RewriteObjC::HandleDeclInMainFile(Decl *D) { 4819 switch (D->getKind()) { 4820 case Decl::Function: { 4821 FunctionDecl *FD = cast<FunctionDecl>(D); 4822 if (FD->isOverloadedOperator()) 4823 return; 4824 4825 // Since function prototypes don't have ParmDecl's, we check the function 4826 // prototype. This enables us to rewrite function declarations and 4827 // definitions using the same code. 4828 RewriteBlocksInFunctionProtoType(FD->getType(), FD); 4829 4830 if (!FD->isThisDeclarationADefinition()) 4831 break; 4832 4833 // FIXME: If this should support Obj-C++, support CXXTryStmt 4834 if (CompoundStmt *Body = dyn_cast_or_null<CompoundStmt>(FD->getBody())) { 4835 CurFunctionDef = FD; 4836 CurFunctionDeclToDeclareForBlock = FD; 4837 CurrentBody = Body; 4838 Body = 4839 cast_or_null<CompoundStmt>(RewriteFunctionBodyOrGlobalInitializer(Body)); 4840 FD->setBody(Body); 4841 CurrentBody = nullptr; 4842 if (PropParentMap) { 4843 delete PropParentMap; 4844 PropParentMap = nullptr; 4845 } 4846 // This synthesizes and inserts the block "impl" struct, invoke function, 4847 // and any copy/dispose helper functions. 4848 InsertBlockLiteralsWithinFunction(FD); 4849 CurFunctionDef = nullptr; 4850 CurFunctionDeclToDeclareForBlock = nullptr; 4851 } 4852 break; 4853 } 4854 case Decl::ObjCMethod: { 4855 ObjCMethodDecl *MD = cast<ObjCMethodDecl>(D); 4856 if (CompoundStmt *Body = MD->getCompoundBody()) { 4857 CurMethodDef = MD; 4858 CurrentBody = Body; 4859 Body = 4860 cast_or_null<CompoundStmt>(RewriteFunctionBodyOrGlobalInitializer(Body)); 4861 MD->setBody(Body); 4862 CurrentBody = nullptr; 4863 if (PropParentMap) { 4864 delete PropParentMap; 4865 PropParentMap = nullptr; 4866 } 4867 InsertBlockLiteralsWithinMethod(MD); 4868 CurMethodDef = nullptr; 4869 } 4870 break; 4871 } 4872 case Decl::ObjCImplementation: { 4873 ObjCImplementationDecl *CI = cast<ObjCImplementationDecl>(D); 4874 ClassImplementation.push_back(CI); 4875 break; 4876 } 4877 case Decl::ObjCCategoryImpl: { 4878 ObjCCategoryImplDecl *CI = cast<ObjCCategoryImplDecl>(D); 4879 CategoryImplementation.push_back(CI); 4880 break; 4881 } 4882 case Decl::Var: { 4883 VarDecl *VD = cast<VarDecl>(D); 4884 RewriteObjCQualifiedInterfaceTypes(VD); 4885 if (isTopLevelBlockPointerType(VD->getType())) 4886 RewriteBlockPointerDecl(VD); 4887 else if (VD->getType()->isFunctionPointerType()) { 4888 CheckFunctionPointerDecl(VD->getType(), VD); 4889 if (VD->getInit()) { 4890 if (CStyleCastExpr *CE = dyn_cast<CStyleCastExpr>(VD->getInit())) { 4891 RewriteCastExpr(CE); 4892 } 4893 } 4894 } else if (VD->getType()->isRecordType()) { 4895 RecordDecl *RD = VD->getType()->getAs<RecordType>()->getDecl(); 4896 if (RD->isCompleteDefinition()) 4897 RewriteRecordBody(RD); 4898 } 4899 if (VD->getInit()) { 4900 GlobalVarDecl = VD; 4901 CurrentBody = VD->getInit(); 4902 RewriteFunctionBodyOrGlobalInitializer(VD->getInit()); 4903 CurrentBody = nullptr; 4904 if (PropParentMap) { 4905 delete PropParentMap; 4906 PropParentMap = nullptr; 4907 } 4908 SynthesizeBlockLiterals(VD->getTypeSpecStartLoc(), VD->getName()); 4909 GlobalVarDecl = nullptr; 4910 4911 // This is needed for blocks. 4912 if (CStyleCastExpr *CE = dyn_cast<CStyleCastExpr>(VD->getInit())) { 4913 RewriteCastExpr(CE); 4914 } 4915 } 4916 break; 4917 } 4918 case Decl::TypeAlias: 4919 case Decl::Typedef: { 4920 if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D)) { 4921 if (isTopLevelBlockPointerType(TD->getUnderlyingType())) 4922 RewriteBlockPointerDecl(TD); 4923 else if (TD->getUnderlyingType()->isFunctionPointerType()) 4924 CheckFunctionPointerDecl(TD->getUnderlyingType(), TD); 4925 } 4926 break; 4927 } 4928 case Decl::CXXRecord: 4929 case Decl::Record: { 4930 RecordDecl *RD = cast<RecordDecl>(D); 4931 if (RD->isCompleteDefinition()) 4932 RewriteRecordBody(RD); 4933 break; 4934 } 4935 default: 4936 break; 4937 } 4938 // Nothing yet. 4939} 4940 4941void RewriteObjC::HandleTranslationUnit(ASTContext &C) { 4942 if (Diags.hasErrorOccurred()) 4943 return; 4944 4945 RewriteInclude(); 4946 4947 // Here's a great place to add any extra declarations that may be needed. 4948 // Write out meta data for each @protocol(<expr>). 4949 for (ObjCProtocolDecl *ProtDecl : ProtocolExprDecls) 4950 RewriteObjCProtocolMetaData(ProtDecl, "", "", Preamble); 4951 4952 InsertText(SM->getLocForStartOfFile(MainFileID), Preamble, false); 4953 if (ClassImplementation.size() || CategoryImplementation.size()) 4954 RewriteImplementations(); 4955 4956 // Get the buffer corresponding to MainFileID. If we haven't changed it, then 4957 // we are done. 4958 if (const RewriteBuffer *RewriteBuf = 4959 Rewrite.getRewriteBufferFor(MainFileID)) { 4960 //printf("Changed:\n"); 4961 *OutFile << std::string(RewriteBuf->begin(), RewriteBuf->end()); 4962 } else { 4963 llvm::errs() << "No changes\n"; 4964 } 4965 4966 if (ClassImplementation.size() || CategoryImplementation.size() || 4967 ProtocolExprDecls.size()) { 4968 // Rewrite Objective-c meta data* 4969 std::string ResultStr; 4970 RewriteMetaDataIntoBuffer(ResultStr); 4971 // Emit metadata. 4972 *OutFile << ResultStr; 4973 } 4974 OutFile->flush(); 4975} 4976 4977void RewriteObjCFragileABI::Initialize(ASTContext &context) { 4978 InitializeCommon(context); 4979 4980 // declaring objc_selector outside the parameter list removes a silly 4981 // scope related warning... 4982 if (IsHeader) 4983 Preamble = "#pragma once\n"; 4984 Preamble += "struct objc_selector; struct objc_class;\n"; 4985 Preamble += "struct __rw_objc_super { struct objc_object *object; "; 4986 Preamble += "struct objc_object *superClass; "; 4987 if (LangOpts.MicrosoftExt) { 4988 // Add a constructor for creating temporary objects. 4989 Preamble += "__rw_objc_super(struct objc_object *o, struct objc_object *s) " 4990 ": "; 4991 Preamble += "object(o), superClass(s) {} "; 4992 } 4993 Preamble += "};\n"; 4994 Preamble += "#ifndef _REWRITER_typedef_Protocol\n"; 4995 Preamble += "typedef struct objc_object Protocol;\n"; 4996 Preamble += "#define _REWRITER_typedef_Protocol\n"; 4997 Preamble += "#endif\n"; 4998 if (LangOpts.MicrosoftExt) { 4999 Preamble += "#define __OBJC_RW_DLLIMPORT extern \"C\" __declspec(dllimport)\n"; 5000 Preamble += "#define __OBJC_RW_STATICIMPORT extern \"C\"\n"; 5001 } else 5002 Preamble += "#define __OBJC_RW_DLLIMPORT extern\n"; 5003 Preamble += "__OBJC_RW_DLLIMPORT struct objc_object *objc_msgSend"; 5004 Preamble += "(struct objc_object *, struct objc_selector *, ...);\n"; 5005 Preamble += "__OBJC_RW_DLLIMPORT struct objc_object *objc_msgSendSuper"; 5006 Preamble += "(struct objc_super *, struct objc_selector *, ...);\n"; 5007 Preamble += "__OBJC_RW_DLLIMPORT struct objc_object* objc_msgSend_stret"; 5008 Preamble += "(struct objc_object *, struct objc_selector *, ...);\n"; 5009 Preamble += "__OBJC_RW_DLLIMPORT struct objc_object* objc_msgSendSuper_stret"; 5010 Preamble += "(struct objc_super *, struct objc_selector *, ...);\n"; 5011 Preamble += "__OBJC_RW_DLLIMPORT double objc_msgSend_fpret"; 5012 Preamble += "(struct objc_object *, struct objc_selector *, ...);\n"; 5013 Preamble += "__OBJC_RW_DLLIMPORT struct objc_object *objc_getClass"; 5014 Preamble += "(const char *);\n"; 5015 Preamble += "__OBJC_RW_DLLIMPORT struct objc_class *class_getSuperclass"; 5016 Preamble += "(struct objc_class *);\n"; 5017 Preamble += "__OBJC_RW_DLLIMPORT struct objc_object *objc_getMetaClass"; 5018 Preamble += "(const char *);\n"; 5019 Preamble += "__OBJC_RW_DLLIMPORT void objc_exception_throw(struct objc_object *);\n"; 5020 Preamble += "__OBJC_RW_DLLIMPORT void objc_exception_try_enter(void *);\n"; 5021 Preamble += "__OBJC_RW_DLLIMPORT void objc_exception_try_exit(void *);\n"; 5022 Preamble += "__OBJC_RW_DLLIMPORT struct objc_object *objc_exception_extract(void *);\n"; 5023 Preamble += "__OBJC_RW_DLLIMPORT int objc_exception_match"; 5024 Preamble += "(struct objc_class *, struct objc_object *);\n"; 5025 // @synchronized hooks. 5026 Preamble += "__OBJC_RW_DLLIMPORT int objc_sync_enter(struct objc_object *);\n"; 5027 Preamble += "__OBJC_RW_DLLIMPORT int objc_sync_exit(struct objc_object *);\n"; 5028 Preamble += "__OBJC_RW_DLLIMPORT Protocol *objc_getProtocol(const char *);\n"; 5029 Preamble += "#ifndef __FASTENUMERATIONSTATE\n"; 5030 Preamble += "struct __objcFastEnumerationState {\n\t"; 5031 Preamble += "unsigned long state;\n\t"; 5032 Preamble += "void **itemsPtr;\n\t"; 5033 Preamble += "unsigned long *mutationsPtr;\n\t"; 5034 Preamble += "unsigned long extra[5];\n};\n"; 5035 Preamble += "__OBJC_RW_DLLIMPORT void objc_enumerationMutation(struct objc_object *);\n"; 5036 Preamble += "#define __FASTENUMERATIONSTATE\n"; 5037 Preamble += "#endif\n"; 5038 Preamble += "#ifndef __NSCONSTANTSTRINGIMPL\n"; 5039 Preamble += "struct __NSConstantStringImpl {\n"; 5040 Preamble += " int *isa;\n"; 5041 Preamble += " int flags;\n"; 5042 Preamble += " char *str;\n"; 5043 Preamble += " long length;\n"; 5044 Preamble += "};\n"; 5045 Preamble += "#ifdef CF_EXPORT_CONSTANT_STRING\n"; 5046 Preamble += "extern \"C\" __declspec(dllexport) int __CFConstantStringClassReference[];\n"; 5047 Preamble += "#else\n"; 5048 Preamble += "__OBJC_RW_DLLIMPORT int __CFConstantStringClassReference[];\n"; 5049 Preamble += "#endif\n"; 5050 Preamble += "#define __NSCONSTANTSTRINGIMPL\n"; 5051 Preamble += "#endif\n"; 5052 // Blocks preamble. 5053 Preamble += "#ifndef BLOCK_IMPL\n"; 5054 Preamble += "#define BLOCK_IMPL\n"; 5055 Preamble += "struct __block_impl {\n"; 5056 Preamble += " void *isa;\n"; 5057 Preamble += " int Flags;\n"; 5058 Preamble += " int Reserved;\n"; 5059 Preamble += " void *FuncPtr;\n"; 5060 Preamble += "};\n"; 5061 Preamble += "// Runtime copy/destroy helper functions (from Block_private.h)\n"; 5062 Preamble += "#ifdef __OBJC_EXPORT_BLOCKS\n"; 5063 Preamble += "extern \"C\" __declspec(dllexport) " 5064 "void _Block_object_assign(void *, const void *, const int);\n"; 5065 Preamble += "extern \"C\" __declspec(dllexport) void _Block_object_dispose(const void *, const int);\n"; 5066 Preamble += "extern \"C\" __declspec(dllexport) void *_NSConcreteGlobalBlock[32];\n"; 5067 Preamble += "extern \"C\" __declspec(dllexport) void *_NSConcreteStackBlock[32];\n"; 5068 Preamble += "#else\n"; 5069 Preamble += "__OBJC_RW_DLLIMPORT void _Block_object_assign(void *, const void *, const int);\n"; 5070 Preamble += "__OBJC_RW_DLLIMPORT void _Block_object_dispose(const void *, const int);\n"; 5071 Preamble += "__OBJC_RW_DLLIMPORT void *_NSConcreteGlobalBlock[32];\n"; 5072 Preamble += "__OBJC_RW_DLLIMPORT void *_NSConcreteStackBlock[32];\n"; 5073 Preamble += "#endif\n"; 5074 Preamble += "#endif\n"; 5075 if (LangOpts.MicrosoftExt) { 5076 Preamble += "#undef __OBJC_RW_DLLIMPORT\n"; 5077 Preamble += "#undef __OBJC_RW_STATICIMPORT\n"; 5078 Preamble += "#ifndef KEEP_ATTRIBUTES\n"; // We use this for clang tests. 5079 Preamble += "#define __attribute__(X)\n"; 5080 Preamble += "#endif\n"; 5081 Preamble += "#define __weak\n"; 5082 } 5083 else { 5084 Preamble += "#define __block\n"; 5085 Preamble += "#define __weak\n"; 5086 } 5087 // NOTE! Windows uses LLP64 for 64bit mode. So, cast pointer to long long 5088 // as this avoids warning in any 64bit/32bit compilation model. 5089 Preamble += "\n#define __OFFSETOFIVAR__(TYPE, MEMBER) ((long long) &((TYPE *)0)->MEMBER)\n"; 5090} 5091 5092/// RewriteIvarOffsetComputation - This rutine synthesizes computation of 5093/// ivar offset. 5094void RewriteObjCFragileABI::RewriteIvarOffsetComputation(ObjCIvarDecl *ivar, 5095 std::string &Result) { 5096 if (ivar->isBitField()) { 5097 // FIXME: The hack below doesn't work for bitfields. For now, we simply 5098 // place all bitfields at offset 0. 5099 Result += "0"; 5100 } else { 5101 Result += "__OFFSETOFIVAR__(struct "; 5102 Result += ivar->getContainingInterface()->getNameAsString(); 5103 if (LangOpts.MicrosoftExt) 5104 Result += "_IMPL"; 5105 Result += ", "; 5106 Result += ivar->getNameAsString(); 5107 Result += ")"; 5108 } 5109} 5110 5111/// RewriteObjCProtocolMetaData - Rewrite protocols meta-data. 5112void RewriteObjCFragileABI::RewriteObjCProtocolMetaData( 5113 ObjCProtocolDecl *PDecl, StringRef prefix, 5114 StringRef ClassName, std::string &Result) { 5115 static bool objc_protocol_methods = false; 5116 5117 // Output struct protocol_methods holder of method selector and type. 5118 if (!objc_protocol_methods && PDecl->hasDefinition()) { 5119 /* struct protocol_methods { 5120 SEL _cmd; 5121 char *method_types; 5122 } 5123 */ 5124 Result += "\nstruct _protocol_methods {\n"; 5125 Result += "\tstruct objc_selector *_cmd;\n"; 5126 Result += "\tchar *method_types;\n"; 5127 Result += "};\n"; 5128 5129 objc_protocol_methods = true; 5130 } 5131 // Do not synthesize the protocol more than once. 5132 if (ObjCSynthesizedProtocols.count(PDecl->getCanonicalDecl())) 5133 return; 5134 5135 if (ObjCProtocolDecl *Def = PDecl->getDefinition()) 5136 PDecl = Def; 5137 5138 if (PDecl->instmeth_begin() != PDecl->instmeth_end()) { 5139 unsigned NumMethods = std::distance(PDecl->instmeth_begin(), 5140 PDecl->instmeth_end()); 5141 /* struct _objc_protocol_method_list { 5142 int protocol_method_count; 5143 struct protocol_methods protocols[]; 5144 } 5145 */ 5146 Result += "\nstatic struct {\n"; 5147 Result += "\tint protocol_method_count;\n"; 5148 Result += "\tstruct _protocol_methods protocol_methods["; 5149 Result += utostr(NumMethods); 5150 Result += "];\n} _OBJC_PROTOCOL_INSTANCE_METHODS_"; 5151 Result += PDecl->getNameAsString(); 5152 Result += " __attribute__ ((used, section (\"__OBJC, __cat_inst_meth\")))= " 5153 "{\n\t" + utostr(NumMethods) + "\n"; 5154 5155 // Output instance methods declared in this protocol. 5156 for (ObjCProtocolDecl::instmeth_iterator 5157 I = PDecl->instmeth_begin(), E = PDecl->instmeth_end(); 5158 I != E; ++I) { 5159 if (I == PDecl->instmeth_begin()) 5160 Result += "\t ,{{(struct objc_selector *)\""; 5161 else 5162 Result += "\t ,{(struct objc_selector *)\""; 5163 Result += (*I)->getSelector().getAsString(); 5164 std::string MethodTypeString; 5165 Context->getObjCEncodingForMethodDecl((*I), MethodTypeString); 5166 Result += "\", \""; 5167 Result += MethodTypeString; 5168 Result += "\"}\n"; 5169 } 5170 Result += "\t }\n};\n"; 5171 } 5172 5173 // Output class methods declared in this protocol. 5174 unsigned NumMethods = std::distance(PDecl->classmeth_begin(), 5175 PDecl->classmeth_end()); 5176 if (NumMethods > 0) { 5177 /* struct _objc_protocol_method_list { 5178 int protocol_method_count; 5179 struct protocol_methods protocols[]; 5180 } 5181 */ 5182 Result += "\nstatic struct {\n"; 5183 Result += "\tint protocol_method_count;\n"; 5184 Result += "\tstruct _protocol_methods protocol_methods["; 5185 Result += utostr(NumMethods); 5186 Result += "];\n} _OBJC_PROTOCOL_CLASS_METHODS_"; 5187 Result += PDecl->getNameAsString(); 5188 Result += " __attribute__ ((used, section (\"__OBJC, __cat_cls_meth\")))= " 5189 "{\n\t"; 5190 Result += utostr(NumMethods); 5191 Result += "\n"; 5192 5193 // Output instance methods declared in this protocol. 5194 for (ObjCProtocolDecl::classmeth_iterator 5195 I = PDecl->classmeth_begin(), E = PDecl->classmeth_end(); 5196 I != E; ++I) { 5197 if (I == PDecl->classmeth_begin()) 5198 Result += "\t ,{{(struct objc_selector *)\""; 5199 else 5200 Result += "\t ,{(struct objc_selector *)\""; 5201 Result += (*I)->getSelector().getAsString(); 5202 std::string MethodTypeString; 5203 Context->getObjCEncodingForMethodDecl((*I), MethodTypeString); 5204 Result += "\", \""; 5205 Result += MethodTypeString; 5206 Result += "\"}\n"; 5207 } 5208 Result += "\t }\n};\n"; 5209 } 5210 5211 // Output: 5212 /* struct _objc_protocol { 5213 // Objective-C 1.0 extensions 5214 struct _objc_protocol_extension *isa; 5215 char *protocol_name; 5216 struct _objc_protocol **protocol_list; 5217 struct _objc_protocol_method_list *instance_methods; 5218 struct _objc_protocol_method_list *class_methods; 5219 }; 5220 */ 5221 static bool objc_protocol = false; 5222 if (!objc_protocol) { 5223 Result += "\nstruct _objc_protocol {\n"; 5224 Result += "\tstruct _objc_protocol_extension *isa;\n"; 5225 Result += "\tchar *protocol_name;\n"; 5226 Result += "\tstruct _objc_protocol **protocol_list;\n"; 5227 Result += "\tstruct _objc_protocol_method_list *instance_methods;\n"; 5228 Result += "\tstruct _objc_protocol_method_list *class_methods;\n"; 5229 Result += "};\n"; 5230 5231 objc_protocol = true; 5232 } 5233 5234 Result += "\nstatic struct _objc_protocol _OBJC_PROTOCOL_"; 5235 Result += PDecl->getNameAsString(); 5236 Result += " __attribute__ ((used, section (\"__OBJC, __protocol\")))= " 5237 "{\n\t0, \""; 5238 Result += PDecl->getNameAsString(); 5239 Result += "\", 0, "; 5240 if (PDecl->instmeth_begin() != PDecl->instmeth_end()) { 5241 Result += "(struct _objc_protocol_method_list *)&_OBJC_PROTOCOL_INSTANCE_METHODS_"; 5242 Result += PDecl->getNameAsString(); 5243 Result += ", "; 5244 } 5245 else 5246 Result += "0, "; 5247 if (PDecl->classmeth_begin() != PDecl->classmeth_end()) { 5248 Result += "(struct _objc_protocol_method_list *)&_OBJC_PROTOCOL_CLASS_METHODS_"; 5249 Result += PDecl->getNameAsString(); 5250 Result += "\n"; 5251 } 5252 else 5253 Result += "0\n"; 5254 Result += "};\n"; 5255 5256 // Mark this protocol as having been generated. 5257 if (!ObjCSynthesizedProtocols.insert(PDecl->getCanonicalDecl()).second) 5258 llvm_unreachable("protocol already synthesized"); 5259 5260} 5261 5262void RewriteObjCFragileABI::RewriteObjCProtocolListMetaData( 5263 const ObjCList<ObjCProtocolDecl> &Protocols, 5264 StringRef prefix, StringRef ClassName, 5265 std::string &Result) { 5266 if (Protocols.empty()) return; 5267 5268 for (unsigned i = 0; i != Protocols.size(); i++) 5269 RewriteObjCProtocolMetaData(Protocols[i], prefix, ClassName, Result); 5270 5271 // Output the top lovel protocol meta-data for the class. 5272 /* struct _objc_protocol_list { 5273 struct _objc_protocol_list *next; 5274 int protocol_count; 5275 struct _objc_protocol *class_protocols[]; 5276 } 5277 */ 5278 Result += "\nstatic struct {\n"; 5279 Result += "\tstruct _objc_protocol_list *next;\n"; 5280 Result += "\tint protocol_count;\n"; 5281 Result += "\tstruct _objc_protocol *class_protocols["; 5282 Result += utostr(Protocols.size()); 5283 Result += "];\n} _OBJC_"; 5284 Result += prefix; 5285 Result += "_PROTOCOLS_"; 5286 Result += ClassName; 5287 Result += " __attribute__ ((used, section (\"__OBJC, __cat_cls_meth\")))= " 5288 "{\n\t0, "; 5289 Result += utostr(Protocols.size()); 5290 Result += "\n"; 5291 5292 Result += "\t,{&_OBJC_PROTOCOL_"; 5293 Result += Protocols[0]->getNameAsString(); 5294 Result += " \n"; 5295 5296 for (unsigned i = 1; i != Protocols.size(); i++) { 5297 Result += "\t ,&_OBJC_PROTOCOL_"; 5298 Result += Protocols[i]->getNameAsString(); 5299 Result += "\n"; 5300 } 5301 Result += "\t }\n};\n"; 5302} 5303 5304void RewriteObjCFragileABI::RewriteObjCClassMetaData(ObjCImplementationDecl *IDecl, 5305 std::string &Result) { 5306 ObjCInterfaceDecl *CDecl = IDecl->getClassInterface(); 5307 5308 // Explicitly declared @interface's are already synthesized. 5309 if (CDecl->isImplicitInterfaceDecl()) { 5310 // FIXME: Implementation of a class with no @interface (legacy) does not 5311 // produce correct synthesis as yet. 5312 RewriteObjCInternalStruct(CDecl, Result); 5313 } 5314 5315 // Build _objc_ivar_list metadata for classes ivars if needed 5316 unsigned NumIvars = !IDecl->ivar_empty() 5317 ? IDecl->ivar_size() 5318 : (CDecl ? CDecl->ivar_size() : 0); 5319 if (NumIvars > 0) { 5320 static bool objc_ivar = false; 5321 if (!objc_ivar) { 5322 /* struct _objc_ivar { 5323 char *ivar_name; 5324 char *ivar_type; 5325 int ivar_offset; 5326 }; 5327 */ 5328 Result += "\nstruct _objc_ivar {\n"; 5329 Result += "\tchar *ivar_name;\n"; 5330 Result += "\tchar *ivar_type;\n"; 5331 Result += "\tint ivar_offset;\n"; 5332 Result += "};\n"; 5333 5334 objc_ivar = true; 5335 } 5336 5337 /* struct { 5338 int ivar_count; 5339 struct _objc_ivar ivar_list[nIvars]; 5340 }; 5341 */ 5342 Result += "\nstatic struct {\n"; 5343 Result += "\tint ivar_count;\n"; 5344 Result += "\tstruct _objc_ivar ivar_list["; 5345 Result += utostr(NumIvars); 5346 Result += "];\n} _OBJC_INSTANCE_VARIABLES_"; 5347 Result += IDecl->getNameAsString(); 5348 Result += " __attribute__ ((used, section (\"__OBJC, __instance_vars\")))= " 5349 "{\n\t"; 5350 Result += utostr(NumIvars); 5351 Result += "\n"; 5352 5353 ObjCInterfaceDecl::ivar_iterator IVI, IVE; 5354 SmallVector<ObjCIvarDecl *, 8> IVars; 5355 if (!IDecl->ivar_empty()) { 5356 for (auto *IV : IDecl->ivars()) 5357 IVars.push_back(IV); 5358 IVI = IDecl->ivar_begin(); 5359 IVE = IDecl->ivar_end(); 5360 } else { 5361 IVI = CDecl->ivar_begin(); 5362 IVE = CDecl->ivar_end(); 5363 } 5364 Result += "\t,{{\""; 5365 Result += IVI->getNameAsString(); 5366 Result += "\", \""; 5367 std::string TmpString, StrEncoding; 5368 Context->getObjCEncodingForType(IVI->getType(), TmpString, *IVI); 5369 QuoteDoublequotes(TmpString, StrEncoding); 5370 Result += StrEncoding; 5371 Result += "\", "; 5372 RewriteIvarOffsetComputation(*IVI, Result); 5373 Result += "}\n"; 5374 for (++IVI; IVI != IVE; ++IVI) { 5375 Result += "\t ,{\""; 5376 Result += IVI->getNameAsString(); 5377 Result += "\", \""; 5378 std::string TmpString, StrEncoding; 5379 Context->getObjCEncodingForType(IVI->getType(), TmpString, *IVI); 5380 QuoteDoublequotes(TmpString, StrEncoding); 5381 Result += StrEncoding; 5382 Result += "\", "; 5383 RewriteIvarOffsetComputation(*IVI, Result); 5384 Result += "}\n"; 5385 } 5386 5387 Result += "\t }\n};\n"; 5388 } 5389 5390 // Build _objc_method_list for class's instance methods if needed 5391 SmallVector<ObjCMethodDecl *, 32> InstanceMethods(IDecl->instance_methods()); 5392 5393 // If any of our property implementations have associated getters or 5394 // setters, produce metadata for them as well. 5395 for (const auto *Prop : IDecl->property_impls()) { 5396 if (Prop->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic) 5397 continue; 5398 if (!Prop->getPropertyIvarDecl()) 5399 continue; 5400 ObjCPropertyDecl *PD = Prop->getPropertyDecl(); 5401 if (!PD) 5402 continue; 5403 if (ObjCMethodDecl *Getter = PD->getGetterMethodDecl()) 5404 if (!Getter->isDefined()) 5405 InstanceMethods.push_back(Getter); 5406 if (PD->isReadOnly()) 5407 continue; 5408 if (ObjCMethodDecl *Setter = PD->getSetterMethodDecl()) 5409 if (!Setter->isDefined()) 5410 InstanceMethods.push_back(Setter); 5411 } 5412 RewriteObjCMethodsMetaData(InstanceMethods.begin(), InstanceMethods.end(), 5413 true, "", IDecl->getName(), Result); 5414 5415 // Build _objc_method_list for class's class methods if needed 5416 RewriteObjCMethodsMetaData(IDecl->classmeth_begin(), IDecl->classmeth_end(), 5417 false, "", IDecl->getName(), Result); 5418 5419 // Protocols referenced in class declaration? 5420 RewriteObjCProtocolListMetaData(CDecl->getReferencedProtocols(), 5421 "CLASS", CDecl->getName(), Result); 5422 5423 // Declaration of class/meta-class metadata 5424 /* struct _objc_class { 5425 struct _objc_class *isa; // or const char *root_class_name when metadata 5426 const char *super_class_name; 5427 char *name; 5428 long version; 5429 long info; 5430 long instance_size; 5431 struct _objc_ivar_list *ivars; 5432 struct _objc_method_list *methods; 5433 struct objc_cache *cache; 5434 struct objc_protocol_list *protocols; 5435 const char *ivar_layout; 5436 struct _objc_class_ext *ext; 5437 }; 5438 */ 5439 static bool objc_class = false; 5440 if (!objc_class) { 5441 Result += "\nstruct _objc_class {\n"; 5442 Result += "\tstruct _objc_class *isa;\n"; 5443 Result += "\tconst char *super_class_name;\n"; 5444 Result += "\tchar *name;\n"; 5445 Result += "\tlong version;\n"; 5446 Result += "\tlong info;\n"; 5447 Result += "\tlong instance_size;\n"; 5448 Result += "\tstruct _objc_ivar_list *ivars;\n"; 5449 Result += "\tstruct _objc_method_list *methods;\n"; 5450 Result += "\tstruct objc_cache *cache;\n"; 5451 Result += "\tstruct _objc_protocol_list *protocols;\n"; 5452 Result += "\tconst char *ivar_layout;\n"; 5453 Result += "\tstruct _objc_class_ext *ext;\n"; 5454 Result += "};\n"; 5455 objc_class = true; 5456 } 5457 5458 // Meta-class metadata generation. 5459 ObjCInterfaceDecl *RootClass = nullptr; 5460 ObjCInterfaceDecl *SuperClass = CDecl->getSuperClass(); 5461 while (SuperClass) { 5462 RootClass = SuperClass; 5463 SuperClass = SuperClass->getSuperClass(); 5464 } 5465 SuperClass = CDecl->getSuperClass(); 5466 5467 Result += "\nstatic struct _objc_class _OBJC_METACLASS_"; 5468 Result += CDecl->getNameAsString(); 5469 Result += " __attribute__ ((used, section (\"__OBJC, __meta_class\")))= " 5470 "{\n\t(struct _objc_class *)\""; 5471 Result += (RootClass ? RootClass->getNameAsString() : CDecl->getNameAsString()); 5472 Result += "\""; 5473 5474 if (SuperClass) { 5475 Result += ", \""; 5476 Result += SuperClass->getNameAsString(); 5477 Result += "\", \""; 5478 Result += CDecl->getNameAsString(); 5479 Result += "\""; 5480 } 5481 else { 5482 Result += ", 0, \""; 5483 Result += CDecl->getNameAsString(); 5484 Result += "\""; 5485 } 5486 // Set 'ivars' field for root class to 0. ObjC1 runtime does not use it. 5487 // 'info' field is initialized to CLS_META(2) for metaclass 5488 Result += ", 0,2, sizeof(struct _objc_class), 0"; 5489 if (IDecl->classmeth_begin() != IDecl->classmeth_end()) { 5490 Result += "\n\t, (struct _objc_method_list *)&_OBJC_CLASS_METHODS_"; 5491 Result += IDecl->getNameAsString(); 5492 Result += "\n"; 5493 } 5494 else 5495 Result += ", 0\n"; 5496 if (CDecl->protocol_begin() != CDecl->protocol_end()) { 5497 Result += "\t,0, (struct _objc_protocol_list *)&_OBJC_CLASS_PROTOCOLS_"; 5498 Result += CDecl->getNameAsString(); 5499 Result += ",0,0\n"; 5500 } 5501 else 5502 Result += "\t,0,0,0,0\n"; 5503 Result += "};\n"; 5504 5505 // class metadata generation. 5506 Result += "\nstatic struct _objc_class _OBJC_CLASS_"; 5507 Result += CDecl->getNameAsString(); 5508 Result += " __attribute__ ((used, section (\"__OBJC, __class\")))= " 5509 "{\n\t&_OBJC_METACLASS_"; 5510 Result += CDecl->getNameAsString(); 5511 if (SuperClass) { 5512 Result += ", \""; 5513 Result += SuperClass->getNameAsString(); 5514 Result += "\", \""; 5515 Result += CDecl->getNameAsString(); 5516 Result += "\""; 5517 } 5518 else { 5519 Result += ", 0, \""; 5520 Result += CDecl->getNameAsString(); 5521 Result += "\""; 5522 } 5523 // 'info' field is initialized to CLS_CLASS(1) for class 5524 Result += ", 0,1"; 5525 if (!ObjCSynthesizedStructs.count(CDecl)) 5526 Result += ",0"; 5527 else { 5528 // class has size. Must synthesize its size. 5529 Result += ",sizeof(struct "; 5530 Result += CDecl->getNameAsString(); 5531 if (LangOpts.MicrosoftExt) 5532 Result += "_IMPL"; 5533 Result += ")"; 5534 } 5535 if (NumIvars > 0) { 5536 Result += ", (struct _objc_ivar_list *)&_OBJC_INSTANCE_VARIABLES_"; 5537 Result += CDecl->getNameAsString(); 5538 Result += "\n\t"; 5539 } 5540 else 5541 Result += ",0"; 5542 if (IDecl->instmeth_begin() != IDecl->instmeth_end()) { 5543 Result += ", (struct _objc_method_list *)&_OBJC_INSTANCE_METHODS_"; 5544 Result += CDecl->getNameAsString(); 5545 Result += ", 0\n\t"; 5546 } 5547 else 5548 Result += ",0,0"; 5549 if (CDecl->protocol_begin() != CDecl->protocol_end()) { 5550 Result += ", (struct _objc_protocol_list*)&_OBJC_CLASS_PROTOCOLS_"; 5551 Result += CDecl->getNameAsString(); 5552 Result += ", 0,0\n"; 5553 } 5554 else 5555 Result += ",0,0,0\n"; 5556 Result += "};\n"; 5557} 5558 5559void RewriteObjCFragileABI::RewriteMetaDataIntoBuffer(std::string &Result) { 5560 int ClsDefCount = ClassImplementation.size(); 5561 int CatDefCount = CategoryImplementation.size(); 5562 5563 // For each implemented class, write out all its meta data. 5564 for (int i = 0; i < ClsDefCount; i++) 5565 RewriteObjCClassMetaData(ClassImplementation[i], Result); 5566 5567 // For each implemented category, write out all its meta data. 5568 for (int i = 0; i < CatDefCount; i++) 5569 RewriteObjCCategoryImplDecl(CategoryImplementation[i], Result); 5570 5571 // Write objc_symtab metadata 5572 /* 5573 struct _objc_symtab 5574 { 5575 long sel_ref_cnt; 5576 SEL *refs; 5577 short cls_def_cnt; 5578 short cat_def_cnt; 5579 void *defs[cls_def_cnt + cat_def_cnt]; 5580 }; 5581 */ 5582 5583 Result += "\nstruct _objc_symtab {\n"; 5584 Result += "\tlong sel_ref_cnt;\n"; 5585 Result += "\tSEL *refs;\n"; 5586 Result += "\tshort cls_def_cnt;\n"; 5587 Result += "\tshort cat_def_cnt;\n"; 5588 Result += "\tvoid *defs[" + utostr(ClsDefCount + CatDefCount)+ "];\n"; 5589 Result += "};\n\n"; 5590 5591 Result += "static struct _objc_symtab " 5592 "_OBJC_SYMBOLS __attribute__((used, section (\"__OBJC, __symbols\")))= {\n"; 5593 Result += "\t0, 0, " + utostr(ClsDefCount) 5594 + ", " + utostr(CatDefCount) + "\n"; 5595 for (int i = 0; i < ClsDefCount; i++) { 5596 Result += "\t,&_OBJC_CLASS_"; 5597 Result += ClassImplementation[i]->getNameAsString(); 5598 Result += "\n"; 5599 } 5600 5601 for (int i = 0; i < CatDefCount; i++) { 5602 Result += "\t,&_OBJC_CATEGORY_"; 5603 Result += CategoryImplementation[i]->getClassInterface()->getNameAsString(); 5604 Result += "_"; 5605 Result += CategoryImplementation[i]->getNameAsString(); 5606 Result += "\n"; 5607 } 5608 5609 Result += "};\n\n"; 5610 5611 // Write objc_module metadata 5612 5613 /* 5614 struct _objc_module { 5615 long version; 5616 long size; 5617 const char *name; 5618 struct _objc_symtab *symtab; 5619 } 5620 */ 5621 5622 Result += "\nstruct _objc_module {\n"; 5623 Result += "\tlong version;\n"; 5624 Result += "\tlong size;\n"; 5625 Result += "\tconst char *name;\n"; 5626 Result += "\tstruct _objc_symtab *symtab;\n"; 5627 Result += "};\n\n"; 5628 Result += "static struct _objc_module " 5629 "_OBJC_MODULES __attribute__ ((used, section (\"__OBJC, __module_info\")))= {\n"; 5630 Result += "\t" + utostr(OBJC_ABI_VERSION) + 5631 ", sizeof(struct _objc_module), \"\", &_OBJC_SYMBOLS\n"; 5632 Result += "};\n\n"; 5633 5634 if (LangOpts.MicrosoftExt) { 5635 if (ProtocolExprDecls.size()) { 5636 Result += "#pragma section(\".objc_protocol$B\",long,read,write)\n"; 5637 Result += "#pragma data_seg(push, \".objc_protocol$B\")\n"; 5638 for (ObjCProtocolDecl *ProtDecl : ProtocolExprDecls) { 5639 Result += "static struct _objc_protocol *_POINTER_OBJC_PROTOCOL_"; 5640 Result += ProtDecl->getNameAsString(); 5641 Result += " = &_OBJC_PROTOCOL_"; 5642 Result += ProtDecl->getNameAsString(); 5643 Result += ";\n"; 5644 } 5645 Result += "#pragma data_seg(pop)\n\n"; 5646 } 5647 Result += "#pragma section(\".objc_module_info$B\",long,read,write)\n"; 5648 Result += "#pragma data_seg(push, \".objc_module_info$B\")\n"; 5649 Result += "static struct _objc_module *_POINTER_OBJC_MODULES = "; 5650 Result += "&_OBJC_MODULES;\n"; 5651 Result += "#pragma data_seg(pop)\n\n"; 5652 } 5653} 5654 5655/// RewriteObjCCategoryImplDecl - Rewrite metadata for each category 5656/// implementation. 5657void RewriteObjCFragileABI::RewriteObjCCategoryImplDecl(ObjCCategoryImplDecl *IDecl, 5658 std::string &Result) { 5659 ObjCInterfaceDecl *ClassDecl = IDecl->getClassInterface(); 5660 // Find category declaration for this implementation. 5661 ObjCCategoryDecl *CDecl 5662 = ClassDecl->FindCategoryDeclaration(IDecl->getIdentifier()); 5663 5664 std::string FullCategoryName = ClassDecl->getNameAsString(); 5665 FullCategoryName += '_'; 5666 FullCategoryName += IDecl->getNameAsString(); 5667 5668 // Build _objc_method_list for class's instance methods if needed 5669 SmallVector<ObjCMethodDecl *, 32> InstanceMethods(IDecl->instance_methods()); 5670 5671 // If any of our property implementations have associated getters or 5672 // setters, produce metadata for them as well. 5673 for (const auto *Prop : IDecl->property_impls()) { 5674 if (Prop->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic) 5675 continue; 5676 if (!Prop->getPropertyIvarDecl()) 5677 continue; 5678 ObjCPropertyDecl *PD = Prop->getPropertyDecl(); 5679 if (!PD) 5680 continue; 5681 if (ObjCMethodDecl *Getter = PD->getGetterMethodDecl()) 5682 InstanceMethods.push_back(Getter); 5683 if (PD->isReadOnly()) 5684 continue; 5685 if (ObjCMethodDecl *Setter = PD->getSetterMethodDecl()) 5686 InstanceMethods.push_back(Setter); 5687 } 5688 RewriteObjCMethodsMetaData(InstanceMethods.begin(), InstanceMethods.end(), 5689 true, "CATEGORY_", FullCategoryName.c_str(), 5690 Result); 5691 5692 // Build _objc_method_list for class's class methods if needed 5693 RewriteObjCMethodsMetaData(IDecl->classmeth_begin(), IDecl->classmeth_end(), 5694 false, "CATEGORY_", FullCategoryName.c_str(), 5695 Result); 5696 5697 // Protocols referenced in class declaration? 5698 // Null CDecl is case of a category implementation with no category interface 5699 if (CDecl) 5700 RewriteObjCProtocolListMetaData(CDecl->getReferencedProtocols(), "CATEGORY", 5701 FullCategoryName, Result); 5702 /* struct _objc_category { 5703 char *category_name; 5704 char *class_name; 5705 struct _objc_method_list *instance_methods; 5706 struct _objc_method_list *class_methods; 5707 struct _objc_protocol_list *protocols; 5708 // Objective-C 1.0 extensions 5709 uint32_t size; // sizeof (struct _objc_category) 5710 struct _objc_property_list *instance_properties; // category's own 5711 // @property decl. 5712 }; 5713 */ 5714 5715 static bool objc_category = false; 5716 if (!objc_category) { 5717 Result += "\nstruct _objc_category {\n"; 5718 Result += "\tchar *category_name;\n"; 5719 Result += "\tchar *class_name;\n"; 5720 Result += "\tstruct _objc_method_list *instance_methods;\n"; 5721 Result += "\tstruct _objc_method_list *class_methods;\n"; 5722 Result += "\tstruct _objc_protocol_list *protocols;\n"; 5723 Result += "\tunsigned int size;\n"; 5724 Result += "\tstruct _objc_property_list *instance_properties;\n"; 5725 Result += "};\n"; 5726 objc_category = true; 5727 } 5728 Result += "\nstatic struct _objc_category _OBJC_CATEGORY_"; 5729 Result += FullCategoryName; 5730 Result += " __attribute__ ((used, section (\"__OBJC, __category\")))= {\n\t\""; 5731 Result += IDecl->getNameAsString(); 5732 Result += "\"\n\t, \""; 5733 Result += ClassDecl->getNameAsString(); 5734 Result += "\"\n"; 5735 5736 if (IDecl->instmeth_begin() != IDecl->instmeth_end()) { 5737 Result += "\t, (struct _objc_method_list *)" 5738 "&_OBJC_CATEGORY_INSTANCE_METHODS_"; 5739 Result += FullCategoryName; 5740 Result += "\n"; 5741 } 5742 else 5743 Result += "\t, 0\n"; 5744 if (IDecl->classmeth_begin() != IDecl->classmeth_end()) { 5745 Result += "\t, (struct _objc_method_list *)" 5746 "&_OBJC_CATEGORY_CLASS_METHODS_"; 5747 Result += FullCategoryName; 5748 Result += "\n"; 5749 } 5750 else 5751 Result += "\t, 0\n"; 5752 5753 if (CDecl && CDecl->protocol_begin() != CDecl->protocol_end()) { 5754 Result += "\t, (struct _objc_protocol_list *)&_OBJC_CATEGORY_PROTOCOLS_"; 5755 Result += FullCategoryName; 5756 Result += "\n"; 5757 } 5758 else 5759 Result += "\t, 0\n"; 5760 Result += "\t, sizeof(struct _objc_category), 0\n};\n"; 5761} 5762 5763// RewriteObjCMethodsMetaData - Rewrite methods metadata for instance or 5764/// class methods. 5765template<typename MethodIterator> 5766void RewriteObjCFragileABI::RewriteObjCMethodsMetaData(MethodIterator MethodBegin, 5767 MethodIterator MethodEnd, 5768 bool IsInstanceMethod, 5769 StringRef prefix, 5770 StringRef ClassName, 5771 std::string &Result) { 5772 if (MethodBegin == MethodEnd) return; 5773 5774 if (!objc_impl_method) { 5775 /* struct _objc_method { 5776 SEL _cmd; 5777 char *method_types; 5778 void *_imp; 5779 } 5780 */ 5781 Result += "\nstruct _objc_method {\n"; 5782 Result += "\tSEL _cmd;\n"; 5783 Result += "\tchar *method_types;\n"; 5784 Result += "\tvoid *_imp;\n"; 5785 Result += "};\n"; 5786 5787 objc_impl_method = true; 5788 } 5789 5790 // Build _objc_method_list for class's methods if needed 5791 5792 /* struct { 5793 struct _objc_method_list *next_method; 5794 int method_count; 5795 struct _objc_method method_list[]; 5796 } 5797 */ 5798 unsigned NumMethods = std::distance(MethodBegin, MethodEnd); 5799 Result += "\nstatic struct {\n"; 5800 Result += "\tstruct _objc_method_list *next_method;\n"; 5801 Result += "\tint method_count;\n"; 5802 Result += "\tstruct _objc_method method_list["; 5803 Result += utostr(NumMethods); 5804 Result += "];\n} _OBJC_"; 5805 Result += prefix; 5806 Result += IsInstanceMethod ? "INSTANCE" : "CLASS"; 5807 Result += "_METHODS_"; 5808 Result += ClassName; 5809 Result += " __attribute__ ((used, section (\"__OBJC, __"; 5810 Result += IsInstanceMethod ? "inst" : "cls"; 5811 Result += "_meth\")))= "; 5812 Result += "{\n\t0, " + utostr(NumMethods) + "\n"; 5813 5814 Result += "\t,{{(SEL)\""; 5815 Result += (*MethodBegin)->getSelector().getAsString().c_str(); 5816 std::string MethodTypeString; 5817 Context->getObjCEncodingForMethodDecl(*MethodBegin, MethodTypeString); 5818 Result += "\", \""; 5819 Result += MethodTypeString; 5820 Result += "\", (void *)"; 5821 Result += MethodInternalNames[*MethodBegin]; 5822 Result += "}\n"; 5823 for (++MethodBegin; MethodBegin != MethodEnd; ++MethodBegin) { 5824 Result += "\t ,{(SEL)\""; 5825 Result += (*MethodBegin)->getSelector().getAsString().c_str(); 5826 std::string MethodTypeString; 5827 Context->getObjCEncodingForMethodDecl(*MethodBegin, MethodTypeString); 5828 Result += "\", \""; 5829 Result += MethodTypeString; 5830 Result += "\", (void *)"; 5831 Result += MethodInternalNames[*MethodBegin]; 5832 Result += "}\n"; 5833 } 5834 Result += "\t }\n};\n"; 5835} 5836 5837Stmt *RewriteObjCFragileABI::RewriteObjCIvarRefExpr(ObjCIvarRefExpr *IV) { 5838 SourceRange OldRange = IV->getSourceRange(); 5839 Expr *BaseExpr = IV->getBase(); 5840 5841 // Rewrite the base, but without actually doing replaces. 5842 { 5843 DisableReplaceStmtScope S(*this); 5844 BaseExpr = cast<Expr>(RewriteFunctionBodyOrGlobalInitializer(BaseExpr)); 5845 IV->setBase(BaseExpr); 5846 } 5847 5848 ObjCIvarDecl *D = IV->getDecl(); 5849 5850 Expr *Replacement = IV; 5851 if (CurMethodDef) { 5852 if (BaseExpr->getType()->isObjCObjectPointerType()) { 5853 const ObjCInterfaceType *iFaceDecl = 5854 dyn_cast<ObjCInterfaceType>(BaseExpr->getType()->getPointeeType()); 5855 assert(iFaceDecl && "RewriteObjCIvarRefExpr - iFaceDecl is null"); 5856 // lookup which class implements the instance variable. 5857 ObjCInterfaceDecl *clsDeclared = nullptr; 5858 iFaceDecl->getDecl()->lookupInstanceVariable(D->getIdentifier(), 5859 clsDeclared); 5860 assert(clsDeclared && "RewriteObjCIvarRefExpr(): Can't find class"); 5861 5862 // Synthesize an explicit cast to gain access to the ivar. 5863 std::string RecName = clsDeclared->getIdentifier()->getName(); 5864 RecName += "_IMPL"; 5865 IdentifierInfo *II = &Context->Idents.get(RecName); 5866 RecordDecl *RD = RecordDecl::Create(*Context, TTK_Struct, TUDecl, 5867 SourceLocation(), SourceLocation(), 5868 II); 5869 assert(RD && "RewriteObjCIvarRefExpr(): Can't find RecordDecl"); 5870 QualType castT = Context->getPointerType(Context->getTagDeclType(RD)); 5871 CastExpr *castExpr = NoTypeInfoCStyleCastExpr(Context, castT, 5872 CK_BitCast, 5873 IV->getBase()); 5874 // Don't forget the parens to enforce the proper binding. 5875 ParenExpr *PE = new (Context) ParenExpr(OldRange.getBegin(), 5876 OldRange.getEnd(), 5877 castExpr); 5878 if (IV->isFreeIvar() && 5879 declaresSameEntity(CurMethodDef->getClassInterface(), iFaceDecl->getDecl())) { 5880 MemberExpr *ME = new (Context) 5881 MemberExpr(PE, true, SourceLocation(), D, IV->getLocation(), 5882 D->getType(), VK_LValue, OK_Ordinary); 5883 Replacement = ME; 5884 } else { 5885 IV->setBase(PE); 5886 } 5887 } 5888 } else { // we are outside a method. 5889 assert(!IV->isFreeIvar() && "Cannot have a free standing ivar outside a method"); 5890 5891 // Explicit ivar refs need to have a cast inserted. 5892 // FIXME: consider sharing some of this code with the code above. 5893 if (BaseExpr->getType()->isObjCObjectPointerType()) { 5894 const ObjCInterfaceType *iFaceDecl = 5895 dyn_cast<ObjCInterfaceType>(BaseExpr->getType()->getPointeeType()); 5896 // lookup which class implements the instance variable. 5897 ObjCInterfaceDecl *clsDeclared = nullptr; 5898 iFaceDecl->getDecl()->lookupInstanceVariable(D->getIdentifier(), 5899 clsDeclared); 5900 assert(clsDeclared && "RewriteObjCIvarRefExpr(): Can't find class"); 5901 5902 // Synthesize an explicit cast to gain access to the ivar. 5903 std::string RecName = clsDeclared->getIdentifier()->getName(); 5904 RecName += "_IMPL"; 5905 IdentifierInfo *II = &Context->Idents.get(RecName); 5906 RecordDecl *RD = RecordDecl::Create(*Context, TTK_Struct, TUDecl, 5907 SourceLocation(), SourceLocation(), 5908 II); 5909 assert(RD && "RewriteObjCIvarRefExpr(): Can't find RecordDecl"); 5910 QualType castT = Context->getPointerType(Context->getTagDeclType(RD)); 5911 CastExpr *castExpr = NoTypeInfoCStyleCastExpr(Context, castT, 5912 CK_BitCast, 5913 IV->getBase()); 5914 // Don't forget the parens to enforce the proper binding. 5915 ParenExpr *PE = new (Context) ParenExpr(IV->getBase()->getLocStart(), 5916 IV->getBase()->getLocEnd(), castExpr); 5917 // Cannot delete IV->getBase(), since PE points to it. 5918 // Replace the old base with the cast. This is important when doing 5919 // embedded rewrites. For example, [newInv->_container addObject:0]. 5920 IV->setBase(PE); 5921 } 5922 } 5923 5924 ReplaceStmtWithRange(IV, Replacement, OldRange); 5925 return Replacement; 5926} 5927 5928#endif 5929