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