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