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