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