RewriteObjC.cpp revision 1d015313b27f6002b1c4a74e478ede1622141b4e
1//===--- RewriteObjC.cpp - Playground for the code rewriter ---------------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// Hacks and fun related to the code rewriter. 11// 12//===----------------------------------------------------------------------===// 13 14#include "clang/Rewrite/ASTConsumers.h" 15#include "clang/Rewrite/Rewriter.h" 16#include "clang/AST/AST.h" 17#include "clang/AST/ASTConsumer.h" 18#include "clang/AST/ParentMap.h" 19#include "clang/Basic/SourceManager.h" 20#include "clang/Basic/IdentifierTable.h" 21#include "clang/Basic/Diagnostic.h" 22#include "clang/Lex/Lexer.h" 23#include "llvm/Support/MemoryBuffer.h" 24#include "llvm/Support/raw_ostream.h" 25#include "llvm/ADT/StringExtras.h" 26#include "llvm/ADT/SmallPtrSet.h" 27#include "llvm/ADT/OwningPtr.h" 28#include "llvm/ADT/DenseSet.h" 29 30using namespace clang; 31using llvm::utostr; 32 33namespace { 34 class RewriteObjC : public ASTConsumer { 35 enum { 36 BLOCK_FIELD_IS_OBJECT = 3, /* id, NSObject, __attribute__((NSObject)), 37 block, ... */ 38 BLOCK_FIELD_IS_BLOCK = 7, /* a block variable */ 39 BLOCK_FIELD_IS_BYREF = 8, /* the on stack structure holding the 40 __block variable */ 41 BLOCK_FIELD_IS_WEAK = 16, /* declared __weak, only used in byref copy 42 helpers */ 43 BLOCK_BYREF_CALLER = 128, /* called from __block (byref) copy/dispose 44 support routines */ 45 BLOCK_BYREF_CURRENT_MAX = 256 46 }; 47 48 enum { 49 BLOCK_NEEDS_FREE = (1 << 24), 50 BLOCK_HAS_COPY_DISPOSE = (1 << 25), 51 BLOCK_HAS_CXX_OBJ = (1 << 26), 52 BLOCK_IS_GC = (1 << 27), 53 BLOCK_IS_GLOBAL = (1 << 28), 54 BLOCK_HAS_DESCRIPTOR = (1 << 29) 55 }; 56 57 Rewriter Rewrite; 58 Diagnostic &Diags; 59 const LangOptions &LangOpts; 60 unsigned RewriteFailedDiag; 61 unsigned TryFinallyContainsReturnDiag; 62 63 ASTContext *Context; 64 SourceManager *SM; 65 TranslationUnitDecl *TUDecl; 66 FileID MainFileID; 67 const char *MainFileStart, *MainFileEnd; 68 SourceLocation LastIncLoc; 69 70 llvm::SmallVector<ObjCImplementationDecl *, 8> ClassImplementation; 71 llvm::SmallVector<ObjCCategoryImplDecl *, 8> CategoryImplementation; 72 llvm::SmallPtrSet<ObjCInterfaceDecl*, 8> ObjCSynthesizedStructs; 73 llvm::SmallPtrSet<ObjCProtocolDecl*, 8> ObjCSynthesizedProtocols; 74 llvm::SmallPtrSet<ObjCInterfaceDecl*, 8> ObjCForwardDecls; 75 llvm::DenseMap<ObjCMethodDecl*, std::string> MethodInternalNames; 76 llvm::SmallVector<Stmt *, 32> Stmts; 77 llvm::SmallVector<int, 8> ObjCBcLabelNo; 78 // Remember all the @protocol(<expr>) expressions. 79 llvm::SmallPtrSet<ObjCProtocolDecl *, 32> ProtocolExprDecls; 80 81 llvm::DenseSet<uint64_t> CopyDestroyCache; 82 83 unsigned NumObjCStringLiterals; 84 85 FunctionDecl *MsgSendFunctionDecl; 86 FunctionDecl *MsgSendSuperFunctionDecl; 87 FunctionDecl *MsgSendStretFunctionDecl; 88 FunctionDecl *MsgSendSuperStretFunctionDecl; 89 FunctionDecl *MsgSendFpretFunctionDecl; 90 FunctionDecl *GetClassFunctionDecl; 91 FunctionDecl *GetMetaClassFunctionDecl; 92 FunctionDecl *GetSuperClassFunctionDecl; 93 FunctionDecl *SelGetUidFunctionDecl; 94 FunctionDecl *CFStringFunctionDecl; 95 FunctionDecl *SuperContructorFunctionDecl; 96 97 // ObjC string constant support. 98 VarDecl *ConstantStringClassReference; 99 RecordDecl *NSStringRecord; 100 101 // ObjC foreach break/continue generation support. 102 int BcLabelCount; 103 104 // Needed for super. 105 ObjCMethodDecl *CurMethodDef; 106 RecordDecl *SuperStructDecl; 107 RecordDecl *ConstantStringDecl; 108 109 TypeDecl *ProtocolTypeDecl; 110 QualType getProtocolType(); 111 112 // Needed for header files being rewritten 113 bool IsHeader; 114 115 std::string InFileName; 116 llvm::raw_ostream* OutFile; 117 118 bool SilenceRewriteMacroWarning; 119 bool objc_impl_method; 120 121 std::string Preamble; 122 123 // Block expressions. 124 llvm::SmallVector<BlockExpr *, 32> Blocks; 125 llvm::SmallVector<int, 32> InnerDeclRefsCount; 126 llvm::SmallVector<BlockDeclRefExpr *, 32> InnerDeclRefs; 127 128 llvm::SmallVector<BlockDeclRefExpr *, 32> BlockDeclRefs; 129 130 // Block related declarations. 131 llvm::SmallVector<ValueDecl *, 8> BlockByCopyDecls; 132 llvm::SmallPtrSet<ValueDecl *, 8> BlockByCopyDeclsPtrSet; 133 llvm::SmallVector<ValueDecl *, 8> BlockByRefDecls; 134 llvm::SmallPtrSet<ValueDecl *, 8> BlockByRefDeclsPtrSet; 135 llvm::DenseMap<ValueDecl *, unsigned> BlockByRefDeclNo; 136 llvm::SmallPtrSet<ValueDecl *, 8> ImportedBlockDecls; 137 llvm::SmallPtrSet<VarDecl *, 8> ImportedLocalExternalDecls; 138 139 llvm::DenseMap<BlockExpr *, std::string> RewrittenBlockExprs; 140 141 // This maps a property to it's assignment statement. 142 llvm::DenseMap<Expr *, BinaryOperator *> PropSetters; 143 // This maps a property to it's synthesied message expression. 144 // This allows us to rewrite chained getters (e.g. o.a.b.c). 145 llvm::DenseMap<Expr *, Stmt *> PropGetters; 146 147 // This maps an original source AST to it's rewritten form. This allows 148 // us to avoid rewriting the same node twice (which is very uncommon). 149 // This is needed to support some of the exotic property rewriting. 150 llvm::DenseMap<Stmt *, Stmt *> ReplacedNodes; 151 152 FunctionDecl *CurFunctionDef; 153 FunctionDecl *CurFunctionDeclToDeclareForBlock; 154 VarDecl *GlobalVarDecl; 155 156 bool DisableReplaceStmt; 157 158 static const int OBJC_ABI_VERSION = 7; 159 public: 160 virtual void Initialize(ASTContext &context); 161 162 // Top Level Driver code. 163 virtual void HandleTopLevelDecl(DeclGroupRef D) { 164 for (DeclGroupRef::iterator I = D.begin(), E = D.end(); I != E; ++I) 165 HandleTopLevelSingleDecl(*I); 166 } 167 void HandleTopLevelSingleDecl(Decl *D); 168 void HandleDeclInMainFile(Decl *D); 169 RewriteObjC(std::string inFile, llvm::raw_ostream *OS, 170 Diagnostic &D, const LangOptions &LOpts, 171 bool silenceMacroWarn); 172 173 ~RewriteObjC() {} 174 175 virtual void HandleTranslationUnit(ASTContext &C); 176 177 void ReplaceStmt(Stmt *Old, Stmt *New) { 178 Stmt *ReplacingStmt = ReplacedNodes[Old]; 179 180 if (ReplacingStmt) 181 return; // We can't rewrite the same node twice. 182 183 if (DisableReplaceStmt) 184 return; // Used when rewriting the assignment of a property setter. 185 186 // If replacement succeeded or warning disabled return with no warning. 187 if (!Rewrite.ReplaceStmt(Old, New)) { 188 ReplacedNodes[Old] = New; 189 return; 190 } 191 if (SilenceRewriteMacroWarning) 192 return; 193 Diags.Report(Context->getFullLoc(Old->getLocStart()), RewriteFailedDiag) 194 << Old->getSourceRange(); 195 } 196 197 void ReplaceStmtWithRange(Stmt *Old, Stmt *New, SourceRange SrcRange) { 198 // Measure the old text. 199 int Size = Rewrite.getRangeSize(SrcRange); 200 if (Size == -1) { 201 Diags.Report(Context->getFullLoc(Old->getLocStart()), RewriteFailedDiag) 202 << Old->getSourceRange(); 203 return; 204 } 205 // Get the new text. 206 std::string SStr; 207 llvm::raw_string_ostream S(SStr); 208 New->printPretty(S, *Context, 0, PrintingPolicy(LangOpts)); 209 const std::string &Str = S.str(); 210 211 // If replacement succeeded or warning disabled return with no warning. 212 if (!Rewrite.ReplaceText(SrcRange.getBegin(), Size, Str)) { 213 ReplacedNodes[Old] = New; 214 return; 215 } 216 if (SilenceRewriteMacroWarning) 217 return; 218 Diags.Report(Context->getFullLoc(Old->getLocStart()), RewriteFailedDiag) 219 << Old->getSourceRange(); 220 } 221 222 void InsertText(SourceLocation Loc, llvm::StringRef Str, 223 bool InsertAfter = true) { 224 // If insertion succeeded or warning disabled return with no warning. 225 if (!Rewrite.InsertText(Loc, Str, InsertAfter) || 226 SilenceRewriteMacroWarning) 227 return; 228 229 Diags.Report(Context->getFullLoc(Loc), RewriteFailedDiag); 230 } 231 232 void ReplaceText(SourceLocation Start, unsigned OrigLength, 233 llvm::StringRef Str) { 234 // If removal succeeded or warning disabled return with no warning. 235 if (!Rewrite.ReplaceText(Start, OrigLength, Str) || 236 SilenceRewriteMacroWarning) 237 return; 238 239 Diags.Report(Context->getFullLoc(Start), RewriteFailedDiag); 240 } 241 242 // Syntactic Rewriting. 243 void RewriteInclude(); 244 void RewriteForwardClassDecl(ObjCClassDecl *Dcl); 245 void RewritePropertyImplDecl(ObjCPropertyImplDecl *PID, 246 ObjCImplementationDecl *IMD, 247 ObjCCategoryImplDecl *CID); 248 void RewriteInterfaceDecl(ObjCInterfaceDecl *Dcl); 249 void RewriteImplementationDecl(Decl *Dcl); 250 void RewriteObjCMethodDecl(const ObjCInterfaceDecl *IDecl, 251 ObjCMethodDecl *MDecl, std::string &ResultStr); 252 void RewriteTypeIntoString(QualType T, std::string &ResultStr, 253 const FunctionType *&FPRetType); 254 void RewriteByRefString(std::string &ResultStr, const std::string &Name, 255 ValueDecl *VD, 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 llvm::StringRef prefix, 336 llvm::StringRef ClassName, 337 std::string &Result); 338 339 void RewriteObjCProtocolMetaData(ObjCProtocolDecl *Protocol, 340 llvm::StringRef prefix, 341 llvm::StringRef ClassName, 342 std::string &Result); 343 void RewriteObjCProtocolListMetaData(const ObjCList<ObjCProtocolDecl> &Prots, 344 llvm::StringRef prefix, 345 llvm::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 llvm::StringRef funcName, std::string Tag); 371 std::string SynthesizeBlockFunc(BlockExpr *CE, int i, 372 llvm::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, llvm::StringRef funcName, 378 unsigned hasCopy); 379 Stmt *SynthesizeBlockCall(CallExpr *Exp, const Expr* BlockExp); 380 void SynthesizeBlockLiterals(SourceLocation FunLocStart, 381 llvm::StringRef FunName); 382 void RewriteRecordBody(RecordDecl *RD); 383 384 void CollectBlockDeclRefInfo(BlockExpr *Exp); 385 void GetBlockDeclRefExprs(Stmt *S); 386 void GetInnerBlockDeclRefExprs(Stmt *S, 387 llvm::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(llvm::StringRef name); 443 Stmt *SynthBlockInitExpr(BlockExpr *Exp, 444 const llvm::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, llvm::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 llvm::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->getInstantiationLoc(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 llvm::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->getInstantiationLineNumber(LocEnd) > 937 SM->getInstantiationLineNumber(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 llvm::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 llvm::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.c_str(), 2114 StrEncoding.length(), false,StrType, 2115 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 llvm::SmallVector<Expr*, 8> SelExprs; 2129 QualType argType = Context->getPointerType(Context->CharTy); 2130 SelExprs.push_back(StringLiteral::Create(*Context, 2131 Exp->getSelector().getAsString().c_str(), 2132 Exp->getSelector().getAsString().size(), 2133 false, 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->getInstantiationLoc(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->getInstantiationLoc(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 llvm::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 llvm::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 llvm::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 llvm::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 llvm::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 llvm::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 llvm::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 llvm::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 llvm::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 llvm::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 } 2698 2699 SuperStructDecl->completeDefinition(); 2700 } 2701 return Context->getTagDeclType(SuperStructDecl); 2702} 2703 2704QualType RewriteObjC::getConstantStringStructType() { 2705 if (!ConstantStringDecl) { 2706 ConstantStringDecl = RecordDecl::Create(*Context, TTK_Struct, TUDecl, 2707 SourceLocation(), SourceLocation(), 2708 &Context->Idents.get("__NSConstantStringImpl")); 2709 QualType FieldTypes[4]; 2710 2711 // struct objc_object *receiver; 2712 FieldTypes[0] = Context->getObjCIdType(); 2713 // int flags; 2714 FieldTypes[1] = Context->IntTy; 2715 // char *str; 2716 FieldTypes[2] = Context->getPointerType(Context->CharTy); 2717 // long length; 2718 FieldTypes[3] = Context->LongTy; 2719 2720 // Create fields 2721 for (unsigned i = 0; i < 4; ++i) { 2722 ConstantStringDecl->addDecl(FieldDecl::Create(*Context, 2723 ConstantStringDecl, 2724 SourceLocation(), 2725 SourceLocation(), 0, 2726 FieldTypes[i], 0, 2727 /*BitWidth=*/0, 2728 /*Mutable=*/true)); 2729 } 2730 2731 ConstantStringDecl->completeDefinition(); 2732 } 2733 return Context->getTagDeclType(ConstantStringDecl); 2734} 2735 2736Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp, 2737 SourceLocation StartLoc, 2738 SourceLocation EndLoc) { 2739 if (!SelGetUidFunctionDecl) 2740 SynthSelGetUidFunctionDecl(); 2741 if (!MsgSendFunctionDecl) 2742 SynthMsgSendFunctionDecl(); 2743 if (!MsgSendSuperFunctionDecl) 2744 SynthMsgSendSuperFunctionDecl(); 2745 if (!MsgSendStretFunctionDecl) 2746 SynthMsgSendStretFunctionDecl(); 2747 if (!MsgSendSuperStretFunctionDecl) 2748 SynthMsgSendSuperStretFunctionDecl(); 2749 if (!MsgSendFpretFunctionDecl) 2750 SynthMsgSendFpretFunctionDecl(); 2751 if (!GetClassFunctionDecl) 2752 SynthGetClassFunctionDecl(); 2753 if (!GetSuperClassFunctionDecl) 2754 SynthGetSuperClassFunctionDecl(); 2755 if (!GetMetaClassFunctionDecl) 2756 SynthGetMetaClassFunctionDecl(); 2757 2758 // default to objc_msgSend(). 2759 FunctionDecl *MsgSendFlavor = MsgSendFunctionDecl; 2760 // May need to use objc_msgSend_stret() as well. 2761 FunctionDecl *MsgSendStretFlavor = 0; 2762 if (ObjCMethodDecl *mDecl = Exp->getMethodDecl()) { 2763 QualType resultType = mDecl->getResultType(); 2764 if (resultType->isRecordType()) 2765 MsgSendStretFlavor = MsgSendStretFunctionDecl; 2766 else if (resultType->isRealFloatingType()) 2767 MsgSendFlavor = MsgSendFpretFunctionDecl; 2768 } 2769 2770 // Synthesize a call to objc_msgSend(). 2771 llvm::SmallVector<Expr*, 8> MsgExprs; 2772 switch (Exp->getReceiverKind()) { 2773 case ObjCMessageExpr::SuperClass: { 2774 MsgSendFlavor = MsgSendSuperFunctionDecl; 2775 if (MsgSendStretFlavor) 2776 MsgSendStretFlavor = MsgSendSuperStretFunctionDecl; 2777 assert(MsgSendFlavor && "MsgSendFlavor is NULL!"); 2778 2779 ObjCInterfaceDecl *ClassDecl = CurMethodDef->getClassInterface(); 2780 2781 llvm::SmallVector<Expr*, 4> InitExprs; 2782 2783 // set the receiver to self, the first argument to all methods. 2784 InitExprs.push_back( 2785 NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(), 2786 CK_BitCast, 2787 new (Context) DeclRefExpr(CurMethodDef->getSelfDecl(), 2788 Context->getObjCIdType(), 2789 VK_RValue, 2790 SourceLocation())) 2791 ); // set the 'receiver'. 2792 2793 // (id)class_getSuperclass((Class)objc_getClass("CurrentClass")) 2794 llvm::SmallVector<Expr*, 8> ClsExprs; 2795 QualType argType = Context->getPointerType(Context->CharTy); 2796 ClsExprs.push_back(StringLiteral::Create(*Context, 2797 ClassDecl->getIdentifier()->getNameStart(), 2798 ClassDecl->getIdentifier()->getLength(), 2799 false, argType, SourceLocation())); 2800 CallExpr *Cls = SynthesizeCallToFunctionDecl(GetMetaClassFunctionDecl, 2801 &ClsExprs[0], 2802 ClsExprs.size(), 2803 StartLoc, 2804 EndLoc); 2805 // (Class)objc_getClass("CurrentClass") 2806 CastExpr *ArgExpr = NoTypeInfoCStyleCastExpr(Context, 2807 Context->getObjCClassType(), 2808 CK_BitCast, Cls); 2809 ClsExprs.clear(); 2810 ClsExprs.push_back(ArgExpr); 2811 Cls = SynthesizeCallToFunctionDecl(GetSuperClassFunctionDecl, 2812 &ClsExprs[0], ClsExprs.size(), 2813 StartLoc, EndLoc); 2814 2815 // (id)class_getSuperclass((Class)objc_getClass("CurrentClass")) 2816 // To turn off a warning, type-cast to 'id' 2817 InitExprs.push_back( // set 'super class', using class_getSuperclass(). 2818 NoTypeInfoCStyleCastExpr(Context, 2819 Context->getObjCIdType(), 2820 CK_BitCast, Cls)); 2821 // struct objc_super 2822 QualType superType = getSuperStructType(); 2823 Expr *SuperRep; 2824 2825 if (LangOpts.Microsoft) { 2826 SynthSuperContructorFunctionDecl(); 2827 // Simulate a contructor call... 2828 DeclRefExpr *DRE = new (Context) DeclRefExpr(SuperContructorFunctionDecl, 2829 superType, VK_LValue, 2830 SourceLocation()); 2831 SuperRep = new (Context) CallExpr(*Context, DRE, &InitExprs[0], 2832 InitExprs.size(), 2833 superType, VK_LValue, 2834 SourceLocation()); 2835 // The code for super is a little tricky to prevent collision with 2836 // the structure definition in the header. The rewriter has it's own 2837 // internal definition (__rw_objc_super) that is uses. This is why 2838 // we need the cast below. For example: 2839 // (struct objc_super *)&__rw_objc_super((id)self, (id)objc_getClass("SUPER")) 2840 // 2841 SuperRep = new (Context) UnaryOperator(SuperRep, UO_AddrOf, 2842 Context->getPointerType(SuperRep->getType()), 2843 VK_RValue, OK_Ordinary, 2844 SourceLocation()); 2845 SuperRep = NoTypeInfoCStyleCastExpr(Context, 2846 Context->getPointerType(superType), 2847 CK_BitCast, SuperRep); 2848 } else { 2849 // (struct objc_super) { <exprs from above> } 2850 InitListExpr *ILE = 2851 new (Context) InitListExpr(*Context, SourceLocation(), 2852 &InitExprs[0], InitExprs.size(), 2853 SourceLocation()); 2854 TypeSourceInfo *superTInfo 2855 = Context->getTrivialTypeSourceInfo(superType); 2856 SuperRep = new (Context) CompoundLiteralExpr(SourceLocation(), superTInfo, 2857 superType, VK_LValue, 2858 ILE, false); 2859 // struct objc_super * 2860 SuperRep = new (Context) UnaryOperator(SuperRep, UO_AddrOf, 2861 Context->getPointerType(SuperRep->getType()), 2862 VK_RValue, OK_Ordinary, 2863 SourceLocation()); 2864 } 2865 MsgExprs.push_back(SuperRep); 2866 break; 2867 } 2868 2869 case ObjCMessageExpr::Class: { 2870 llvm::SmallVector<Expr*, 8> ClsExprs; 2871 QualType argType = Context->getPointerType(Context->CharTy); 2872 ObjCInterfaceDecl *Class 2873 = Exp->getClassReceiver()->getAs<ObjCObjectType>()->getInterface(); 2874 IdentifierInfo *clsName = Class->getIdentifier(); 2875 ClsExprs.push_back(StringLiteral::Create(*Context, 2876 clsName->getNameStart(), 2877 clsName->getLength(), 2878 false, argType, 2879 SourceLocation())); 2880 CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl, 2881 &ClsExprs[0], 2882 ClsExprs.size(), 2883 StartLoc, EndLoc); 2884 MsgExprs.push_back(Cls); 2885 break; 2886 } 2887 2888 case ObjCMessageExpr::SuperInstance:{ 2889 MsgSendFlavor = MsgSendSuperFunctionDecl; 2890 if (MsgSendStretFlavor) 2891 MsgSendStretFlavor = MsgSendSuperStretFunctionDecl; 2892 assert(MsgSendFlavor && "MsgSendFlavor is NULL!"); 2893 ObjCInterfaceDecl *ClassDecl = CurMethodDef->getClassInterface(); 2894 llvm::SmallVector<Expr*, 4> InitExprs; 2895 2896 InitExprs.push_back( 2897 NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(), 2898 CK_BitCast, 2899 new (Context) DeclRefExpr(CurMethodDef->getSelfDecl(), 2900 Context->getObjCIdType(), 2901 VK_RValue, SourceLocation())) 2902 ); // set the 'receiver'. 2903 2904 // (id)class_getSuperclass((Class)objc_getClass("CurrentClass")) 2905 llvm::SmallVector<Expr*, 8> ClsExprs; 2906 QualType argType = Context->getPointerType(Context->CharTy); 2907 ClsExprs.push_back(StringLiteral::Create(*Context, 2908 ClassDecl->getIdentifier()->getNameStart(), 2909 ClassDecl->getIdentifier()->getLength(), 2910 false, argType, SourceLocation())); 2911 CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl, 2912 &ClsExprs[0], 2913 ClsExprs.size(), 2914 StartLoc, EndLoc); 2915 // (Class)objc_getClass("CurrentClass") 2916 CastExpr *ArgExpr = NoTypeInfoCStyleCastExpr(Context, 2917 Context->getObjCClassType(), 2918 CK_BitCast, Cls); 2919 ClsExprs.clear(); 2920 ClsExprs.push_back(ArgExpr); 2921 Cls = SynthesizeCallToFunctionDecl(GetSuperClassFunctionDecl, 2922 &ClsExprs[0], ClsExprs.size(), 2923 StartLoc, EndLoc); 2924 2925 // (id)class_getSuperclass((Class)objc_getClass("CurrentClass")) 2926 // To turn off a warning, type-cast to 'id' 2927 InitExprs.push_back( 2928 // set 'super class', using class_getSuperclass(). 2929 NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(), 2930 CK_BitCast, Cls)); 2931 // struct objc_super 2932 QualType superType = getSuperStructType(); 2933 Expr *SuperRep; 2934 2935 if (LangOpts.Microsoft) { 2936 SynthSuperContructorFunctionDecl(); 2937 // Simulate a contructor call... 2938 DeclRefExpr *DRE = new (Context) DeclRefExpr(SuperContructorFunctionDecl, 2939 superType, VK_LValue, 2940 SourceLocation()); 2941 SuperRep = new (Context) CallExpr(*Context, DRE, &InitExprs[0], 2942 InitExprs.size(), 2943 superType, VK_LValue, SourceLocation()); 2944 // The code for super is a little tricky to prevent collision with 2945 // the structure definition in the header. The rewriter has it's own 2946 // internal definition (__rw_objc_super) that is uses. This is why 2947 // we need the cast below. For example: 2948 // (struct objc_super *)&__rw_objc_super((id)self, (id)objc_getClass("SUPER")) 2949 // 2950 SuperRep = new (Context) UnaryOperator(SuperRep, UO_AddrOf, 2951 Context->getPointerType(SuperRep->getType()), 2952 VK_RValue, OK_Ordinary, 2953 SourceLocation()); 2954 SuperRep = NoTypeInfoCStyleCastExpr(Context, 2955 Context->getPointerType(superType), 2956 CK_BitCast, SuperRep); 2957 } else { 2958 // (struct objc_super) { <exprs from above> } 2959 InitListExpr *ILE = 2960 new (Context) InitListExpr(*Context, SourceLocation(), 2961 &InitExprs[0], InitExprs.size(), 2962 SourceLocation()); 2963 TypeSourceInfo *superTInfo 2964 = Context->getTrivialTypeSourceInfo(superType); 2965 SuperRep = new (Context) CompoundLiteralExpr(SourceLocation(), superTInfo, 2966 superType, VK_RValue, ILE, 2967 false); 2968 } 2969 MsgExprs.push_back(SuperRep); 2970 break; 2971 } 2972 2973 case ObjCMessageExpr::Instance: { 2974 // Remove all type-casts because it may contain objc-style types; e.g. 2975 // Foo<Proto> *. 2976 Expr *recExpr = Exp->getInstanceReceiver(); 2977 while (CStyleCastExpr *CE = dyn_cast<CStyleCastExpr>(recExpr)) 2978 recExpr = CE->getSubExpr(); 2979 recExpr = NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(), 2980 CK_BitCast, recExpr); 2981 MsgExprs.push_back(recExpr); 2982 break; 2983 } 2984 } 2985 2986 // Create a call to sel_registerName("selName"), it will be the 2nd argument. 2987 llvm::SmallVector<Expr*, 8> SelExprs; 2988 QualType argType = Context->getPointerType(Context->CharTy); 2989 SelExprs.push_back(StringLiteral::Create(*Context, 2990 Exp->getSelector().getAsString().c_str(), 2991 Exp->getSelector().getAsString().size(), 2992 false, argType, SourceLocation())); 2993 CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl, 2994 &SelExprs[0], SelExprs.size(), 2995 StartLoc, 2996 EndLoc); 2997 MsgExprs.push_back(SelExp); 2998 2999 // Now push any user supplied arguments. 3000 for (unsigned i = 0; i < Exp->getNumArgs(); i++) { 3001 Expr *userExpr = Exp->getArg(i); 3002 // Make all implicit casts explicit...ICE comes in handy:-) 3003 if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(userExpr)) { 3004 // Reuse the ICE type, it is exactly what the doctor ordered. 3005 QualType type = ICE->getType(); 3006 if (needToScanForQualifiers(type)) 3007 type = Context->getObjCIdType(); 3008 // Make sure we convert "type (^)(...)" to "type (*)(...)". 3009 (void)convertBlockPointerToFunctionPointer(type); 3010 userExpr = NoTypeInfoCStyleCastExpr(Context, type, CK_BitCast, 3011 userExpr); 3012 } 3013 // Make id<P...> cast into an 'id' cast. 3014 else if (CStyleCastExpr *CE = dyn_cast<CStyleCastExpr>(userExpr)) { 3015 if (CE->getType()->isObjCQualifiedIdType()) { 3016 while ((CE = dyn_cast<CStyleCastExpr>(userExpr))) 3017 userExpr = CE->getSubExpr(); 3018 userExpr = NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(), 3019 CK_BitCast, userExpr); 3020 } 3021 } 3022 MsgExprs.push_back(userExpr); 3023 // We've transferred the ownership to MsgExprs. For now, we *don't* null 3024 // out the argument in the original expression (since we aren't deleting 3025 // the ObjCMessageExpr). See RewritePropertyOrImplicitSetter() usage for more info. 3026 //Exp->setArg(i, 0); 3027 } 3028 // Generate the funky cast. 3029 CastExpr *cast; 3030 llvm::SmallVector<QualType, 8> ArgTypes; 3031 QualType returnType; 3032 3033 // Push 'id' and 'SEL', the 2 implicit arguments. 3034 if (MsgSendFlavor == MsgSendSuperFunctionDecl) 3035 ArgTypes.push_back(Context->getPointerType(getSuperStructType())); 3036 else 3037 ArgTypes.push_back(Context->getObjCIdType()); 3038 ArgTypes.push_back(Context->getObjCSelType()); 3039 if (ObjCMethodDecl *OMD = Exp->getMethodDecl()) { 3040 // Push any user argument types. 3041 for (ObjCMethodDecl::param_iterator PI = OMD->param_begin(), 3042 E = OMD->param_end(); PI != E; ++PI) { 3043 QualType t = (*PI)->getType()->isObjCQualifiedIdType() 3044 ? Context->getObjCIdType() 3045 : (*PI)->getType(); 3046 // Make sure we convert "t (^)(...)" to "t (*)(...)". 3047 (void)convertBlockPointerToFunctionPointer(t); 3048 ArgTypes.push_back(t); 3049 } 3050 returnType = OMD->getResultType()->isObjCQualifiedIdType() 3051 ? Context->getObjCIdType() : OMD->getResultType(); 3052 (void)convertBlockPointerToFunctionPointer(returnType); 3053 } else { 3054 returnType = Context->getObjCIdType(); 3055 } 3056 // Get the type, we will need to reference it in a couple spots. 3057 QualType msgSendType = MsgSendFlavor->getType(); 3058 3059 // Create a reference to the objc_msgSend() declaration. 3060 DeclRefExpr *DRE = new (Context) DeclRefExpr(MsgSendFlavor, msgSendType, 3061 VK_LValue, SourceLocation()); 3062 3063 // Need to cast objc_msgSend to "void *" (to workaround a GCC bandaid). 3064 // If we don't do this cast, we get the following bizarre warning/note: 3065 // xx.m:13: warning: function called through a non-compatible type 3066 // xx.m:13: note: if this code is reached, the program will abort 3067 cast = NoTypeInfoCStyleCastExpr(Context, 3068 Context->getPointerType(Context->VoidTy), 3069 CK_BitCast, DRE); 3070 3071 // Now do the "normal" pointer to function cast. 3072 QualType castType = 3073 getSimpleFunctionType(returnType, &ArgTypes[0], ArgTypes.size(), 3074 // If we don't have a method decl, force a variadic cast. 3075 Exp->getMethodDecl() ? Exp->getMethodDecl()->isVariadic() : true); 3076 castType = Context->getPointerType(castType); 3077 cast = NoTypeInfoCStyleCastExpr(Context, castType, CK_BitCast, 3078 cast); 3079 3080 // Don't forget the parens to enforce the proper binding. 3081 ParenExpr *PE = new (Context) ParenExpr(StartLoc, EndLoc, cast); 3082 3083 const FunctionType *FT = msgSendType->getAs<FunctionType>(); 3084 CallExpr *CE = new (Context) CallExpr(*Context, PE, &MsgExprs[0], 3085 MsgExprs.size(), 3086 FT->getResultType(), VK_RValue, 3087 EndLoc); 3088 Stmt *ReplacingStmt = CE; 3089 if (MsgSendStretFlavor) { 3090 // We have the method which returns a struct/union. Must also generate 3091 // call to objc_msgSend_stret and hang both varieties on a conditional 3092 // expression which dictate which one to envoke depending on size of 3093 // method's return type. 3094 3095 // Create a reference to the objc_msgSend_stret() declaration. 3096 DeclRefExpr *STDRE = new (Context) DeclRefExpr(MsgSendStretFlavor, msgSendType, 3097 VK_LValue, SourceLocation()); 3098 // Need to cast objc_msgSend_stret to "void *" (see above comment). 3099 cast = NoTypeInfoCStyleCastExpr(Context, 3100 Context->getPointerType(Context->VoidTy), 3101 CK_BitCast, STDRE); 3102 // Now do the "normal" pointer to function cast. 3103 castType = getSimpleFunctionType(returnType, &ArgTypes[0], ArgTypes.size(), 3104 Exp->getMethodDecl() ? Exp->getMethodDecl()->isVariadic() : false); 3105 castType = Context->getPointerType(castType); 3106 cast = NoTypeInfoCStyleCastExpr(Context, castType, CK_BitCast, 3107 cast); 3108 3109 // Don't forget the parens to enforce the proper binding. 3110 PE = new (Context) ParenExpr(SourceLocation(), SourceLocation(), cast); 3111 3112 FT = msgSendType->getAs<FunctionType>(); 3113 CallExpr *STCE = new (Context) CallExpr(*Context, PE, &MsgExprs[0], 3114 MsgExprs.size(), 3115 FT->getResultType(), VK_RValue, 3116 SourceLocation()); 3117 3118 // Build sizeof(returnType) 3119 UnaryExprOrTypeTraitExpr *sizeofExpr = 3120 new (Context) UnaryExprOrTypeTraitExpr(UETT_SizeOf, 3121 Context->getTrivialTypeSourceInfo(returnType), 3122 Context->getSizeType(), SourceLocation(), 3123 SourceLocation()); 3124 // (sizeof(returnType) <= 8 ? objc_msgSend(...) : objc_msgSend_stret(...)) 3125 // FIXME: Value of 8 is base on ppc32/x86 ABI for the most common cases. 3126 // For X86 it is more complicated and some kind of target specific routine 3127 // is needed to decide what to do. 3128 unsigned IntSize = 3129 static_cast<unsigned>(Context->getTypeSize(Context->IntTy)); 3130 IntegerLiteral *limit = IntegerLiteral::Create(*Context, 3131 llvm::APInt(IntSize, 8), 3132 Context->IntTy, 3133 SourceLocation()); 3134 BinaryOperator *lessThanExpr = 3135 new (Context) BinaryOperator(sizeofExpr, limit, BO_LE, Context->IntTy, 3136 VK_RValue, OK_Ordinary, SourceLocation()); 3137 // (sizeof(returnType) <= 8 ? objc_msgSend(...) : objc_msgSend_stret(...)) 3138 ConditionalOperator *CondExpr = 3139 new (Context) ConditionalOperator(lessThanExpr, 3140 SourceLocation(), CE, 3141 SourceLocation(), STCE, 3142 returnType, VK_RValue, OK_Ordinary); 3143 ReplacingStmt = new (Context) ParenExpr(SourceLocation(), SourceLocation(), 3144 CondExpr); 3145 } 3146 // delete Exp; leak for now, see RewritePropertyOrImplicitSetter() usage for more info. 3147 return ReplacingStmt; 3148} 3149 3150Stmt *RewriteObjC::RewriteMessageExpr(ObjCMessageExpr *Exp) { 3151 Stmt *ReplacingStmt = SynthMessageExpr(Exp, Exp->getLocStart(), 3152 Exp->getLocEnd()); 3153 3154 // Now do the actual rewrite. 3155 ReplaceStmt(Exp, ReplacingStmt); 3156 3157 // delete Exp; leak for now, see RewritePropertyOrImplicitSetter() usage for more info. 3158 return ReplacingStmt; 3159} 3160 3161// typedef struct objc_object Protocol; 3162QualType RewriteObjC::getProtocolType() { 3163 if (!ProtocolTypeDecl) { 3164 TypeSourceInfo *TInfo 3165 = Context->getTrivialTypeSourceInfo(Context->getObjCIdType()); 3166 ProtocolTypeDecl = TypedefDecl::Create(*Context, TUDecl, 3167 SourceLocation(), SourceLocation(), 3168 &Context->Idents.get("Protocol"), 3169 TInfo); 3170 } 3171 return Context->getTypeDeclType(ProtocolTypeDecl); 3172} 3173 3174/// RewriteObjCProtocolExpr - Rewrite a protocol expression into 3175/// a synthesized/forward data reference (to the protocol's metadata). 3176/// The forward references (and metadata) are generated in 3177/// RewriteObjC::HandleTranslationUnit(). 3178Stmt *RewriteObjC::RewriteObjCProtocolExpr(ObjCProtocolExpr *Exp) { 3179 std::string Name = "_OBJC_PROTOCOL_" + Exp->getProtocol()->getNameAsString(); 3180 IdentifierInfo *ID = &Context->Idents.get(Name); 3181 VarDecl *VD = VarDecl::Create(*Context, TUDecl, SourceLocation(), 3182 SourceLocation(), ID, getProtocolType(), 0, 3183 SC_Extern, SC_None); 3184 DeclRefExpr *DRE = new (Context) DeclRefExpr(VD, getProtocolType(), VK_LValue, 3185 SourceLocation()); 3186 Expr *DerefExpr = new (Context) UnaryOperator(DRE, UO_AddrOf, 3187 Context->getPointerType(DRE->getType()), 3188 VK_RValue, OK_Ordinary, SourceLocation()); 3189 CastExpr *castExpr = NoTypeInfoCStyleCastExpr(Context, DerefExpr->getType(), 3190 CK_BitCast, 3191 DerefExpr); 3192 ReplaceStmt(Exp, castExpr); 3193 ProtocolExprDecls.insert(Exp->getProtocol()); 3194 // delete Exp; leak for now, see RewritePropertyOrImplicitSetter() usage for more info. 3195 return castExpr; 3196 3197} 3198 3199bool RewriteObjC::BufferContainsPPDirectives(const char *startBuf, 3200 const char *endBuf) { 3201 while (startBuf < endBuf) { 3202 if (*startBuf == '#') { 3203 // Skip whitespace. 3204 for (++startBuf; startBuf[0] == ' ' || startBuf[0] == '\t'; ++startBuf) 3205 ; 3206 if (!strncmp(startBuf, "if", strlen("if")) || 3207 !strncmp(startBuf, "ifdef", strlen("ifdef")) || 3208 !strncmp(startBuf, "ifndef", strlen("ifndef")) || 3209 !strncmp(startBuf, "define", strlen("define")) || 3210 !strncmp(startBuf, "undef", strlen("undef")) || 3211 !strncmp(startBuf, "else", strlen("else")) || 3212 !strncmp(startBuf, "elif", strlen("elif")) || 3213 !strncmp(startBuf, "endif", strlen("endif")) || 3214 !strncmp(startBuf, "pragma", strlen("pragma")) || 3215 !strncmp(startBuf, "include", strlen("include")) || 3216 !strncmp(startBuf, "import", strlen("import")) || 3217 !strncmp(startBuf, "include_next", strlen("include_next"))) 3218 return true; 3219 } 3220 startBuf++; 3221 } 3222 return false; 3223} 3224 3225/// SynthesizeObjCInternalStruct - Rewrite one internal struct corresponding to 3226/// an objective-c class with ivars. 3227void RewriteObjC::SynthesizeObjCInternalStruct(ObjCInterfaceDecl *CDecl, 3228 std::string &Result) { 3229 assert(CDecl && "Class missing in SynthesizeObjCInternalStruct"); 3230 assert(CDecl->getName() != "" && 3231 "Name missing in SynthesizeObjCInternalStruct"); 3232 // Do not synthesize more than once. 3233 if (ObjCSynthesizedStructs.count(CDecl)) 3234 return; 3235 ObjCInterfaceDecl *RCDecl = CDecl->getSuperClass(); 3236 int NumIvars = CDecl->ivar_size(); 3237 SourceLocation LocStart = CDecl->getLocStart(); 3238 SourceLocation LocEnd = CDecl->getLocEnd(); 3239 3240 const char *startBuf = SM->getCharacterData(LocStart); 3241 const char *endBuf = SM->getCharacterData(LocEnd); 3242 3243 // If no ivars and no root or if its root, directly or indirectly, 3244 // have no ivars (thus not synthesized) then no need to synthesize this class. 3245 if ((CDecl->isForwardDecl() || NumIvars == 0) && 3246 (!RCDecl || !ObjCSynthesizedStructs.count(RCDecl))) { 3247 endBuf += Lexer::MeasureTokenLength(LocEnd, *SM, LangOpts); 3248 ReplaceText(LocStart, endBuf-startBuf, Result); 3249 return; 3250 } 3251 3252 // FIXME: This has potential of causing problem. If 3253 // SynthesizeObjCInternalStruct is ever called recursively. 3254 Result += "\nstruct "; 3255 Result += CDecl->getNameAsString(); 3256 if (LangOpts.Microsoft) 3257 Result += "_IMPL"; 3258 3259 if (NumIvars > 0) { 3260 const char *cursor = strchr(startBuf, '{'); 3261 assert((cursor && endBuf) 3262 && "SynthesizeObjCInternalStruct - malformed @interface"); 3263 // If the buffer contains preprocessor directives, we do more fine-grained 3264 // rewrites. This is intended to fix code that looks like (which occurs in 3265 // NSURL.h, for example): 3266 // 3267 // #ifdef XYZ 3268 // @interface Foo : NSObject 3269 // #else 3270 // @interface FooBar : NSObject 3271 // #endif 3272 // { 3273 // int i; 3274 // } 3275 // @end 3276 // 3277 // This clause is segregated to avoid breaking the common case. 3278 if (BufferContainsPPDirectives(startBuf, cursor)) { 3279 SourceLocation L = RCDecl ? CDecl->getSuperClassLoc() : 3280 CDecl->getClassLoc(); 3281 const char *endHeader = SM->getCharacterData(L); 3282 endHeader += Lexer::MeasureTokenLength(L, *SM, LangOpts); 3283 3284 if (CDecl->protocol_begin() != CDecl->protocol_end()) { 3285 // advance to the end of the referenced protocols. 3286 while (endHeader < cursor && *endHeader != '>') endHeader++; 3287 endHeader++; 3288 } 3289 // rewrite the original header 3290 ReplaceText(LocStart, endHeader-startBuf, Result); 3291 } else { 3292 // rewrite the original header *without* disturbing the '{' 3293 ReplaceText(LocStart, cursor-startBuf, Result); 3294 } 3295 if (RCDecl && ObjCSynthesizedStructs.count(RCDecl)) { 3296 Result = "\n struct "; 3297 Result += RCDecl->getNameAsString(); 3298 Result += "_IMPL "; 3299 Result += RCDecl->getNameAsString(); 3300 Result += "_IVARS;\n"; 3301 3302 // insert the super class structure definition. 3303 SourceLocation OnePastCurly = 3304 LocStart.getFileLocWithOffset(cursor-startBuf+1); 3305 InsertText(OnePastCurly, Result); 3306 } 3307 cursor++; // past '{' 3308 3309 // Now comment out any visibility specifiers. 3310 while (cursor < endBuf) { 3311 if (*cursor == '@') { 3312 SourceLocation atLoc = LocStart.getFileLocWithOffset(cursor-startBuf); 3313 // Skip whitespace. 3314 for (++cursor; cursor[0] == ' ' || cursor[0] == '\t'; ++cursor) 3315 /*scan*/; 3316 3317 // FIXME: presence of @public, etc. inside comment results in 3318 // this transformation as well, which is still correct c-code. 3319 if (!strncmp(cursor, "public", strlen("public")) || 3320 !strncmp(cursor, "private", strlen("private")) || 3321 !strncmp(cursor, "package", strlen("package")) || 3322 !strncmp(cursor, "protected", strlen("protected"))) 3323 InsertText(atLoc, "// "); 3324 } 3325 // FIXME: If there are cases where '<' is used in ivar declaration part 3326 // of user code, then scan the ivar list and use needToScanForQualifiers 3327 // for type checking. 3328 else if (*cursor == '<') { 3329 SourceLocation atLoc = LocStart.getFileLocWithOffset(cursor-startBuf); 3330 InsertText(atLoc, "/* "); 3331 cursor = strchr(cursor, '>'); 3332 cursor++; 3333 atLoc = LocStart.getFileLocWithOffset(cursor-startBuf); 3334 InsertText(atLoc, " */"); 3335 } else if (*cursor == '^') { // rewrite block specifier. 3336 SourceLocation caretLoc = LocStart.getFileLocWithOffset(cursor-startBuf); 3337 ReplaceText(caretLoc, 1, "*"); 3338 } 3339 cursor++; 3340 } 3341 // Don't forget to add a ';'!! 3342 InsertText(LocEnd.getFileLocWithOffset(1), ";"); 3343 } else { // we don't have any instance variables - insert super struct. 3344 endBuf += Lexer::MeasureTokenLength(LocEnd, *SM, LangOpts); 3345 Result += " {\n struct "; 3346 Result += RCDecl->getNameAsString(); 3347 Result += "_IMPL "; 3348 Result += RCDecl->getNameAsString(); 3349 Result += "_IVARS;\n};\n"; 3350 ReplaceText(LocStart, endBuf-startBuf, Result); 3351 } 3352 // Mark this struct as having been generated. 3353 if (!ObjCSynthesizedStructs.insert(CDecl)) 3354 assert(false && "struct already synthesize- SynthesizeObjCInternalStruct"); 3355} 3356 3357// RewriteObjCMethodsMetaData - Rewrite methods metadata for instance or 3358/// class methods. 3359template<typename MethodIterator> 3360void RewriteObjC::RewriteObjCMethodsMetaData(MethodIterator MethodBegin, 3361 MethodIterator MethodEnd, 3362 bool IsInstanceMethod, 3363 llvm::StringRef prefix, 3364 llvm::StringRef ClassName, 3365 std::string &Result) { 3366 if (MethodBegin == MethodEnd) return; 3367 3368 if (!objc_impl_method) { 3369 /* struct _objc_method { 3370 SEL _cmd; 3371 char *method_types; 3372 void *_imp; 3373 } 3374 */ 3375 Result += "\nstruct _objc_method {\n"; 3376 Result += "\tSEL _cmd;\n"; 3377 Result += "\tchar *method_types;\n"; 3378 Result += "\tvoid *_imp;\n"; 3379 Result += "};\n"; 3380 3381 objc_impl_method = true; 3382 } 3383 3384 // Build _objc_method_list for class's methods if needed 3385 3386 /* struct { 3387 struct _objc_method_list *next_method; 3388 int method_count; 3389 struct _objc_method method_list[]; 3390 } 3391 */ 3392 unsigned NumMethods = std::distance(MethodBegin, MethodEnd); 3393 Result += "\nstatic struct {\n"; 3394 Result += "\tstruct _objc_method_list *next_method;\n"; 3395 Result += "\tint method_count;\n"; 3396 Result += "\tstruct _objc_method method_list["; 3397 Result += utostr(NumMethods); 3398 Result += "];\n} _OBJC_"; 3399 Result += prefix; 3400 Result += IsInstanceMethod ? "INSTANCE" : "CLASS"; 3401 Result += "_METHODS_"; 3402 Result += ClassName; 3403 Result += " __attribute__ ((used, section (\"__OBJC, __"; 3404 Result += IsInstanceMethod ? "inst" : "cls"; 3405 Result += "_meth\")))= "; 3406 Result += "{\n\t0, " + utostr(NumMethods) + "\n"; 3407 3408 Result += "\t,{{(SEL)\""; 3409 Result += (*MethodBegin)->getSelector().getAsString().c_str(); 3410 std::string MethodTypeString; 3411 Context->getObjCEncodingForMethodDecl(*MethodBegin, MethodTypeString); 3412 Result += "\", \""; 3413 Result += MethodTypeString; 3414 Result += "\", (void *)"; 3415 Result += MethodInternalNames[*MethodBegin]; 3416 Result += "}\n"; 3417 for (++MethodBegin; MethodBegin != MethodEnd; ++MethodBegin) { 3418 Result += "\t ,{(SEL)\""; 3419 Result += (*MethodBegin)->getSelector().getAsString().c_str(); 3420 std::string MethodTypeString; 3421 Context->getObjCEncodingForMethodDecl(*MethodBegin, MethodTypeString); 3422 Result += "\", \""; 3423 Result += MethodTypeString; 3424 Result += "\", (void *)"; 3425 Result += MethodInternalNames[*MethodBegin]; 3426 Result += "}\n"; 3427 } 3428 Result += "\t }\n};\n"; 3429} 3430 3431/// RewriteObjCProtocolMetaData - Rewrite protocols meta-data. 3432void RewriteObjC:: 3433RewriteObjCProtocolMetaData(ObjCProtocolDecl *PDecl, llvm::StringRef prefix, 3434 llvm::StringRef ClassName, std::string &Result) { 3435 static bool objc_protocol_methods = false; 3436 3437 // Output struct protocol_methods holder of method selector and type. 3438 if (!objc_protocol_methods && !PDecl->isForwardDecl()) { 3439 /* struct protocol_methods { 3440 SEL _cmd; 3441 char *method_types; 3442 } 3443 */ 3444 Result += "\nstruct _protocol_methods {\n"; 3445 Result += "\tstruct objc_selector *_cmd;\n"; 3446 Result += "\tchar *method_types;\n"; 3447 Result += "};\n"; 3448 3449 objc_protocol_methods = true; 3450 } 3451 // Do not synthesize the protocol more than once. 3452 if (ObjCSynthesizedProtocols.count(PDecl)) 3453 return; 3454 3455 if (PDecl->instmeth_begin() != PDecl->instmeth_end()) { 3456 unsigned NumMethods = std::distance(PDecl->instmeth_begin(), 3457 PDecl->instmeth_end()); 3458 /* struct _objc_protocol_method_list { 3459 int protocol_method_count; 3460 struct protocol_methods protocols[]; 3461 } 3462 */ 3463 Result += "\nstatic struct {\n"; 3464 Result += "\tint protocol_method_count;\n"; 3465 Result += "\tstruct _protocol_methods protocol_methods["; 3466 Result += utostr(NumMethods); 3467 Result += "];\n} _OBJC_PROTOCOL_INSTANCE_METHODS_"; 3468 Result += PDecl->getNameAsString(); 3469 Result += " __attribute__ ((used, section (\"__OBJC, __cat_inst_meth\")))= " 3470 "{\n\t" + utostr(NumMethods) + "\n"; 3471 3472 // Output instance methods declared in this protocol. 3473 for (ObjCProtocolDecl::instmeth_iterator 3474 I = PDecl->instmeth_begin(), E = PDecl->instmeth_end(); 3475 I != E; ++I) { 3476 if (I == PDecl->instmeth_begin()) 3477 Result += "\t ,{{(struct objc_selector *)\""; 3478 else 3479 Result += "\t ,{(struct objc_selector *)\""; 3480 Result += (*I)->getSelector().getAsString(); 3481 std::string MethodTypeString; 3482 Context->getObjCEncodingForMethodDecl((*I), MethodTypeString); 3483 Result += "\", \""; 3484 Result += MethodTypeString; 3485 Result += "\"}\n"; 3486 } 3487 Result += "\t }\n};\n"; 3488 } 3489 3490 // Output class methods declared in this protocol. 3491 unsigned NumMethods = std::distance(PDecl->classmeth_begin(), 3492 PDecl->classmeth_end()); 3493 if (NumMethods > 0) { 3494 /* struct _objc_protocol_method_list { 3495 int protocol_method_count; 3496 struct protocol_methods protocols[]; 3497 } 3498 */ 3499 Result += "\nstatic struct {\n"; 3500 Result += "\tint protocol_method_count;\n"; 3501 Result += "\tstruct _protocol_methods protocol_methods["; 3502 Result += utostr(NumMethods); 3503 Result += "];\n} _OBJC_PROTOCOL_CLASS_METHODS_"; 3504 Result += PDecl->getNameAsString(); 3505 Result += " __attribute__ ((used, section (\"__OBJC, __cat_cls_meth\")))= " 3506 "{\n\t"; 3507 Result += utostr(NumMethods); 3508 Result += "\n"; 3509 3510 // Output instance methods declared in this protocol. 3511 for (ObjCProtocolDecl::classmeth_iterator 3512 I = PDecl->classmeth_begin(), E = PDecl->classmeth_end(); 3513 I != E; ++I) { 3514 if (I == PDecl->classmeth_begin()) 3515 Result += "\t ,{{(struct objc_selector *)\""; 3516 else 3517 Result += "\t ,{(struct objc_selector *)\""; 3518 Result += (*I)->getSelector().getAsString(); 3519 std::string MethodTypeString; 3520 Context->getObjCEncodingForMethodDecl((*I), MethodTypeString); 3521 Result += "\", \""; 3522 Result += MethodTypeString; 3523 Result += "\"}\n"; 3524 } 3525 Result += "\t }\n};\n"; 3526 } 3527 3528 // Output: 3529 /* struct _objc_protocol { 3530 // Objective-C 1.0 extensions 3531 struct _objc_protocol_extension *isa; 3532 char *protocol_name; 3533 struct _objc_protocol **protocol_list; 3534 struct _objc_protocol_method_list *instance_methods; 3535 struct _objc_protocol_method_list *class_methods; 3536 }; 3537 */ 3538 static bool objc_protocol = false; 3539 if (!objc_protocol) { 3540 Result += "\nstruct _objc_protocol {\n"; 3541 Result += "\tstruct _objc_protocol_extension *isa;\n"; 3542 Result += "\tchar *protocol_name;\n"; 3543 Result += "\tstruct _objc_protocol **protocol_list;\n"; 3544 Result += "\tstruct _objc_protocol_method_list *instance_methods;\n"; 3545 Result += "\tstruct _objc_protocol_method_list *class_methods;\n"; 3546 Result += "};\n"; 3547 3548 objc_protocol = true; 3549 } 3550 3551 Result += "\nstatic struct _objc_protocol _OBJC_PROTOCOL_"; 3552 Result += PDecl->getNameAsString(); 3553 Result += " __attribute__ ((used, section (\"__OBJC, __protocol\")))= " 3554 "{\n\t0, \""; 3555 Result += PDecl->getNameAsString(); 3556 Result += "\", 0, "; 3557 if (PDecl->instmeth_begin() != PDecl->instmeth_end()) { 3558 Result += "(struct _objc_protocol_method_list *)&_OBJC_PROTOCOL_INSTANCE_METHODS_"; 3559 Result += PDecl->getNameAsString(); 3560 Result += ", "; 3561 } 3562 else 3563 Result += "0, "; 3564 if (PDecl->classmeth_begin() != PDecl->classmeth_end()) { 3565 Result += "(struct _objc_protocol_method_list *)&_OBJC_PROTOCOL_CLASS_METHODS_"; 3566 Result += PDecl->getNameAsString(); 3567 Result += "\n"; 3568 } 3569 else 3570 Result += "0\n"; 3571 Result += "};\n"; 3572 3573 // Mark this protocol as having been generated. 3574 if (!ObjCSynthesizedProtocols.insert(PDecl)) 3575 assert(false && "protocol already synthesized"); 3576 3577} 3578 3579void RewriteObjC:: 3580RewriteObjCProtocolListMetaData(const ObjCList<ObjCProtocolDecl> &Protocols, 3581 llvm::StringRef prefix, llvm::StringRef ClassName, 3582 std::string &Result) { 3583 if (Protocols.empty()) return; 3584 3585 for (unsigned i = 0; i != Protocols.size(); i++) 3586 RewriteObjCProtocolMetaData(Protocols[i], prefix, ClassName, Result); 3587 3588 // Output the top lovel protocol meta-data for the class. 3589 /* struct _objc_protocol_list { 3590 struct _objc_protocol_list *next; 3591 int protocol_count; 3592 struct _objc_protocol *class_protocols[]; 3593 } 3594 */ 3595 Result += "\nstatic struct {\n"; 3596 Result += "\tstruct _objc_protocol_list *next;\n"; 3597 Result += "\tint protocol_count;\n"; 3598 Result += "\tstruct _objc_protocol *class_protocols["; 3599 Result += utostr(Protocols.size()); 3600 Result += "];\n} _OBJC_"; 3601 Result += prefix; 3602 Result += "_PROTOCOLS_"; 3603 Result += ClassName; 3604 Result += " __attribute__ ((used, section (\"__OBJC, __cat_cls_meth\")))= " 3605 "{\n\t0, "; 3606 Result += utostr(Protocols.size()); 3607 Result += "\n"; 3608 3609 Result += "\t,{&_OBJC_PROTOCOL_"; 3610 Result += Protocols[0]->getNameAsString(); 3611 Result += " \n"; 3612 3613 for (unsigned i = 1; i != Protocols.size(); i++) { 3614 Result += "\t ,&_OBJC_PROTOCOL_"; 3615 Result += Protocols[i]->getNameAsString(); 3616 Result += "\n"; 3617 } 3618 Result += "\t }\n};\n"; 3619} 3620 3621 3622/// RewriteObjCCategoryImplDecl - Rewrite metadata for each category 3623/// implementation. 3624void RewriteObjC::RewriteObjCCategoryImplDecl(ObjCCategoryImplDecl *IDecl, 3625 std::string &Result) { 3626 ObjCInterfaceDecl *ClassDecl = IDecl->getClassInterface(); 3627 // Find category declaration for this implementation. 3628 ObjCCategoryDecl *CDecl; 3629 for (CDecl = ClassDecl->getCategoryList(); CDecl; 3630 CDecl = CDecl->getNextClassCategory()) 3631 if (CDecl->getIdentifier() == IDecl->getIdentifier()) 3632 break; 3633 3634 std::string FullCategoryName = ClassDecl->getNameAsString(); 3635 FullCategoryName += '_'; 3636 FullCategoryName += IDecl->getNameAsString(); 3637 3638 // Build _objc_method_list for class's instance methods if needed 3639 llvm::SmallVector<ObjCMethodDecl *, 32> 3640 InstanceMethods(IDecl->instmeth_begin(), IDecl->instmeth_end()); 3641 3642 // If any of our property implementations have associated getters or 3643 // setters, produce metadata for them as well. 3644 for (ObjCImplDecl::propimpl_iterator Prop = IDecl->propimpl_begin(), 3645 PropEnd = IDecl->propimpl_end(); 3646 Prop != PropEnd; ++Prop) { 3647 if ((*Prop)->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic) 3648 continue; 3649 if (!(*Prop)->getPropertyIvarDecl()) 3650 continue; 3651 ObjCPropertyDecl *PD = (*Prop)->getPropertyDecl(); 3652 if (!PD) 3653 continue; 3654 if (ObjCMethodDecl *Getter = PD->getGetterMethodDecl()) 3655 InstanceMethods.push_back(Getter); 3656 if (PD->isReadOnly()) 3657 continue; 3658 if (ObjCMethodDecl *Setter = PD->getSetterMethodDecl()) 3659 InstanceMethods.push_back(Setter); 3660 } 3661 RewriteObjCMethodsMetaData(InstanceMethods.begin(), InstanceMethods.end(), 3662 true, "CATEGORY_", FullCategoryName.c_str(), 3663 Result); 3664 3665 // Build _objc_method_list for class's class methods if needed 3666 RewriteObjCMethodsMetaData(IDecl->classmeth_begin(), IDecl->classmeth_end(), 3667 false, "CATEGORY_", FullCategoryName.c_str(), 3668 Result); 3669 3670 // Protocols referenced in class declaration? 3671 // Null CDecl is case of a category implementation with no category interface 3672 if (CDecl) 3673 RewriteObjCProtocolListMetaData(CDecl->getReferencedProtocols(), "CATEGORY", 3674 FullCategoryName, Result); 3675 /* struct _objc_category { 3676 char *category_name; 3677 char *class_name; 3678 struct _objc_method_list *instance_methods; 3679 struct _objc_method_list *class_methods; 3680 struct _objc_protocol_list *protocols; 3681 // Objective-C 1.0 extensions 3682 uint32_t size; // sizeof (struct _objc_category) 3683 struct _objc_property_list *instance_properties; // category's own 3684 // @property decl. 3685 }; 3686 */ 3687 3688 static bool objc_category = false; 3689 if (!objc_category) { 3690 Result += "\nstruct _objc_category {\n"; 3691 Result += "\tchar *category_name;\n"; 3692 Result += "\tchar *class_name;\n"; 3693 Result += "\tstruct _objc_method_list *instance_methods;\n"; 3694 Result += "\tstruct _objc_method_list *class_methods;\n"; 3695 Result += "\tstruct _objc_protocol_list *protocols;\n"; 3696 Result += "\tunsigned int size;\n"; 3697 Result += "\tstruct _objc_property_list *instance_properties;\n"; 3698 Result += "};\n"; 3699 objc_category = true; 3700 } 3701 Result += "\nstatic struct _objc_category _OBJC_CATEGORY_"; 3702 Result += FullCategoryName; 3703 Result += " __attribute__ ((used, section (\"__OBJC, __category\")))= {\n\t\""; 3704 Result += IDecl->getNameAsString(); 3705 Result += "\"\n\t, \""; 3706 Result += ClassDecl->getNameAsString(); 3707 Result += "\"\n"; 3708 3709 if (IDecl->instmeth_begin() != IDecl->instmeth_end()) { 3710 Result += "\t, (struct _objc_method_list *)" 3711 "&_OBJC_CATEGORY_INSTANCE_METHODS_"; 3712 Result += FullCategoryName; 3713 Result += "\n"; 3714 } 3715 else 3716 Result += "\t, 0\n"; 3717 if (IDecl->classmeth_begin() != IDecl->classmeth_end()) { 3718 Result += "\t, (struct _objc_method_list *)" 3719 "&_OBJC_CATEGORY_CLASS_METHODS_"; 3720 Result += FullCategoryName; 3721 Result += "\n"; 3722 } 3723 else 3724 Result += "\t, 0\n"; 3725 3726 if (CDecl && CDecl->protocol_begin() != CDecl->protocol_end()) { 3727 Result += "\t, (struct _objc_protocol_list *)&_OBJC_CATEGORY_PROTOCOLS_"; 3728 Result += FullCategoryName; 3729 Result += "\n"; 3730 } 3731 else 3732 Result += "\t, 0\n"; 3733 Result += "\t, sizeof(struct _objc_category), 0\n};\n"; 3734} 3735 3736/// SynthesizeIvarOffsetComputation - This rutine synthesizes computation of 3737/// ivar offset. 3738void RewriteObjC::SynthesizeIvarOffsetComputation(ObjCIvarDecl *ivar, 3739 std::string &Result) { 3740 if (ivar->isBitField()) { 3741 // FIXME: The hack below doesn't work for bitfields. For now, we simply 3742 // place all bitfields at offset 0. 3743 Result += "0"; 3744 } else { 3745 Result += "__OFFSETOFIVAR__(struct "; 3746 Result += ivar->getContainingInterface()->getNameAsString(); 3747 if (LangOpts.Microsoft) 3748 Result += "_IMPL"; 3749 Result += ", "; 3750 Result += ivar->getNameAsString(); 3751 Result += ")"; 3752 } 3753} 3754 3755//===----------------------------------------------------------------------===// 3756// Meta Data Emission 3757//===----------------------------------------------------------------------===// 3758 3759void RewriteObjC::RewriteObjCClassMetaData(ObjCImplementationDecl *IDecl, 3760 std::string &Result) { 3761 ObjCInterfaceDecl *CDecl = IDecl->getClassInterface(); 3762 3763 // Explictly declared @interface's are already synthesized. 3764 if (CDecl->isImplicitInterfaceDecl()) { 3765 // FIXME: Implementation of a class with no @interface (legacy) doese not 3766 // produce correct synthesis as yet. 3767 SynthesizeObjCInternalStruct(CDecl, Result); 3768 } 3769 3770 // Build _objc_ivar_list metadata for classes ivars if needed 3771 unsigned NumIvars = !IDecl->ivar_empty() 3772 ? IDecl->ivar_size() 3773 : (CDecl ? CDecl->ivar_size() : 0); 3774 if (NumIvars > 0) { 3775 static bool objc_ivar = false; 3776 if (!objc_ivar) { 3777 /* struct _objc_ivar { 3778 char *ivar_name; 3779 char *ivar_type; 3780 int ivar_offset; 3781 }; 3782 */ 3783 Result += "\nstruct _objc_ivar {\n"; 3784 Result += "\tchar *ivar_name;\n"; 3785 Result += "\tchar *ivar_type;\n"; 3786 Result += "\tint ivar_offset;\n"; 3787 Result += "};\n"; 3788 3789 objc_ivar = true; 3790 } 3791 3792 /* struct { 3793 int ivar_count; 3794 struct _objc_ivar ivar_list[nIvars]; 3795 }; 3796 */ 3797 Result += "\nstatic struct {\n"; 3798 Result += "\tint ivar_count;\n"; 3799 Result += "\tstruct _objc_ivar ivar_list["; 3800 Result += utostr(NumIvars); 3801 Result += "];\n} _OBJC_INSTANCE_VARIABLES_"; 3802 Result += IDecl->getNameAsString(); 3803 Result += " __attribute__ ((used, section (\"__OBJC, __instance_vars\")))= " 3804 "{\n\t"; 3805 Result += utostr(NumIvars); 3806 Result += "\n"; 3807 3808 ObjCInterfaceDecl::ivar_iterator IVI, IVE; 3809 llvm::SmallVector<ObjCIvarDecl *, 8> IVars; 3810 if (!IDecl->ivar_empty()) { 3811 for (ObjCInterfaceDecl::ivar_iterator 3812 IV = IDecl->ivar_begin(), IVEnd = IDecl->ivar_end(); 3813 IV != IVEnd; ++IV) 3814 IVars.push_back(*IV); 3815 IVI = IDecl->ivar_begin(); 3816 IVE = IDecl->ivar_end(); 3817 } else { 3818 IVI = CDecl->ivar_begin(); 3819 IVE = CDecl->ivar_end(); 3820 } 3821 Result += "\t,{{\""; 3822 Result += (*IVI)->getNameAsString(); 3823 Result += "\", \""; 3824 std::string TmpString, StrEncoding; 3825 Context->getObjCEncodingForType((*IVI)->getType(), TmpString, *IVI); 3826 QuoteDoublequotes(TmpString, StrEncoding); 3827 Result += StrEncoding; 3828 Result += "\", "; 3829 SynthesizeIvarOffsetComputation(*IVI, Result); 3830 Result += "}\n"; 3831 for (++IVI; IVI != IVE; ++IVI) { 3832 Result += "\t ,{\""; 3833 Result += (*IVI)->getNameAsString(); 3834 Result += "\", \""; 3835 std::string TmpString, StrEncoding; 3836 Context->getObjCEncodingForType((*IVI)->getType(), TmpString, *IVI); 3837 QuoteDoublequotes(TmpString, StrEncoding); 3838 Result += StrEncoding; 3839 Result += "\", "; 3840 SynthesizeIvarOffsetComputation((*IVI), Result); 3841 Result += "}\n"; 3842 } 3843 3844 Result += "\t }\n};\n"; 3845 } 3846 3847 // Build _objc_method_list for class's instance methods if needed 3848 llvm::SmallVector<ObjCMethodDecl *, 32> 3849 InstanceMethods(IDecl->instmeth_begin(), IDecl->instmeth_end()); 3850 3851 // If any of our property implementations have associated getters or 3852 // setters, produce metadata for them as well. 3853 for (ObjCImplDecl::propimpl_iterator Prop = IDecl->propimpl_begin(), 3854 PropEnd = IDecl->propimpl_end(); 3855 Prop != PropEnd; ++Prop) { 3856 if ((*Prop)->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic) 3857 continue; 3858 if (!(*Prop)->getPropertyIvarDecl()) 3859 continue; 3860 ObjCPropertyDecl *PD = (*Prop)->getPropertyDecl(); 3861 if (!PD) 3862 continue; 3863 if (ObjCMethodDecl *Getter = PD->getGetterMethodDecl()) 3864 if (!Getter->isDefined()) 3865 InstanceMethods.push_back(Getter); 3866 if (PD->isReadOnly()) 3867 continue; 3868 if (ObjCMethodDecl *Setter = PD->getSetterMethodDecl()) 3869 if (!Setter->isDefined()) 3870 InstanceMethods.push_back(Setter); 3871 } 3872 RewriteObjCMethodsMetaData(InstanceMethods.begin(), InstanceMethods.end(), 3873 true, "", IDecl->getName(), Result); 3874 3875 // Build _objc_method_list for class's class methods if needed 3876 RewriteObjCMethodsMetaData(IDecl->classmeth_begin(), IDecl->classmeth_end(), 3877 false, "", IDecl->getName(), Result); 3878 3879 // Protocols referenced in class declaration? 3880 RewriteObjCProtocolListMetaData(CDecl->getReferencedProtocols(), 3881 "CLASS", CDecl->getName(), Result); 3882 3883 // Declaration of class/meta-class metadata 3884 /* struct _objc_class { 3885 struct _objc_class *isa; // or const char *root_class_name when metadata 3886 const char *super_class_name; 3887 char *name; 3888 long version; 3889 long info; 3890 long instance_size; 3891 struct _objc_ivar_list *ivars; 3892 struct _objc_method_list *methods; 3893 struct objc_cache *cache; 3894 struct objc_protocol_list *protocols; 3895 const char *ivar_layout; 3896 struct _objc_class_ext *ext; 3897 }; 3898 */ 3899 static bool objc_class = false; 3900 if (!objc_class) { 3901 Result += "\nstruct _objc_class {\n"; 3902 Result += "\tstruct _objc_class *isa;\n"; 3903 Result += "\tconst char *super_class_name;\n"; 3904 Result += "\tchar *name;\n"; 3905 Result += "\tlong version;\n"; 3906 Result += "\tlong info;\n"; 3907 Result += "\tlong instance_size;\n"; 3908 Result += "\tstruct _objc_ivar_list *ivars;\n"; 3909 Result += "\tstruct _objc_method_list *methods;\n"; 3910 Result += "\tstruct objc_cache *cache;\n"; 3911 Result += "\tstruct _objc_protocol_list *protocols;\n"; 3912 Result += "\tconst char *ivar_layout;\n"; 3913 Result += "\tstruct _objc_class_ext *ext;\n"; 3914 Result += "};\n"; 3915 objc_class = true; 3916 } 3917 3918 // Meta-class metadata generation. 3919 ObjCInterfaceDecl *RootClass = 0; 3920 ObjCInterfaceDecl *SuperClass = CDecl->getSuperClass(); 3921 while (SuperClass) { 3922 RootClass = SuperClass; 3923 SuperClass = SuperClass->getSuperClass(); 3924 } 3925 SuperClass = CDecl->getSuperClass(); 3926 3927 Result += "\nstatic struct _objc_class _OBJC_METACLASS_"; 3928 Result += CDecl->getNameAsString(); 3929 Result += " __attribute__ ((used, section (\"__OBJC, __meta_class\")))= " 3930 "{\n\t(struct _objc_class *)\""; 3931 Result += (RootClass ? RootClass->getNameAsString() : CDecl->getNameAsString()); 3932 Result += "\""; 3933 3934 if (SuperClass) { 3935 Result += ", \""; 3936 Result += SuperClass->getNameAsString(); 3937 Result += "\", \""; 3938 Result += CDecl->getNameAsString(); 3939 Result += "\""; 3940 } 3941 else { 3942 Result += ", 0, \""; 3943 Result += CDecl->getNameAsString(); 3944 Result += "\""; 3945 } 3946 // Set 'ivars' field for root class to 0. ObjC1 runtime does not use it. 3947 // 'info' field is initialized to CLS_META(2) for metaclass 3948 Result += ", 0,2, sizeof(struct _objc_class), 0"; 3949 if (IDecl->classmeth_begin() != IDecl->classmeth_end()) { 3950 Result += "\n\t, (struct _objc_method_list *)&_OBJC_CLASS_METHODS_"; 3951 Result += IDecl->getNameAsString(); 3952 Result += "\n"; 3953 } 3954 else 3955 Result += ", 0\n"; 3956 if (CDecl->protocol_begin() != CDecl->protocol_end()) { 3957 Result += "\t,0, (struct _objc_protocol_list *)&_OBJC_CLASS_PROTOCOLS_"; 3958 Result += CDecl->getNameAsString(); 3959 Result += ",0,0\n"; 3960 } 3961 else 3962 Result += "\t,0,0,0,0\n"; 3963 Result += "};\n"; 3964 3965 // class metadata generation. 3966 Result += "\nstatic struct _objc_class _OBJC_CLASS_"; 3967 Result += CDecl->getNameAsString(); 3968 Result += " __attribute__ ((used, section (\"__OBJC, __class\")))= " 3969 "{\n\t&_OBJC_METACLASS_"; 3970 Result += CDecl->getNameAsString(); 3971 if (SuperClass) { 3972 Result += ", \""; 3973 Result += SuperClass->getNameAsString(); 3974 Result += "\", \""; 3975 Result += CDecl->getNameAsString(); 3976 Result += "\""; 3977 } 3978 else { 3979 Result += ", 0, \""; 3980 Result += CDecl->getNameAsString(); 3981 Result += "\""; 3982 } 3983 // 'info' field is initialized to CLS_CLASS(1) for class 3984 Result += ", 0,1"; 3985 if (!ObjCSynthesizedStructs.count(CDecl)) 3986 Result += ",0"; 3987 else { 3988 // class has size. Must synthesize its size. 3989 Result += ",sizeof(struct "; 3990 Result += CDecl->getNameAsString(); 3991 if (LangOpts.Microsoft) 3992 Result += "_IMPL"; 3993 Result += ")"; 3994 } 3995 if (NumIvars > 0) { 3996 Result += ", (struct _objc_ivar_list *)&_OBJC_INSTANCE_VARIABLES_"; 3997 Result += CDecl->getNameAsString(); 3998 Result += "\n\t"; 3999 } 4000 else 4001 Result += ",0"; 4002 if (IDecl->instmeth_begin() != IDecl->instmeth_end()) { 4003 Result += ", (struct _objc_method_list *)&_OBJC_INSTANCE_METHODS_"; 4004 Result += CDecl->getNameAsString(); 4005 Result += ", 0\n\t"; 4006 } 4007 else 4008 Result += ",0,0"; 4009 if (CDecl->protocol_begin() != CDecl->protocol_end()) { 4010 Result += ", (struct _objc_protocol_list*)&_OBJC_CLASS_PROTOCOLS_"; 4011 Result += CDecl->getNameAsString(); 4012 Result += ", 0,0\n"; 4013 } 4014 else 4015 Result += ",0,0,0\n"; 4016 Result += "};\n"; 4017} 4018 4019/// RewriteImplementations - This routine rewrites all method implementations 4020/// and emits meta-data. 4021 4022void RewriteObjC::RewriteImplementations() { 4023 int ClsDefCount = ClassImplementation.size(); 4024 int CatDefCount = CategoryImplementation.size(); 4025 4026 // Rewrite implemented methods 4027 for (int i = 0; i < ClsDefCount; i++) 4028 RewriteImplementationDecl(ClassImplementation[i]); 4029 4030 for (int i = 0; i < CatDefCount; i++) 4031 RewriteImplementationDecl(CategoryImplementation[i]); 4032} 4033 4034void RewriteObjC::SynthesizeMetaDataIntoBuffer(std::string &Result) { 4035 int ClsDefCount = ClassImplementation.size(); 4036 int CatDefCount = CategoryImplementation.size(); 4037 4038 // For each implemented class, write out all its meta data. 4039 for (int i = 0; i < ClsDefCount; i++) 4040 RewriteObjCClassMetaData(ClassImplementation[i], Result); 4041 4042 // For each implemented category, write out all its meta data. 4043 for (int i = 0; i < CatDefCount; i++) 4044 RewriteObjCCategoryImplDecl(CategoryImplementation[i], Result); 4045 4046 // Write objc_symtab metadata 4047 /* 4048 struct _objc_symtab 4049 { 4050 long sel_ref_cnt; 4051 SEL *refs; 4052 short cls_def_cnt; 4053 short cat_def_cnt; 4054 void *defs[cls_def_cnt + cat_def_cnt]; 4055 }; 4056 */ 4057 4058 Result += "\nstruct _objc_symtab {\n"; 4059 Result += "\tlong sel_ref_cnt;\n"; 4060 Result += "\tSEL *refs;\n"; 4061 Result += "\tshort cls_def_cnt;\n"; 4062 Result += "\tshort cat_def_cnt;\n"; 4063 Result += "\tvoid *defs[" + utostr(ClsDefCount + CatDefCount)+ "];\n"; 4064 Result += "};\n\n"; 4065 4066 Result += "static struct _objc_symtab " 4067 "_OBJC_SYMBOLS __attribute__((used, section (\"__OBJC, __symbols\")))= {\n"; 4068 Result += "\t0, 0, " + utostr(ClsDefCount) 4069 + ", " + utostr(CatDefCount) + "\n"; 4070 for (int i = 0; i < ClsDefCount; i++) { 4071 Result += "\t,&_OBJC_CLASS_"; 4072 Result += ClassImplementation[i]->getNameAsString(); 4073 Result += "\n"; 4074 } 4075 4076 for (int i = 0; i < CatDefCount; i++) { 4077 Result += "\t,&_OBJC_CATEGORY_"; 4078 Result += CategoryImplementation[i]->getClassInterface()->getNameAsString(); 4079 Result += "_"; 4080 Result += CategoryImplementation[i]->getNameAsString(); 4081 Result += "\n"; 4082 } 4083 4084 Result += "};\n\n"; 4085 4086 // Write objc_module metadata 4087 4088 /* 4089 struct _objc_module { 4090 long version; 4091 long size; 4092 const char *name; 4093 struct _objc_symtab *symtab; 4094 } 4095 */ 4096 4097 Result += "\nstruct _objc_module {\n"; 4098 Result += "\tlong version;\n"; 4099 Result += "\tlong size;\n"; 4100 Result += "\tconst char *name;\n"; 4101 Result += "\tstruct _objc_symtab *symtab;\n"; 4102 Result += "};\n\n"; 4103 Result += "static struct _objc_module " 4104 "_OBJC_MODULES __attribute__ ((used, section (\"__OBJC, __module_info\")))= {\n"; 4105 Result += "\t" + utostr(OBJC_ABI_VERSION) + 4106 ", sizeof(struct _objc_module), \"\", &_OBJC_SYMBOLS\n"; 4107 Result += "};\n\n"; 4108 4109 if (LangOpts.Microsoft) { 4110 if (ProtocolExprDecls.size()) { 4111 Result += "#pragma section(\".objc_protocol$B\",long,read,write)\n"; 4112 Result += "#pragma data_seg(push, \".objc_protocol$B\")\n"; 4113 for (llvm::SmallPtrSet<ObjCProtocolDecl *,8>::iterator I = ProtocolExprDecls.begin(), 4114 E = ProtocolExprDecls.end(); I != E; ++I) { 4115 Result += "static struct _objc_protocol *_POINTER_OBJC_PROTOCOL_"; 4116 Result += (*I)->getNameAsString(); 4117 Result += " = &_OBJC_PROTOCOL_"; 4118 Result += (*I)->getNameAsString(); 4119 Result += ";\n"; 4120 } 4121 Result += "#pragma data_seg(pop)\n\n"; 4122 } 4123 Result += "#pragma section(\".objc_module_info$B\",long,read,write)\n"; 4124 Result += "#pragma data_seg(push, \".objc_module_info$B\")\n"; 4125 Result += "static struct _objc_module *_POINTER_OBJC_MODULES = "; 4126 Result += "&_OBJC_MODULES;\n"; 4127 Result += "#pragma data_seg(pop)\n\n"; 4128 } 4129} 4130 4131void RewriteObjC::RewriteByRefString(std::string &ResultStr, 4132 const std::string &Name, 4133 ValueDecl *VD, bool def) { 4134 assert(BlockByRefDeclNo.count(VD) && 4135 "RewriteByRefString: ByRef decl missing"); 4136 if (def) 4137 ResultStr += "struct "; 4138 ResultStr += "__Block_byref_" + Name + 4139 "_" + utostr(BlockByRefDeclNo[VD]) ; 4140} 4141 4142static bool HasLocalVariableExternalStorage(ValueDecl *VD) { 4143 if (VarDecl *Var = dyn_cast<VarDecl>(VD)) 4144 return (Var->isFunctionOrMethodVarDecl() && !Var->hasLocalStorage()); 4145 return false; 4146} 4147 4148std::string RewriteObjC::SynthesizeBlockFunc(BlockExpr *CE, int i, 4149 llvm::StringRef funcName, 4150 std::string Tag) { 4151 const FunctionType *AFT = CE->getFunctionType(); 4152 QualType RT = AFT->getResultType(); 4153 std::string StructRef = "struct " + Tag; 4154 std::string S = "static " + RT.getAsString(Context->PrintingPolicy) + " __" + 4155 funcName.str() + "_" + "block_func_" + utostr(i); 4156 4157 BlockDecl *BD = CE->getBlockDecl(); 4158 4159 if (isa<FunctionNoProtoType>(AFT)) { 4160 // No user-supplied arguments. Still need to pass in a pointer to the 4161 // block (to reference imported block decl refs). 4162 S += "(" + StructRef + " *__cself)"; 4163 } else if (BD->param_empty()) { 4164 S += "(" + StructRef + " *__cself)"; 4165 } else { 4166 const FunctionProtoType *FT = cast<FunctionProtoType>(AFT); 4167 assert(FT && "SynthesizeBlockFunc: No function proto"); 4168 S += '('; 4169 // first add the implicit argument. 4170 S += StructRef + " *__cself, "; 4171 std::string ParamStr; 4172 for (BlockDecl::param_iterator AI = BD->param_begin(), 4173 E = BD->param_end(); AI != E; ++AI) { 4174 if (AI != BD->param_begin()) S += ", "; 4175 ParamStr = (*AI)->getNameAsString(); 4176 QualType QT = (*AI)->getType(); 4177 if (convertBlockPointerToFunctionPointer(QT)) 4178 QT.getAsStringInternal(ParamStr, Context->PrintingPolicy); 4179 else 4180 QT.getAsStringInternal(ParamStr, Context->PrintingPolicy); 4181 S += ParamStr; 4182 } 4183 if (FT->isVariadic()) { 4184 if (!BD->param_empty()) S += ", "; 4185 S += "..."; 4186 } 4187 S += ')'; 4188 } 4189 S += " {\n"; 4190 4191 // Create local declarations to avoid rewriting all closure decl ref exprs. 4192 // First, emit a declaration for all "by ref" decls. 4193 for (llvm::SmallVector<ValueDecl*,8>::iterator I = BlockByRefDecls.begin(), 4194 E = BlockByRefDecls.end(); I != E; ++I) { 4195 S += " "; 4196 std::string Name = (*I)->getNameAsString(); 4197 std::string TypeString; 4198 RewriteByRefString(TypeString, Name, (*I)); 4199 TypeString += " *"; 4200 Name = TypeString + Name; 4201 S += Name + " = __cself->" + (*I)->getNameAsString() + "; // bound by ref\n"; 4202 } 4203 // Next, emit a declaration for all "by copy" declarations. 4204 for (llvm::SmallVector<ValueDecl*,8>::iterator I = BlockByCopyDecls.begin(), 4205 E = BlockByCopyDecls.end(); I != E; ++I) { 4206 S += " "; 4207 // Handle nested closure invocation. For example: 4208 // 4209 // void (^myImportedClosure)(void); 4210 // myImportedClosure = ^(void) { setGlobalInt(x + y); }; 4211 // 4212 // void (^anotherClosure)(void); 4213 // anotherClosure = ^(void) { 4214 // myImportedClosure(); // import and invoke the closure 4215 // }; 4216 // 4217 if (isTopLevelBlockPointerType((*I)->getType())) { 4218 RewriteBlockPointerTypeVariable(S, (*I)); 4219 S += " = ("; 4220 RewriteBlockPointerType(S, (*I)->getType()); 4221 S += ")"; 4222 S += "__cself->" + (*I)->getNameAsString() + "; // bound by copy\n"; 4223 } 4224 else { 4225 std::string Name = (*I)->getNameAsString(); 4226 QualType QT = (*I)->getType(); 4227 if (HasLocalVariableExternalStorage(*I)) 4228 QT = Context->getPointerType(QT); 4229 QT.getAsStringInternal(Name, Context->PrintingPolicy); 4230 S += Name + " = __cself->" + 4231 (*I)->getNameAsString() + "; // bound by copy\n"; 4232 } 4233 } 4234 std::string RewrittenStr = RewrittenBlockExprs[CE]; 4235 const char *cstr = RewrittenStr.c_str(); 4236 while (*cstr++ != '{') ; 4237 S += cstr; 4238 S += "\n"; 4239 return S; 4240} 4241 4242std::string RewriteObjC::SynthesizeBlockHelperFuncs(BlockExpr *CE, int i, 4243 llvm::StringRef funcName, 4244 std::string Tag) { 4245 std::string StructRef = "struct " + Tag; 4246 std::string S = "static void __"; 4247 4248 S += funcName; 4249 S += "_block_copy_" + utostr(i); 4250 S += "(" + StructRef; 4251 S += "*dst, " + StructRef; 4252 S += "*src) {"; 4253 for (llvm::SmallPtrSet<ValueDecl*,8>::iterator I = ImportedBlockDecls.begin(), 4254 E = ImportedBlockDecls.end(); I != E; ++I) { 4255 S += "_Block_object_assign((void*)&dst->"; 4256 S += (*I)->getNameAsString(); 4257 S += ", (void*)src->"; 4258 S += (*I)->getNameAsString(); 4259 if (BlockByRefDeclsPtrSet.count((*I))) 4260 S += ", " + utostr(BLOCK_FIELD_IS_BYREF) + "/*BLOCK_FIELD_IS_BYREF*/);"; 4261 else 4262 S += ", " + utostr(BLOCK_FIELD_IS_OBJECT) + "/*BLOCK_FIELD_IS_OBJECT*/);"; 4263 } 4264 S += "}\n"; 4265 4266 S += "\nstatic void __"; 4267 S += funcName; 4268 S += "_block_dispose_" + utostr(i); 4269 S += "(" + StructRef; 4270 S += "*src) {"; 4271 for (llvm::SmallPtrSet<ValueDecl*,8>::iterator I = ImportedBlockDecls.begin(), 4272 E = ImportedBlockDecls.end(); I != E; ++I) { 4273 S += "_Block_object_dispose((void*)src->"; 4274 S += (*I)->getNameAsString(); 4275 if (BlockByRefDeclsPtrSet.count((*I))) 4276 S += ", " + utostr(BLOCK_FIELD_IS_BYREF) + "/*BLOCK_FIELD_IS_BYREF*/);"; 4277 else 4278 S += ", " + utostr(BLOCK_FIELD_IS_OBJECT) + "/*BLOCK_FIELD_IS_OBJECT*/);"; 4279 } 4280 S += "}\n"; 4281 return S; 4282} 4283 4284std::string RewriteObjC::SynthesizeBlockImpl(BlockExpr *CE, std::string Tag, 4285 std::string Desc) { 4286 std::string S = "\nstruct " + Tag; 4287 std::string Constructor = " " + Tag; 4288 4289 S += " {\n struct __block_impl impl;\n"; 4290 S += " struct " + Desc; 4291 S += "* Desc;\n"; 4292 4293 Constructor += "(void *fp, "; // Invoke function pointer. 4294 Constructor += "struct " + Desc; // Descriptor pointer. 4295 Constructor += " *desc"; 4296 4297 if (BlockDeclRefs.size()) { 4298 // Output all "by copy" declarations. 4299 for (llvm::SmallVector<ValueDecl*,8>::iterator I = BlockByCopyDecls.begin(), 4300 E = BlockByCopyDecls.end(); I != E; ++I) { 4301 S += " "; 4302 std::string FieldName = (*I)->getNameAsString(); 4303 std::string ArgName = "_" + FieldName; 4304 // Handle nested closure invocation. For example: 4305 // 4306 // void (^myImportedBlock)(void); 4307 // myImportedBlock = ^(void) { setGlobalInt(x + y); }; 4308 // 4309 // void (^anotherBlock)(void); 4310 // anotherBlock = ^(void) { 4311 // myImportedBlock(); // import and invoke the closure 4312 // }; 4313 // 4314 if (isTopLevelBlockPointerType((*I)->getType())) { 4315 S += "struct __block_impl *"; 4316 Constructor += ", void *" + ArgName; 4317 } else { 4318 QualType QT = (*I)->getType(); 4319 if (HasLocalVariableExternalStorage(*I)) 4320 QT = Context->getPointerType(QT); 4321 QT.getAsStringInternal(FieldName, Context->PrintingPolicy); 4322 QT.getAsStringInternal(ArgName, Context->PrintingPolicy); 4323 Constructor += ", " + ArgName; 4324 } 4325 S += FieldName + ";\n"; 4326 } 4327 // Output all "by ref" declarations. 4328 for (llvm::SmallVector<ValueDecl*,8>::iterator I = BlockByRefDecls.begin(), 4329 E = BlockByRefDecls.end(); I != E; ++I) { 4330 S += " "; 4331 std::string FieldName = (*I)->getNameAsString(); 4332 std::string ArgName = "_" + FieldName; 4333 { 4334 std::string TypeString; 4335 RewriteByRefString(TypeString, FieldName, (*I)); 4336 TypeString += " *"; 4337 FieldName = TypeString + FieldName; 4338 ArgName = TypeString + ArgName; 4339 Constructor += ", " + ArgName; 4340 } 4341 S += FieldName + "; // by ref\n"; 4342 } 4343 // Finish writing the constructor. 4344 Constructor += ", int flags=0)"; 4345 // Initialize all "by copy" arguments. 4346 bool firsTime = true; 4347 for (llvm::SmallVector<ValueDecl*,8>::iterator I = BlockByCopyDecls.begin(), 4348 E = BlockByCopyDecls.end(); I != E; ++I) { 4349 std::string Name = (*I)->getNameAsString(); 4350 if (firsTime) { 4351 Constructor += " : "; 4352 firsTime = false; 4353 } 4354 else 4355 Constructor += ", "; 4356 if (isTopLevelBlockPointerType((*I)->getType())) 4357 Constructor += Name + "((struct __block_impl *)_" + Name + ")"; 4358 else 4359 Constructor += Name + "(_" + Name + ")"; 4360 } 4361 // Initialize all "by ref" arguments. 4362 for (llvm::SmallVector<ValueDecl*,8>::iterator I = BlockByRefDecls.begin(), 4363 E = BlockByRefDecls.end(); I != E; ++I) { 4364 std::string Name = (*I)->getNameAsString(); 4365 if (firsTime) { 4366 Constructor += " : "; 4367 firsTime = false; 4368 } 4369 else 4370 Constructor += ", "; 4371 Constructor += Name + "(_" + Name + "->__forwarding)"; 4372 } 4373 4374 Constructor += " {\n"; 4375 if (GlobalVarDecl) 4376 Constructor += " impl.isa = &_NSConcreteGlobalBlock;\n"; 4377 else 4378 Constructor += " impl.isa = &_NSConcreteStackBlock;\n"; 4379 Constructor += " impl.Flags = flags;\n impl.FuncPtr = fp;\n"; 4380 4381 Constructor += " Desc = desc;\n"; 4382 } else { 4383 // Finish writing the constructor. 4384 Constructor += ", int flags=0) {\n"; 4385 if (GlobalVarDecl) 4386 Constructor += " impl.isa = &_NSConcreteGlobalBlock;\n"; 4387 else 4388 Constructor += " impl.isa = &_NSConcreteStackBlock;\n"; 4389 Constructor += " impl.Flags = flags;\n impl.FuncPtr = fp;\n"; 4390 Constructor += " Desc = desc;\n"; 4391 } 4392 Constructor += " "; 4393 Constructor += "}\n"; 4394 S += Constructor; 4395 S += "};\n"; 4396 return S; 4397} 4398 4399std::string RewriteObjC::SynthesizeBlockDescriptor(std::string DescTag, 4400 std::string ImplTag, int i, 4401 llvm::StringRef FunName, 4402 unsigned hasCopy) { 4403 std::string S = "\nstatic struct " + DescTag; 4404 4405 S += " {\n unsigned long reserved;\n"; 4406 S += " unsigned long Block_size;\n"; 4407 if (hasCopy) { 4408 S += " void (*copy)(struct "; 4409 S += ImplTag; S += "*, struct "; 4410 S += ImplTag; S += "*);\n"; 4411 4412 S += " void (*dispose)(struct "; 4413 S += ImplTag; S += "*);\n"; 4414 } 4415 S += "} "; 4416 4417 S += DescTag + "_DATA = { 0, sizeof(struct "; 4418 S += ImplTag + ")"; 4419 if (hasCopy) { 4420 S += ", __" + FunName.str() + "_block_copy_" + utostr(i); 4421 S += ", __" + FunName.str() + "_block_dispose_" + utostr(i); 4422 } 4423 S += "};\n"; 4424 return S; 4425} 4426 4427void RewriteObjC::SynthesizeBlockLiterals(SourceLocation FunLocStart, 4428 llvm::StringRef FunName) { 4429 // Insert declaration for the function in which block literal is used. 4430 if (CurFunctionDeclToDeclareForBlock && !Blocks.empty()) 4431 RewriteBlockLiteralFunctionDecl(CurFunctionDeclToDeclareForBlock); 4432 bool RewriteSC = (GlobalVarDecl && 4433 !Blocks.empty() && 4434 GlobalVarDecl->getStorageClass() == SC_Static && 4435 GlobalVarDecl->getType().getCVRQualifiers()); 4436 if (RewriteSC) { 4437 std::string SC(" void __"); 4438 SC += GlobalVarDecl->getNameAsString(); 4439 SC += "() {}"; 4440 InsertText(FunLocStart, SC); 4441 } 4442 4443 // Insert closures that were part of the function. 4444 for (unsigned i = 0, count=0; i < Blocks.size(); i++) { 4445 CollectBlockDeclRefInfo(Blocks[i]); 4446 // Need to copy-in the inner copied-in variables not actually used in this 4447 // block. 4448 for (int j = 0; j < InnerDeclRefsCount[i]; j++) { 4449 BlockDeclRefExpr *Exp = InnerDeclRefs[count++]; 4450 ValueDecl *VD = Exp->getDecl(); 4451 BlockDeclRefs.push_back(Exp); 4452 if (!Exp->isByRef() && !BlockByCopyDeclsPtrSet.count(VD)) { 4453 BlockByCopyDeclsPtrSet.insert(VD); 4454 BlockByCopyDecls.push_back(VD); 4455 } 4456 if (Exp->isByRef() && !BlockByRefDeclsPtrSet.count(VD)) { 4457 BlockByRefDeclsPtrSet.insert(VD); 4458 BlockByRefDecls.push_back(VD); 4459 } 4460 // imported objects in the inner blocks not used in the outer 4461 // blocks must be copied/disposed in the outer block as well. 4462 if (Exp->isByRef() || 4463 VD->getType()->isObjCObjectPointerType() || 4464 VD->getType()->isBlockPointerType()) 4465 ImportedBlockDecls.insert(VD); 4466 } 4467 4468 std::string ImplTag = "__" + FunName.str() + "_block_impl_" + utostr(i); 4469 std::string DescTag = "__" + FunName.str() + "_block_desc_" + utostr(i); 4470 4471 std::string CI = SynthesizeBlockImpl(Blocks[i], ImplTag, DescTag); 4472 4473 InsertText(FunLocStart, CI); 4474 4475 std::string CF = SynthesizeBlockFunc(Blocks[i], i, FunName, ImplTag); 4476 4477 InsertText(FunLocStart, CF); 4478 4479 if (ImportedBlockDecls.size()) { 4480 std::string HF = SynthesizeBlockHelperFuncs(Blocks[i], i, FunName, ImplTag); 4481 InsertText(FunLocStart, HF); 4482 } 4483 std::string BD = SynthesizeBlockDescriptor(DescTag, ImplTag, i, FunName, 4484 ImportedBlockDecls.size() > 0); 4485 InsertText(FunLocStart, BD); 4486 4487 BlockDeclRefs.clear(); 4488 BlockByRefDecls.clear(); 4489 BlockByRefDeclsPtrSet.clear(); 4490 BlockByCopyDecls.clear(); 4491 BlockByCopyDeclsPtrSet.clear(); 4492 ImportedBlockDecls.clear(); 4493 } 4494 if (RewriteSC) { 4495 // Must insert any 'const/volatile/static here. Since it has been 4496 // removed as result of rewriting of block literals. 4497 std::string SC; 4498 if (GlobalVarDecl->getStorageClass() == SC_Static) 4499 SC = "static "; 4500 if (GlobalVarDecl->getType().isConstQualified()) 4501 SC += "const "; 4502 if (GlobalVarDecl->getType().isVolatileQualified()) 4503 SC += "volatile "; 4504 if (GlobalVarDecl->getType().isRestrictQualified()) 4505 SC += "restrict "; 4506 InsertText(FunLocStart, SC); 4507 } 4508 4509 Blocks.clear(); 4510 InnerDeclRefsCount.clear(); 4511 InnerDeclRefs.clear(); 4512 RewrittenBlockExprs.clear(); 4513} 4514 4515void RewriteObjC::InsertBlockLiteralsWithinFunction(FunctionDecl *FD) { 4516 SourceLocation FunLocStart = FD->getTypeSpecStartLoc(); 4517 llvm::StringRef FuncName = FD->getName(); 4518 4519 SynthesizeBlockLiterals(FunLocStart, FuncName); 4520} 4521 4522static void BuildUniqueMethodName(std::string &Name, 4523 ObjCMethodDecl *MD) { 4524 ObjCInterfaceDecl *IFace = MD->getClassInterface(); 4525 Name = IFace->getName(); 4526 Name += "__" + MD->getSelector().getAsString(); 4527 // Convert colons to underscores. 4528 std::string::size_type loc = 0; 4529 while ((loc = Name.find(":", loc)) != std::string::npos) 4530 Name.replace(loc, 1, "_"); 4531} 4532 4533void RewriteObjC::InsertBlockLiteralsWithinMethod(ObjCMethodDecl *MD) { 4534 //fprintf(stderr,"In InsertBlockLiteralsWitinMethod\n"); 4535 //SourceLocation FunLocStart = MD->getLocStart(); 4536 SourceLocation FunLocStart = MD->getLocStart(); 4537 std::string FuncName; 4538 BuildUniqueMethodName(FuncName, MD); 4539 SynthesizeBlockLiterals(FunLocStart, FuncName); 4540} 4541 4542void RewriteObjC::GetBlockDeclRefExprs(Stmt *S) { 4543 for (Stmt::child_range CI = S->children(); CI; ++CI) 4544 if (*CI) { 4545 if (BlockExpr *CBE = dyn_cast<BlockExpr>(*CI)) 4546 GetBlockDeclRefExprs(CBE->getBody()); 4547 else 4548 GetBlockDeclRefExprs(*CI); 4549 } 4550 // Handle specific things. 4551 if (BlockDeclRefExpr *CDRE = dyn_cast<BlockDeclRefExpr>(S)) { 4552 // FIXME: Handle enums. 4553 if (!isa<FunctionDecl>(CDRE->getDecl())) 4554 BlockDeclRefs.push_back(CDRE); 4555 } 4556 else if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(S)) 4557 if (HasLocalVariableExternalStorage(DRE->getDecl())) { 4558 BlockDeclRefExpr *BDRE = 4559 new (Context)BlockDeclRefExpr(cast<VarDecl>(DRE->getDecl()), 4560 DRE->getType(), 4561 VK_LValue, DRE->getLocation(), false); 4562 BlockDeclRefs.push_back(BDRE); 4563 } 4564 4565 return; 4566} 4567 4568void RewriteObjC::GetInnerBlockDeclRefExprs(Stmt *S, 4569 llvm::SmallVector<BlockDeclRefExpr *, 8> &InnerBlockDeclRefs, 4570 llvm::SmallPtrSet<const DeclContext *, 8> &InnerContexts) { 4571 for (Stmt::child_range CI = S->children(); CI; ++CI) 4572 if (*CI) { 4573 if (BlockExpr *CBE = dyn_cast<BlockExpr>(*CI)) { 4574 InnerContexts.insert(cast<DeclContext>(CBE->getBlockDecl())); 4575 GetInnerBlockDeclRefExprs(CBE->getBody(), 4576 InnerBlockDeclRefs, 4577 InnerContexts); 4578 } 4579 else 4580 GetInnerBlockDeclRefExprs(*CI, 4581 InnerBlockDeclRefs, 4582 InnerContexts); 4583 4584 } 4585 // Handle specific things. 4586 if (BlockDeclRefExpr *CDRE = dyn_cast<BlockDeclRefExpr>(S)) { 4587 if (!isa<FunctionDecl>(CDRE->getDecl()) && 4588 !InnerContexts.count(CDRE->getDecl()->getDeclContext())) 4589 InnerBlockDeclRefs.push_back(CDRE); 4590 } 4591 else if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(S)) { 4592 if (VarDecl *Var = dyn_cast<VarDecl>(DRE->getDecl())) 4593 if (Var->isFunctionOrMethodVarDecl()) 4594 ImportedLocalExternalDecls.insert(Var); 4595 } 4596 4597 return; 4598} 4599 4600/// convertFunctionTypeOfBlocks - This routine converts a function type 4601/// whose result type may be a block pointer or whose argument type(s) 4602/// might be block pointers to an equivalent funtion type replacing 4603/// all block pointers to function pointers. 4604QualType RewriteObjC::convertFunctionTypeOfBlocks(const FunctionType *FT) { 4605 const FunctionProtoType *FTP = dyn_cast<FunctionProtoType>(FT); 4606 // FTP will be null for closures that don't take arguments. 4607 // Generate a funky cast. 4608 llvm::SmallVector<QualType, 8> ArgTypes; 4609 QualType Res = FT->getResultType(); 4610 bool HasBlockType = convertBlockPointerToFunctionPointer(Res); 4611 4612 if (FTP) { 4613 for (FunctionProtoType::arg_type_iterator I = FTP->arg_type_begin(), 4614 E = FTP->arg_type_end(); I && (I != E); ++I) { 4615 QualType t = *I; 4616 // Make sure we convert "t (^)(...)" to "t (*)(...)". 4617 if (convertBlockPointerToFunctionPointer(t)) 4618 HasBlockType = true; 4619 ArgTypes.push_back(t); 4620 } 4621 } 4622 QualType FuncType; 4623 // FIXME. Does this work if block takes no argument but has a return type 4624 // which is of block type? 4625 if (HasBlockType) 4626 FuncType = getSimpleFunctionType(Res, &ArgTypes[0], ArgTypes.size()); 4627 else FuncType = QualType(FT, 0); 4628 return FuncType; 4629} 4630 4631Stmt *RewriteObjC::SynthesizeBlockCall(CallExpr *Exp, const Expr *BlockExp) { 4632 // Navigate to relevant type information. 4633 const BlockPointerType *CPT = 0; 4634 4635 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(BlockExp)) { 4636 CPT = DRE->getType()->getAs<BlockPointerType>(); 4637 } else if (const BlockDeclRefExpr *CDRE = 4638 dyn_cast<BlockDeclRefExpr>(BlockExp)) { 4639 CPT = CDRE->getType()->getAs<BlockPointerType>(); 4640 } else if (const MemberExpr *MExpr = dyn_cast<MemberExpr>(BlockExp)) { 4641 CPT = MExpr->getType()->getAs<BlockPointerType>(); 4642 } 4643 else if (const ParenExpr *PRE = dyn_cast<ParenExpr>(BlockExp)) { 4644 return SynthesizeBlockCall(Exp, PRE->getSubExpr()); 4645 } 4646 else if (const ImplicitCastExpr *IEXPR = dyn_cast<ImplicitCastExpr>(BlockExp)) 4647 CPT = IEXPR->getType()->getAs<BlockPointerType>(); 4648 else if (const ConditionalOperator *CEXPR = 4649 dyn_cast<ConditionalOperator>(BlockExp)) { 4650 Expr *LHSExp = CEXPR->getLHS(); 4651 Stmt *LHSStmt = SynthesizeBlockCall(Exp, LHSExp); 4652 Expr *RHSExp = CEXPR->getRHS(); 4653 Stmt *RHSStmt = SynthesizeBlockCall(Exp, RHSExp); 4654 Expr *CONDExp = CEXPR->getCond(); 4655 ConditionalOperator *CondExpr = 4656 new (Context) ConditionalOperator(CONDExp, 4657 SourceLocation(), cast<Expr>(LHSStmt), 4658 SourceLocation(), cast<Expr>(RHSStmt), 4659 Exp->getType(), VK_RValue, OK_Ordinary); 4660 return CondExpr; 4661 } else if (const ObjCIvarRefExpr *IRE = dyn_cast<ObjCIvarRefExpr>(BlockExp)) { 4662 CPT = IRE->getType()->getAs<BlockPointerType>(); 4663 } else { 4664 assert(1 && "RewriteBlockClass: Bad type"); 4665 } 4666 assert(CPT && "RewriteBlockClass: Bad type"); 4667 const FunctionType *FT = CPT->getPointeeType()->getAs<FunctionType>(); 4668 assert(FT && "RewriteBlockClass: Bad type"); 4669 const FunctionProtoType *FTP = dyn_cast<FunctionProtoType>(FT); 4670 // FTP will be null for closures that don't take arguments. 4671 4672 RecordDecl *RD = RecordDecl::Create(*Context, TTK_Struct, TUDecl, 4673 SourceLocation(), SourceLocation(), 4674 &Context->Idents.get("__block_impl")); 4675 QualType PtrBlock = Context->getPointerType(Context->getTagDeclType(RD)); 4676 4677 // Generate a funky cast. 4678 llvm::SmallVector<QualType, 8> ArgTypes; 4679 4680 // Push the block argument type. 4681 ArgTypes.push_back(PtrBlock); 4682 if (FTP) { 4683 for (FunctionProtoType::arg_type_iterator I = FTP->arg_type_begin(), 4684 E = FTP->arg_type_end(); I && (I != E); ++I) { 4685 QualType t = *I; 4686 // Make sure we convert "t (^)(...)" to "t (*)(...)". 4687 if (!convertBlockPointerToFunctionPointer(t)) 4688 convertToUnqualifiedObjCType(t); 4689 ArgTypes.push_back(t); 4690 } 4691 } 4692 // Now do the pointer to function cast. 4693 QualType PtrToFuncCastType 4694 = getSimpleFunctionType(Exp->getType(), &ArgTypes[0], ArgTypes.size()); 4695 4696 PtrToFuncCastType = Context->getPointerType(PtrToFuncCastType); 4697 4698 CastExpr *BlkCast = NoTypeInfoCStyleCastExpr(Context, PtrBlock, 4699 CK_BitCast, 4700 const_cast<Expr*>(BlockExp)); 4701 // Don't forget the parens to enforce the proper binding. 4702 ParenExpr *PE = new (Context) ParenExpr(SourceLocation(), SourceLocation(), 4703 BlkCast); 4704 //PE->dump(); 4705 4706 FieldDecl *FD = FieldDecl::Create(*Context, 0, SourceLocation(), 4707 SourceLocation(), 4708 &Context->Idents.get("FuncPtr"), 4709 Context->VoidPtrTy, 0, 4710 /*BitWidth=*/0, /*Mutable=*/true); 4711 MemberExpr *ME = new (Context) MemberExpr(PE, true, FD, SourceLocation(), 4712 FD->getType(), VK_LValue, 4713 OK_Ordinary); 4714 4715 4716 CastExpr *FunkCast = NoTypeInfoCStyleCastExpr(Context, PtrToFuncCastType, 4717 CK_BitCast, ME); 4718 PE = new (Context) ParenExpr(SourceLocation(), SourceLocation(), FunkCast); 4719 4720 llvm::SmallVector<Expr*, 8> BlkExprs; 4721 // Add the implicit argument. 4722 BlkExprs.push_back(BlkCast); 4723 // Add the user arguments. 4724 for (CallExpr::arg_iterator I = Exp->arg_begin(), 4725 E = Exp->arg_end(); I != E; ++I) { 4726 BlkExprs.push_back(*I); 4727 } 4728 CallExpr *CE = new (Context) CallExpr(*Context, PE, &BlkExprs[0], 4729 BlkExprs.size(), 4730 Exp->getType(), VK_RValue, 4731 SourceLocation()); 4732 return CE; 4733} 4734 4735// We need to return the rewritten expression to handle cases where the 4736// BlockDeclRefExpr is embedded in another expression being rewritten. 4737// For example: 4738// 4739// int main() { 4740// __block Foo *f; 4741// __block int i; 4742// 4743// void (^myblock)() = ^() { 4744// [f test]; // f is a BlockDeclRefExpr embedded in a message (which is being rewritten). 4745// i = 77; 4746// }; 4747//} 4748Stmt *RewriteObjC::RewriteBlockDeclRefExpr(Expr *DeclRefExp) { 4749 // Rewrite the byref variable into BYREFVAR->__forwarding->BYREFVAR 4750 // for each DeclRefExp where BYREFVAR is name of the variable. 4751 ValueDecl *VD; 4752 bool isArrow = true; 4753 if (BlockDeclRefExpr *BDRE = dyn_cast<BlockDeclRefExpr>(DeclRefExp)) 4754 VD = BDRE->getDecl(); 4755 else { 4756 VD = cast<DeclRefExpr>(DeclRefExp)->getDecl(); 4757 isArrow = false; 4758 } 4759 4760 FieldDecl *FD = FieldDecl::Create(*Context, 0, SourceLocation(), 4761 SourceLocation(), 4762 &Context->Idents.get("__forwarding"), 4763 Context->VoidPtrTy, 0, 4764 /*BitWidth=*/0, /*Mutable=*/true); 4765 MemberExpr *ME = new (Context) MemberExpr(DeclRefExp, isArrow, 4766 FD, SourceLocation(), 4767 FD->getType(), VK_LValue, 4768 OK_Ordinary); 4769 4770 llvm::StringRef Name = VD->getName(); 4771 FD = FieldDecl::Create(*Context, 0, SourceLocation(), SourceLocation(), 4772 &Context->Idents.get(Name), 4773 Context->VoidPtrTy, 0, 4774 /*BitWidth=*/0, /*Mutable=*/true); 4775 ME = new (Context) MemberExpr(ME, true, FD, SourceLocation(), 4776 DeclRefExp->getType(), VK_LValue, OK_Ordinary); 4777 4778 4779 4780 // Need parens to enforce precedence. 4781 ParenExpr *PE = new (Context) ParenExpr(DeclRefExp->getExprLoc(), 4782 DeclRefExp->getExprLoc(), 4783 ME); 4784 ReplaceStmt(DeclRefExp, PE); 4785 return PE; 4786} 4787 4788// Rewrites the imported local variable V with external storage 4789// (static, extern, etc.) as *V 4790// 4791Stmt *RewriteObjC::RewriteLocalVariableExternalStorage(DeclRefExpr *DRE) { 4792 ValueDecl *VD = DRE->getDecl(); 4793 if (VarDecl *Var = dyn_cast<VarDecl>(VD)) 4794 if (!ImportedLocalExternalDecls.count(Var)) 4795 return DRE; 4796 Expr *Exp = new (Context) UnaryOperator(DRE, UO_Deref, DRE->getType(), 4797 VK_LValue, OK_Ordinary, 4798 DRE->getLocation()); 4799 // Need parens to enforce precedence. 4800 ParenExpr *PE = new (Context) ParenExpr(SourceLocation(), SourceLocation(), 4801 Exp); 4802 ReplaceStmt(DRE, PE); 4803 return PE; 4804} 4805 4806void RewriteObjC::RewriteCastExpr(CStyleCastExpr *CE) { 4807 SourceLocation LocStart = CE->getLParenLoc(); 4808 SourceLocation LocEnd = CE->getRParenLoc(); 4809 4810 // Need to avoid trying to rewrite synthesized casts. 4811 if (LocStart.isInvalid()) 4812 return; 4813 // Need to avoid trying to rewrite casts contained in macros. 4814 if (!Rewriter::isRewritable(LocStart) || !Rewriter::isRewritable(LocEnd)) 4815 return; 4816 4817 const char *startBuf = SM->getCharacterData(LocStart); 4818 const char *endBuf = SM->getCharacterData(LocEnd); 4819 QualType QT = CE->getType(); 4820 const Type* TypePtr = QT->getAs<Type>(); 4821 if (isa<TypeOfExprType>(TypePtr)) { 4822 const TypeOfExprType *TypeOfExprTypePtr = cast<TypeOfExprType>(TypePtr); 4823 QT = TypeOfExprTypePtr->getUnderlyingExpr()->getType(); 4824 std::string TypeAsString = "("; 4825 RewriteBlockPointerType(TypeAsString, QT); 4826 TypeAsString += ")"; 4827 ReplaceText(LocStart, endBuf-startBuf+1, TypeAsString); 4828 return; 4829 } 4830 // advance the location to startArgList. 4831 const char *argPtr = startBuf; 4832 4833 while (*argPtr++ && (argPtr < endBuf)) { 4834 switch (*argPtr) { 4835 case '^': 4836 // Replace the '^' with '*'. 4837 LocStart = LocStart.getFileLocWithOffset(argPtr-startBuf); 4838 ReplaceText(LocStart, 1, "*"); 4839 break; 4840 } 4841 } 4842 return; 4843} 4844 4845void RewriteObjC::RewriteBlockPointerFunctionArgs(FunctionDecl *FD) { 4846 SourceLocation DeclLoc = FD->getLocation(); 4847 unsigned parenCount = 0; 4848 4849 // We have 1 or more arguments that have closure pointers. 4850 const char *startBuf = SM->getCharacterData(DeclLoc); 4851 const char *startArgList = strchr(startBuf, '('); 4852 4853 assert((*startArgList == '(') && "Rewriter fuzzy parser confused"); 4854 4855 parenCount++; 4856 // advance the location to startArgList. 4857 DeclLoc = DeclLoc.getFileLocWithOffset(startArgList-startBuf); 4858 assert((DeclLoc.isValid()) && "Invalid DeclLoc"); 4859 4860 const char *argPtr = startArgList; 4861 4862 while (*argPtr++ && parenCount) { 4863 switch (*argPtr) { 4864 case '^': 4865 // Replace the '^' with '*'. 4866 DeclLoc = DeclLoc.getFileLocWithOffset(argPtr-startArgList); 4867 ReplaceText(DeclLoc, 1, "*"); 4868 break; 4869 case '(': 4870 parenCount++; 4871 break; 4872 case ')': 4873 parenCount--; 4874 break; 4875 } 4876 } 4877 return; 4878} 4879 4880bool RewriteObjC::PointerTypeTakesAnyBlockArguments(QualType QT) { 4881 const FunctionProtoType *FTP; 4882 const PointerType *PT = QT->getAs<PointerType>(); 4883 if (PT) { 4884 FTP = PT->getPointeeType()->getAs<FunctionProtoType>(); 4885 } else { 4886 const BlockPointerType *BPT = QT->getAs<BlockPointerType>(); 4887 assert(BPT && "BlockPointerTypeTakeAnyBlockArguments(): not a block pointer type"); 4888 FTP = BPT->getPointeeType()->getAs<FunctionProtoType>(); 4889 } 4890 if (FTP) { 4891 for (FunctionProtoType::arg_type_iterator I = FTP->arg_type_begin(), 4892 E = FTP->arg_type_end(); I != E; ++I) 4893 if (isTopLevelBlockPointerType(*I)) 4894 return true; 4895 } 4896 return false; 4897} 4898 4899bool RewriteObjC::PointerTypeTakesAnyObjCQualifiedType(QualType QT) { 4900 const FunctionProtoType *FTP; 4901 const PointerType *PT = QT->getAs<PointerType>(); 4902 if (PT) { 4903 FTP = PT->getPointeeType()->getAs<FunctionProtoType>(); 4904 } else { 4905 const BlockPointerType *BPT = QT->getAs<BlockPointerType>(); 4906 assert(BPT && "BlockPointerTypeTakeAnyBlockArguments(): not a block pointer type"); 4907 FTP = BPT->getPointeeType()->getAs<FunctionProtoType>(); 4908 } 4909 if (FTP) { 4910 for (FunctionProtoType::arg_type_iterator I = FTP->arg_type_begin(), 4911 E = FTP->arg_type_end(); I != E; ++I) { 4912 if ((*I)->isObjCQualifiedIdType()) 4913 return true; 4914 if ((*I)->isObjCObjectPointerType() && 4915 (*I)->getPointeeType()->isObjCQualifiedInterfaceType()) 4916 return true; 4917 } 4918 4919 } 4920 return false; 4921} 4922 4923void RewriteObjC::GetExtentOfArgList(const char *Name, const char *&LParen, 4924 const char *&RParen) { 4925 const char *argPtr = strchr(Name, '('); 4926 assert((*argPtr == '(') && "Rewriter fuzzy parser confused"); 4927 4928 LParen = argPtr; // output the start. 4929 argPtr++; // skip past the left paren. 4930 unsigned parenCount = 1; 4931 4932 while (*argPtr && parenCount) { 4933 switch (*argPtr) { 4934 case '(': parenCount++; break; 4935 case ')': parenCount--; break; 4936 default: break; 4937 } 4938 if (parenCount) argPtr++; 4939 } 4940 assert((*argPtr == ')') && "Rewriter fuzzy parser confused"); 4941 RParen = argPtr; // output the end 4942} 4943 4944void RewriteObjC::RewriteBlockPointerDecl(NamedDecl *ND) { 4945 if (FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) { 4946 RewriteBlockPointerFunctionArgs(FD); 4947 return; 4948 } 4949 // Handle Variables and Typedefs. 4950 SourceLocation DeclLoc = ND->getLocation(); 4951 QualType DeclT; 4952 if (VarDecl *VD = dyn_cast<VarDecl>(ND)) 4953 DeclT = VD->getType(); 4954 else if (TypedefDecl *TDD = dyn_cast<TypedefDecl>(ND)) 4955 DeclT = TDD->getUnderlyingType(); 4956 else if (FieldDecl *FD = dyn_cast<FieldDecl>(ND)) 4957 DeclT = FD->getType(); 4958 else 4959 assert(0 && "RewriteBlockPointerDecl(): Decl type not yet handled"); 4960 4961 const char *startBuf = SM->getCharacterData(DeclLoc); 4962 const char *endBuf = startBuf; 4963 // scan backward (from the decl location) for the end of the previous decl. 4964 while (*startBuf != '^' && *startBuf != ';' && startBuf != MainFileStart) 4965 startBuf--; 4966 SourceLocation Start = DeclLoc.getFileLocWithOffset(startBuf-endBuf); 4967 std::string buf; 4968 unsigned OrigLength=0; 4969 // *startBuf != '^' if we are dealing with a pointer to function that 4970 // may take block argument types (which will be handled below). 4971 if (*startBuf == '^') { 4972 // Replace the '^' with '*', computing a negative offset. 4973 buf = '*'; 4974 startBuf++; 4975 OrigLength++; 4976 } 4977 while (*startBuf != ')') { 4978 buf += *startBuf; 4979 startBuf++; 4980 OrigLength++; 4981 } 4982 buf += ')'; 4983 OrigLength++; 4984 4985 if (PointerTypeTakesAnyBlockArguments(DeclT) || 4986 PointerTypeTakesAnyObjCQualifiedType(DeclT)) { 4987 // Replace the '^' with '*' for arguments. 4988 // Replace id<P> with id/*<>*/ 4989 DeclLoc = ND->getLocation(); 4990 startBuf = SM->getCharacterData(DeclLoc); 4991 const char *argListBegin, *argListEnd; 4992 GetExtentOfArgList(startBuf, argListBegin, argListEnd); 4993 while (argListBegin < argListEnd) { 4994 if (*argListBegin == '^') 4995 buf += '*'; 4996 else if (*argListBegin == '<') { 4997 buf += "/*"; 4998 buf += *argListBegin++; 4999 OrigLength++;; 5000 while (*argListBegin != '>') { 5001 buf += *argListBegin++; 5002 OrigLength++; 5003 } 5004 buf += *argListBegin; 5005 buf += "*/"; 5006 } 5007 else 5008 buf += *argListBegin; 5009 argListBegin++; 5010 OrigLength++; 5011 } 5012 buf += ')'; 5013 OrigLength++; 5014 } 5015 ReplaceText(Start, OrigLength, buf); 5016 5017 return; 5018} 5019 5020 5021/// SynthesizeByrefCopyDestroyHelper - This routine synthesizes: 5022/// void __Block_byref_id_object_copy(struct Block_byref_id_object *dst, 5023/// struct Block_byref_id_object *src) { 5024/// _Block_object_assign (&_dest->object, _src->object, 5025/// BLOCK_BYREF_CALLER | BLOCK_FIELD_IS_OBJECT 5026/// [|BLOCK_FIELD_IS_WEAK]) // object 5027/// _Block_object_assign(&_dest->object, _src->object, 5028/// BLOCK_BYREF_CALLER | BLOCK_FIELD_IS_BLOCK 5029/// [|BLOCK_FIELD_IS_WEAK]) // block 5030/// } 5031/// And: 5032/// void __Block_byref_id_object_dispose(struct Block_byref_id_object *_src) { 5033/// _Block_object_dispose(_src->object, 5034/// BLOCK_BYREF_CALLER | BLOCK_FIELD_IS_OBJECT 5035/// [|BLOCK_FIELD_IS_WEAK]) // object 5036/// _Block_object_dispose(_src->object, 5037/// BLOCK_BYREF_CALLER | BLOCK_FIELD_IS_BLOCK 5038/// [|BLOCK_FIELD_IS_WEAK]) // block 5039/// } 5040 5041std::string RewriteObjC::SynthesizeByrefCopyDestroyHelper(VarDecl *VD, 5042 int flag) { 5043 std::string S; 5044 if (CopyDestroyCache.count(flag)) 5045 return S; 5046 CopyDestroyCache.insert(flag); 5047 S = "static void __Block_byref_id_object_copy_"; 5048 S += utostr(flag); 5049 S += "(void *dst, void *src) {\n"; 5050 5051 // offset into the object pointer is computed as: 5052 // void * + void* + int + int + void* + void * 5053 unsigned IntSize = 5054 static_cast<unsigned>(Context->getTypeSize(Context->IntTy)); 5055 unsigned VoidPtrSize = 5056 static_cast<unsigned>(Context->getTypeSize(Context->VoidPtrTy)); 5057 5058 unsigned offset = (VoidPtrSize*4 + IntSize + IntSize)/8; 5059 S += " _Block_object_assign((char*)dst + "; 5060 S += utostr(offset); 5061 S += ", *(void * *) ((char*)src + "; 5062 S += utostr(offset); 5063 S += "), "; 5064 S += utostr(flag); 5065 S += ");\n}\n"; 5066 5067 S += "static void __Block_byref_id_object_dispose_"; 5068 S += utostr(flag); 5069 S += "(void *src) {\n"; 5070 S += " _Block_object_dispose(*(void * *) ((char*)src + "; 5071 S += utostr(offset); 5072 S += "), "; 5073 S += utostr(flag); 5074 S += ");\n}\n"; 5075 return S; 5076} 5077 5078/// RewriteByRefVar - For each __block typex ND variable this routine transforms 5079/// the declaration into: 5080/// struct __Block_byref_ND { 5081/// void *__isa; // NULL for everything except __weak pointers 5082/// struct __Block_byref_ND *__forwarding; 5083/// int32_t __flags; 5084/// int32_t __size; 5085/// void *__Block_byref_id_object_copy; // If variable is __block ObjC object 5086/// void *__Block_byref_id_object_dispose; // If variable is __block ObjC object 5087/// typex ND; 5088/// }; 5089/// 5090/// It then replaces declaration of ND variable with: 5091/// struct __Block_byref_ND ND = {__isa=0B, __forwarding=&ND, __flags=some_flag, 5092/// __size=sizeof(struct __Block_byref_ND), 5093/// ND=initializer-if-any}; 5094/// 5095/// 5096void RewriteObjC::RewriteByRefVar(VarDecl *ND) { 5097 // Insert declaration for the function in which block literal is 5098 // used. 5099 if (CurFunctionDeclToDeclareForBlock) 5100 RewriteBlockLiteralFunctionDecl(CurFunctionDeclToDeclareForBlock); 5101 int flag = 0; 5102 int isa = 0; 5103 SourceLocation DeclLoc = ND->getTypeSpecStartLoc(); 5104 if (DeclLoc.isInvalid()) 5105 // If type location is missing, it is because of missing type (a warning). 5106 // Use variable's location which is good for this case. 5107 DeclLoc = ND->getLocation(); 5108 const char *startBuf = SM->getCharacterData(DeclLoc); 5109 SourceLocation X = ND->getLocEnd(); 5110 X = SM->getInstantiationLoc(X); 5111 const char *endBuf = SM->getCharacterData(X); 5112 std::string Name(ND->getNameAsString()); 5113 std::string ByrefType; 5114 RewriteByRefString(ByrefType, Name, ND, true); 5115 ByrefType += " {\n"; 5116 ByrefType += " void *__isa;\n"; 5117 RewriteByRefString(ByrefType, Name, ND); 5118 ByrefType += " *__forwarding;\n"; 5119 ByrefType += " int __flags;\n"; 5120 ByrefType += " int __size;\n"; 5121 // Add void *__Block_byref_id_object_copy; 5122 // void *__Block_byref_id_object_dispose; if needed. 5123 QualType Ty = ND->getType(); 5124 bool HasCopyAndDispose = Context->BlockRequiresCopying(Ty); 5125 if (HasCopyAndDispose) { 5126 ByrefType += " void (*__Block_byref_id_object_copy)(void*, void*);\n"; 5127 ByrefType += " void (*__Block_byref_id_object_dispose)(void*);\n"; 5128 } 5129 5130 QualType T = Ty; 5131 (void)convertBlockPointerToFunctionPointer(T); 5132 T.getAsStringInternal(Name, Context->PrintingPolicy); 5133 5134 ByrefType += " " + Name + ";\n"; 5135 ByrefType += "};\n"; 5136 // Insert this type in global scope. It is needed by helper function. 5137 SourceLocation FunLocStart; 5138 if (CurFunctionDef) 5139 FunLocStart = CurFunctionDef->getTypeSpecStartLoc(); 5140 else { 5141 assert(CurMethodDef && "RewriteByRefVar - CurMethodDef is null"); 5142 FunLocStart = CurMethodDef->getLocStart(); 5143 } 5144 InsertText(FunLocStart, ByrefType); 5145 if (Ty.isObjCGCWeak()) { 5146 flag |= BLOCK_FIELD_IS_WEAK; 5147 isa = 1; 5148 } 5149 5150 if (HasCopyAndDispose) { 5151 flag = BLOCK_BYREF_CALLER; 5152 QualType Ty = ND->getType(); 5153 // FIXME. Handle __weak variable (BLOCK_FIELD_IS_WEAK) as well. 5154 if (Ty->isBlockPointerType()) 5155 flag |= BLOCK_FIELD_IS_BLOCK; 5156 else 5157 flag |= BLOCK_FIELD_IS_OBJECT; 5158 std::string HF = SynthesizeByrefCopyDestroyHelper(ND, flag); 5159 if (!HF.empty()) 5160 InsertText(FunLocStart, HF); 5161 } 5162 5163 // struct __Block_byref_ND ND = 5164 // {0, &ND, some_flag, __size=sizeof(struct __Block_byref_ND), 5165 // initializer-if-any}; 5166 bool hasInit = (ND->getInit() != 0); 5167 unsigned flags = 0; 5168 if (HasCopyAndDispose) 5169 flags |= BLOCK_HAS_COPY_DISPOSE; 5170 Name = ND->getNameAsString(); 5171 ByrefType.clear(); 5172 RewriteByRefString(ByrefType, Name, ND); 5173 std::string ForwardingCastType("("); 5174 ForwardingCastType += ByrefType + " *)"; 5175 if (!hasInit) { 5176 ByrefType += " " + Name + " = {(void*)"; 5177 ByrefType += utostr(isa); 5178 ByrefType += "," + ForwardingCastType + "&" + Name + ", "; 5179 ByrefType += utostr(flags); 5180 ByrefType += ", "; 5181 ByrefType += "sizeof("; 5182 RewriteByRefString(ByrefType, Name, ND); 5183 ByrefType += ")"; 5184 if (HasCopyAndDispose) { 5185 ByrefType += ", __Block_byref_id_object_copy_"; 5186 ByrefType += utostr(flag); 5187 ByrefType += ", __Block_byref_id_object_dispose_"; 5188 ByrefType += utostr(flag); 5189 } 5190 ByrefType += "};\n"; 5191 unsigned nameSize = Name.size(); 5192 // for block or function pointer declaration. Name is aleady 5193 // part of the declaration. 5194 if (Ty->isBlockPointerType() || Ty->isFunctionPointerType()) 5195 nameSize = 1; 5196 ReplaceText(DeclLoc, endBuf-startBuf+nameSize, ByrefType); 5197 } 5198 else { 5199 SourceLocation startLoc; 5200 Expr *E = ND->getInit(); 5201 if (const CStyleCastExpr *ECE = dyn_cast<CStyleCastExpr>(E)) 5202 startLoc = ECE->getLParenLoc(); 5203 else 5204 startLoc = E->getLocStart(); 5205 startLoc = SM->getInstantiationLoc(startLoc); 5206 endBuf = SM->getCharacterData(startLoc); 5207 ByrefType += " " + Name; 5208 ByrefType += " = {(void*)"; 5209 ByrefType += utostr(isa); 5210 ByrefType += "," + ForwardingCastType + "&" + Name + ", "; 5211 ByrefType += utostr(flags); 5212 ByrefType += ", "; 5213 ByrefType += "sizeof("; 5214 RewriteByRefString(ByrefType, Name, ND); 5215 ByrefType += "), "; 5216 if (HasCopyAndDispose) { 5217 ByrefType += "__Block_byref_id_object_copy_"; 5218 ByrefType += utostr(flag); 5219 ByrefType += ", __Block_byref_id_object_dispose_"; 5220 ByrefType += utostr(flag); 5221 ByrefType += ", "; 5222 } 5223 ReplaceText(DeclLoc, endBuf-startBuf, ByrefType); 5224 5225 // Complete the newly synthesized compound expression by inserting a right 5226 // curly brace before the end of the declaration. 5227 // FIXME: This approach avoids rewriting the initializer expression. It 5228 // also assumes there is only one declarator. For example, the following 5229 // isn't currently supported by this routine (in general): 5230 // 5231 // double __block BYREFVAR = 1.34, BYREFVAR2 = 1.37; 5232 // 5233 const char *startInitializerBuf = SM->getCharacterData(startLoc); 5234 const char *semiBuf = strchr(startInitializerBuf, ';'); 5235 assert((*semiBuf == ';') && "RewriteByRefVar: can't find ';'"); 5236 SourceLocation semiLoc = 5237 startLoc.getFileLocWithOffset(semiBuf-startInitializerBuf); 5238 5239 InsertText(semiLoc, "}"); 5240 } 5241 return; 5242} 5243 5244void RewriteObjC::CollectBlockDeclRefInfo(BlockExpr *Exp) { 5245 // Add initializers for any closure decl refs. 5246 GetBlockDeclRefExprs(Exp->getBody()); 5247 if (BlockDeclRefs.size()) { 5248 // Unique all "by copy" declarations. 5249 for (unsigned i = 0; i < BlockDeclRefs.size(); i++) 5250 if (!BlockDeclRefs[i]->isByRef()) { 5251 if (!BlockByCopyDeclsPtrSet.count(BlockDeclRefs[i]->getDecl())) { 5252 BlockByCopyDeclsPtrSet.insert(BlockDeclRefs[i]->getDecl()); 5253 BlockByCopyDecls.push_back(BlockDeclRefs[i]->getDecl()); 5254 } 5255 } 5256 // Unique all "by ref" declarations. 5257 for (unsigned i = 0; i < BlockDeclRefs.size(); i++) 5258 if (BlockDeclRefs[i]->isByRef()) { 5259 if (!BlockByRefDeclsPtrSet.count(BlockDeclRefs[i]->getDecl())) { 5260 BlockByRefDeclsPtrSet.insert(BlockDeclRefs[i]->getDecl()); 5261 BlockByRefDecls.push_back(BlockDeclRefs[i]->getDecl()); 5262 } 5263 } 5264 // Find any imported blocks...they will need special attention. 5265 for (unsigned i = 0; i < BlockDeclRefs.size(); i++) 5266 if (BlockDeclRefs[i]->isByRef() || 5267 BlockDeclRefs[i]->getType()->isObjCObjectPointerType() || 5268 BlockDeclRefs[i]->getType()->isBlockPointerType()) 5269 ImportedBlockDecls.insert(BlockDeclRefs[i]->getDecl()); 5270 } 5271} 5272 5273FunctionDecl *RewriteObjC::SynthBlockInitFunctionDecl(llvm::StringRef name) { 5274 IdentifierInfo *ID = &Context->Idents.get(name); 5275 QualType FType = Context->getFunctionNoProtoType(Context->VoidPtrTy); 5276 return FunctionDecl::Create(*Context, TUDecl, SourceLocation(), 5277 SourceLocation(), ID, FType, 0, SC_Extern, 5278 SC_None, false, false); 5279} 5280 5281Stmt *RewriteObjC::SynthBlockInitExpr(BlockExpr *Exp, 5282 const llvm::SmallVector<BlockDeclRefExpr *, 8> &InnerBlockDeclRefs) { 5283 const BlockDecl *block = Exp->getBlockDecl(); 5284 Blocks.push_back(Exp); 5285 5286 CollectBlockDeclRefInfo(Exp); 5287 5288 // Add inner imported variables now used in current block. 5289 int countOfInnerDecls = 0; 5290 if (!InnerBlockDeclRefs.empty()) { 5291 for (unsigned i = 0; i < InnerBlockDeclRefs.size(); i++) { 5292 BlockDeclRefExpr *Exp = InnerBlockDeclRefs[i]; 5293 ValueDecl *VD = Exp->getDecl(); 5294 if (!Exp->isByRef() && !BlockByCopyDeclsPtrSet.count(VD)) { 5295 // We need to save the copied-in variables in nested 5296 // blocks because it is needed at the end for some of the API generations. 5297 // See SynthesizeBlockLiterals routine. 5298 InnerDeclRefs.push_back(Exp); countOfInnerDecls++; 5299 BlockDeclRefs.push_back(Exp); 5300 BlockByCopyDeclsPtrSet.insert(VD); 5301 BlockByCopyDecls.push_back(VD); 5302 } 5303 if (Exp->isByRef() && !BlockByRefDeclsPtrSet.count(VD)) { 5304 InnerDeclRefs.push_back(Exp); countOfInnerDecls++; 5305 BlockDeclRefs.push_back(Exp); 5306 BlockByRefDeclsPtrSet.insert(VD); 5307 BlockByRefDecls.push_back(VD); 5308 } 5309 } 5310 // Find any imported blocks...they will need special attention. 5311 for (unsigned i = 0; i < InnerBlockDeclRefs.size(); i++) 5312 if (InnerBlockDeclRefs[i]->isByRef() || 5313 InnerBlockDeclRefs[i]->getType()->isObjCObjectPointerType() || 5314 InnerBlockDeclRefs[i]->getType()->isBlockPointerType()) 5315 ImportedBlockDecls.insert(InnerBlockDeclRefs[i]->getDecl()); 5316 } 5317 InnerDeclRefsCount.push_back(countOfInnerDecls); 5318 5319 std::string FuncName; 5320 5321 if (CurFunctionDef) 5322 FuncName = CurFunctionDef->getNameAsString(); 5323 else if (CurMethodDef) 5324 BuildUniqueMethodName(FuncName, CurMethodDef); 5325 else if (GlobalVarDecl) 5326 FuncName = std::string(GlobalVarDecl->getNameAsString()); 5327 5328 std::string BlockNumber = utostr(Blocks.size()-1); 5329 5330 std::string Tag = "__" + FuncName + "_block_impl_" + BlockNumber; 5331 std::string Func = "__" + FuncName + "_block_func_" + BlockNumber; 5332 5333 // Get a pointer to the function type so we can cast appropriately. 5334 QualType BFT = convertFunctionTypeOfBlocks(Exp->getFunctionType()); 5335 QualType FType = Context->getPointerType(BFT); 5336 5337 FunctionDecl *FD; 5338 Expr *NewRep; 5339 5340 // Simulate a contructor call... 5341 FD = SynthBlockInitFunctionDecl(Tag); 5342 DeclRefExpr *DRE = new (Context) DeclRefExpr(FD, FType, VK_RValue, 5343 SourceLocation()); 5344 5345 llvm::SmallVector<Expr*, 4> InitExprs; 5346 5347 // Initialize the block function. 5348 FD = SynthBlockInitFunctionDecl(Func); 5349 DeclRefExpr *Arg = new (Context) DeclRefExpr(FD, FD->getType(), VK_LValue, 5350 SourceLocation()); 5351 CastExpr *castExpr = NoTypeInfoCStyleCastExpr(Context, Context->VoidPtrTy, 5352 CK_BitCast, Arg); 5353 InitExprs.push_back(castExpr); 5354 5355 // Initialize the block descriptor. 5356 std::string DescData = "__" + FuncName + "_block_desc_" + BlockNumber + "_DATA"; 5357 5358 VarDecl *NewVD = VarDecl::Create(*Context, TUDecl, 5359 SourceLocation(), SourceLocation(), 5360 &Context->Idents.get(DescData.c_str()), 5361 Context->VoidPtrTy, 0, 5362 SC_Static, SC_None); 5363 UnaryOperator *DescRefExpr = 5364 new (Context) UnaryOperator(new (Context) DeclRefExpr(NewVD, 5365 Context->VoidPtrTy, 5366 VK_LValue, 5367 SourceLocation()), 5368 UO_AddrOf, 5369 Context->getPointerType(Context->VoidPtrTy), 5370 VK_RValue, OK_Ordinary, 5371 SourceLocation()); 5372 InitExprs.push_back(DescRefExpr); 5373 5374 // Add initializers for any closure decl refs. 5375 if (BlockDeclRefs.size()) { 5376 Expr *Exp; 5377 // Output all "by copy" declarations. 5378 for (llvm::SmallVector<ValueDecl*,8>::iterator I = BlockByCopyDecls.begin(), 5379 E = BlockByCopyDecls.end(); I != E; ++I) { 5380 if (isObjCType((*I)->getType())) { 5381 // FIXME: Conform to ABI ([[obj retain] autorelease]). 5382 FD = SynthBlockInitFunctionDecl((*I)->getName()); 5383 Exp = new (Context) DeclRefExpr(FD, FD->getType(), VK_LValue, 5384 SourceLocation()); 5385 if (HasLocalVariableExternalStorage(*I)) { 5386 QualType QT = (*I)->getType(); 5387 QT = Context->getPointerType(QT); 5388 Exp = new (Context) UnaryOperator(Exp, UO_AddrOf, QT, VK_RValue, 5389 OK_Ordinary, SourceLocation()); 5390 } 5391 } else if (isTopLevelBlockPointerType((*I)->getType())) { 5392 FD = SynthBlockInitFunctionDecl((*I)->getName()); 5393 Arg = new (Context) DeclRefExpr(FD, FD->getType(), VK_LValue, 5394 SourceLocation()); 5395 Exp = NoTypeInfoCStyleCastExpr(Context, Context->VoidPtrTy, 5396 CK_BitCast, Arg); 5397 } else { 5398 FD = SynthBlockInitFunctionDecl((*I)->getName()); 5399 Exp = new (Context) DeclRefExpr(FD, FD->getType(), VK_LValue, 5400 SourceLocation()); 5401 if (HasLocalVariableExternalStorage(*I)) { 5402 QualType QT = (*I)->getType(); 5403 QT = Context->getPointerType(QT); 5404 Exp = new (Context) UnaryOperator(Exp, UO_AddrOf, QT, VK_RValue, 5405 OK_Ordinary, SourceLocation()); 5406 } 5407 5408 } 5409 InitExprs.push_back(Exp); 5410 } 5411 // Output all "by ref" declarations. 5412 for (llvm::SmallVector<ValueDecl*,8>::iterator I = BlockByRefDecls.begin(), 5413 E = BlockByRefDecls.end(); I != E; ++I) { 5414 ValueDecl *ND = (*I); 5415 std::string Name(ND->getNameAsString()); 5416 std::string RecName; 5417 RewriteByRefString(RecName, Name, ND, true); 5418 IdentifierInfo *II = &Context->Idents.get(RecName.c_str() 5419 + sizeof("struct")); 5420 RecordDecl *RD = RecordDecl::Create(*Context, TTK_Struct, TUDecl, 5421 SourceLocation(), SourceLocation(), 5422 II); 5423 assert(RD && "SynthBlockInitExpr(): Can't find RecordDecl"); 5424 QualType castT = Context->getPointerType(Context->getTagDeclType(RD)); 5425 5426 FD = SynthBlockInitFunctionDecl((*I)->getName()); 5427 Exp = new (Context) DeclRefExpr(FD, FD->getType(), VK_LValue, 5428 SourceLocation()); 5429 bool isNestedCapturedVar = false; 5430 if (block) 5431 for (BlockDecl::capture_const_iterator ci = block->capture_begin(), 5432 ce = block->capture_end(); ci != ce; ++ci) { 5433 const VarDecl *variable = ci->getVariable(); 5434 if (variable == ND && ci->isNested()) { 5435 assert (ci->isByRef() && 5436 "SynthBlockInitExpr - captured block variable is not byref"); 5437 isNestedCapturedVar = true; 5438 break; 5439 } 5440 } 5441 // captured nested byref variable has its address passed. Do not take 5442 // its address again. 5443 if (!isNestedCapturedVar) 5444 Exp = new (Context) UnaryOperator(Exp, UO_AddrOf, 5445 Context->getPointerType(Exp->getType()), 5446 VK_RValue, OK_Ordinary, SourceLocation()); 5447 Exp = NoTypeInfoCStyleCastExpr(Context, castT, CK_BitCast, Exp); 5448 InitExprs.push_back(Exp); 5449 } 5450 } 5451 if (ImportedBlockDecls.size()) { 5452 // generate BLOCK_HAS_COPY_DISPOSE(have helper funcs) | BLOCK_HAS_DESCRIPTOR 5453 int flag = (BLOCK_HAS_COPY_DISPOSE | BLOCK_HAS_DESCRIPTOR); 5454 unsigned IntSize = 5455 static_cast<unsigned>(Context->getTypeSize(Context->IntTy)); 5456 Expr *FlagExp = IntegerLiteral::Create(*Context, llvm::APInt(IntSize, flag), 5457 Context->IntTy, SourceLocation()); 5458 InitExprs.push_back(FlagExp); 5459 } 5460 NewRep = new (Context) CallExpr(*Context, DRE, &InitExprs[0], InitExprs.size(), 5461 FType, VK_LValue, SourceLocation()); 5462 NewRep = new (Context) UnaryOperator(NewRep, UO_AddrOf, 5463 Context->getPointerType(NewRep->getType()), 5464 VK_RValue, OK_Ordinary, SourceLocation()); 5465 NewRep = NoTypeInfoCStyleCastExpr(Context, FType, CK_BitCast, 5466 NewRep); 5467 BlockDeclRefs.clear(); 5468 BlockByRefDecls.clear(); 5469 BlockByRefDeclsPtrSet.clear(); 5470 BlockByCopyDecls.clear(); 5471 BlockByCopyDeclsPtrSet.clear(); 5472 ImportedBlockDecls.clear(); 5473 return NewRep; 5474} 5475 5476bool RewriteObjC::IsDeclStmtInForeachHeader(DeclStmt *DS) { 5477 if (const ObjCForCollectionStmt * CS = 5478 dyn_cast<ObjCForCollectionStmt>(Stmts.back())) 5479 return CS->getElement() == DS; 5480 return false; 5481} 5482 5483//===----------------------------------------------------------------------===// 5484// Function Body / Expression rewriting 5485//===----------------------------------------------------------------------===// 5486 5487// This is run as a first "pass" prior to RewriteFunctionBodyOrGlobalInitializer(). 5488// The allows the main rewrite loop to associate all ObjCPropertyRefExprs with 5489// their respective BinaryOperator. Without this knowledge, we'd need to rewrite 5490// the ObjCPropertyRefExpr twice (once as a getter, and later as a setter). 5491// Since the rewriter isn't capable of rewriting rewritten code, it's important 5492// we get this right. 5493void RewriteObjC::CollectPropertySetters(Stmt *S) { 5494 // Perform a bottom up traversal of all children. 5495 for (Stmt::child_range CI = S->children(); CI; ++CI) 5496 if (*CI) 5497 CollectPropertySetters(*CI); 5498 5499 if (BinaryOperator *BinOp = dyn_cast<BinaryOperator>(S)) { 5500 if (BinOp->isAssignmentOp()) { 5501 if (isa<ObjCPropertyRefExpr>(BinOp->getLHS())) 5502 PropSetters[BinOp->getLHS()] = BinOp; 5503 } 5504 } 5505} 5506 5507Stmt *RewriteObjC::RewriteFunctionBodyOrGlobalInitializer(Stmt *S) { 5508 if (isa<SwitchStmt>(S) || isa<WhileStmt>(S) || 5509 isa<DoStmt>(S) || isa<ForStmt>(S)) 5510 Stmts.push_back(S); 5511 else if (isa<ObjCForCollectionStmt>(S)) { 5512 Stmts.push_back(S); 5513 ObjCBcLabelNo.push_back(++BcLabelCount); 5514 } 5515 5516 SourceRange OrigStmtRange = S->getSourceRange(); 5517 5518 // Perform a bottom up rewrite of all children. 5519 for (Stmt::child_range CI = S->children(); CI; ++CI) 5520 if (*CI) { 5521 Stmt *newStmt; 5522 Stmt *ChildStmt = (*CI); 5523 if (ObjCIvarRefExpr *IvarRefExpr = dyn_cast<ObjCIvarRefExpr>(ChildStmt)) { 5524 Expr *OldBase = IvarRefExpr->getBase(); 5525 bool replaced = false; 5526 newStmt = RewriteObjCNestedIvarRefExpr(ChildStmt, replaced); 5527 if (replaced) { 5528 if (ObjCIvarRefExpr *IRE = dyn_cast<ObjCIvarRefExpr>(newStmt)) 5529 ReplaceStmt(OldBase, IRE->getBase()); 5530 else 5531 ReplaceStmt(ChildStmt, newStmt); 5532 } 5533 } 5534 else 5535 newStmt = RewriteFunctionBodyOrGlobalInitializer(ChildStmt); 5536 if (newStmt) { 5537 if (Expr *PropOrImplicitRefExpr = dyn_cast<Expr>(ChildStmt)) 5538 if (PropSetters[PropOrImplicitRefExpr] == S) { 5539 S = newStmt; 5540 newStmt = 0; 5541 } 5542 if (newStmt) 5543 *CI = newStmt; 5544 } 5545 // If dealing with an assignment with LHS being a property reference 5546 // expression, the entire assignment tree is rewritten into a property 5547 // setter messaging. This involvs the RHS too. Do not attempt to rewrite 5548 // RHS again. 5549 if (Expr *Exp = dyn_cast<Expr>(ChildStmt)) 5550 if (isa<ObjCPropertyRefExpr>(Exp)) { 5551 if (PropSetters[Exp]) { 5552 ++CI; 5553 continue; 5554 } 5555 } 5556 } 5557 5558 if (BlockExpr *BE = dyn_cast<BlockExpr>(S)) { 5559 llvm::SmallVector<BlockDeclRefExpr *, 8> InnerBlockDeclRefs; 5560 llvm::SmallPtrSet<const DeclContext *, 8> InnerContexts; 5561 InnerContexts.insert(BE->getBlockDecl()); 5562 ImportedLocalExternalDecls.clear(); 5563 GetInnerBlockDeclRefExprs(BE->getBody(), 5564 InnerBlockDeclRefs, InnerContexts); 5565 // Rewrite the block body in place. 5566 Stmt *SaveCurrentBody = CurrentBody; 5567 CurrentBody = BE->getBody(); 5568 CollectPropertySetters(CurrentBody); 5569 PropParentMap = 0; 5570 RewriteFunctionBodyOrGlobalInitializer(BE->getBody()); 5571 CurrentBody = SaveCurrentBody; 5572 PropParentMap = 0; 5573 ImportedLocalExternalDecls.clear(); 5574 // Now we snarf the rewritten text and stash it away for later use. 5575 std::string Str = Rewrite.ConvertToString(BE->getBody()); 5576 RewrittenBlockExprs[BE] = Str; 5577 5578 Stmt *blockTranscribed = SynthBlockInitExpr(BE, InnerBlockDeclRefs); 5579 5580 //blockTranscribed->dump(); 5581 ReplaceStmt(S, blockTranscribed); 5582 return blockTranscribed; 5583 } 5584 // Handle specific things. 5585 if (ObjCEncodeExpr *AtEncode = dyn_cast<ObjCEncodeExpr>(S)) 5586 return RewriteAtEncode(AtEncode); 5587 5588 if (isa<ObjCPropertyRefExpr>(S)) { 5589 Expr *PropOrImplicitRefExpr = dyn_cast<Expr>(S); 5590 assert(PropOrImplicitRefExpr && "Property or implicit setter/getter is null"); 5591 5592 BinaryOperator *BinOp = PropSetters[PropOrImplicitRefExpr]; 5593 if (BinOp) { 5594 // Because the rewriter doesn't allow us to rewrite rewritten code, 5595 // we need to rewrite the right hand side prior to rewriting the setter. 5596 DisableReplaceStmt = true; 5597 // Save the source range. Even if we disable the replacement, the 5598 // rewritten node will have been inserted into the tree. If the synthesized 5599 // node is at the 'end', the rewriter will fail. Consider this: 5600 // self.errorHandler = handler ? handler : 5601 // ^(NSURL *errorURL, NSError *error) { return (BOOL)1; }; 5602 SourceRange SrcRange = BinOp->getSourceRange(); 5603 Stmt *newStmt = RewriteFunctionBodyOrGlobalInitializer(BinOp->getRHS()); 5604 // Need to rewrite the ivar access expression if need be. 5605 if (isa<ObjCIvarRefExpr>(newStmt)) { 5606 bool replaced = false; 5607 newStmt = RewriteObjCNestedIvarRefExpr(newStmt, replaced); 5608 } 5609 5610 DisableReplaceStmt = false; 5611 // 5612 // Unlike the main iterator, we explicily avoid changing 'BinOp'. If 5613 // we changed the RHS of BinOp, the rewriter would fail (since it needs 5614 // to see the original expression). Consider this example: 5615 // 5616 // Foo *obj1, *obj2; 5617 // 5618 // obj1.i = [obj2 rrrr]; 5619 // 5620 // 'BinOp' for the previous expression looks like: 5621 // 5622 // (BinaryOperator 0x231ccf0 'int' '=' 5623 // (ObjCPropertyRefExpr 0x231cc70 'int' Kind=PropertyRef Property="i" 5624 // (DeclRefExpr 0x231cc50 'Foo *' Var='obj1' 0x231cbb0)) 5625 // (ObjCMessageExpr 0x231ccb0 'int' selector=rrrr 5626 // (DeclRefExpr 0x231cc90 'Foo *' Var='obj2' 0x231cbe0))) 5627 // 5628 // 'newStmt' represents the rewritten message expression. For example: 5629 // 5630 // (CallExpr 0x231d300 'id':'struct objc_object *' 5631 // (ParenExpr 0x231d2e0 'int (*)(id, SEL)' 5632 // (CStyleCastExpr 0x231d2c0 'int (*)(id, SEL)' 5633 // (CStyleCastExpr 0x231d220 'void *' 5634 // (DeclRefExpr 0x231d200 'id (id, SEL, ...)' FunctionDecl='objc_msgSend' 0x231cdc0)))) 5635 // 5636 // Note that 'newStmt' is passed to RewritePropertyOrImplicitSetter so that it 5637 // can be used as the setter argument. ReplaceStmt() will still 'see' 5638 // the original RHS (since we haven't altered BinOp). 5639 // 5640 // This implies the Rewrite* routines can no longer delete the original 5641 // node. As a result, we now leak the original AST nodes. 5642 // 5643 return RewritePropertyOrImplicitSetter(BinOp, dyn_cast<Expr>(newStmt), SrcRange); 5644 } else { 5645 return RewritePropertyOrImplicitGetter(PropOrImplicitRefExpr); 5646 } 5647 } 5648 5649 if (ObjCSelectorExpr *AtSelector = dyn_cast<ObjCSelectorExpr>(S)) 5650 return RewriteAtSelector(AtSelector); 5651 5652 if (ObjCStringLiteral *AtString = dyn_cast<ObjCStringLiteral>(S)) 5653 return RewriteObjCStringLiteral(AtString); 5654 5655 if (ObjCMessageExpr *MessExpr = dyn_cast<ObjCMessageExpr>(S)) { 5656#if 0 5657 // Before we rewrite it, put the original message expression in a comment. 5658 SourceLocation startLoc = MessExpr->getLocStart(); 5659 SourceLocation endLoc = MessExpr->getLocEnd(); 5660 5661 const char *startBuf = SM->getCharacterData(startLoc); 5662 const char *endBuf = SM->getCharacterData(endLoc); 5663 5664 std::string messString; 5665 messString += "// "; 5666 messString.append(startBuf, endBuf-startBuf+1); 5667 messString += "\n"; 5668 5669 // FIXME: Missing definition of 5670 // InsertText(clang::SourceLocation, char const*, unsigned int). 5671 // InsertText(startLoc, messString.c_str(), messString.size()); 5672 // Tried this, but it didn't work either... 5673 // ReplaceText(startLoc, 0, messString.c_str(), messString.size()); 5674#endif 5675 return RewriteMessageExpr(MessExpr); 5676 } 5677 5678 if (ObjCAtTryStmt *StmtTry = dyn_cast<ObjCAtTryStmt>(S)) 5679 return RewriteObjCTryStmt(StmtTry); 5680 5681 if (ObjCAtSynchronizedStmt *StmtTry = dyn_cast<ObjCAtSynchronizedStmt>(S)) 5682 return RewriteObjCSynchronizedStmt(StmtTry); 5683 5684 if (ObjCAtThrowStmt *StmtThrow = dyn_cast<ObjCAtThrowStmt>(S)) 5685 return RewriteObjCThrowStmt(StmtThrow); 5686 5687 if (ObjCProtocolExpr *ProtocolExp = dyn_cast<ObjCProtocolExpr>(S)) 5688 return RewriteObjCProtocolExpr(ProtocolExp); 5689 5690 if (ObjCForCollectionStmt *StmtForCollection = 5691 dyn_cast<ObjCForCollectionStmt>(S)) 5692 return RewriteObjCForCollectionStmt(StmtForCollection, 5693 OrigStmtRange.getEnd()); 5694 if (BreakStmt *StmtBreakStmt = 5695 dyn_cast<BreakStmt>(S)) 5696 return RewriteBreakStmt(StmtBreakStmt); 5697 if (ContinueStmt *StmtContinueStmt = 5698 dyn_cast<ContinueStmt>(S)) 5699 return RewriteContinueStmt(StmtContinueStmt); 5700 5701 // Need to check for protocol refs (id <P>, Foo <P> *) in variable decls 5702 // and cast exprs. 5703 if (DeclStmt *DS = dyn_cast<DeclStmt>(S)) { 5704 // FIXME: What we're doing here is modifying the type-specifier that 5705 // precedes the first Decl. In the future the DeclGroup should have 5706 // a separate type-specifier that we can rewrite. 5707 // NOTE: We need to avoid rewriting the DeclStmt if it is within 5708 // the context of an ObjCForCollectionStmt. For example: 5709 // NSArray *someArray; 5710 // for (id <FooProtocol> index in someArray) ; 5711 // This is because RewriteObjCForCollectionStmt() does textual rewriting 5712 // and it depends on the original text locations/positions. 5713 if (Stmts.empty() || !IsDeclStmtInForeachHeader(DS)) 5714 RewriteObjCQualifiedInterfaceTypes(*DS->decl_begin()); 5715 5716 // Blocks rewrite rules. 5717 for (DeclStmt::decl_iterator DI = DS->decl_begin(), DE = DS->decl_end(); 5718 DI != DE; ++DI) { 5719 Decl *SD = *DI; 5720 if (ValueDecl *ND = dyn_cast<ValueDecl>(SD)) { 5721 if (isTopLevelBlockPointerType(ND->getType())) 5722 RewriteBlockPointerDecl(ND); 5723 else if (ND->getType()->isFunctionPointerType()) 5724 CheckFunctionPointerDecl(ND->getType(), ND); 5725 if (VarDecl *VD = dyn_cast<VarDecl>(SD)) { 5726 if (VD->hasAttr<BlocksAttr>()) { 5727 static unsigned uniqueByrefDeclCount = 0; 5728 assert(!BlockByRefDeclNo.count(ND) && 5729 "RewriteFunctionBodyOrGlobalInitializer: Duplicate byref decl"); 5730 BlockByRefDeclNo[ND] = uniqueByrefDeclCount++; 5731 RewriteByRefVar(VD); 5732 } 5733 else 5734 RewriteTypeOfDecl(VD); 5735 } 5736 } 5737 if (TypedefDecl *TD = dyn_cast<TypedefDecl>(SD)) { 5738 if (isTopLevelBlockPointerType(TD->getUnderlyingType())) 5739 RewriteBlockPointerDecl(TD); 5740 else if (TD->getUnderlyingType()->isFunctionPointerType()) 5741 CheckFunctionPointerDecl(TD->getUnderlyingType(), TD); 5742 } 5743 } 5744 } 5745 5746 if (CStyleCastExpr *CE = dyn_cast<CStyleCastExpr>(S)) 5747 RewriteObjCQualifiedInterfaceTypes(CE); 5748 5749 if (isa<SwitchStmt>(S) || isa<WhileStmt>(S) || 5750 isa<DoStmt>(S) || isa<ForStmt>(S)) { 5751 assert(!Stmts.empty() && "Statement stack is empty"); 5752 assert ((isa<SwitchStmt>(Stmts.back()) || isa<WhileStmt>(Stmts.back()) || 5753 isa<DoStmt>(Stmts.back()) || isa<ForStmt>(Stmts.back())) 5754 && "Statement stack mismatch"); 5755 Stmts.pop_back(); 5756 } 5757 // Handle blocks rewriting. 5758 if (BlockDeclRefExpr *BDRE = dyn_cast<BlockDeclRefExpr>(S)) { 5759 if (BDRE->isByRef()) 5760 return RewriteBlockDeclRefExpr(BDRE); 5761 } 5762 if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(S)) { 5763 ValueDecl *VD = DRE->getDecl(); 5764 if (VD->hasAttr<BlocksAttr>()) 5765 return RewriteBlockDeclRefExpr(DRE); 5766 if (HasLocalVariableExternalStorage(VD)) 5767 return RewriteLocalVariableExternalStorage(DRE); 5768 } 5769 5770 if (CallExpr *CE = dyn_cast<CallExpr>(S)) { 5771 if (CE->getCallee()->getType()->isBlockPointerType()) { 5772 Stmt *BlockCall = SynthesizeBlockCall(CE, CE->getCallee()); 5773 ReplaceStmt(S, BlockCall); 5774 return BlockCall; 5775 } 5776 } 5777 if (CStyleCastExpr *CE = dyn_cast<CStyleCastExpr>(S)) { 5778 RewriteCastExpr(CE); 5779 } 5780#if 0 5781 if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(S)) { 5782 CastExpr *Replacement = new (Context) CastExpr(ICE->getType(), 5783 ICE->getSubExpr(), 5784 SourceLocation()); 5785 // Get the new text. 5786 std::string SStr; 5787 llvm::raw_string_ostream Buf(SStr); 5788 Replacement->printPretty(Buf, *Context); 5789 const std::string &Str = Buf.str(); 5790 5791 printf("CAST = %s\n", &Str[0]); 5792 InsertText(ICE->getSubExpr()->getLocStart(), &Str[0], Str.size()); 5793 delete S; 5794 return Replacement; 5795 } 5796#endif 5797 // Return this stmt unmodified. 5798 return S; 5799} 5800 5801void RewriteObjC::RewriteRecordBody(RecordDecl *RD) { 5802 for (RecordDecl::field_iterator i = RD->field_begin(), 5803 e = RD->field_end(); i != e; ++i) { 5804 FieldDecl *FD = *i; 5805 if (isTopLevelBlockPointerType(FD->getType())) 5806 RewriteBlockPointerDecl(FD); 5807 if (FD->getType()->isObjCQualifiedIdType() || 5808 FD->getType()->isObjCQualifiedInterfaceType()) 5809 RewriteObjCQualifiedInterfaceTypes(FD); 5810 } 5811} 5812 5813/// HandleDeclInMainFile - This is called for each top-level decl defined in the 5814/// main file of the input. 5815void RewriteObjC::HandleDeclInMainFile(Decl *D) { 5816 if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { 5817 if (FD->isOverloadedOperator()) 5818 return; 5819 5820 // Since function prototypes don't have ParmDecl's, we check the function 5821 // prototype. This enables us to rewrite function declarations and 5822 // definitions using the same code. 5823 RewriteBlocksInFunctionProtoType(FD->getType(), FD); 5824 5825 // FIXME: If this should support Obj-C++, support CXXTryStmt 5826 if (CompoundStmt *Body = dyn_cast_or_null<CompoundStmt>(FD->getBody())) { 5827 CurFunctionDef = FD; 5828 CurFunctionDeclToDeclareForBlock = FD; 5829 CollectPropertySetters(Body); 5830 CurrentBody = Body; 5831 Body = 5832 cast_or_null<CompoundStmt>(RewriteFunctionBodyOrGlobalInitializer(Body)); 5833 FD->setBody(Body); 5834 CurrentBody = 0; 5835 if (PropParentMap) { 5836 delete PropParentMap; 5837 PropParentMap = 0; 5838 } 5839 // This synthesizes and inserts the block "impl" struct, invoke function, 5840 // and any copy/dispose helper functions. 5841 InsertBlockLiteralsWithinFunction(FD); 5842 CurFunctionDef = 0; 5843 CurFunctionDeclToDeclareForBlock = 0; 5844 } 5845 return; 5846 } 5847 if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) { 5848 if (CompoundStmt *Body = MD->getCompoundBody()) { 5849 CurMethodDef = MD; 5850 CollectPropertySetters(Body); 5851 CurrentBody = Body; 5852 Body = 5853 cast_or_null<CompoundStmt>(RewriteFunctionBodyOrGlobalInitializer(Body)); 5854 MD->setBody(Body); 5855 CurrentBody = 0; 5856 if (PropParentMap) { 5857 delete PropParentMap; 5858 PropParentMap = 0; 5859 } 5860 InsertBlockLiteralsWithinMethod(MD); 5861 CurMethodDef = 0; 5862 } 5863 } 5864 if (ObjCImplementationDecl *CI = dyn_cast<ObjCImplementationDecl>(D)) 5865 ClassImplementation.push_back(CI); 5866 else if (ObjCCategoryImplDecl *CI = dyn_cast<ObjCCategoryImplDecl>(D)) 5867 CategoryImplementation.push_back(CI); 5868 else if (ObjCClassDecl *CD = dyn_cast<ObjCClassDecl>(D)) 5869 RewriteForwardClassDecl(CD); 5870 else if (VarDecl *VD = dyn_cast<VarDecl>(D)) { 5871 RewriteObjCQualifiedInterfaceTypes(VD); 5872 if (isTopLevelBlockPointerType(VD->getType())) 5873 RewriteBlockPointerDecl(VD); 5874 else if (VD->getType()->isFunctionPointerType()) { 5875 CheckFunctionPointerDecl(VD->getType(), VD); 5876 if (VD->getInit()) { 5877 if (CStyleCastExpr *CE = dyn_cast<CStyleCastExpr>(VD->getInit())) { 5878 RewriteCastExpr(CE); 5879 } 5880 } 5881 } else if (VD->getType()->isRecordType()) { 5882 RecordDecl *RD = VD->getType()->getAs<RecordType>()->getDecl(); 5883 if (RD->isDefinition()) 5884 RewriteRecordBody(RD); 5885 } 5886 if (VD->getInit()) { 5887 GlobalVarDecl = VD; 5888 CollectPropertySetters(VD->getInit()); 5889 CurrentBody = VD->getInit(); 5890 RewriteFunctionBodyOrGlobalInitializer(VD->getInit()); 5891 CurrentBody = 0; 5892 if (PropParentMap) { 5893 delete PropParentMap; 5894 PropParentMap = 0; 5895 } 5896 SynthesizeBlockLiterals(VD->getTypeSpecStartLoc(), 5897 VD->getName()); 5898 GlobalVarDecl = 0; 5899 5900 // This is needed for blocks. 5901 if (CStyleCastExpr *CE = dyn_cast<CStyleCastExpr>(VD->getInit())) { 5902 RewriteCastExpr(CE); 5903 } 5904 } 5905 return; 5906 } 5907 if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) { 5908 if (isTopLevelBlockPointerType(TD->getUnderlyingType())) 5909 RewriteBlockPointerDecl(TD); 5910 else if (TD->getUnderlyingType()->isFunctionPointerType()) 5911 CheckFunctionPointerDecl(TD->getUnderlyingType(), TD); 5912 return; 5913 } 5914 if (RecordDecl *RD = dyn_cast<RecordDecl>(D)) { 5915 if (RD->isDefinition()) 5916 RewriteRecordBody(RD); 5917 return; 5918 } 5919 // Nothing yet. 5920} 5921 5922void RewriteObjC::HandleTranslationUnit(ASTContext &C) { 5923 if (Diags.hasErrorOccurred()) 5924 return; 5925 5926 RewriteInclude(); 5927 5928 // Here's a great place to add any extra declarations that may be needed. 5929 // Write out meta data for each @protocol(<expr>). 5930 for (llvm::SmallPtrSet<ObjCProtocolDecl *,8>::iterator I = ProtocolExprDecls.begin(), 5931 E = ProtocolExprDecls.end(); I != E; ++I) 5932 RewriteObjCProtocolMetaData(*I, "", "", Preamble); 5933 5934 InsertText(SM->getLocForStartOfFile(MainFileID), Preamble, false); 5935 if (ClassImplementation.size() || CategoryImplementation.size()) 5936 RewriteImplementations(); 5937 5938 // Get the buffer corresponding to MainFileID. If we haven't changed it, then 5939 // we are done. 5940 if (const RewriteBuffer *RewriteBuf = 5941 Rewrite.getRewriteBufferFor(MainFileID)) { 5942 //printf("Changed:\n"); 5943 *OutFile << std::string(RewriteBuf->begin(), RewriteBuf->end()); 5944 } else { 5945 llvm::errs() << "No changes\n"; 5946 } 5947 5948 if (ClassImplementation.size() || CategoryImplementation.size() || 5949 ProtocolExprDecls.size()) { 5950 // Rewrite Objective-c meta data* 5951 std::string ResultStr; 5952 SynthesizeMetaDataIntoBuffer(ResultStr); 5953 // Emit metadata. 5954 *OutFile << ResultStr; 5955 } 5956 OutFile->flush(); 5957} 5958