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