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