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