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/Frontend/ASTConsumers.h" 15 #include "clang/AST/AST.h" 16 #include "clang/AST/ASTConsumer.h" 17 #include "clang/AST/Attr.h" 18 #include "clang/AST/ParentMap.h" 19 #include "clang/Basic/CharInfo.h" 20 #include "clang/Basic/Diagnostic.h" 21 #include "clang/Basic/IdentifierTable.h" 22 #include "clang/Basic/SourceManager.h" 23 #include "clang/Basic/TargetInfo.h" 24 #include "clang/Lex/Lexer.h" 25 #include "clang/Rewrite/Core/Rewriter.h" 26 #include "llvm/ADT/DenseSet.h" 27 #include "llvm/ADT/OwningPtr.h" 28 #include "llvm/ADT/SmallPtrSet.h" 29 #include "llvm/ADT/StringExtras.h" 30 #include "llvm/Support/MemoryBuffer.h" 31 #include "llvm/Support/raw_ostream.h" 32 33 using namespace clang; 34 using llvm::utostr; 35 36 namespace { 37 class RewriteModernObjC : public ASTConsumer { 38 protected: 39 40 enum { 41 BLOCK_FIELD_IS_OBJECT = 3, /* id, NSObject, __attribute__((NSObject)), 42 block, ... */ 43 BLOCK_FIELD_IS_BLOCK = 7, /* a block variable */ 44 BLOCK_FIELD_IS_BYREF = 8, /* the on stack structure holding the 45 __block variable */ 46 BLOCK_FIELD_IS_WEAK = 16, /* declared __weak, only used in byref copy 47 helpers */ 48 BLOCK_BYREF_CALLER = 128, /* called from __block (byref) copy/dispose 49 support routines */ 50 BLOCK_BYREF_CURRENT_MAX = 256 51 }; 52 53 enum { 54 BLOCK_NEEDS_FREE = (1 << 24), 55 BLOCK_HAS_COPY_DISPOSE = (1 << 25), 56 BLOCK_HAS_CXX_OBJ = (1 << 26), 57 BLOCK_IS_GC = (1 << 27), 58 BLOCK_IS_GLOBAL = (1 << 28), 59 BLOCK_HAS_DESCRIPTOR = (1 << 29) 60 }; 61 static const int OBJC_ABI_VERSION = 7; 62 63 Rewriter Rewrite; 64 DiagnosticsEngine &Diags; 65 const LangOptions &LangOpts; 66 ASTContext *Context; 67 SourceManager *SM; 68 TranslationUnitDecl *TUDecl; 69 FileID MainFileID; 70 const char *MainFileStart, *MainFileEnd; 71 Stmt *CurrentBody; 72 ParentMap *PropParentMap; // created lazily. 73 std::string InFileName; 74 raw_ostream* OutFile; 75 std::string Preamble; 76 77 TypeDecl *ProtocolTypeDecl; 78 VarDecl *GlobalVarDecl; 79 Expr *GlobalConstructionExp; 80 unsigned RewriteFailedDiag; 81 unsigned GlobalBlockRewriteFailedDiag; 82 // ObjC string constant support. 83 unsigned NumObjCStringLiterals; 84 VarDecl *ConstantStringClassReference; 85 RecordDecl *NSStringRecord; 86 87 // ObjC foreach break/continue generation support. 88 int BcLabelCount; 89 90 unsigned TryFinallyContainsReturnDiag; 91 // Needed for super. 92 ObjCMethodDecl *CurMethodDef; 93 RecordDecl *SuperStructDecl; 94 RecordDecl *ConstantStringDecl; 95 96 FunctionDecl *MsgSendFunctionDecl; 97 FunctionDecl *MsgSendSuperFunctionDecl; 98 FunctionDecl *MsgSendStretFunctionDecl; 99 FunctionDecl *MsgSendSuperStretFunctionDecl; 100 FunctionDecl *MsgSendFpretFunctionDecl; 101 FunctionDecl *GetClassFunctionDecl; 102 FunctionDecl *GetMetaClassFunctionDecl; 103 FunctionDecl *GetSuperClassFunctionDecl; 104 FunctionDecl *SelGetUidFunctionDecl; 105 FunctionDecl *CFStringFunctionDecl; 106 FunctionDecl *SuperContructorFunctionDecl; 107 FunctionDecl *CurFunctionDef; 108 109 /* Misc. containers needed for meta-data rewrite. */ 110 SmallVector<ObjCImplementationDecl *, 8> ClassImplementation; 111 SmallVector<ObjCCategoryImplDecl *, 8> CategoryImplementation; 112 llvm::SmallPtrSet<ObjCInterfaceDecl*, 8> ObjCSynthesizedStructs; 113 llvm::SmallPtrSet<ObjCProtocolDecl*, 8> ObjCSynthesizedProtocols; 114 llvm::SmallPtrSet<ObjCInterfaceDecl*, 8> ObjCWrittenInterfaces; 115 llvm::SmallPtrSet<TagDecl*, 32> GlobalDefinedTags; 116 SmallVector<ObjCInterfaceDecl*, 32> ObjCInterfacesSeen; 117 /// DefinedNonLazyClasses - List of defined "non-lazy" classes. 118 SmallVector<ObjCInterfaceDecl*, 8> DefinedNonLazyClasses; 119 120 /// DefinedNonLazyCategories - List of defined "non-lazy" categories. 121 SmallVector<ObjCCategoryDecl *, 8> DefinedNonLazyCategories; 122 123 SmallVector<Stmt *, 32> Stmts; 124 SmallVector<int, 8> ObjCBcLabelNo; 125 // Remember all the @protocol(<expr>) expressions. 126 llvm::SmallPtrSet<ObjCProtocolDecl *, 32> ProtocolExprDecls; 127 128 llvm::DenseSet<uint64_t> CopyDestroyCache; 129 130 // Block expressions. 131 SmallVector<BlockExpr *, 32> Blocks; 132 SmallVector<int, 32> InnerDeclRefsCount; 133 SmallVector<DeclRefExpr *, 32> InnerDeclRefs; 134 135 SmallVector<DeclRefExpr *, 32> BlockDeclRefs; 136 137 138 // Block related declarations. 139 SmallVector<ValueDecl *, 8> BlockByCopyDecls; 140 llvm::SmallPtrSet<ValueDecl *, 8> BlockByCopyDeclsPtrSet; 141 SmallVector<ValueDecl *, 8> BlockByRefDecls; 142 llvm::SmallPtrSet<ValueDecl *, 8> BlockByRefDeclsPtrSet; 143 llvm::DenseMap<ValueDecl *, unsigned> BlockByRefDeclNo; 144 llvm::SmallPtrSet<ValueDecl *, 8> ImportedBlockDecls; 145 llvm::SmallPtrSet<VarDecl *, 8> ImportedLocalExternalDecls; 146 147 llvm::DenseMap<BlockExpr *, std::string> RewrittenBlockExprs; 148 llvm::DenseMap<ObjCInterfaceDecl *, 149 llvm::SmallPtrSet<ObjCIvarDecl *, 8> > ReferencedIvars; 150 151 // ivar bitfield grouping containers 152 llvm::DenseSet<const ObjCInterfaceDecl *> ObjCInterefaceHasBitfieldGroups; 153 llvm::DenseMap<const ObjCIvarDecl* , unsigned> IvarGroupNumber; 154 // This container maps an <class, group number for ivar> tuple to the type 155 // of the struct where the bitfield belongs. 156 llvm::DenseMap<std::pair<const ObjCInterfaceDecl*, unsigned>, QualType> GroupRecordType; 157 SmallVector<FunctionDecl*, 32> FunctionDefinitionsSeen; 158 159 // This maps an original source AST to it's rewritten form. This allows 160 // us to avoid rewriting the same node twice (which is very uncommon). 161 // This is needed to support some of the exotic property rewriting. 162 llvm::DenseMap<Stmt *, Stmt *> ReplacedNodes; 163 164 // Needed for header files being rewritten 165 bool IsHeader; 166 bool SilenceRewriteMacroWarning; 167 bool GenerateLineInfo; 168 bool objc_impl_method; 169 170 bool DisableReplaceStmt; 171 class DisableReplaceStmtScope { 172 RewriteModernObjC &R; 173 bool SavedValue; 174 175 public: 176 DisableReplaceStmtScope(RewriteModernObjC &R) 177 : R(R), SavedValue(R.DisableReplaceStmt) { 178 R.DisableReplaceStmt = true; 179 } 180 ~DisableReplaceStmtScope() { 181 R.DisableReplaceStmt = SavedValue; 182 } 183 }; 184 void InitializeCommon(ASTContext &context); 185 186 public: 187 llvm::DenseMap<ObjCMethodDecl*, std::string> MethodInternalNames; 188 // Top Level Driver code. 189 virtual bool HandleTopLevelDecl(DeclGroupRef D) { 190 for (DeclGroupRef::iterator I = D.begin(), E = D.end(); I != E; ++I) { 191 if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(*I)) { 192 if (!Class->isThisDeclarationADefinition()) { 193 RewriteForwardClassDecl(D); 194 break; 195 } else { 196 // Keep track of all interface declarations seen. 197 ObjCInterfacesSeen.push_back(Class); 198 break; 199 } 200 } 201 202 if (ObjCProtocolDecl *Proto = dyn_cast<ObjCProtocolDecl>(*I)) { 203 if (!Proto->isThisDeclarationADefinition()) { 204 RewriteForwardProtocolDecl(D); 205 break; 206 } 207 } 208 209 if (FunctionDecl *FDecl = dyn_cast<FunctionDecl>(*I)) { 210 // Under modern abi, we cannot translate body of the function 211 // yet until all class extensions and its implementation is seen. 212 // This is because they may introduce new bitfields which must go 213 // into their grouping struct. 214 if (FDecl->isThisDeclarationADefinition() && 215 // Not c functions defined inside an objc container. 216 !FDecl->isTopLevelDeclInObjCContainer()) { 217 FunctionDefinitionsSeen.push_back(FDecl); 218 break; 219 } 220 } 221 HandleTopLevelSingleDecl(*I); 222 } 223 return true; 224 } 225 void HandleTopLevelSingleDecl(Decl *D); 226 void HandleDeclInMainFile(Decl *D); 227 RewriteModernObjC(std::string inFile, raw_ostream *OS, 228 DiagnosticsEngine &D, const LangOptions &LOpts, 229 bool silenceMacroWarn, bool LineInfo); 230 231 ~RewriteModernObjC() {} 232 233 virtual void HandleTranslationUnit(ASTContext &C); 234 235 void ReplaceStmt(Stmt *Old, Stmt *New) { 236 Stmt *ReplacingStmt = ReplacedNodes[Old]; 237 238 if (ReplacingStmt) 239 return; // We can't rewrite the same node twice. 240 241 if (DisableReplaceStmt) 242 return; 243 244 // If replacement succeeded or warning disabled return with no warning. 245 if (!Rewrite.ReplaceStmt(Old, New)) { 246 ReplacedNodes[Old] = New; 247 return; 248 } 249 if (SilenceRewriteMacroWarning) 250 return; 251 Diags.Report(Context->getFullLoc(Old->getLocStart()), RewriteFailedDiag) 252 << Old->getSourceRange(); 253 } 254 255 void ReplaceStmtWithRange(Stmt *Old, Stmt *New, SourceRange SrcRange) { 256 if (DisableReplaceStmt) 257 return; 258 259 // Measure the old text. 260 int Size = Rewrite.getRangeSize(SrcRange); 261 if (Size == -1) { 262 Diags.Report(Context->getFullLoc(Old->getLocStart()), RewriteFailedDiag) 263 << Old->getSourceRange(); 264 return; 265 } 266 // Get the new text. 267 std::string SStr; 268 llvm::raw_string_ostream S(SStr); 269 New->printPretty(S, 0, PrintingPolicy(LangOpts)); 270 const std::string &Str = S.str(); 271 272 // If replacement succeeded or warning disabled return with no warning. 273 if (!Rewrite.ReplaceText(SrcRange.getBegin(), Size, Str)) { 274 ReplacedNodes[Old] = New; 275 return; 276 } 277 if (SilenceRewriteMacroWarning) 278 return; 279 Diags.Report(Context->getFullLoc(Old->getLocStart()), RewriteFailedDiag) 280 << Old->getSourceRange(); 281 } 282 283 void InsertText(SourceLocation Loc, StringRef Str, 284 bool InsertAfter = true) { 285 // If insertion succeeded or warning disabled return with no warning. 286 if (!Rewrite.InsertText(Loc, Str, InsertAfter) || 287 SilenceRewriteMacroWarning) 288 return; 289 290 Diags.Report(Context->getFullLoc(Loc), RewriteFailedDiag); 291 } 292 293 void ReplaceText(SourceLocation Start, unsigned OrigLength, 294 StringRef Str) { 295 // If removal succeeded or warning disabled return with no warning. 296 if (!Rewrite.ReplaceText(Start, OrigLength, Str) || 297 SilenceRewriteMacroWarning) 298 return; 299 300 Diags.Report(Context->getFullLoc(Start), RewriteFailedDiag); 301 } 302 303 // Syntactic Rewriting. 304 void RewriteRecordBody(RecordDecl *RD); 305 void RewriteInclude(); 306 void RewriteLineDirective(const Decl *D); 307 void ConvertSourceLocationToLineDirective(SourceLocation Loc, 308 std::string &LineString); 309 void RewriteForwardClassDecl(DeclGroupRef D); 310 void RewriteForwardClassDecl(const SmallVectorImpl<Decl *> &DG); 311 void RewriteForwardClassEpilogue(ObjCInterfaceDecl *ClassDecl, 312 const std::string &typedefString); 313 void RewriteImplementations(); 314 void RewritePropertyImplDecl(ObjCPropertyImplDecl *PID, 315 ObjCImplementationDecl *IMD, 316 ObjCCategoryImplDecl *CID); 317 void RewriteInterfaceDecl(ObjCInterfaceDecl *Dcl); 318 void RewriteImplementationDecl(Decl *Dcl); 319 void RewriteObjCMethodDecl(const ObjCInterfaceDecl *IDecl, 320 ObjCMethodDecl *MDecl, std::string &ResultStr); 321 void RewriteTypeIntoString(QualType T, std::string &ResultStr, 322 const FunctionType *&FPRetType); 323 void RewriteByRefString(std::string &ResultStr, const std::string &Name, 324 ValueDecl *VD, bool def=false); 325 void RewriteCategoryDecl(ObjCCategoryDecl *Dcl); 326 void RewriteProtocolDecl(ObjCProtocolDecl *Dcl); 327 void RewriteForwardProtocolDecl(DeclGroupRef D); 328 void RewriteForwardProtocolDecl(const SmallVectorImpl<Decl *> &DG); 329 void RewriteMethodDeclaration(ObjCMethodDecl *Method); 330 void RewriteProperty(ObjCPropertyDecl *prop); 331 void RewriteFunctionDecl(FunctionDecl *FD); 332 void RewriteBlockPointerType(std::string& Str, QualType Type); 333 void RewriteBlockPointerTypeVariable(std::string& Str, ValueDecl *VD); 334 void RewriteBlockLiteralFunctionDecl(FunctionDecl *FD); 335 void RewriteObjCQualifiedInterfaceTypes(Decl *Dcl); 336 void RewriteTypeOfDecl(VarDecl *VD); 337 void RewriteObjCQualifiedInterfaceTypes(Expr *E); 338 339 std::string getIvarAccessString(ObjCIvarDecl *D); 340 341 // Expression Rewriting. 342 Stmt *RewriteFunctionBodyOrGlobalInitializer(Stmt *S); 343 Stmt *RewriteAtEncode(ObjCEncodeExpr *Exp); 344 Stmt *RewritePropertyOrImplicitGetter(PseudoObjectExpr *Pseudo); 345 Stmt *RewritePropertyOrImplicitSetter(PseudoObjectExpr *Pseudo); 346 Stmt *RewriteAtSelector(ObjCSelectorExpr *Exp); 347 Stmt *RewriteMessageExpr(ObjCMessageExpr *Exp); 348 Stmt *RewriteObjCStringLiteral(ObjCStringLiteral *Exp); 349 Stmt *RewriteObjCBoolLiteralExpr(ObjCBoolLiteralExpr *Exp); 350 Stmt *RewriteObjCBoxedExpr(ObjCBoxedExpr *Exp); 351 Stmt *RewriteObjCArrayLiteralExpr(ObjCArrayLiteral *Exp); 352 Stmt *RewriteObjCDictionaryLiteralExpr(ObjCDictionaryLiteral *Exp); 353 Stmt *RewriteObjCProtocolExpr(ObjCProtocolExpr *Exp); 354 Stmt *RewriteObjCTryStmt(ObjCAtTryStmt *S); 355 Stmt *RewriteObjCAutoreleasePoolStmt(ObjCAutoreleasePoolStmt *S); 356 Stmt *RewriteObjCSynchronizedStmt(ObjCAtSynchronizedStmt *S); 357 Stmt *RewriteObjCThrowStmt(ObjCAtThrowStmt *S); 358 Stmt *RewriteObjCForCollectionStmt(ObjCForCollectionStmt *S, 359 SourceLocation OrigEnd); 360 Stmt *RewriteBreakStmt(BreakStmt *S); 361 Stmt *RewriteContinueStmt(ContinueStmt *S); 362 void RewriteCastExpr(CStyleCastExpr *CE); 363 void RewriteImplicitCastObjCExpr(CastExpr *IE); 364 void RewriteLinkageSpec(LinkageSpecDecl *LSD); 365 366 // Computes ivar bitfield group no. 367 unsigned ObjCIvarBitfieldGroupNo(ObjCIvarDecl *IV); 368 // Names field decl. for ivar bitfield group. 369 void ObjCIvarBitfieldGroupDecl(ObjCIvarDecl *IV, std::string &Result); 370 // Names struct type for ivar bitfield group. 371 void ObjCIvarBitfieldGroupType(ObjCIvarDecl *IV, std::string &Result); 372 // Names symbol for ivar bitfield group field offset. 373 void ObjCIvarBitfieldGroupOffset(ObjCIvarDecl *IV, std::string &Result); 374 // Given an ivar bitfield, it builds (or finds) its group record type. 375 QualType GetGroupRecordTypeForObjCIvarBitfield(ObjCIvarDecl *IV); 376 QualType SynthesizeBitfieldGroupStructType( 377 ObjCIvarDecl *IV, 378 SmallVectorImpl<ObjCIvarDecl *> &IVars); 379 380 // Block rewriting. 381 void RewriteBlocksInFunctionProtoType(QualType funcType, NamedDecl *D); 382 383 // Block specific rewrite rules. 384 void RewriteBlockPointerDecl(NamedDecl *VD); 385 void RewriteByRefVar(VarDecl *VD, bool firstDecl, bool lastDecl); 386 Stmt *RewriteBlockDeclRefExpr(DeclRefExpr *VD); 387 Stmt *RewriteLocalVariableExternalStorage(DeclRefExpr *DRE); 388 void RewriteBlockPointerFunctionArgs(FunctionDecl *FD); 389 390 void RewriteObjCInternalStruct(ObjCInterfaceDecl *CDecl, 391 std::string &Result); 392 393 void RewriteObjCFieldDecl(FieldDecl *fieldDecl, std::string &Result); 394 bool IsTagDefinedInsideClass(ObjCContainerDecl *IDecl, TagDecl *Tag, 395 bool &IsNamedDefinition); 396 void RewriteLocallyDefinedNamedAggregates(FieldDecl *fieldDecl, 397 std::string &Result); 398 399 bool RewriteObjCFieldDeclType(QualType &Type, std::string &Result); 400 401 void RewriteIvarOffsetSymbols(ObjCInterfaceDecl *CDecl, 402 std::string &Result); 403 404 virtual void Initialize(ASTContext &context); 405 406 // Misc. AST transformation routines. Sometimes they end up calling 407 // rewriting routines on the new ASTs. 408 CallExpr *SynthesizeCallToFunctionDecl(FunctionDecl *FD, 409 Expr **args, unsigned nargs, 410 SourceLocation StartLoc=SourceLocation(), 411 SourceLocation EndLoc=SourceLocation()); 412 413 Expr *SynthMsgSendStretCallExpr(FunctionDecl *MsgSendStretFlavor, 414 QualType msgSendType, 415 QualType returnType, 416 SmallVectorImpl<QualType> &ArgTypes, 417 SmallVectorImpl<Expr*> &MsgExprs, 418 ObjCMethodDecl *Method); 419 420 Stmt *SynthMessageExpr(ObjCMessageExpr *Exp, 421 SourceLocation StartLoc=SourceLocation(), 422 SourceLocation EndLoc=SourceLocation()); 423 424 void SynthCountByEnumWithState(std::string &buf); 425 void SynthMsgSendFunctionDecl(); 426 void SynthMsgSendSuperFunctionDecl(); 427 void SynthMsgSendStretFunctionDecl(); 428 void SynthMsgSendFpretFunctionDecl(); 429 void SynthMsgSendSuperStretFunctionDecl(); 430 void SynthGetClassFunctionDecl(); 431 void SynthGetMetaClassFunctionDecl(); 432 void SynthGetSuperClassFunctionDecl(); 433 void SynthSelGetUidFunctionDecl(); 434 void SynthSuperContructorFunctionDecl(); 435 436 // Rewriting metadata 437 template<typename MethodIterator> 438 void RewriteObjCMethodsMetaData(MethodIterator MethodBegin, 439 MethodIterator MethodEnd, 440 bool IsInstanceMethod, 441 StringRef prefix, 442 StringRef ClassName, 443 std::string &Result); 444 void RewriteObjCProtocolMetaData(ObjCProtocolDecl *Protocol, 445 std::string &Result); 446 void RewriteObjCProtocolListMetaData( 447 const ObjCList<ObjCProtocolDecl> &Prots, 448 StringRef prefix, StringRef ClassName, std::string &Result); 449 void RewriteObjCClassMetaData(ObjCImplementationDecl *IDecl, 450 std::string &Result); 451 void RewriteClassSetupInitHook(std::string &Result); 452 453 void RewriteMetaDataIntoBuffer(std::string &Result); 454 void WriteImageInfo(std::string &Result); 455 void RewriteObjCCategoryImplDecl(ObjCCategoryImplDecl *CDecl, 456 std::string &Result); 457 void RewriteCategorySetupInitHook(std::string &Result); 458 459 // Rewriting ivar 460 void RewriteIvarOffsetComputation(ObjCIvarDecl *ivar, 461 std::string &Result); 462 Stmt *RewriteObjCIvarRefExpr(ObjCIvarRefExpr *IV); 463 464 465 std::string SynthesizeByrefCopyDestroyHelper(VarDecl *VD, int flag); 466 std::string SynthesizeBlockHelperFuncs(BlockExpr *CE, int i, 467 StringRef funcName, std::string Tag); 468 std::string SynthesizeBlockFunc(BlockExpr *CE, int i, 469 StringRef funcName, std::string Tag); 470 std::string SynthesizeBlockImpl(BlockExpr *CE, 471 std::string Tag, std::string Desc); 472 std::string SynthesizeBlockDescriptor(std::string DescTag, 473 std::string ImplTag, 474 int i, StringRef funcName, 475 unsigned hasCopy); 476 Stmt *SynthesizeBlockCall(CallExpr *Exp, const Expr* BlockExp); 477 void SynthesizeBlockLiterals(SourceLocation FunLocStart, 478 StringRef FunName); 479 FunctionDecl *SynthBlockInitFunctionDecl(StringRef name); 480 Stmt *SynthBlockInitExpr(BlockExpr *Exp, 481 const SmallVectorImpl<DeclRefExpr *> &InnerBlockDeclRefs); 482 483 // Misc. helper routines. 484 QualType getProtocolType(); 485 void WarnAboutReturnGotoStmts(Stmt *S); 486 void CheckFunctionPointerDecl(QualType dType, NamedDecl *ND); 487 void InsertBlockLiteralsWithinFunction(FunctionDecl *FD); 488 void InsertBlockLiteralsWithinMethod(ObjCMethodDecl *MD); 489 490 bool IsDeclStmtInForeachHeader(DeclStmt *DS); 491 void CollectBlockDeclRefInfo(BlockExpr *Exp); 492 void GetBlockDeclRefExprs(Stmt *S); 493 void GetInnerBlockDeclRefExprs(Stmt *S, 494 SmallVectorImpl<DeclRefExpr *> &InnerBlockDeclRefs, 495 llvm::SmallPtrSet<const DeclContext *, 8> &InnerContexts); 496 497 // We avoid calling Type::isBlockPointerType(), since it operates on the 498 // canonical type. We only care if the top-level type is a closure pointer. 499 bool isTopLevelBlockPointerType(QualType T) { 500 return isa<BlockPointerType>(T); 501 } 502 503 /// convertBlockPointerToFunctionPointer - Converts a block-pointer type 504 /// to a function pointer type and upon success, returns true; false 505 /// otherwise. 506 bool convertBlockPointerToFunctionPointer(QualType &T) { 507 if (isTopLevelBlockPointerType(T)) { 508 const BlockPointerType *BPT = T->getAs<BlockPointerType>(); 509 T = Context->getPointerType(BPT->getPointeeType()); 510 return true; 511 } 512 return false; 513 } 514 515 bool convertObjCTypeToCStyleType(QualType &T); 516 517 bool needToScanForQualifiers(QualType T); 518 QualType getSuperStructType(); 519 QualType getConstantStringStructType(); 520 QualType convertFunctionTypeOfBlocks(const FunctionType *FT); 521 bool BufferContainsPPDirectives(const char *startBuf, const char *endBuf); 522 523 void convertToUnqualifiedObjCType(QualType &T) { 524 if (T->isObjCQualifiedIdType()) { 525 bool isConst = T.isConstQualified(); 526 T = isConst ? Context->getObjCIdType().withConst() 527 : Context->getObjCIdType(); 528 } 529 else if (T->isObjCQualifiedClassType()) 530 T = Context->getObjCClassType(); 531 else if (T->isObjCObjectPointerType() && 532 T->getPointeeType()->isObjCQualifiedInterfaceType()) { 533 if (const ObjCObjectPointerType * OBJPT = 534 T->getAsObjCInterfacePointerType()) { 535 const ObjCInterfaceType *IFaceT = OBJPT->getInterfaceType(); 536 T = QualType(IFaceT, 0); 537 T = Context->getPointerType(T); 538 } 539 } 540 } 541 542 // FIXME: This predicate seems like it would be useful to add to ASTContext. 543 bool isObjCType(QualType T) { 544 if (!LangOpts.ObjC1 && !LangOpts.ObjC2) 545 return false; 546 547 QualType OCT = Context->getCanonicalType(T).getUnqualifiedType(); 548 549 if (OCT == Context->getCanonicalType(Context->getObjCIdType()) || 550 OCT == Context->getCanonicalType(Context->getObjCClassType())) 551 return true; 552 553 if (const PointerType *PT = OCT->getAs<PointerType>()) { 554 if (isa<ObjCInterfaceType>(PT->getPointeeType()) || 555 PT->getPointeeType()->isObjCQualifiedIdType()) 556 return true; 557 } 558 return false; 559 } 560 bool PointerTypeTakesAnyBlockArguments(QualType QT); 561 bool PointerTypeTakesAnyObjCQualifiedType(QualType QT); 562 void GetExtentOfArgList(const char *Name, const char *&LParen, 563 const char *&RParen); 564 565 void QuoteDoublequotes(std::string &From, std::string &To) { 566 for (unsigned i = 0; i < From.length(); i++) { 567 if (From[i] == '"') 568 To += "\\\""; 569 else 570 To += From[i]; 571 } 572 } 573 574 QualType getSimpleFunctionType(QualType result, 575 ArrayRef<QualType> args, 576 bool variadic = false) { 577 if (result == Context->getObjCInstanceType()) 578 result = Context->getObjCIdType(); 579 FunctionProtoType::ExtProtoInfo fpi; 580 fpi.Variadic = variadic; 581 return Context->getFunctionType(result, args, fpi); 582 } 583 584 // Helper function: create a CStyleCastExpr with trivial type source info. 585 CStyleCastExpr* NoTypeInfoCStyleCastExpr(ASTContext *Ctx, QualType Ty, 586 CastKind Kind, Expr *E) { 587 TypeSourceInfo *TInfo = Ctx->getTrivialTypeSourceInfo(Ty, SourceLocation()); 588 return CStyleCastExpr::Create(*Ctx, Ty, VK_RValue, Kind, E, 0, TInfo, 589 SourceLocation(), SourceLocation()); 590 } 591 592 bool ImplementationIsNonLazy(const ObjCImplDecl *OD) const { 593 IdentifierInfo* II = &Context->Idents.get("load"); 594 Selector LoadSel = Context->Selectors.getSelector(0, &II); 595 return OD->getClassMethod(LoadSel) != 0; 596 } 597 }; 598 599 } 600 601 void RewriteModernObjC::RewriteBlocksInFunctionProtoType(QualType funcType, 602 NamedDecl *D) { 603 if (const FunctionProtoType *fproto 604 = dyn_cast<FunctionProtoType>(funcType.IgnoreParens())) { 605 for (FunctionProtoType::arg_type_iterator I = fproto->arg_type_begin(), 606 E = fproto->arg_type_end(); I && (I != E); ++I) 607 if (isTopLevelBlockPointerType(*I)) { 608 // All the args are checked/rewritten. Don't call twice! 609 RewriteBlockPointerDecl(D); 610 break; 611 } 612 } 613 } 614 615 void RewriteModernObjC::CheckFunctionPointerDecl(QualType funcType, NamedDecl *ND) { 616 const PointerType *PT = funcType->getAs<PointerType>(); 617 if (PT && PointerTypeTakesAnyBlockArguments(funcType)) 618 RewriteBlocksInFunctionProtoType(PT->getPointeeType(), ND); 619 } 620 621 static bool IsHeaderFile(const std::string &Filename) { 622 std::string::size_type DotPos = Filename.rfind('.'); 623 624 if (DotPos == std::string::npos) { 625 // no file extension 626 return false; 627 } 628 629 std::string Ext = std::string(Filename.begin()+DotPos+1, Filename.end()); 630 // C header: .h 631 // C++ header: .hh or .H; 632 return Ext == "h" || Ext == "hh" || Ext == "H"; 633 } 634 635 RewriteModernObjC::RewriteModernObjC(std::string inFile, raw_ostream* OS, 636 DiagnosticsEngine &D, const LangOptions &LOpts, 637 bool silenceMacroWarn, 638 bool LineInfo) 639 : Diags(D), LangOpts(LOpts), InFileName(inFile), OutFile(OS), 640 SilenceRewriteMacroWarning(silenceMacroWarn), GenerateLineInfo(LineInfo) { 641 IsHeader = IsHeaderFile(inFile); 642 RewriteFailedDiag = Diags.getCustomDiagID(DiagnosticsEngine::Warning, 643 "rewriting sub-expression within a macro (may not be correct)"); 644 // FIXME. This should be an error. But if block is not called, it is OK. And it 645 // may break including some headers. 646 GlobalBlockRewriteFailedDiag = Diags.getCustomDiagID(DiagnosticsEngine::Warning, 647 "rewriting block literal declared in global scope is not implemented"); 648 649 TryFinallyContainsReturnDiag = Diags.getCustomDiagID( 650 DiagnosticsEngine::Warning, 651 "rewriter doesn't support user-specified control flow semantics " 652 "for @try/@finally (code may not execute properly)"); 653 } 654 655 ASTConsumer *clang::CreateModernObjCRewriter(const std::string& InFile, 656 raw_ostream* OS, 657 DiagnosticsEngine &Diags, 658 const LangOptions &LOpts, 659 bool SilenceRewriteMacroWarning, 660 bool LineInfo) { 661 return new RewriteModernObjC(InFile, OS, Diags, LOpts, 662 SilenceRewriteMacroWarning, LineInfo); 663 } 664 665 void RewriteModernObjC::InitializeCommon(ASTContext &context) { 666 Context = &context; 667 SM = &Context->getSourceManager(); 668 TUDecl = Context->getTranslationUnitDecl(); 669 MsgSendFunctionDecl = 0; 670 MsgSendSuperFunctionDecl = 0; 671 MsgSendStretFunctionDecl = 0; 672 MsgSendSuperStretFunctionDecl = 0; 673 MsgSendFpretFunctionDecl = 0; 674 GetClassFunctionDecl = 0; 675 GetMetaClassFunctionDecl = 0; 676 GetSuperClassFunctionDecl = 0; 677 SelGetUidFunctionDecl = 0; 678 CFStringFunctionDecl = 0; 679 ConstantStringClassReference = 0; 680 NSStringRecord = 0; 681 CurMethodDef = 0; 682 CurFunctionDef = 0; 683 GlobalVarDecl = 0; 684 GlobalConstructionExp = 0; 685 SuperStructDecl = 0; 686 ProtocolTypeDecl = 0; 687 ConstantStringDecl = 0; 688 BcLabelCount = 0; 689 SuperContructorFunctionDecl = 0; 690 NumObjCStringLiterals = 0; 691 PropParentMap = 0; 692 CurrentBody = 0; 693 DisableReplaceStmt = false; 694 objc_impl_method = false; 695 696 // Get the ID and start/end of the main file. 697 MainFileID = SM->getMainFileID(); 698 const llvm::MemoryBuffer *MainBuf = SM->getBuffer(MainFileID); 699 MainFileStart = MainBuf->getBufferStart(); 700 MainFileEnd = MainBuf->getBufferEnd(); 701 702 Rewrite.setSourceMgr(Context->getSourceManager(), Context->getLangOpts()); 703 } 704 705 //===----------------------------------------------------------------------===// 706 // Top Level Driver Code 707 //===----------------------------------------------------------------------===// 708 709 void RewriteModernObjC::HandleTopLevelSingleDecl(Decl *D) { 710 if (Diags.hasErrorOccurred()) 711 return; 712 713 // Two cases: either the decl could be in the main file, or it could be in a 714 // #included file. If the former, rewrite it now. If the later, check to see 715 // if we rewrote the #include/#import. 716 SourceLocation Loc = D->getLocation(); 717 Loc = SM->getExpansionLoc(Loc); 718 719 // If this is for a builtin, ignore it. 720 if (Loc.isInvalid()) return; 721 722 // Look for built-in declarations that we need to refer during the rewrite. 723 if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { 724 RewriteFunctionDecl(FD); 725 } else if (VarDecl *FVD = dyn_cast<VarDecl>(D)) { 726 // declared in <Foundation/NSString.h> 727 if (FVD->getName() == "_NSConstantStringClassReference") { 728 ConstantStringClassReference = FVD; 729 return; 730 } 731 } else if (ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(D)) { 732 RewriteCategoryDecl(CD); 733 } else if (ObjCProtocolDecl *PD = dyn_cast<ObjCProtocolDecl>(D)) { 734 if (PD->isThisDeclarationADefinition()) 735 RewriteProtocolDecl(PD); 736 } else if (LinkageSpecDecl *LSD = dyn_cast<LinkageSpecDecl>(D)) { 737 // FIXME. This will not work in all situations and leaving it out 738 // is harmless. 739 // RewriteLinkageSpec(LSD); 740 741 // Recurse into linkage specifications 742 for (DeclContext::decl_iterator DI = LSD->decls_begin(), 743 DIEnd = LSD->decls_end(); 744 DI != DIEnd; ) { 745 if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>((*DI))) { 746 if (!IFace->isThisDeclarationADefinition()) { 747 SmallVector<Decl *, 8> DG; 748 SourceLocation StartLoc = IFace->getLocStart(); 749 do { 750 if (isa<ObjCInterfaceDecl>(*DI) && 751 !cast<ObjCInterfaceDecl>(*DI)->isThisDeclarationADefinition() && 752 StartLoc == (*DI)->getLocStart()) 753 DG.push_back(*DI); 754 else 755 break; 756 757 ++DI; 758 } while (DI != DIEnd); 759 RewriteForwardClassDecl(DG); 760 continue; 761 } 762 else { 763 // Keep track of all interface declarations seen. 764 ObjCInterfacesSeen.push_back(IFace); 765 ++DI; 766 continue; 767 } 768 } 769 770 if (ObjCProtocolDecl *Proto = dyn_cast<ObjCProtocolDecl>((*DI))) { 771 if (!Proto->isThisDeclarationADefinition()) { 772 SmallVector<Decl *, 8> DG; 773 SourceLocation StartLoc = Proto->getLocStart(); 774 do { 775 if (isa<ObjCProtocolDecl>(*DI) && 776 !cast<ObjCProtocolDecl>(*DI)->isThisDeclarationADefinition() && 777 StartLoc == (*DI)->getLocStart()) 778 DG.push_back(*DI); 779 else 780 break; 781 782 ++DI; 783 } while (DI != DIEnd); 784 RewriteForwardProtocolDecl(DG); 785 continue; 786 } 787 } 788 789 HandleTopLevelSingleDecl(*DI); 790 ++DI; 791 } 792 } 793 // If we have a decl in the main file, see if we should rewrite it. 794 if (SM->isFromMainFile(Loc)) 795 return HandleDeclInMainFile(D); 796 } 797 798 //===----------------------------------------------------------------------===// 799 // Syntactic (non-AST) Rewriting Code 800 //===----------------------------------------------------------------------===// 801 802 void RewriteModernObjC::RewriteInclude() { 803 SourceLocation LocStart = SM->getLocForStartOfFile(MainFileID); 804 StringRef MainBuf = SM->getBufferData(MainFileID); 805 const char *MainBufStart = MainBuf.begin(); 806 const char *MainBufEnd = MainBuf.end(); 807 size_t ImportLen = strlen("import"); 808 809 // Loop over the whole file, looking for includes. 810 for (const char *BufPtr = MainBufStart; BufPtr < MainBufEnd; ++BufPtr) { 811 if (*BufPtr == '#') { 812 if (++BufPtr == MainBufEnd) 813 return; 814 while (*BufPtr == ' ' || *BufPtr == '\t') 815 if (++BufPtr == MainBufEnd) 816 return; 817 if (!strncmp(BufPtr, "import", ImportLen)) { 818 // replace import with include 819 SourceLocation ImportLoc = 820 LocStart.getLocWithOffset(BufPtr-MainBufStart); 821 ReplaceText(ImportLoc, ImportLen, "include"); 822 BufPtr += ImportLen; 823 } 824 } 825 } 826 } 827 828 static void WriteInternalIvarName(const ObjCInterfaceDecl *IDecl, 829 ObjCIvarDecl *IvarDecl, std::string &Result) { 830 Result += "OBJC_IVAR_$_"; 831 Result += IDecl->getName(); 832 Result += "$"; 833 Result += IvarDecl->getName(); 834 } 835 836 std::string 837 RewriteModernObjC::getIvarAccessString(ObjCIvarDecl *D) { 838 const ObjCInterfaceDecl *ClassDecl = D->getContainingInterface(); 839 840 // Build name of symbol holding ivar offset. 841 std::string IvarOffsetName; 842 if (D->isBitField()) 843 ObjCIvarBitfieldGroupOffset(D, IvarOffsetName); 844 else 845 WriteInternalIvarName(ClassDecl, D, IvarOffsetName); 846 847 848 std::string S = "(*("; 849 QualType IvarT = D->getType(); 850 if (D->isBitField()) 851 IvarT = GetGroupRecordTypeForObjCIvarBitfield(D); 852 853 if (!isa<TypedefType>(IvarT) && IvarT->isRecordType()) { 854 RecordDecl *RD = IvarT->getAs<RecordType>()->getDecl(); 855 RD = RD->getDefinition(); 856 if (RD && !RD->getDeclName().getAsIdentifierInfo()) { 857 // decltype(((Foo_IMPL*)0)->bar) * 858 ObjCContainerDecl *CDecl = 859 dyn_cast<ObjCContainerDecl>(D->getDeclContext()); 860 // ivar in class extensions requires special treatment. 861 if (ObjCCategoryDecl *CatDecl = dyn_cast<ObjCCategoryDecl>(CDecl)) 862 CDecl = CatDecl->getClassInterface(); 863 std::string RecName = CDecl->getName(); 864 RecName += "_IMPL"; 865 RecordDecl *RD = RecordDecl::Create(*Context, TTK_Struct, TUDecl, 866 SourceLocation(), SourceLocation(), 867 &Context->Idents.get(RecName.c_str())); 868 QualType PtrStructIMPL = Context->getPointerType(Context->getTagDeclType(RD)); 869 unsigned UnsignedIntSize = 870 static_cast<unsigned>(Context->getTypeSize(Context->UnsignedIntTy)); 871 Expr *Zero = IntegerLiteral::Create(*Context, 872 llvm::APInt(UnsignedIntSize, 0), 873 Context->UnsignedIntTy, SourceLocation()); 874 Zero = NoTypeInfoCStyleCastExpr(Context, PtrStructIMPL, CK_BitCast, Zero); 875 ParenExpr *PE = new (Context) ParenExpr(SourceLocation(), SourceLocation(), 876 Zero); 877 FieldDecl *FD = FieldDecl::Create(*Context, 0, SourceLocation(), 878 SourceLocation(), 879 &Context->Idents.get(D->getNameAsString()), 880 IvarT, 0, 881 /*BitWidth=*/0, /*Mutable=*/true, 882 ICIS_NoInit); 883 MemberExpr *ME = new (Context) MemberExpr(PE, true, FD, SourceLocation(), 884 FD->getType(), VK_LValue, 885 OK_Ordinary); 886 IvarT = Context->getDecltypeType(ME, ME->getType()); 887 } 888 } 889 convertObjCTypeToCStyleType(IvarT); 890 QualType castT = Context->getPointerType(IvarT); 891 std::string TypeString(castT.getAsString(Context->getPrintingPolicy())); 892 S += TypeString; 893 S += ")"; 894 895 // ((char *)self + IVAR_OFFSET_SYMBOL_NAME) 896 S += "((char *)self + "; 897 S += IvarOffsetName; 898 S += "))"; 899 if (D->isBitField()) { 900 S += "."; 901 S += D->getNameAsString(); 902 } 903 ReferencedIvars[const_cast<ObjCInterfaceDecl *>(ClassDecl)].insert(D); 904 return S; 905 } 906 907 /// mustSynthesizeSetterGetterMethod - returns true if setter or getter has not 908 /// been found in the class implementation. In this case, it must be synthesized. 909 static bool mustSynthesizeSetterGetterMethod(ObjCImplementationDecl *IMP, 910 ObjCPropertyDecl *PD, 911 bool getter) { 912 return getter ? !IMP->getInstanceMethod(PD->getGetterName()) 913 : !IMP->getInstanceMethod(PD->getSetterName()); 914 915 } 916 917 void RewriteModernObjC::RewritePropertyImplDecl(ObjCPropertyImplDecl *PID, 918 ObjCImplementationDecl *IMD, 919 ObjCCategoryImplDecl *CID) { 920 static bool objcGetPropertyDefined = false; 921 static bool objcSetPropertyDefined = false; 922 SourceLocation startGetterSetterLoc; 923 924 if (PID->getLocStart().isValid()) { 925 SourceLocation startLoc = PID->getLocStart(); 926 InsertText(startLoc, "// "); 927 const char *startBuf = SM->getCharacterData(startLoc); 928 assert((*startBuf == '@') && "bogus @synthesize location"); 929 const char *semiBuf = strchr(startBuf, ';'); 930 assert((*semiBuf == ';') && "@synthesize: can't find ';'"); 931 startGetterSetterLoc = startLoc.getLocWithOffset(semiBuf-startBuf+1); 932 } 933 else 934 startGetterSetterLoc = IMD ? IMD->getLocEnd() : CID->getLocEnd(); 935 936 if (PID->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic) 937 return; // FIXME: is this correct? 938 939 // Generate the 'getter' function. 940 ObjCPropertyDecl *PD = PID->getPropertyDecl(); 941 ObjCIvarDecl *OID = PID->getPropertyIvarDecl(); 942 assert(IMD && OID && "Synthesized ivars must be attached to @implementation"); 943 944 unsigned Attributes = PD->getPropertyAttributes(); 945 if (mustSynthesizeSetterGetterMethod(IMD, PD, true /*getter*/)) { 946 bool GenGetProperty = !(Attributes & ObjCPropertyDecl::OBJC_PR_nonatomic) && 947 (Attributes & (ObjCPropertyDecl::OBJC_PR_retain | 948 ObjCPropertyDecl::OBJC_PR_copy)); 949 std::string Getr; 950 if (GenGetProperty && !objcGetPropertyDefined) { 951 objcGetPropertyDefined = true; 952 // FIXME. Is this attribute correct in all cases? 953 Getr = "\nextern \"C\" __declspec(dllimport) " 954 "id objc_getProperty(id, SEL, long, bool);\n"; 955 } 956 RewriteObjCMethodDecl(OID->getContainingInterface(), 957 PD->getGetterMethodDecl(), Getr); 958 Getr += "{ "; 959 // Synthesize an explicit cast to gain access to the ivar. 960 // See objc-act.c:objc_synthesize_new_getter() for details. 961 if (GenGetProperty) { 962 // return objc_getProperty(self, _cmd, offsetof(ClassDecl, OID), 1) 963 Getr += "typedef "; 964 const FunctionType *FPRetType = 0; 965 RewriteTypeIntoString(PD->getGetterMethodDecl()->getResultType(), Getr, 966 FPRetType); 967 Getr += " _TYPE"; 968 if (FPRetType) { 969 Getr += ")"; // close the precedence "scope" for "*". 970 971 // Now, emit the argument types (if any). 972 if (const FunctionProtoType *FT = dyn_cast<FunctionProtoType>(FPRetType)){ 973 Getr += "("; 974 for (unsigned i = 0, e = FT->getNumArgs(); i != e; ++i) { 975 if (i) Getr += ", "; 976 std::string ParamStr = FT->getArgType(i).getAsString( 977 Context->getPrintingPolicy()); 978 Getr += ParamStr; 979 } 980 if (FT->isVariadic()) { 981 if (FT->getNumArgs()) Getr += ", "; 982 Getr += "..."; 983 } 984 Getr += ")"; 985 } else 986 Getr += "()"; 987 } 988 Getr += ";\n"; 989 Getr += "return (_TYPE)"; 990 Getr += "objc_getProperty(self, _cmd, "; 991 RewriteIvarOffsetComputation(OID, Getr); 992 Getr += ", 1)"; 993 } 994 else 995 Getr += "return " + getIvarAccessString(OID); 996 Getr += "; }"; 997 InsertText(startGetterSetterLoc, Getr); 998 } 999 1000 if (PD->isReadOnly() || 1001 !mustSynthesizeSetterGetterMethod(IMD, PD, false /*setter*/)) 1002 return; 1003 1004 // Generate the 'setter' function. 1005 std::string Setr; 1006 bool GenSetProperty = Attributes & (ObjCPropertyDecl::OBJC_PR_retain | 1007 ObjCPropertyDecl::OBJC_PR_copy); 1008 if (GenSetProperty && !objcSetPropertyDefined) { 1009 objcSetPropertyDefined = true; 1010 // FIXME. Is this attribute correct in all cases? 1011 Setr = "\nextern \"C\" __declspec(dllimport) " 1012 "void objc_setProperty (id, SEL, long, id, bool, bool);\n"; 1013 } 1014 1015 RewriteObjCMethodDecl(OID->getContainingInterface(), 1016 PD->getSetterMethodDecl(), Setr); 1017 Setr += "{ "; 1018 // Synthesize an explicit cast to initialize the ivar. 1019 // See objc-act.c:objc_synthesize_new_setter() for details. 1020 if (GenSetProperty) { 1021 Setr += "objc_setProperty (self, _cmd, "; 1022 RewriteIvarOffsetComputation(OID, Setr); 1023 Setr += ", (id)"; 1024 Setr += PD->getName(); 1025 Setr += ", "; 1026 if (Attributes & ObjCPropertyDecl::OBJC_PR_nonatomic) 1027 Setr += "0, "; 1028 else 1029 Setr += "1, "; 1030 if (Attributes & ObjCPropertyDecl::OBJC_PR_copy) 1031 Setr += "1)"; 1032 else 1033 Setr += "0)"; 1034 } 1035 else { 1036 Setr += getIvarAccessString(OID) + " = "; 1037 Setr += PD->getName(); 1038 } 1039 Setr += "; }\n"; 1040 InsertText(startGetterSetterLoc, Setr); 1041 } 1042 1043 static void RewriteOneForwardClassDecl(ObjCInterfaceDecl *ForwardDecl, 1044 std::string &typedefString) { 1045 typedefString += "\n#ifndef _REWRITER_typedef_"; 1046 typedefString += ForwardDecl->getNameAsString(); 1047 typedefString += "\n"; 1048 typedefString += "#define _REWRITER_typedef_"; 1049 typedefString += ForwardDecl->getNameAsString(); 1050 typedefString += "\n"; 1051 typedefString += "typedef struct objc_object "; 1052 typedefString += ForwardDecl->getNameAsString(); 1053 // typedef struct { } _objc_exc_Classname; 1054 typedefString += ";\ntypedef struct {} _objc_exc_"; 1055 typedefString += ForwardDecl->getNameAsString(); 1056 typedefString += ";\n#endif\n"; 1057 } 1058 1059 void RewriteModernObjC::RewriteForwardClassEpilogue(ObjCInterfaceDecl *ClassDecl, 1060 const std::string &typedefString) { 1061 SourceLocation startLoc = ClassDecl->getLocStart(); 1062 const char *startBuf = SM->getCharacterData(startLoc); 1063 const char *semiPtr = strchr(startBuf, ';'); 1064 // Replace the @class with typedefs corresponding to the classes. 1065 ReplaceText(startLoc, semiPtr-startBuf+1, typedefString); 1066 } 1067 1068 void RewriteModernObjC::RewriteForwardClassDecl(DeclGroupRef D) { 1069 std::string typedefString; 1070 for (DeclGroupRef::iterator I = D.begin(), E = D.end(); I != E; ++I) { 1071 ObjCInterfaceDecl *ForwardDecl = cast<ObjCInterfaceDecl>(*I); 1072 if (I == D.begin()) { 1073 // Translate to typedef's that forward reference structs with the same name 1074 // as the class. As a convenience, we include the original declaration 1075 // as a comment. 1076 typedefString += "// @class "; 1077 typedefString += ForwardDecl->getNameAsString(); 1078 typedefString += ";"; 1079 } 1080 RewriteOneForwardClassDecl(ForwardDecl, typedefString); 1081 } 1082 DeclGroupRef::iterator I = D.begin(); 1083 RewriteForwardClassEpilogue(cast<ObjCInterfaceDecl>(*I), typedefString); 1084 } 1085 1086 void RewriteModernObjC::RewriteForwardClassDecl( 1087 const SmallVectorImpl<Decl *> &D) { 1088 std::string typedefString; 1089 for (unsigned i = 0; i < D.size(); i++) { 1090 ObjCInterfaceDecl *ForwardDecl = cast<ObjCInterfaceDecl>(D[i]); 1091 if (i == 0) { 1092 typedefString += "// @class "; 1093 typedefString += ForwardDecl->getNameAsString(); 1094 typedefString += ";"; 1095 } 1096 RewriteOneForwardClassDecl(ForwardDecl, typedefString); 1097 } 1098 RewriteForwardClassEpilogue(cast<ObjCInterfaceDecl>(D[0]), typedefString); 1099 } 1100 1101 void RewriteModernObjC::RewriteMethodDeclaration(ObjCMethodDecl *Method) { 1102 // When method is a synthesized one, such as a getter/setter there is 1103 // nothing to rewrite. 1104 if (Method->isImplicit()) 1105 return; 1106 SourceLocation LocStart = Method->getLocStart(); 1107 SourceLocation LocEnd = Method->getLocEnd(); 1108 1109 if (SM->getExpansionLineNumber(LocEnd) > 1110 SM->getExpansionLineNumber(LocStart)) { 1111 InsertText(LocStart, "#if 0\n"); 1112 ReplaceText(LocEnd, 1, ";\n#endif\n"); 1113 } else { 1114 InsertText(LocStart, "// "); 1115 } 1116 } 1117 1118 void RewriteModernObjC::RewriteProperty(ObjCPropertyDecl *prop) { 1119 SourceLocation Loc = prop->getAtLoc(); 1120 1121 ReplaceText(Loc, 0, "// "); 1122 // FIXME: handle properties that are declared across multiple lines. 1123 } 1124 1125 void RewriteModernObjC::RewriteCategoryDecl(ObjCCategoryDecl *CatDecl) { 1126 SourceLocation LocStart = CatDecl->getLocStart(); 1127 1128 // FIXME: handle category headers that are declared across multiple lines. 1129 if (CatDecl->getIvarRBraceLoc().isValid()) { 1130 ReplaceText(LocStart, 1, "/** "); 1131 ReplaceText(CatDecl->getIvarRBraceLoc(), 1, "**/ "); 1132 } 1133 else { 1134 ReplaceText(LocStart, 0, "// "); 1135 } 1136 1137 for (ObjCCategoryDecl::prop_iterator I = CatDecl->prop_begin(), 1138 E = CatDecl->prop_end(); I != E; ++I) 1139 RewriteProperty(*I); 1140 1141 for (ObjCCategoryDecl::instmeth_iterator 1142 I = CatDecl->instmeth_begin(), E = CatDecl->instmeth_end(); 1143 I != E; ++I) 1144 RewriteMethodDeclaration(*I); 1145 for (ObjCCategoryDecl::classmeth_iterator 1146 I = CatDecl->classmeth_begin(), E = CatDecl->classmeth_end(); 1147 I != E; ++I) 1148 RewriteMethodDeclaration(*I); 1149 1150 // Lastly, comment out the @end. 1151 ReplaceText(CatDecl->getAtEndRange().getBegin(), 1152 strlen("@end"), "/* @end */\n"); 1153 } 1154 1155 void RewriteModernObjC::RewriteProtocolDecl(ObjCProtocolDecl *PDecl) { 1156 SourceLocation LocStart = PDecl->getLocStart(); 1157 assert(PDecl->isThisDeclarationADefinition()); 1158 1159 // FIXME: handle protocol headers that are declared across multiple lines. 1160 ReplaceText(LocStart, 0, "// "); 1161 1162 for (ObjCProtocolDecl::instmeth_iterator 1163 I = PDecl->instmeth_begin(), E = PDecl->instmeth_end(); 1164 I != E; ++I) 1165 RewriteMethodDeclaration(*I); 1166 for (ObjCProtocolDecl::classmeth_iterator 1167 I = PDecl->classmeth_begin(), E = PDecl->classmeth_end(); 1168 I != E; ++I) 1169 RewriteMethodDeclaration(*I); 1170 1171 for (ObjCInterfaceDecl::prop_iterator I = PDecl->prop_begin(), 1172 E = PDecl->prop_end(); I != E; ++I) 1173 RewriteProperty(*I); 1174 1175 // Lastly, comment out the @end. 1176 SourceLocation LocEnd = PDecl->getAtEndRange().getBegin(); 1177 ReplaceText(LocEnd, strlen("@end"), "/* @end */\n"); 1178 1179 // Must comment out @optional/@required 1180 const char *startBuf = SM->getCharacterData(LocStart); 1181 const char *endBuf = SM->getCharacterData(LocEnd); 1182 for (const char *p = startBuf; p < endBuf; p++) { 1183 if (*p == '@' && !strncmp(p+1, "optional", strlen("optional"))) { 1184 SourceLocation OptionalLoc = LocStart.getLocWithOffset(p-startBuf); 1185 ReplaceText(OptionalLoc, strlen("@optional"), "/* @optional */"); 1186 1187 } 1188 else if (*p == '@' && !strncmp(p+1, "required", strlen("required"))) { 1189 SourceLocation OptionalLoc = LocStart.getLocWithOffset(p-startBuf); 1190 ReplaceText(OptionalLoc, strlen("@required"), "/* @required */"); 1191 1192 } 1193 } 1194 } 1195 1196 void RewriteModernObjC::RewriteForwardProtocolDecl(DeclGroupRef D) { 1197 SourceLocation LocStart = (*D.begin())->getLocStart(); 1198 if (LocStart.isInvalid()) 1199 llvm_unreachable("Invalid SourceLocation"); 1200 // FIXME: handle forward protocol that are declared across multiple lines. 1201 ReplaceText(LocStart, 0, "// "); 1202 } 1203 1204 void 1205 RewriteModernObjC::RewriteForwardProtocolDecl(const SmallVectorImpl<Decl *> &DG) { 1206 SourceLocation LocStart = DG[0]->getLocStart(); 1207 if (LocStart.isInvalid()) 1208 llvm_unreachable("Invalid SourceLocation"); 1209 // FIXME: handle forward protocol that are declared across multiple lines. 1210 ReplaceText(LocStart, 0, "// "); 1211 } 1212 1213 void 1214 RewriteModernObjC::RewriteLinkageSpec(LinkageSpecDecl *LSD) { 1215 SourceLocation LocStart = LSD->getExternLoc(); 1216 if (LocStart.isInvalid()) 1217 llvm_unreachable("Invalid extern SourceLocation"); 1218 1219 ReplaceText(LocStart, 0, "// "); 1220 if (!LSD->hasBraces()) 1221 return; 1222 // FIXME. We don't rewrite well if '{' is not on same line as 'extern'. 1223 SourceLocation LocRBrace = LSD->getRBraceLoc(); 1224 if (LocRBrace.isInvalid()) 1225 llvm_unreachable("Invalid rbrace SourceLocation"); 1226 ReplaceText(LocRBrace, 0, "// "); 1227 } 1228 1229 void RewriteModernObjC::RewriteTypeIntoString(QualType T, std::string &ResultStr, 1230 const FunctionType *&FPRetType) { 1231 if (T->isObjCQualifiedIdType()) 1232 ResultStr += "id"; 1233 else if (T->isFunctionPointerType() || 1234 T->isBlockPointerType()) { 1235 // needs special handling, since pointer-to-functions have special 1236 // syntax (where a decaration models use). 1237 QualType retType = T; 1238 QualType PointeeTy; 1239 if (const PointerType* PT = retType->getAs<PointerType>()) 1240 PointeeTy = PT->getPointeeType(); 1241 else if (const BlockPointerType *BPT = retType->getAs<BlockPointerType>()) 1242 PointeeTy = BPT->getPointeeType(); 1243 if ((FPRetType = PointeeTy->getAs<FunctionType>())) { 1244 ResultStr += FPRetType->getResultType().getAsString( 1245 Context->getPrintingPolicy()); 1246 ResultStr += "(*"; 1247 } 1248 } else 1249 ResultStr += T.getAsString(Context->getPrintingPolicy()); 1250 } 1251 1252 void RewriteModernObjC::RewriteObjCMethodDecl(const ObjCInterfaceDecl *IDecl, 1253 ObjCMethodDecl *OMD, 1254 std::string &ResultStr) { 1255 //fprintf(stderr,"In RewriteObjCMethodDecl\n"); 1256 const FunctionType *FPRetType = 0; 1257 ResultStr += "\nstatic "; 1258 RewriteTypeIntoString(OMD->getResultType(), ResultStr, FPRetType); 1259 ResultStr += " "; 1260 1261 // Unique method name 1262 std::string NameStr; 1263 1264 if (OMD->isInstanceMethod()) 1265 NameStr += "_I_"; 1266 else 1267 NameStr += "_C_"; 1268 1269 NameStr += IDecl->getNameAsString(); 1270 NameStr += "_"; 1271 1272 if (ObjCCategoryImplDecl *CID = 1273 dyn_cast<ObjCCategoryImplDecl>(OMD->getDeclContext())) { 1274 NameStr += CID->getNameAsString(); 1275 NameStr += "_"; 1276 } 1277 // Append selector names, replacing ':' with '_' 1278 { 1279 std::string selString = OMD->getSelector().getAsString(); 1280 int len = selString.size(); 1281 for (int i = 0; i < len; i++) 1282 if (selString[i] == ':') 1283 selString[i] = '_'; 1284 NameStr += selString; 1285 } 1286 // Remember this name for metadata emission 1287 MethodInternalNames[OMD] = NameStr; 1288 ResultStr += NameStr; 1289 1290 // Rewrite arguments 1291 ResultStr += "("; 1292 1293 // invisible arguments 1294 if (OMD->isInstanceMethod()) { 1295 QualType selfTy = Context->getObjCInterfaceType(IDecl); 1296 selfTy = Context->getPointerType(selfTy); 1297 if (!LangOpts.MicrosoftExt) { 1298 if (ObjCSynthesizedStructs.count(const_cast<ObjCInterfaceDecl*>(IDecl))) 1299 ResultStr += "struct "; 1300 } 1301 // When rewriting for Microsoft, explicitly omit the structure name. 1302 ResultStr += IDecl->getNameAsString(); 1303 ResultStr += " *"; 1304 } 1305 else 1306 ResultStr += Context->getObjCClassType().getAsString( 1307 Context->getPrintingPolicy()); 1308 1309 ResultStr += " self, "; 1310 ResultStr += Context->getObjCSelType().getAsString(Context->getPrintingPolicy()); 1311 ResultStr += " _cmd"; 1312 1313 // Method arguments. 1314 for (ObjCMethodDecl::param_iterator PI = OMD->param_begin(), 1315 E = OMD->param_end(); PI != E; ++PI) { 1316 ParmVarDecl *PDecl = *PI; 1317 ResultStr += ", "; 1318 if (PDecl->getType()->isObjCQualifiedIdType()) { 1319 ResultStr += "id "; 1320 ResultStr += PDecl->getNameAsString(); 1321 } else { 1322 std::string Name = PDecl->getNameAsString(); 1323 QualType QT = PDecl->getType(); 1324 // Make sure we convert "t (^)(...)" to "t (*)(...)". 1325 (void)convertBlockPointerToFunctionPointer(QT); 1326 QT.getAsStringInternal(Name, Context->getPrintingPolicy()); 1327 ResultStr += Name; 1328 } 1329 } 1330 if (OMD->isVariadic()) 1331 ResultStr += ", ..."; 1332 ResultStr += ") "; 1333 1334 if (FPRetType) { 1335 ResultStr += ")"; // close the precedence "scope" for "*". 1336 1337 // Now, emit the argument types (if any). 1338 if (const FunctionProtoType *FT = dyn_cast<FunctionProtoType>(FPRetType)) { 1339 ResultStr += "("; 1340 for (unsigned i = 0, e = FT->getNumArgs(); i != e; ++i) { 1341 if (i) ResultStr += ", "; 1342 std::string ParamStr = FT->getArgType(i).getAsString( 1343 Context->getPrintingPolicy()); 1344 ResultStr += ParamStr; 1345 } 1346 if (FT->isVariadic()) { 1347 if (FT->getNumArgs()) ResultStr += ", "; 1348 ResultStr += "..."; 1349 } 1350 ResultStr += ")"; 1351 } else { 1352 ResultStr += "()"; 1353 } 1354 } 1355 } 1356 void RewriteModernObjC::RewriteImplementationDecl(Decl *OID) { 1357 ObjCImplementationDecl *IMD = dyn_cast<ObjCImplementationDecl>(OID); 1358 ObjCCategoryImplDecl *CID = dyn_cast<ObjCCategoryImplDecl>(OID); 1359 1360 if (IMD) { 1361 if (IMD->getIvarRBraceLoc().isValid()) { 1362 ReplaceText(IMD->getLocStart(), 1, "/** "); 1363 ReplaceText(IMD->getIvarRBraceLoc(), 1, "**/ "); 1364 } 1365 else { 1366 InsertText(IMD->getLocStart(), "// "); 1367 } 1368 } 1369 else 1370 InsertText(CID->getLocStart(), "// "); 1371 1372 for (ObjCCategoryImplDecl::instmeth_iterator 1373 I = IMD ? IMD->instmeth_begin() : CID->instmeth_begin(), 1374 E = IMD ? IMD->instmeth_end() : CID->instmeth_end(); 1375 I != E; ++I) { 1376 std::string ResultStr; 1377 ObjCMethodDecl *OMD = *I; 1378 RewriteObjCMethodDecl(OMD->getClassInterface(), OMD, ResultStr); 1379 SourceLocation LocStart = OMD->getLocStart(); 1380 SourceLocation LocEnd = OMD->getCompoundBody()->getLocStart(); 1381 1382 const char *startBuf = SM->getCharacterData(LocStart); 1383 const char *endBuf = SM->getCharacterData(LocEnd); 1384 ReplaceText(LocStart, endBuf-startBuf, ResultStr); 1385 } 1386 1387 for (ObjCCategoryImplDecl::classmeth_iterator 1388 I = IMD ? IMD->classmeth_begin() : CID->classmeth_begin(), 1389 E = IMD ? IMD->classmeth_end() : CID->classmeth_end(); 1390 I != E; ++I) { 1391 std::string ResultStr; 1392 ObjCMethodDecl *OMD = *I; 1393 RewriteObjCMethodDecl(OMD->getClassInterface(), OMD, ResultStr); 1394 SourceLocation LocStart = OMD->getLocStart(); 1395 SourceLocation LocEnd = OMD->getCompoundBody()->getLocStart(); 1396 1397 const char *startBuf = SM->getCharacterData(LocStart); 1398 const char *endBuf = SM->getCharacterData(LocEnd); 1399 ReplaceText(LocStart, endBuf-startBuf, ResultStr); 1400 } 1401 for (ObjCCategoryImplDecl::propimpl_iterator 1402 I = IMD ? IMD->propimpl_begin() : CID->propimpl_begin(), 1403 E = IMD ? IMD->propimpl_end() : CID->propimpl_end(); 1404 I != E; ++I) { 1405 RewritePropertyImplDecl(*I, IMD, CID); 1406 } 1407 1408 InsertText(IMD ? IMD->getLocEnd() : CID->getLocEnd(), "// "); 1409 } 1410 1411 void RewriteModernObjC::RewriteInterfaceDecl(ObjCInterfaceDecl *ClassDecl) { 1412 // Do not synthesize more than once. 1413 if (ObjCSynthesizedStructs.count(ClassDecl)) 1414 return; 1415 // Make sure super class's are written before current class is written. 1416 ObjCInterfaceDecl *SuperClass = ClassDecl->getSuperClass(); 1417 while (SuperClass) { 1418 RewriteInterfaceDecl(SuperClass); 1419 SuperClass = SuperClass->getSuperClass(); 1420 } 1421 std::string ResultStr; 1422 if (!ObjCWrittenInterfaces.count(ClassDecl->getCanonicalDecl())) { 1423 // we haven't seen a forward decl - generate a typedef. 1424 RewriteOneForwardClassDecl(ClassDecl, ResultStr); 1425 RewriteIvarOffsetSymbols(ClassDecl, ResultStr); 1426 1427 RewriteObjCInternalStruct(ClassDecl, ResultStr); 1428 // Mark this typedef as having been written into its c++ equivalent. 1429 ObjCWrittenInterfaces.insert(ClassDecl->getCanonicalDecl()); 1430 1431 for (ObjCInterfaceDecl::prop_iterator I = ClassDecl->prop_begin(), 1432 E = ClassDecl->prop_end(); I != E; ++I) 1433 RewriteProperty(*I); 1434 for (ObjCInterfaceDecl::instmeth_iterator 1435 I = ClassDecl->instmeth_begin(), E = ClassDecl->instmeth_end(); 1436 I != E; ++I) 1437 RewriteMethodDeclaration(*I); 1438 for (ObjCInterfaceDecl::classmeth_iterator 1439 I = ClassDecl->classmeth_begin(), E = ClassDecl->classmeth_end(); 1440 I != E; ++I) 1441 RewriteMethodDeclaration(*I); 1442 1443 // Lastly, comment out the @end. 1444 ReplaceText(ClassDecl->getAtEndRange().getBegin(), strlen("@end"), 1445 "/* @end */\n"); 1446 } 1447 } 1448 1449 Stmt *RewriteModernObjC::RewritePropertyOrImplicitSetter(PseudoObjectExpr *PseudoOp) { 1450 SourceRange OldRange = PseudoOp->getSourceRange(); 1451 1452 // We just magically know some things about the structure of this 1453 // expression. 1454 ObjCMessageExpr *OldMsg = 1455 cast<ObjCMessageExpr>(PseudoOp->getSemanticExpr( 1456 PseudoOp->getNumSemanticExprs() - 1)); 1457 1458 // Because the rewriter doesn't allow us to rewrite rewritten code, 1459 // we need to suppress rewriting the sub-statements. 1460 Expr *Base; 1461 SmallVector<Expr*, 2> Args; 1462 { 1463 DisableReplaceStmtScope S(*this); 1464 1465 // Rebuild the base expression if we have one. 1466 Base = 0; 1467 if (OldMsg->getReceiverKind() == ObjCMessageExpr::Instance) { 1468 Base = OldMsg->getInstanceReceiver(); 1469 Base = cast<OpaqueValueExpr>(Base)->getSourceExpr(); 1470 Base = cast<Expr>(RewriteFunctionBodyOrGlobalInitializer(Base)); 1471 } 1472 1473 unsigned numArgs = OldMsg->getNumArgs(); 1474 for (unsigned i = 0; i < numArgs; i++) { 1475 Expr *Arg = OldMsg->getArg(i); 1476 if (isa<OpaqueValueExpr>(Arg)) 1477 Arg = cast<OpaqueValueExpr>(Arg)->getSourceExpr(); 1478 Arg = cast<Expr>(RewriteFunctionBodyOrGlobalInitializer(Arg)); 1479 Args.push_back(Arg); 1480 } 1481 } 1482 1483 // TODO: avoid this copy. 1484 SmallVector<SourceLocation, 1> SelLocs; 1485 OldMsg->getSelectorLocs(SelLocs); 1486 1487 ObjCMessageExpr *NewMsg = 0; 1488 switch (OldMsg->getReceiverKind()) { 1489 case ObjCMessageExpr::Class: 1490 NewMsg = ObjCMessageExpr::Create(*Context, OldMsg->getType(), 1491 OldMsg->getValueKind(), 1492 OldMsg->getLeftLoc(), 1493 OldMsg->getClassReceiverTypeInfo(), 1494 OldMsg->getSelector(), 1495 SelLocs, 1496 OldMsg->getMethodDecl(), 1497 Args, 1498 OldMsg->getRightLoc(), 1499 OldMsg->isImplicit()); 1500 break; 1501 1502 case ObjCMessageExpr::Instance: 1503 NewMsg = ObjCMessageExpr::Create(*Context, OldMsg->getType(), 1504 OldMsg->getValueKind(), 1505 OldMsg->getLeftLoc(), 1506 Base, 1507 OldMsg->getSelector(), 1508 SelLocs, 1509 OldMsg->getMethodDecl(), 1510 Args, 1511 OldMsg->getRightLoc(), 1512 OldMsg->isImplicit()); 1513 break; 1514 1515 case ObjCMessageExpr::SuperClass: 1516 case ObjCMessageExpr::SuperInstance: 1517 NewMsg = ObjCMessageExpr::Create(*Context, OldMsg->getType(), 1518 OldMsg->getValueKind(), 1519 OldMsg->getLeftLoc(), 1520 OldMsg->getSuperLoc(), 1521 OldMsg->getReceiverKind() == ObjCMessageExpr::SuperInstance, 1522 OldMsg->getSuperType(), 1523 OldMsg->getSelector(), 1524 SelLocs, 1525 OldMsg->getMethodDecl(), 1526 Args, 1527 OldMsg->getRightLoc(), 1528 OldMsg->isImplicit()); 1529 break; 1530 } 1531 1532 Stmt *Replacement = SynthMessageExpr(NewMsg); 1533 ReplaceStmtWithRange(PseudoOp, Replacement, OldRange); 1534 return Replacement; 1535 } 1536 1537 Stmt *RewriteModernObjC::RewritePropertyOrImplicitGetter(PseudoObjectExpr *PseudoOp) { 1538 SourceRange OldRange = PseudoOp->getSourceRange(); 1539 1540 // We just magically know some things about the structure of this 1541 // expression. 1542 ObjCMessageExpr *OldMsg = 1543 cast<ObjCMessageExpr>(PseudoOp->getResultExpr()->IgnoreImplicit()); 1544 1545 // Because the rewriter doesn't allow us to rewrite rewritten code, 1546 // we need to suppress rewriting the sub-statements. 1547 Expr *Base = 0; 1548 SmallVector<Expr*, 1> Args; 1549 { 1550 DisableReplaceStmtScope S(*this); 1551 // Rebuild the base expression if we have one. 1552 if (OldMsg->getReceiverKind() == ObjCMessageExpr::Instance) { 1553 Base = OldMsg->getInstanceReceiver(); 1554 Base = cast<OpaqueValueExpr>(Base)->getSourceExpr(); 1555 Base = cast<Expr>(RewriteFunctionBodyOrGlobalInitializer(Base)); 1556 } 1557 unsigned numArgs = OldMsg->getNumArgs(); 1558 for (unsigned i = 0; i < numArgs; i++) { 1559 Expr *Arg = OldMsg->getArg(i); 1560 if (isa<OpaqueValueExpr>(Arg)) 1561 Arg = cast<OpaqueValueExpr>(Arg)->getSourceExpr(); 1562 Arg = cast<Expr>(RewriteFunctionBodyOrGlobalInitializer(Arg)); 1563 Args.push_back(Arg); 1564 } 1565 } 1566 1567 // Intentionally empty. 1568 SmallVector<SourceLocation, 1> SelLocs; 1569 1570 ObjCMessageExpr *NewMsg = 0; 1571 switch (OldMsg->getReceiverKind()) { 1572 case ObjCMessageExpr::Class: 1573 NewMsg = ObjCMessageExpr::Create(*Context, OldMsg->getType(), 1574 OldMsg->getValueKind(), 1575 OldMsg->getLeftLoc(), 1576 OldMsg->getClassReceiverTypeInfo(), 1577 OldMsg->getSelector(), 1578 SelLocs, 1579 OldMsg->getMethodDecl(), 1580 Args, 1581 OldMsg->getRightLoc(), 1582 OldMsg->isImplicit()); 1583 break; 1584 1585 case ObjCMessageExpr::Instance: 1586 NewMsg = ObjCMessageExpr::Create(*Context, OldMsg->getType(), 1587 OldMsg->getValueKind(), 1588 OldMsg->getLeftLoc(), 1589 Base, 1590 OldMsg->getSelector(), 1591 SelLocs, 1592 OldMsg->getMethodDecl(), 1593 Args, 1594 OldMsg->getRightLoc(), 1595 OldMsg->isImplicit()); 1596 break; 1597 1598 case ObjCMessageExpr::SuperClass: 1599 case ObjCMessageExpr::SuperInstance: 1600 NewMsg = ObjCMessageExpr::Create(*Context, OldMsg->getType(), 1601 OldMsg->getValueKind(), 1602 OldMsg->getLeftLoc(), 1603 OldMsg->getSuperLoc(), 1604 OldMsg->getReceiverKind() == ObjCMessageExpr::SuperInstance, 1605 OldMsg->getSuperType(), 1606 OldMsg->getSelector(), 1607 SelLocs, 1608 OldMsg->getMethodDecl(), 1609 Args, 1610 OldMsg->getRightLoc(), 1611 OldMsg->isImplicit()); 1612 break; 1613 } 1614 1615 Stmt *Replacement = SynthMessageExpr(NewMsg); 1616 ReplaceStmtWithRange(PseudoOp, Replacement, OldRange); 1617 return Replacement; 1618 } 1619 1620 /// SynthCountByEnumWithState - To print: 1621 /// ((unsigned int (*) 1622 /// (id, SEL, struct __objcFastEnumerationState *, id *, unsigned int)) 1623 /// (void *)objc_msgSend)((id)l_collection, 1624 /// sel_registerName( 1625 /// "countByEnumeratingWithState:objects:count:"), 1626 /// &enumState, 1627 /// (id *)__rw_items, (unsigned int)16) 1628 /// 1629 void RewriteModernObjC::SynthCountByEnumWithState(std::string &buf) { 1630 buf += "((unsigned int (*) (id, SEL, struct __objcFastEnumerationState *, " 1631 "id *, unsigned int))(void *)objc_msgSend)"; 1632 buf += "\n\t\t"; 1633 buf += "((id)l_collection,\n\t\t"; 1634 buf += "sel_registerName(\"countByEnumeratingWithState:objects:count:\"),"; 1635 buf += "\n\t\t"; 1636 buf += "&enumState, " 1637 "(id *)__rw_items, (unsigned int)16)"; 1638 } 1639 1640 /// RewriteBreakStmt - Rewrite for a break-stmt inside an ObjC2's foreach 1641 /// statement to exit to its outer synthesized loop. 1642 /// 1643 Stmt *RewriteModernObjC::RewriteBreakStmt(BreakStmt *S) { 1644 if (Stmts.empty() || !isa<ObjCForCollectionStmt>(Stmts.back())) 1645 return S; 1646 // replace break with goto __break_label 1647 std::string buf; 1648 1649 SourceLocation startLoc = S->getLocStart(); 1650 buf = "goto __break_label_"; 1651 buf += utostr(ObjCBcLabelNo.back()); 1652 ReplaceText(startLoc, strlen("break"), buf); 1653 1654 return 0; 1655 } 1656 1657 void RewriteModernObjC::ConvertSourceLocationToLineDirective( 1658 SourceLocation Loc, 1659 std::string &LineString) { 1660 if (Loc.isFileID() && GenerateLineInfo) { 1661 LineString += "\n#line "; 1662 PresumedLoc PLoc = SM->getPresumedLoc(Loc); 1663 LineString += utostr(PLoc.getLine()); 1664 LineString += " \""; 1665 LineString += Lexer::Stringify(PLoc.getFilename()); 1666 LineString += "\"\n"; 1667 } 1668 } 1669 1670 /// RewriteContinueStmt - Rewrite for a continue-stmt inside an ObjC2's foreach 1671 /// statement to continue with its inner synthesized loop. 1672 /// 1673 Stmt *RewriteModernObjC::RewriteContinueStmt(ContinueStmt *S) { 1674 if (Stmts.empty() || !isa<ObjCForCollectionStmt>(Stmts.back())) 1675 return S; 1676 // replace continue with goto __continue_label 1677 std::string buf; 1678 1679 SourceLocation startLoc = S->getLocStart(); 1680 buf = "goto __continue_label_"; 1681 buf += utostr(ObjCBcLabelNo.back()); 1682 ReplaceText(startLoc, strlen("continue"), buf); 1683 1684 return 0; 1685 } 1686 1687 /// RewriteObjCForCollectionStmt - Rewriter for ObjC2's foreach statement. 1688 /// It rewrites: 1689 /// for ( type elem in collection) { stmts; } 1690 1691 /// Into: 1692 /// { 1693 /// type elem; 1694 /// struct __objcFastEnumerationState enumState = { 0 }; 1695 /// id __rw_items[16]; 1696 /// id l_collection = (id)collection; 1697 /// unsigned long limit = [l_collection countByEnumeratingWithState:&enumState 1698 /// objects:__rw_items count:16]; 1699 /// if (limit) { 1700 /// unsigned long startMutations = *enumState.mutationsPtr; 1701 /// do { 1702 /// unsigned long counter = 0; 1703 /// do { 1704 /// if (startMutations != *enumState.mutationsPtr) 1705 /// objc_enumerationMutation(l_collection); 1706 /// elem = (type)enumState.itemsPtr[counter++]; 1707 /// stmts; 1708 /// __continue_label: ; 1709 /// } while (counter < limit); 1710 /// } while (limit = [l_collection countByEnumeratingWithState:&enumState 1711 /// objects:__rw_items count:16]); 1712 /// elem = nil; 1713 /// __break_label: ; 1714 /// } 1715 /// else 1716 /// elem = nil; 1717 /// } 1718 /// 1719 Stmt *RewriteModernObjC::RewriteObjCForCollectionStmt(ObjCForCollectionStmt *S, 1720 SourceLocation OrigEnd) { 1721 assert(!Stmts.empty() && "ObjCForCollectionStmt - Statement stack empty"); 1722 assert(isa<ObjCForCollectionStmt>(Stmts.back()) && 1723 "ObjCForCollectionStmt Statement stack mismatch"); 1724 assert(!ObjCBcLabelNo.empty() && 1725 "ObjCForCollectionStmt - Label No stack empty"); 1726 1727 SourceLocation startLoc = S->getLocStart(); 1728 const char *startBuf = SM->getCharacterData(startLoc); 1729 StringRef elementName; 1730 std::string elementTypeAsString; 1731 std::string buf; 1732 // line directive first. 1733 SourceLocation ForEachLoc = S->getForLoc(); 1734 ConvertSourceLocationToLineDirective(ForEachLoc, buf); 1735 buf += "{\n\t"; 1736 if (DeclStmt *DS = dyn_cast<DeclStmt>(S->getElement())) { 1737 // type elem; 1738 NamedDecl* D = cast<NamedDecl>(DS->getSingleDecl()); 1739 QualType ElementType = cast<ValueDecl>(D)->getType(); 1740 if (ElementType->isObjCQualifiedIdType() || 1741 ElementType->isObjCQualifiedInterfaceType()) 1742 // Simply use 'id' for all qualified types. 1743 elementTypeAsString = "id"; 1744 else 1745 elementTypeAsString = ElementType.getAsString(Context->getPrintingPolicy()); 1746 buf += elementTypeAsString; 1747 buf += " "; 1748 elementName = D->getName(); 1749 buf += elementName; 1750 buf += ";\n\t"; 1751 } 1752 else { 1753 DeclRefExpr *DR = cast<DeclRefExpr>(S->getElement()); 1754 elementName = DR->getDecl()->getName(); 1755 ValueDecl *VD = cast<ValueDecl>(DR->getDecl()); 1756 if (VD->getType()->isObjCQualifiedIdType() || 1757 VD->getType()->isObjCQualifiedInterfaceType()) 1758 // Simply use 'id' for all qualified types. 1759 elementTypeAsString = "id"; 1760 else 1761 elementTypeAsString = VD->getType().getAsString(Context->getPrintingPolicy()); 1762 } 1763 1764 // struct __objcFastEnumerationState enumState = { 0 }; 1765 buf += "struct __objcFastEnumerationState enumState = { 0 };\n\t"; 1766 // id __rw_items[16]; 1767 buf += "id __rw_items[16];\n\t"; 1768 // id l_collection = (id) 1769 buf += "id l_collection = (id)"; 1770 // Find start location of 'collection' the hard way! 1771 const char *startCollectionBuf = startBuf; 1772 startCollectionBuf += 3; // skip 'for' 1773 startCollectionBuf = strchr(startCollectionBuf, '('); 1774 startCollectionBuf++; // skip '(' 1775 // find 'in' and skip it. 1776 while (*startCollectionBuf != ' ' || 1777 *(startCollectionBuf+1) != 'i' || *(startCollectionBuf+2) != 'n' || 1778 (*(startCollectionBuf+3) != ' ' && 1779 *(startCollectionBuf+3) != '[' && *(startCollectionBuf+3) != '(')) 1780 startCollectionBuf++; 1781 startCollectionBuf += 3; 1782 1783 // Replace: "for (type element in" with string constructed thus far. 1784 ReplaceText(startLoc, startCollectionBuf - startBuf, buf); 1785 // Replace ')' in for '(' type elem in collection ')' with ';' 1786 SourceLocation rightParenLoc = S->getRParenLoc(); 1787 const char *rparenBuf = SM->getCharacterData(rightParenLoc); 1788 SourceLocation lparenLoc = startLoc.getLocWithOffset(rparenBuf-startBuf); 1789 buf = ";\n\t"; 1790 1791 // unsigned long limit = [l_collection countByEnumeratingWithState:&enumState 1792 // objects:__rw_items count:16]; 1793 // which is synthesized into: 1794 // unsigned int limit = 1795 // ((unsigned int (*) 1796 // (id, SEL, struct __objcFastEnumerationState *, id *, unsigned int)) 1797 // (void *)objc_msgSend)((id)l_collection, 1798 // sel_registerName( 1799 // "countByEnumeratingWithState:objects:count:"), 1800 // (struct __objcFastEnumerationState *)&state, 1801 // (id *)__rw_items, (unsigned int)16); 1802 buf += "unsigned long limit =\n\t\t"; 1803 SynthCountByEnumWithState(buf); 1804 buf += ";\n\t"; 1805 /// if (limit) { 1806 /// unsigned long startMutations = *enumState.mutationsPtr; 1807 /// do { 1808 /// unsigned long counter = 0; 1809 /// do { 1810 /// if (startMutations != *enumState.mutationsPtr) 1811 /// objc_enumerationMutation(l_collection); 1812 /// elem = (type)enumState.itemsPtr[counter++]; 1813 buf += "if (limit) {\n\t"; 1814 buf += "unsigned long startMutations = *enumState.mutationsPtr;\n\t"; 1815 buf += "do {\n\t\t"; 1816 buf += "unsigned long counter = 0;\n\t\t"; 1817 buf += "do {\n\t\t\t"; 1818 buf += "if (startMutations != *enumState.mutationsPtr)\n\t\t\t\t"; 1819 buf += "objc_enumerationMutation(l_collection);\n\t\t\t"; 1820 buf += elementName; 1821 buf += " = ("; 1822 buf += elementTypeAsString; 1823 buf += ")enumState.itemsPtr[counter++];"; 1824 // Replace ')' in for '(' type elem in collection ')' with all of these. 1825 ReplaceText(lparenLoc, 1, buf); 1826 1827 /// __continue_label: ; 1828 /// } while (counter < limit); 1829 /// } while (limit = [l_collection countByEnumeratingWithState:&enumState 1830 /// objects:__rw_items count:16]); 1831 /// elem = nil; 1832 /// __break_label: ; 1833 /// } 1834 /// else 1835 /// elem = nil; 1836 /// } 1837 /// 1838 buf = ";\n\t"; 1839 buf += "__continue_label_"; 1840 buf += utostr(ObjCBcLabelNo.back()); 1841 buf += ": ;"; 1842 buf += "\n\t\t"; 1843 buf += "} while (counter < limit);\n\t"; 1844 buf += "} while (limit = "; 1845 SynthCountByEnumWithState(buf); 1846 buf += ");\n\t"; 1847 buf += elementName; 1848 buf += " = (("; 1849 buf += elementTypeAsString; 1850 buf += ")0);\n\t"; 1851 buf += "__break_label_"; 1852 buf += utostr(ObjCBcLabelNo.back()); 1853 buf += ": ;\n\t"; 1854 buf += "}\n\t"; 1855 buf += "else\n\t\t"; 1856 buf += elementName; 1857 buf += " = (("; 1858 buf += elementTypeAsString; 1859 buf += ")0);\n\t"; 1860 buf += "}\n"; 1861 1862 // Insert all these *after* the statement body. 1863 // FIXME: If this should support Obj-C++, support CXXTryStmt 1864 if (isa<CompoundStmt>(S->getBody())) { 1865 SourceLocation endBodyLoc = OrigEnd.getLocWithOffset(1); 1866 InsertText(endBodyLoc, buf); 1867 } else { 1868 /* Need to treat single statements specially. For example: 1869 * 1870 * for (A *a in b) if (stuff()) break; 1871 * for (A *a in b) xxxyy; 1872 * 1873 * The following code simply scans ahead to the semi to find the actual end. 1874 */ 1875 const char *stmtBuf = SM->getCharacterData(OrigEnd); 1876 const char *semiBuf = strchr(stmtBuf, ';'); 1877 assert(semiBuf && "Can't find ';'"); 1878 SourceLocation endBodyLoc = OrigEnd.getLocWithOffset(semiBuf-stmtBuf+1); 1879 InsertText(endBodyLoc, buf); 1880 } 1881 Stmts.pop_back(); 1882 ObjCBcLabelNo.pop_back(); 1883 return 0; 1884 } 1885 1886 static void Write_RethrowObject(std::string &buf) { 1887 buf += "{ struct _FIN { _FIN(id reth) : rethrow(reth) {}\n"; 1888 buf += "\t~_FIN() { if (rethrow) objc_exception_throw(rethrow); }\n"; 1889 buf += "\tid rethrow;\n"; 1890 buf += "\t} _fin_force_rethow(_rethrow);"; 1891 } 1892 1893 /// RewriteObjCSynchronizedStmt - 1894 /// This routine rewrites @synchronized(expr) stmt; 1895 /// into: 1896 /// objc_sync_enter(expr); 1897 /// @try stmt @finally { objc_sync_exit(expr); } 1898 /// 1899 Stmt *RewriteModernObjC::RewriteObjCSynchronizedStmt(ObjCAtSynchronizedStmt *S) { 1900 // Get the start location and compute the semi location. 1901 SourceLocation startLoc = S->getLocStart(); 1902 const char *startBuf = SM->getCharacterData(startLoc); 1903 1904 assert((*startBuf == '@') && "bogus @synchronized location"); 1905 1906 std::string buf; 1907 SourceLocation SynchLoc = S->getAtSynchronizedLoc(); 1908 ConvertSourceLocationToLineDirective(SynchLoc, buf); 1909 buf += "{ id _rethrow = 0; id _sync_obj = "; 1910 1911 const char *lparenBuf = startBuf; 1912 while (*lparenBuf != '(') lparenBuf++; 1913 ReplaceText(startLoc, lparenBuf-startBuf+1, buf); 1914 1915 buf = "; objc_sync_enter(_sync_obj);\n"; 1916 buf += "try {\n\tstruct _SYNC_EXIT { _SYNC_EXIT(id arg) : sync_exit(arg) {}"; 1917 buf += "\n\t~_SYNC_EXIT() {objc_sync_exit(sync_exit);}"; 1918 buf += "\n\tid sync_exit;"; 1919 buf += "\n\t} _sync_exit(_sync_obj);\n"; 1920 1921 // We can't use S->getSynchExpr()->getLocEnd() to find the end location, since 1922 // the sync expression is typically a message expression that's already 1923 // been rewritten! (which implies the SourceLocation's are invalid). 1924 SourceLocation RParenExprLoc = S->getSynchBody()->getLocStart(); 1925 const char *RParenExprLocBuf = SM->getCharacterData(RParenExprLoc); 1926 while (*RParenExprLocBuf != ')') RParenExprLocBuf--; 1927 RParenExprLoc = startLoc.getLocWithOffset(RParenExprLocBuf-startBuf); 1928 1929 SourceLocation LBranceLoc = S->getSynchBody()->getLocStart(); 1930 const char *LBraceLocBuf = SM->getCharacterData(LBranceLoc); 1931 assert (*LBraceLocBuf == '{'); 1932 ReplaceText(RParenExprLoc, (LBraceLocBuf - SM->getCharacterData(RParenExprLoc) + 1), buf); 1933 1934 SourceLocation startRBraceLoc = S->getSynchBody()->getLocEnd(); 1935 assert((*SM->getCharacterData(startRBraceLoc) == '}') && 1936 "bogus @synchronized block"); 1937 1938 buf = "} catch (id e) {_rethrow = e;}\n"; 1939 Write_RethrowObject(buf); 1940 buf += "}\n"; 1941 buf += "}\n"; 1942 1943 ReplaceText(startRBraceLoc, 1, buf); 1944 1945 return 0; 1946 } 1947 1948 void RewriteModernObjC::WarnAboutReturnGotoStmts(Stmt *S) 1949 { 1950 // Perform a bottom up traversal of all children. 1951 for (Stmt::child_range CI = S->children(); CI; ++CI) 1952 if (*CI) 1953 WarnAboutReturnGotoStmts(*CI); 1954 1955 if (isa<ReturnStmt>(S) || isa<GotoStmt>(S)) { 1956 Diags.Report(Context->getFullLoc(S->getLocStart()), 1957 TryFinallyContainsReturnDiag); 1958 } 1959 return; 1960 } 1961 1962 Stmt *RewriteModernObjC::RewriteObjCAutoreleasePoolStmt(ObjCAutoreleasePoolStmt *S) { 1963 SourceLocation startLoc = S->getAtLoc(); 1964 ReplaceText(startLoc, strlen("@autoreleasepool"), "/* @autoreleasepool */"); 1965 ReplaceText(S->getSubStmt()->getLocStart(), 1, 1966 "{ __AtAutoreleasePool __autoreleasepool; "); 1967 1968 return 0; 1969 } 1970 1971 Stmt *RewriteModernObjC::RewriteObjCTryStmt(ObjCAtTryStmt *S) { 1972 ObjCAtFinallyStmt *finalStmt = S->getFinallyStmt(); 1973 bool noCatch = S->getNumCatchStmts() == 0; 1974 std::string buf; 1975 SourceLocation TryLocation = S->getAtTryLoc(); 1976 ConvertSourceLocationToLineDirective(TryLocation, buf); 1977 1978 if (finalStmt) { 1979 if (noCatch) 1980 buf += "{ id volatile _rethrow = 0;\n"; 1981 else { 1982 buf += "{ id volatile _rethrow = 0;\ntry {\n"; 1983 } 1984 } 1985 // Get the start location and compute the semi location. 1986 SourceLocation startLoc = S->getLocStart(); 1987 const char *startBuf = SM->getCharacterData(startLoc); 1988 1989 assert((*startBuf == '@') && "bogus @try location"); 1990 if (finalStmt) 1991 ReplaceText(startLoc, 1, buf); 1992 else 1993 // @try -> try 1994 ReplaceText(startLoc, 1, ""); 1995 1996 for (unsigned I = 0, N = S->getNumCatchStmts(); I != N; ++I) { 1997 ObjCAtCatchStmt *Catch = S->getCatchStmt(I); 1998 VarDecl *catchDecl = Catch->getCatchParamDecl(); 1999 2000 startLoc = Catch->getLocStart(); 2001 bool AtRemoved = false; 2002 if (catchDecl) { 2003 QualType t = catchDecl->getType(); 2004 if (const ObjCObjectPointerType *Ptr = t->getAs<ObjCObjectPointerType>()) { 2005 // Should be a pointer to a class. 2006 ObjCInterfaceDecl *IDecl = Ptr->getObjectType()->getInterface(); 2007 if (IDecl) { 2008 std::string Result; 2009 ConvertSourceLocationToLineDirective(Catch->getLocStart(), Result); 2010 2011 startBuf = SM->getCharacterData(startLoc); 2012 assert((*startBuf == '@') && "bogus @catch location"); 2013 SourceLocation rParenLoc = Catch->getRParenLoc(); 2014 const char *rParenBuf = SM->getCharacterData(rParenLoc); 2015 2016 // _objc_exc_Foo *_e as argument to catch. 2017 Result += "catch (_objc_exc_"; Result += IDecl->getNameAsString(); 2018 Result += " *_"; Result += catchDecl->getNameAsString(); 2019 Result += ")"; 2020 ReplaceText(startLoc, rParenBuf-startBuf+1, Result); 2021 // Foo *e = (Foo *)_e; 2022 Result.clear(); 2023 Result = "{ "; 2024 Result += IDecl->getNameAsString(); 2025 Result += " *"; Result += catchDecl->getNameAsString(); 2026 Result += " = ("; Result += IDecl->getNameAsString(); Result += "*)"; 2027 Result += "_"; Result += catchDecl->getNameAsString(); 2028 2029 Result += "; "; 2030 SourceLocation lBraceLoc = Catch->getCatchBody()->getLocStart(); 2031 ReplaceText(lBraceLoc, 1, Result); 2032 AtRemoved = true; 2033 } 2034 } 2035 } 2036 if (!AtRemoved) 2037 // @catch -> catch 2038 ReplaceText(startLoc, 1, ""); 2039 2040 } 2041 if (finalStmt) { 2042 buf.clear(); 2043 SourceLocation FinallyLoc = finalStmt->getLocStart(); 2044 2045 if (noCatch) { 2046 ConvertSourceLocationToLineDirective(FinallyLoc, buf); 2047 buf += "catch (id e) {_rethrow = e;}\n"; 2048 } 2049 else { 2050 buf += "}\n"; 2051 ConvertSourceLocationToLineDirective(FinallyLoc, buf); 2052 buf += "catch (id e) {_rethrow = e;}\n"; 2053 } 2054 2055 SourceLocation startFinalLoc = finalStmt->getLocStart(); 2056 ReplaceText(startFinalLoc, 8, buf); 2057 Stmt *body = finalStmt->getFinallyBody(); 2058 SourceLocation startFinalBodyLoc = body->getLocStart(); 2059 buf.clear(); 2060 Write_RethrowObject(buf); 2061 ReplaceText(startFinalBodyLoc, 1, buf); 2062 2063 SourceLocation endFinalBodyLoc = body->getLocEnd(); 2064 ReplaceText(endFinalBodyLoc, 1, "}\n}"); 2065 // Now check for any return/continue/go statements within the @try. 2066 WarnAboutReturnGotoStmts(S->getTryBody()); 2067 } 2068 2069 return 0; 2070 } 2071 2072 // This can't be done with ReplaceStmt(S, ThrowExpr), since 2073 // the throw expression is typically a message expression that's already 2074 // been rewritten! (which implies the SourceLocation's are invalid). 2075 Stmt *RewriteModernObjC::RewriteObjCThrowStmt(ObjCAtThrowStmt *S) { 2076 // Get the start location and compute the semi location. 2077 SourceLocation startLoc = S->getLocStart(); 2078 const char *startBuf = SM->getCharacterData(startLoc); 2079 2080 assert((*startBuf == '@') && "bogus @throw location"); 2081 2082 std::string buf; 2083 /* void objc_exception_throw(id) __attribute__((noreturn)); */ 2084 if (S->getThrowExpr()) 2085 buf = "objc_exception_throw("; 2086 else 2087 buf = "throw"; 2088 2089 // handle "@ throw" correctly. 2090 const char *wBuf = strchr(startBuf, 'w'); 2091 assert((*wBuf == 'w') && "@throw: can't find 'w'"); 2092 ReplaceText(startLoc, wBuf-startBuf+1, buf); 2093 2094 SourceLocation endLoc = S->getLocEnd(); 2095 const char *endBuf = SM->getCharacterData(endLoc); 2096 const char *semiBuf = strchr(endBuf, ';'); 2097 assert((*semiBuf == ';') && "@throw: can't find ';'"); 2098 SourceLocation semiLoc = startLoc.getLocWithOffset(semiBuf-startBuf); 2099 if (S->getThrowExpr()) 2100 ReplaceText(semiLoc, 1, ");"); 2101 return 0; 2102 } 2103 2104 Stmt *RewriteModernObjC::RewriteAtEncode(ObjCEncodeExpr *Exp) { 2105 // Create a new string expression. 2106 QualType StrType = Context->getPointerType(Context->CharTy); 2107 std::string StrEncoding; 2108 Context->getObjCEncodingForType(Exp->getEncodedType(), StrEncoding); 2109 Expr *Replacement = StringLiteral::Create(*Context, StrEncoding, 2110 StringLiteral::Ascii, false, 2111 StrType, SourceLocation()); 2112 ReplaceStmt(Exp, Replacement); 2113 2114 // Replace this subexpr in the parent. 2115 // delete Exp; leak for now, see RewritePropertyOrImplicitSetter() usage for more info. 2116 return Replacement; 2117 } 2118 2119 Stmt *RewriteModernObjC::RewriteAtSelector(ObjCSelectorExpr *Exp) { 2120 if (!SelGetUidFunctionDecl) 2121 SynthSelGetUidFunctionDecl(); 2122 assert(SelGetUidFunctionDecl && "Can't find sel_registerName() decl"); 2123 // Create a call to sel_registerName("selName"). 2124 SmallVector<Expr*, 8> SelExprs; 2125 QualType argType = Context->getPointerType(Context->CharTy); 2126 SelExprs.push_back(StringLiteral::Create(*Context, 2127 Exp->getSelector().getAsString(), 2128 StringLiteral::Ascii, false, 2129 argType, SourceLocation())); 2130 CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl, 2131 &SelExprs[0], SelExprs.size()); 2132 ReplaceStmt(Exp, SelExp); 2133 // delete Exp; leak for now, see RewritePropertyOrImplicitSetter() usage for more info. 2134 return SelExp; 2135 } 2136 2137 CallExpr *RewriteModernObjC::SynthesizeCallToFunctionDecl( 2138 FunctionDecl *FD, Expr **args, unsigned nargs, SourceLocation StartLoc, 2139 SourceLocation EndLoc) { 2140 // Get the type, we will need to reference it in a couple spots. 2141 QualType msgSendType = FD->getType(); 2142 2143 // Create a reference to the objc_msgSend() declaration. 2144 DeclRefExpr *DRE = 2145 new (Context) DeclRefExpr(FD, false, msgSendType, VK_LValue, SourceLocation()); 2146 2147 // Now, we cast the reference to a pointer to the objc_msgSend type. 2148 QualType pToFunc = Context->getPointerType(msgSendType); 2149 ImplicitCastExpr *ICE = 2150 ImplicitCastExpr::Create(*Context, pToFunc, CK_FunctionToPointerDecay, 2151 DRE, 0, VK_RValue); 2152 2153 const FunctionType *FT = msgSendType->getAs<FunctionType>(); 2154 2155 CallExpr *Exp = 2156 new (Context) CallExpr(*Context, ICE, llvm::makeArrayRef(args, nargs), 2157 FT->getCallResultType(*Context), 2158 VK_RValue, EndLoc); 2159 return Exp; 2160 } 2161 2162 static bool scanForProtocolRefs(const char *startBuf, const char *endBuf, 2163 const char *&startRef, const char *&endRef) { 2164 while (startBuf < endBuf) { 2165 if (*startBuf == '<') 2166 startRef = startBuf; // mark the start. 2167 if (*startBuf == '>') { 2168 if (startRef && *startRef == '<') { 2169 endRef = startBuf; // mark the end. 2170 return true; 2171 } 2172 return false; 2173 } 2174 startBuf++; 2175 } 2176 return false; 2177 } 2178 2179 static void scanToNextArgument(const char *&argRef) { 2180 int angle = 0; 2181 while (*argRef != ')' && (*argRef != ',' || angle > 0)) { 2182 if (*argRef == '<') 2183 angle++; 2184 else if (*argRef == '>') 2185 angle--; 2186 argRef++; 2187 } 2188 assert(angle == 0 && "scanToNextArgument - bad protocol type syntax"); 2189 } 2190 2191 bool RewriteModernObjC::needToScanForQualifiers(QualType T) { 2192 if (T->isObjCQualifiedIdType()) 2193 return true; 2194 if (const PointerType *PT = T->getAs<PointerType>()) { 2195 if (PT->getPointeeType()->isObjCQualifiedIdType()) 2196 return true; 2197 } 2198 if (T->isObjCObjectPointerType()) { 2199 T = T->getPointeeType(); 2200 return T->isObjCQualifiedInterfaceType(); 2201 } 2202 if (T->isArrayType()) { 2203 QualType ElemTy = Context->getBaseElementType(T); 2204 return needToScanForQualifiers(ElemTy); 2205 } 2206 return false; 2207 } 2208 2209 void RewriteModernObjC::RewriteObjCQualifiedInterfaceTypes(Expr *E) { 2210 QualType Type = E->getType(); 2211 if (needToScanForQualifiers(Type)) { 2212 SourceLocation Loc, EndLoc; 2213 2214 if (const CStyleCastExpr *ECE = dyn_cast<CStyleCastExpr>(E)) { 2215 Loc = ECE->getLParenLoc(); 2216 EndLoc = ECE->getRParenLoc(); 2217 } else { 2218 Loc = E->getLocStart(); 2219 EndLoc = E->getLocEnd(); 2220 } 2221 // This will defend against trying to rewrite synthesized expressions. 2222 if (Loc.isInvalid() || EndLoc.isInvalid()) 2223 return; 2224 2225 const char *startBuf = SM->getCharacterData(Loc); 2226 const char *endBuf = SM->getCharacterData(EndLoc); 2227 const char *startRef = 0, *endRef = 0; 2228 if (scanForProtocolRefs(startBuf, endBuf, startRef, endRef)) { 2229 // Get the locations of the startRef, endRef. 2230 SourceLocation LessLoc = Loc.getLocWithOffset(startRef-startBuf); 2231 SourceLocation GreaterLoc = Loc.getLocWithOffset(endRef-startBuf+1); 2232 // Comment out the protocol references. 2233 InsertText(LessLoc, "/*"); 2234 InsertText(GreaterLoc, "*/"); 2235 } 2236 } 2237 } 2238 2239 void RewriteModernObjC::RewriteObjCQualifiedInterfaceTypes(Decl *Dcl) { 2240 SourceLocation Loc; 2241 QualType Type; 2242 const FunctionProtoType *proto = 0; 2243 if (VarDecl *VD = dyn_cast<VarDecl>(Dcl)) { 2244 Loc = VD->getLocation(); 2245 Type = VD->getType(); 2246 } 2247 else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(Dcl)) { 2248 Loc = FD->getLocation(); 2249 // Check for ObjC 'id' and class types that have been adorned with protocol 2250 // information (id<p>, C<p>*). The protocol references need to be rewritten! 2251 const FunctionType *funcType = FD->getType()->getAs<FunctionType>(); 2252 assert(funcType && "missing function type"); 2253 proto = dyn_cast<FunctionProtoType>(funcType); 2254 if (!proto) 2255 return; 2256 Type = proto->getResultType(); 2257 } 2258 else if (FieldDecl *FD = dyn_cast<FieldDecl>(Dcl)) { 2259 Loc = FD->getLocation(); 2260 Type = FD->getType(); 2261 } 2262 else if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(Dcl)) { 2263 Loc = TD->getLocation(); 2264 Type = TD->getUnderlyingType(); 2265 } 2266 else 2267 return; 2268 2269 if (needToScanForQualifiers(Type)) { 2270 // Since types are unique, we need to scan the buffer. 2271 2272 const char *endBuf = SM->getCharacterData(Loc); 2273 const char *startBuf = endBuf; 2274 while (*startBuf != ';' && *startBuf != '<' && startBuf != MainFileStart) 2275 startBuf--; // scan backward (from the decl location) for return type. 2276 const char *startRef = 0, *endRef = 0; 2277 if (scanForProtocolRefs(startBuf, endBuf, startRef, endRef)) { 2278 // Get the locations of the startRef, endRef. 2279 SourceLocation LessLoc = Loc.getLocWithOffset(startRef-endBuf); 2280 SourceLocation GreaterLoc = Loc.getLocWithOffset(endRef-endBuf+1); 2281 // Comment out the protocol references. 2282 InsertText(LessLoc, "/*"); 2283 InsertText(GreaterLoc, "*/"); 2284 } 2285 } 2286 if (!proto) 2287 return; // most likely, was a variable 2288 // Now check arguments. 2289 const char *startBuf = SM->getCharacterData(Loc); 2290 const char *startFuncBuf = startBuf; 2291 for (unsigned i = 0; i < proto->getNumArgs(); i++) { 2292 if (needToScanForQualifiers(proto->getArgType(i))) { 2293 // Since types are unique, we need to scan the buffer. 2294 2295 const char *endBuf = startBuf; 2296 // scan forward (from the decl location) for argument types. 2297 scanToNextArgument(endBuf); 2298 const char *startRef = 0, *endRef = 0; 2299 if (scanForProtocolRefs(startBuf, endBuf, startRef, endRef)) { 2300 // Get the locations of the startRef, endRef. 2301 SourceLocation LessLoc = 2302 Loc.getLocWithOffset(startRef-startFuncBuf); 2303 SourceLocation GreaterLoc = 2304 Loc.getLocWithOffset(endRef-startFuncBuf+1); 2305 // Comment out the protocol references. 2306 InsertText(LessLoc, "/*"); 2307 InsertText(GreaterLoc, "*/"); 2308 } 2309 startBuf = ++endBuf; 2310 } 2311 else { 2312 // If the function name is derived from a macro expansion, then the 2313 // argument buffer will not follow the name. Need to speak with Chris. 2314 while (*startBuf && *startBuf != ')' && *startBuf != ',') 2315 startBuf++; // scan forward (from the decl location) for argument types. 2316 startBuf++; 2317 } 2318 } 2319 } 2320 2321 void RewriteModernObjC::RewriteTypeOfDecl(VarDecl *ND) { 2322 QualType QT = ND->getType(); 2323 const Type* TypePtr = QT->getAs<Type>(); 2324 if (!isa<TypeOfExprType>(TypePtr)) 2325 return; 2326 while (isa<TypeOfExprType>(TypePtr)) { 2327 const TypeOfExprType *TypeOfExprTypePtr = cast<TypeOfExprType>(TypePtr); 2328 QT = TypeOfExprTypePtr->getUnderlyingExpr()->getType(); 2329 TypePtr = QT->getAs<Type>(); 2330 } 2331 // FIXME. This will not work for multiple declarators; as in: 2332 // __typeof__(a) b,c,d; 2333 std::string TypeAsString(QT.getAsString(Context->getPrintingPolicy())); 2334 SourceLocation DeclLoc = ND->getTypeSpecStartLoc(); 2335 const char *startBuf = SM->getCharacterData(DeclLoc); 2336 if (ND->getInit()) { 2337 std::string Name(ND->getNameAsString()); 2338 TypeAsString += " " + Name + " = "; 2339 Expr *E = ND->getInit(); 2340 SourceLocation startLoc; 2341 if (const CStyleCastExpr *ECE = dyn_cast<CStyleCastExpr>(E)) 2342 startLoc = ECE->getLParenLoc(); 2343 else 2344 startLoc = E->getLocStart(); 2345 startLoc = SM->getExpansionLoc(startLoc); 2346 const char *endBuf = SM->getCharacterData(startLoc); 2347 ReplaceText(DeclLoc, endBuf-startBuf-1, TypeAsString); 2348 } 2349 else { 2350 SourceLocation X = ND->getLocEnd(); 2351 X = SM->getExpansionLoc(X); 2352 const char *endBuf = SM->getCharacterData(X); 2353 ReplaceText(DeclLoc, endBuf-startBuf-1, TypeAsString); 2354 } 2355 } 2356 2357 // SynthSelGetUidFunctionDecl - SEL sel_registerName(const char *str); 2358 void RewriteModernObjC::SynthSelGetUidFunctionDecl() { 2359 IdentifierInfo *SelGetUidIdent = &Context->Idents.get("sel_registerName"); 2360 SmallVector<QualType, 16> ArgTys; 2361 ArgTys.push_back(Context->getPointerType(Context->CharTy.withConst())); 2362 QualType getFuncType = 2363 getSimpleFunctionType(Context->getObjCSelType(), ArgTys); 2364 SelGetUidFunctionDecl = FunctionDecl::Create(*Context, TUDecl, 2365 SourceLocation(), 2366 SourceLocation(), 2367 SelGetUidIdent, getFuncType, 0, 2368 SC_Extern); 2369 } 2370 2371 void RewriteModernObjC::RewriteFunctionDecl(FunctionDecl *FD) { 2372 // declared in <objc/objc.h> 2373 if (FD->getIdentifier() && 2374 FD->getName() == "sel_registerName") { 2375 SelGetUidFunctionDecl = FD; 2376 return; 2377 } 2378 RewriteObjCQualifiedInterfaceTypes(FD); 2379 } 2380 2381 void RewriteModernObjC::RewriteBlockPointerType(std::string& Str, QualType Type) { 2382 std::string TypeString(Type.getAsString(Context->getPrintingPolicy())); 2383 const char *argPtr = TypeString.c_str(); 2384 if (!strchr(argPtr, '^')) { 2385 Str += TypeString; 2386 return; 2387 } 2388 while (*argPtr) { 2389 Str += (*argPtr == '^' ? '*' : *argPtr); 2390 argPtr++; 2391 } 2392 } 2393 2394 // FIXME. Consolidate this routine with RewriteBlockPointerType. 2395 void RewriteModernObjC::RewriteBlockPointerTypeVariable(std::string& Str, 2396 ValueDecl *VD) { 2397 QualType Type = VD->getType(); 2398 std::string TypeString(Type.getAsString(Context->getPrintingPolicy())); 2399 const char *argPtr = TypeString.c_str(); 2400 int paren = 0; 2401 while (*argPtr) { 2402 switch (*argPtr) { 2403 case '(': 2404 Str += *argPtr; 2405 paren++; 2406 break; 2407 case ')': 2408 Str += *argPtr; 2409 paren--; 2410 break; 2411 case '^': 2412 Str += '*'; 2413 if (paren == 1) 2414 Str += VD->getNameAsString(); 2415 break; 2416 default: 2417 Str += *argPtr; 2418 break; 2419 } 2420 argPtr++; 2421 } 2422 } 2423 2424 void RewriteModernObjC::RewriteBlockLiteralFunctionDecl(FunctionDecl *FD) { 2425 SourceLocation FunLocStart = FD->getTypeSpecStartLoc(); 2426 const FunctionType *funcType = FD->getType()->getAs<FunctionType>(); 2427 const FunctionProtoType *proto = dyn_cast<FunctionProtoType>(funcType); 2428 if (!proto) 2429 return; 2430 QualType Type = proto->getResultType(); 2431 std::string FdStr = Type.getAsString(Context->getPrintingPolicy()); 2432 FdStr += " "; 2433 FdStr += FD->getName(); 2434 FdStr += "("; 2435 unsigned numArgs = proto->getNumArgs(); 2436 for (unsigned i = 0; i < numArgs; i++) { 2437 QualType ArgType = proto->getArgType(i); 2438 RewriteBlockPointerType(FdStr, ArgType); 2439 if (i+1 < numArgs) 2440 FdStr += ", "; 2441 } 2442 if (FD->isVariadic()) { 2443 FdStr += (numArgs > 0) ? ", ...);\n" : "...);\n"; 2444 } 2445 else 2446 FdStr += ");\n"; 2447 InsertText(FunLocStart, FdStr); 2448 } 2449 2450 // SynthSuperContructorFunctionDecl - id __rw_objc_super(id obj, id super); 2451 void RewriteModernObjC::SynthSuperContructorFunctionDecl() { 2452 if (SuperContructorFunctionDecl) 2453 return; 2454 IdentifierInfo *msgSendIdent = &Context->Idents.get("__rw_objc_super"); 2455 SmallVector<QualType, 16> ArgTys; 2456 QualType argT = Context->getObjCIdType(); 2457 assert(!argT.isNull() && "Can't find 'id' type"); 2458 ArgTys.push_back(argT); 2459 ArgTys.push_back(argT); 2460 QualType msgSendType = getSimpleFunctionType(Context->getObjCIdType(), 2461 ArgTys); 2462 SuperContructorFunctionDecl = FunctionDecl::Create(*Context, TUDecl, 2463 SourceLocation(), 2464 SourceLocation(), 2465 msgSendIdent, msgSendType, 2466 0, SC_Extern); 2467 } 2468 2469 // SynthMsgSendFunctionDecl - id objc_msgSend(id self, SEL op, ...); 2470 void RewriteModernObjC::SynthMsgSendFunctionDecl() { 2471 IdentifierInfo *msgSendIdent = &Context->Idents.get("objc_msgSend"); 2472 SmallVector<QualType, 16> ArgTys; 2473 QualType argT = Context->getObjCIdType(); 2474 assert(!argT.isNull() && "Can't find 'id' type"); 2475 ArgTys.push_back(argT); 2476 argT = Context->getObjCSelType(); 2477 assert(!argT.isNull() && "Can't find 'SEL' type"); 2478 ArgTys.push_back(argT); 2479 QualType msgSendType = getSimpleFunctionType(Context->getObjCIdType(), 2480 ArgTys, /*isVariadic=*/true); 2481 MsgSendFunctionDecl = FunctionDecl::Create(*Context, TUDecl, 2482 SourceLocation(), 2483 SourceLocation(), 2484 msgSendIdent, msgSendType, 0, 2485 SC_Extern); 2486 } 2487 2488 // SynthMsgSendSuperFunctionDecl - id objc_msgSendSuper(void); 2489 void RewriteModernObjC::SynthMsgSendSuperFunctionDecl() { 2490 IdentifierInfo *msgSendIdent = &Context->Idents.get("objc_msgSendSuper"); 2491 SmallVector<QualType, 2> ArgTys; 2492 ArgTys.push_back(Context->VoidTy); 2493 QualType msgSendType = getSimpleFunctionType(Context->getObjCIdType(), 2494 ArgTys, /*isVariadic=*/true); 2495 MsgSendSuperFunctionDecl = FunctionDecl::Create(*Context, TUDecl, 2496 SourceLocation(), 2497 SourceLocation(), 2498 msgSendIdent, msgSendType, 0, 2499 SC_Extern); 2500 } 2501 2502 // SynthMsgSendStretFunctionDecl - id objc_msgSend_stret(id self, SEL op, ...); 2503 void RewriteModernObjC::SynthMsgSendStretFunctionDecl() { 2504 IdentifierInfo *msgSendIdent = &Context->Idents.get("objc_msgSend_stret"); 2505 SmallVector<QualType, 16> ArgTys; 2506 QualType argT = Context->getObjCIdType(); 2507 assert(!argT.isNull() && "Can't find 'id' type"); 2508 ArgTys.push_back(argT); 2509 argT = Context->getObjCSelType(); 2510 assert(!argT.isNull() && "Can't find 'SEL' type"); 2511 ArgTys.push_back(argT); 2512 QualType msgSendType = getSimpleFunctionType(Context->getObjCIdType(), 2513 ArgTys, /*isVariadic=*/true); 2514 MsgSendStretFunctionDecl = FunctionDecl::Create(*Context, TUDecl, 2515 SourceLocation(), 2516 SourceLocation(), 2517 msgSendIdent, msgSendType, 0, 2518 SC_Extern); 2519 } 2520 2521 // SynthMsgSendSuperStretFunctionDecl - 2522 // id objc_msgSendSuper_stret(void); 2523 void RewriteModernObjC::SynthMsgSendSuperStretFunctionDecl() { 2524 IdentifierInfo *msgSendIdent = 2525 &Context->Idents.get("objc_msgSendSuper_stret"); 2526 SmallVector<QualType, 2> ArgTys; 2527 ArgTys.push_back(Context->VoidTy); 2528 QualType msgSendType = getSimpleFunctionType(Context->getObjCIdType(), 2529 ArgTys, /*isVariadic=*/true); 2530 MsgSendSuperStretFunctionDecl = FunctionDecl::Create(*Context, TUDecl, 2531 SourceLocation(), 2532 SourceLocation(), 2533 msgSendIdent, 2534 msgSendType, 0, 2535 SC_Extern); 2536 } 2537 2538 // SynthMsgSendFpretFunctionDecl - double objc_msgSend_fpret(id self, SEL op, ...); 2539 void RewriteModernObjC::SynthMsgSendFpretFunctionDecl() { 2540 IdentifierInfo *msgSendIdent = &Context->Idents.get("objc_msgSend_fpret"); 2541 SmallVector<QualType, 16> ArgTys; 2542 QualType argT = Context->getObjCIdType(); 2543 assert(!argT.isNull() && "Can't find 'id' type"); 2544 ArgTys.push_back(argT); 2545 argT = Context->getObjCSelType(); 2546 assert(!argT.isNull() && "Can't find 'SEL' type"); 2547 ArgTys.push_back(argT); 2548 QualType msgSendType = getSimpleFunctionType(Context->DoubleTy, 2549 ArgTys, /*isVariadic=*/true); 2550 MsgSendFpretFunctionDecl = FunctionDecl::Create(*Context, TUDecl, 2551 SourceLocation(), 2552 SourceLocation(), 2553 msgSendIdent, msgSendType, 0, 2554 SC_Extern); 2555 } 2556 2557 // SynthGetClassFunctionDecl - Class objc_getClass(const char *name); 2558 void RewriteModernObjC::SynthGetClassFunctionDecl() { 2559 IdentifierInfo *getClassIdent = &Context->Idents.get("objc_getClass"); 2560 SmallVector<QualType, 16> ArgTys; 2561 ArgTys.push_back(Context->getPointerType(Context->CharTy.withConst())); 2562 QualType getClassType = getSimpleFunctionType(Context->getObjCClassType(), 2563 ArgTys); 2564 GetClassFunctionDecl = FunctionDecl::Create(*Context, TUDecl, 2565 SourceLocation(), 2566 SourceLocation(), 2567 getClassIdent, getClassType, 0, 2568 SC_Extern); 2569 } 2570 2571 // SynthGetSuperClassFunctionDecl - Class class_getSuperclass(Class cls); 2572 void RewriteModernObjC::SynthGetSuperClassFunctionDecl() { 2573 IdentifierInfo *getSuperClassIdent = 2574 &Context->Idents.get("class_getSuperclass"); 2575 SmallVector<QualType, 16> ArgTys; 2576 ArgTys.push_back(Context->getObjCClassType()); 2577 QualType getClassType = getSimpleFunctionType(Context->getObjCClassType(), 2578 ArgTys); 2579 GetSuperClassFunctionDecl = FunctionDecl::Create(*Context, TUDecl, 2580 SourceLocation(), 2581 SourceLocation(), 2582 getSuperClassIdent, 2583 getClassType, 0, 2584 SC_Extern); 2585 } 2586 2587 // SynthGetMetaClassFunctionDecl - Class objc_getMetaClass(const char *name); 2588 void RewriteModernObjC::SynthGetMetaClassFunctionDecl() { 2589 IdentifierInfo *getClassIdent = &Context->Idents.get("objc_getMetaClass"); 2590 SmallVector<QualType, 16> ArgTys; 2591 ArgTys.push_back(Context->getPointerType(Context->CharTy.withConst())); 2592 QualType getClassType = getSimpleFunctionType(Context->getObjCClassType(), 2593 ArgTys); 2594 GetMetaClassFunctionDecl = FunctionDecl::Create(*Context, TUDecl, 2595 SourceLocation(), 2596 SourceLocation(), 2597 getClassIdent, getClassType, 2598 0, SC_Extern); 2599 } 2600 2601 Stmt *RewriteModernObjC::RewriteObjCStringLiteral(ObjCStringLiteral *Exp) { 2602 QualType strType = getConstantStringStructType(); 2603 2604 std::string S = "__NSConstantStringImpl_"; 2605 2606 std::string tmpName = InFileName; 2607 unsigned i; 2608 for (i=0; i < tmpName.length(); i++) { 2609 char c = tmpName.at(i); 2610 // replace any non alphanumeric characters with '_'. 2611 if (!isAlphanumeric(c)) 2612 tmpName[i] = '_'; 2613 } 2614 S += tmpName; 2615 S += "_"; 2616 S += utostr(NumObjCStringLiterals++); 2617 2618 Preamble += "static __NSConstantStringImpl " + S; 2619 Preamble += " __attribute__ ((section (\"__DATA, __cfstring\"))) = {__CFConstantStringClassReference,"; 2620 Preamble += "0x000007c8,"; // utf8_str 2621 // The pretty printer for StringLiteral handles escape characters properly. 2622 std::string prettyBufS; 2623 llvm::raw_string_ostream prettyBuf(prettyBufS); 2624 Exp->getString()->printPretty(prettyBuf, 0, PrintingPolicy(LangOpts)); 2625 Preamble += prettyBuf.str(); 2626 Preamble += ","; 2627 Preamble += utostr(Exp->getString()->getByteLength()) + "};\n"; 2628 2629 VarDecl *NewVD = VarDecl::Create(*Context, TUDecl, SourceLocation(), 2630 SourceLocation(), &Context->Idents.get(S), 2631 strType, 0, SC_Static); 2632 DeclRefExpr *DRE = new (Context) DeclRefExpr(NewVD, false, strType, VK_LValue, 2633 SourceLocation()); 2634 Expr *Unop = new (Context) UnaryOperator(DRE, UO_AddrOf, 2635 Context->getPointerType(DRE->getType()), 2636 VK_RValue, OK_Ordinary, 2637 SourceLocation()); 2638 // cast to NSConstantString * 2639 CastExpr *cast = NoTypeInfoCStyleCastExpr(Context, Exp->getType(), 2640 CK_CPointerToObjCPointerCast, Unop); 2641 ReplaceStmt(Exp, cast); 2642 // delete Exp; leak for now, see RewritePropertyOrImplicitSetter() usage for more info. 2643 return cast; 2644 } 2645 2646 Stmt *RewriteModernObjC::RewriteObjCBoolLiteralExpr(ObjCBoolLiteralExpr *Exp) { 2647 unsigned IntSize = 2648 static_cast<unsigned>(Context->getTypeSize(Context->IntTy)); 2649 2650 Expr *FlagExp = IntegerLiteral::Create(*Context, 2651 llvm::APInt(IntSize, Exp->getValue()), 2652 Context->IntTy, Exp->getLocation()); 2653 CastExpr *cast = NoTypeInfoCStyleCastExpr(Context, Context->ObjCBuiltinBoolTy, 2654 CK_BitCast, FlagExp); 2655 ParenExpr *PE = new (Context) ParenExpr(Exp->getLocation(), Exp->getExprLoc(), 2656 cast); 2657 ReplaceStmt(Exp, PE); 2658 return PE; 2659 } 2660 2661 Stmt *RewriteModernObjC::RewriteObjCBoxedExpr(ObjCBoxedExpr *Exp) { 2662 // synthesize declaration of helper functions needed in this routine. 2663 if (!SelGetUidFunctionDecl) 2664 SynthSelGetUidFunctionDecl(); 2665 // use objc_msgSend() for all. 2666 if (!MsgSendFunctionDecl) 2667 SynthMsgSendFunctionDecl(); 2668 if (!GetClassFunctionDecl) 2669 SynthGetClassFunctionDecl(); 2670 2671 FunctionDecl *MsgSendFlavor = MsgSendFunctionDecl; 2672 SourceLocation StartLoc = Exp->getLocStart(); 2673 SourceLocation EndLoc = Exp->getLocEnd(); 2674 2675 // Synthesize a call to objc_msgSend(). 2676 SmallVector<Expr*, 4> MsgExprs; 2677 SmallVector<Expr*, 4> ClsExprs; 2678 QualType argType = Context->getPointerType(Context->CharTy); 2679 2680 // Create a call to objc_getClass("<BoxingClass>"). It will be the 1st argument. 2681 ObjCMethodDecl *BoxingMethod = Exp->getBoxingMethod(); 2682 ObjCInterfaceDecl *BoxingClass = BoxingMethod->getClassInterface(); 2683 2684 IdentifierInfo *clsName = BoxingClass->getIdentifier(); 2685 ClsExprs.push_back(StringLiteral::Create(*Context, 2686 clsName->getName(), 2687 StringLiteral::Ascii, false, 2688 argType, SourceLocation())); 2689 CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl, 2690 &ClsExprs[0], 2691 ClsExprs.size(), 2692 StartLoc, EndLoc); 2693 MsgExprs.push_back(Cls); 2694 2695 // Create a call to sel_registerName("<BoxingMethod>:"), etc. 2696 // it will be the 2nd argument. 2697 SmallVector<Expr*, 4> SelExprs; 2698 SelExprs.push_back(StringLiteral::Create(*Context, 2699 BoxingMethod->getSelector().getAsString(), 2700 StringLiteral::Ascii, false, 2701 argType, SourceLocation())); 2702 CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl, 2703 &SelExprs[0], SelExprs.size(), 2704 StartLoc, EndLoc); 2705 MsgExprs.push_back(SelExp); 2706 2707 // User provided sub-expression is the 3rd, and last, argument. 2708 Expr *subExpr = Exp->getSubExpr(); 2709 if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(subExpr)) { 2710 QualType type = ICE->getType(); 2711 const Expr *SubExpr = ICE->IgnoreParenImpCasts(); 2712 CastKind CK = CK_BitCast; 2713 if (SubExpr->getType()->isIntegralType(*Context) && type->isBooleanType()) 2714 CK = CK_IntegralToBoolean; 2715 subExpr = NoTypeInfoCStyleCastExpr(Context, type, CK, subExpr); 2716 } 2717 MsgExprs.push_back(subExpr); 2718 2719 SmallVector<QualType, 4> ArgTypes; 2720 ArgTypes.push_back(Context->getObjCIdType()); 2721 ArgTypes.push_back(Context->getObjCSelType()); 2722 for (ObjCMethodDecl::param_iterator PI = BoxingMethod->param_begin(), 2723 E = BoxingMethod->param_end(); PI != E; ++PI) 2724 ArgTypes.push_back((*PI)->getType()); 2725 2726 QualType returnType = Exp->getType(); 2727 // Get the type, we will need to reference it in a couple spots. 2728 QualType msgSendType = MsgSendFlavor->getType(); 2729 2730 // Create a reference to the objc_msgSend() declaration. 2731 DeclRefExpr *DRE = new (Context) DeclRefExpr(MsgSendFlavor, false, msgSendType, 2732 VK_LValue, SourceLocation()); 2733 2734 CastExpr *cast = NoTypeInfoCStyleCastExpr(Context, 2735 Context->getPointerType(Context->VoidTy), 2736 CK_BitCast, DRE); 2737 2738 // Now do the "normal" pointer to function cast. 2739 QualType castType = 2740 getSimpleFunctionType(returnType, ArgTypes, BoxingMethod->isVariadic()); 2741 castType = Context->getPointerType(castType); 2742 cast = NoTypeInfoCStyleCastExpr(Context, castType, CK_BitCast, 2743 cast); 2744 2745 // Don't forget the parens to enforce the proper binding. 2746 ParenExpr *PE = new (Context) ParenExpr(StartLoc, EndLoc, cast); 2747 2748 const FunctionType *FT = msgSendType->getAs<FunctionType>(); 2749 CallExpr *CE = new (Context) CallExpr(*Context, PE, MsgExprs, 2750 FT->getResultType(), VK_RValue, 2751 EndLoc); 2752 ReplaceStmt(Exp, CE); 2753 return CE; 2754 } 2755 2756 Stmt *RewriteModernObjC::RewriteObjCArrayLiteralExpr(ObjCArrayLiteral *Exp) { 2757 // synthesize declaration of helper functions needed in this routine. 2758 if (!SelGetUidFunctionDecl) 2759 SynthSelGetUidFunctionDecl(); 2760 // use objc_msgSend() for all. 2761 if (!MsgSendFunctionDecl) 2762 SynthMsgSendFunctionDecl(); 2763 if (!GetClassFunctionDecl) 2764 SynthGetClassFunctionDecl(); 2765 2766 FunctionDecl *MsgSendFlavor = MsgSendFunctionDecl; 2767 SourceLocation StartLoc = Exp->getLocStart(); 2768 SourceLocation EndLoc = Exp->getLocEnd(); 2769 2770 // Build the expression: __NSContainer_literal(int, ...).arr 2771 QualType IntQT = Context->IntTy; 2772 QualType NSArrayFType = 2773 getSimpleFunctionType(Context->VoidTy, IntQT, true); 2774 std::string NSArrayFName("__NSContainer_literal"); 2775 FunctionDecl *NSArrayFD = SynthBlockInitFunctionDecl(NSArrayFName); 2776 DeclRefExpr *NSArrayDRE = 2777 new (Context) DeclRefExpr(NSArrayFD, false, NSArrayFType, VK_RValue, 2778 SourceLocation()); 2779 2780 SmallVector<Expr*, 16> InitExprs; 2781 unsigned NumElements = Exp->getNumElements(); 2782 unsigned UnsignedIntSize = 2783 static_cast<unsigned>(Context->getTypeSize(Context->UnsignedIntTy)); 2784 Expr *count = IntegerLiteral::Create(*Context, 2785 llvm::APInt(UnsignedIntSize, NumElements), 2786 Context->UnsignedIntTy, SourceLocation()); 2787 InitExprs.push_back(count); 2788 for (unsigned i = 0; i < NumElements; i++) 2789 InitExprs.push_back(Exp->getElement(i)); 2790 Expr *NSArrayCallExpr = 2791 new (Context) CallExpr(*Context, NSArrayDRE, InitExprs, 2792 NSArrayFType, VK_LValue, SourceLocation()); 2793 2794 FieldDecl *ARRFD = FieldDecl::Create(*Context, 0, SourceLocation(), 2795 SourceLocation(), 2796 &Context->Idents.get("arr"), 2797 Context->getPointerType(Context->VoidPtrTy), 0, 2798 /*BitWidth=*/0, /*Mutable=*/true, 2799 ICIS_NoInit); 2800 MemberExpr *ArrayLiteralME = 2801 new (Context) MemberExpr(NSArrayCallExpr, false, ARRFD, 2802 SourceLocation(), 2803 ARRFD->getType(), VK_LValue, 2804 OK_Ordinary); 2805 QualType ConstIdT = Context->getObjCIdType().withConst(); 2806 CStyleCastExpr * ArrayLiteralObjects = 2807 NoTypeInfoCStyleCastExpr(Context, 2808 Context->getPointerType(ConstIdT), 2809 CK_BitCast, 2810 ArrayLiteralME); 2811 2812 // Synthesize a call to objc_msgSend(). 2813 SmallVector<Expr*, 32> MsgExprs; 2814 SmallVector<Expr*, 4> ClsExprs; 2815 QualType argType = Context->getPointerType(Context->CharTy); 2816 QualType expType = Exp->getType(); 2817 2818 // Create a call to objc_getClass("NSArray"). It will be th 1st argument. 2819 ObjCInterfaceDecl *Class = 2820 expType->getPointeeType()->getAs<ObjCObjectType>()->getInterface(); 2821 2822 IdentifierInfo *clsName = Class->getIdentifier(); 2823 ClsExprs.push_back(StringLiteral::Create(*Context, 2824 clsName->getName(), 2825 StringLiteral::Ascii, false, 2826 argType, SourceLocation())); 2827 CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl, 2828 &ClsExprs[0], 2829 ClsExprs.size(), 2830 StartLoc, EndLoc); 2831 MsgExprs.push_back(Cls); 2832 2833 // Create a call to sel_registerName("arrayWithObjects:count:"). 2834 // it will be the 2nd argument. 2835 SmallVector<Expr*, 4> SelExprs; 2836 ObjCMethodDecl *ArrayMethod = Exp->getArrayWithObjectsMethod(); 2837 SelExprs.push_back(StringLiteral::Create(*Context, 2838 ArrayMethod->getSelector().getAsString(), 2839 StringLiteral::Ascii, false, 2840 argType, SourceLocation())); 2841 CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl, 2842 &SelExprs[0], SelExprs.size(), 2843 StartLoc, EndLoc); 2844 MsgExprs.push_back(SelExp); 2845 2846 // (const id [])objects 2847 MsgExprs.push_back(ArrayLiteralObjects); 2848 2849 // (NSUInteger)cnt 2850 Expr *cnt = IntegerLiteral::Create(*Context, 2851 llvm::APInt(UnsignedIntSize, NumElements), 2852 Context->UnsignedIntTy, SourceLocation()); 2853 MsgExprs.push_back(cnt); 2854 2855 2856 SmallVector<QualType, 4> ArgTypes; 2857 ArgTypes.push_back(Context->getObjCIdType()); 2858 ArgTypes.push_back(Context->getObjCSelType()); 2859 for (ObjCMethodDecl::param_iterator PI = ArrayMethod->param_begin(), 2860 E = ArrayMethod->param_end(); PI != E; ++PI) 2861 ArgTypes.push_back((*PI)->getType()); 2862 2863 QualType returnType = Exp->getType(); 2864 // Get the type, we will need to reference it in a couple spots. 2865 QualType msgSendType = MsgSendFlavor->getType(); 2866 2867 // Create a reference to the objc_msgSend() declaration. 2868 DeclRefExpr *DRE = new (Context) DeclRefExpr(MsgSendFlavor, false, msgSendType, 2869 VK_LValue, SourceLocation()); 2870 2871 CastExpr *cast = NoTypeInfoCStyleCastExpr(Context, 2872 Context->getPointerType(Context->VoidTy), 2873 CK_BitCast, DRE); 2874 2875 // Now do the "normal" pointer to function cast. 2876 QualType castType = 2877 getSimpleFunctionType(returnType, ArgTypes, ArrayMethod->isVariadic()); 2878 castType = Context->getPointerType(castType); 2879 cast = NoTypeInfoCStyleCastExpr(Context, castType, CK_BitCast, 2880 cast); 2881 2882 // Don't forget the parens to enforce the proper binding. 2883 ParenExpr *PE = new (Context) ParenExpr(StartLoc, EndLoc, cast); 2884 2885 const FunctionType *FT = msgSendType->getAs<FunctionType>(); 2886 CallExpr *CE = new (Context) CallExpr(*Context, PE, MsgExprs, 2887 FT->getResultType(), VK_RValue, 2888 EndLoc); 2889 ReplaceStmt(Exp, CE); 2890 return CE; 2891 } 2892 2893 Stmt *RewriteModernObjC::RewriteObjCDictionaryLiteralExpr(ObjCDictionaryLiteral *Exp) { 2894 // synthesize declaration of helper functions needed in this routine. 2895 if (!SelGetUidFunctionDecl) 2896 SynthSelGetUidFunctionDecl(); 2897 // use objc_msgSend() for all. 2898 if (!MsgSendFunctionDecl) 2899 SynthMsgSendFunctionDecl(); 2900 if (!GetClassFunctionDecl) 2901 SynthGetClassFunctionDecl(); 2902 2903 FunctionDecl *MsgSendFlavor = MsgSendFunctionDecl; 2904 SourceLocation StartLoc = Exp->getLocStart(); 2905 SourceLocation EndLoc = Exp->getLocEnd(); 2906 2907 // Build the expression: __NSContainer_literal(int, ...).arr 2908 QualType IntQT = Context->IntTy; 2909 QualType NSDictFType = 2910 getSimpleFunctionType(Context->VoidTy, IntQT, true); 2911 std::string NSDictFName("__NSContainer_literal"); 2912 FunctionDecl *NSDictFD = SynthBlockInitFunctionDecl(NSDictFName); 2913 DeclRefExpr *NSDictDRE = 2914 new (Context) DeclRefExpr(NSDictFD, false, NSDictFType, VK_RValue, 2915 SourceLocation()); 2916 2917 SmallVector<Expr*, 16> KeyExprs; 2918 SmallVector<Expr*, 16> ValueExprs; 2919 2920 unsigned NumElements = Exp->getNumElements(); 2921 unsigned UnsignedIntSize = 2922 static_cast<unsigned>(Context->getTypeSize(Context->UnsignedIntTy)); 2923 Expr *count = IntegerLiteral::Create(*Context, 2924 llvm::APInt(UnsignedIntSize, NumElements), 2925 Context->UnsignedIntTy, SourceLocation()); 2926 KeyExprs.push_back(count); 2927 ValueExprs.push_back(count); 2928 for (unsigned i = 0; i < NumElements; i++) { 2929 ObjCDictionaryElement Element = Exp->getKeyValueElement(i); 2930 KeyExprs.push_back(Element.Key); 2931 ValueExprs.push_back(Element.Value); 2932 } 2933 2934 // (const id [])objects 2935 Expr *NSValueCallExpr = 2936 new (Context) CallExpr(*Context, NSDictDRE, ValueExprs, 2937 NSDictFType, VK_LValue, SourceLocation()); 2938 2939 FieldDecl *ARRFD = FieldDecl::Create(*Context, 0, SourceLocation(), 2940 SourceLocation(), 2941 &Context->Idents.get("arr"), 2942 Context->getPointerType(Context->VoidPtrTy), 0, 2943 /*BitWidth=*/0, /*Mutable=*/true, 2944 ICIS_NoInit); 2945 MemberExpr *DictLiteralValueME = 2946 new (Context) MemberExpr(NSValueCallExpr, false, ARRFD, 2947 SourceLocation(), 2948 ARRFD->getType(), VK_LValue, 2949 OK_Ordinary); 2950 QualType ConstIdT = Context->getObjCIdType().withConst(); 2951 CStyleCastExpr * DictValueObjects = 2952 NoTypeInfoCStyleCastExpr(Context, 2953 Context->getPointerType(ConstIdT), 2954 CK_BitCast, 2955 DictLiteralValueME); 2956 // (const id <NSCopying> [])keys 2957 Expr *NSKeyCallExpr = 2958 new (Context) CallExpr(*Context, NSDictDRE, KeyExprs, 2959 NSDictFType, VK_LValue, SourceLocation()); 2960 2961 MemberExpr *DictLiteralKeyME = 2962 new (Context) MemberExpr(NSKeyCallExpr, false, ARRFD, 2963 SourceLocation(), 2964 ARRFD->getType(), VK_LValue, 2965 OK_Ordinary); 2966 2967 CStyleCastExpr * DictKeyObjects = 2968 NoTypeInfoCStyleCastExpr(Context, 2969 Context->getPointerType(ConstIdT), 2970 CK_BitCast, 2971 DictLiteralKeyME); 2972 2973 2974 2975 // Synthesize a call to objc_msgSend(). 2976 SmallVector<Expr*, 32> MsgExprs; 2977 SmallVector<Expr*, 4> ClsExprs; 2978 QualType argType = Context->getPointerType(Context->CharTy); 2979 QualType expType = Exp->getType(); 2980 2981 // Create a call to objc_getClass("NSArray"). It will be th 1st argument. 2982 ObjCInterfaceDecl *Class = 2983 expType->getPointeeType()->getAs<ObjCObjectType>()->getInterface(); 2984 2985 IdentifierInfo *clsName = Class->getIdentifier(); 2986 ClsExprs.push_back(StringLiteral::Create(*Context, 2987 clsName->getName(), 2988 StringLiteral::Ascii, false, 2989 argType, SourceLocation())); 2990 CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl, 2991 &ClsExprs[0], 2992 ClsExprs.size(), 2993 StartLoc, EndLoc); 2994 MsgExprs.push_back(Cls); 2995 2996 // Create a call to sel_registerName("arrayWithObjects:count:"). 2997 // it will be the 2nd argument. 2998 SmallVector<Expr*, 4> SelExprs; 2999 ObjCMethodDecl *DictMethod = Exp->getDictWithObjectsMethod(); 3000 SelExprs.push_back(StringLiteral::Create(*Context, 3001 DictMethod->getSelector().getAsString(), 3002 StringLiteral::Ascii, false, 3003 argType, SourceLocation())); 3004 CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl, 3005 &SelExprs[0], SelExprs.size(), 3006 StartLoc, EndLoc); 3007 MsgExprs.push_back(SelExp); 3008 3009 // (const id [])objects 3010 MsgExprs.push_back(DictValueObjects); 3011 3012 // (const id <NSCopying> [])keys 3013 MsgExprs.push_back(DictKeyObjects); 3014 3015 // (NSUInteger)cnt 3016 Expr *cnt = IntegerLiteral::Create(*Context, 3017 llvm::APInt(UnsignedIntSize, NumElements), 3018 Context->UnsignedIntTy, SourceLocation()); 3019 MsgExprs.push_back(cnt); 3020 3021 3022 SmallVector<QualType, 8> ArgTypes; 3023 ArgTypes.push_back(Context->getObjCIdType()); 3024 ArgTypes.push_back(Context->getObjCSelType()); 3025 for (ObjCMethodDecl::param_iterator PI = DictMethod->param_begin(), 3026 E = DictMethod->param_end(); PI != E; ++PI) { 3027 QualType T = (*PI)->getType(); 3028 if (const PointerType* PT = T->getAs<PointerType>()) { 3029 QualType PointeeTy = PT->getPointeeType(); 3030 convertToUnqualifiedObjCType(PointeeTy); 3031 T = Context->getPointerType(PointeeTy); 3032 } 3033 ArgTypes.push_back(T); 3034 } 3035 3036 QualType returnType = Exp->getType(); 3037 // Get the type, we will need to reference it in a couple spots. 3038 QualType msgSendType = MsgSendFlavor->getType(); 3039 3040 // Create a reference to the objc_msgSend() declaration. 3041 DeclRefExpr *DRE = new (Context) DeclRefExpr(MsgSendFlavor, false, msgSendType, 3042 VK_LValue, SourceLocation()); 3043 3044 CastExpr *cast = NoTypeInfoCStyleCastExpr(Context, 3045 Context->getPointerType(Context->VoidTy), 3046 CK_BitCast, DRE); 3047 3048 // Now do the "normal" pointer to function cast. 3049 QualType castType = 3050 getSimpleFunctionType(returnType, ArgTypes, DictMethod->isVariadic()); 3051 castType = Context->getPointerType(castType); 3052 cast = NoTypeInfoCStyleCastExpr(Context, castType, CK_BitCast, 3053 cast); 3054 3055 // Don't forget the parens to enforce the proper binding. 3056 ParenExpr *PE = new (Context) ParenExpr(StartLoc, EndLoc, cast); 3057 3058 const FunctionType *FT = msgSendType->getAs<FunctionType>(); 3059 CallExpr *CE = new (Context) CallExpr(*Context, PE, MsgExprs, 3060 FT->getResultType(), VK_RValue, 3061 EndLoc); 3062 ReplaceStmt(Exp, CE); 3063 return CE; 3064 } 3065 3066 // struct __rw_objc_super { 3067 // struct objc_object *object; struct objc_object *superClass; 3068 // }; 3069 QualType RewriteModernObjC::getSuperStructType() { 3070 if (!SuperStructDecl) { 3071 SuperStructDecl = RecordDecl::Create(*Context, TTK_Struct, TUDecl, 3072 SourceLocation(), SourceLocation(), 3073 &Context->Idents.get("__rw_objc_super")); 3074 QualType FieldTypes[2]; 3075 3076 // struct objc_object *object; 3077 FieldTypes[0] = Context->getObjCIdType(); 3078 // struct objc_object *superClass; 3079 FieldTypes[1] = Context->getObjCIdType(); 3080 3081 // Create fields 3082 for (unsigned i = 0; i < 2; ++i) { 3083 SuperStructDecl->addDecl(FieldDecl::Create(*Context, SuperStructDecl, 3084 SourceLocation(), 3085 SourceLocation(), 0, 3086 FieldTypes[i], 0, 3087 /*BitWidth=*/0, 3088 /*Mutable=*/false, 3089 ICIS_NoInit)); 3090 } 3091 3092 SuperStructDecl->completeDefinition(); 3093 } 3094 return Context->getTagDeclType(SuperStructDecl); 3095 } 3096 3097 QualType RewriteModernObjC::getConstantStringStructType() { 3098 if (!ConstantStringDecl) { 3099 ConstantStringDecl = RecordDecl::Create(*Context, TTK_Struct, TUDecl, 3100 SourceLocation(), SourceLocation(), 3101 &Context->Idents.get("__NSConstantStringImpl")); 3102 QualType FieldTypes[4]; 3103 3104 // struct objc_object *receiver; 3105 FieldTypes[0] = Context->getObjCIdType(); 3106 // int flags; 3107 FieldTypes[1] = Context->IntTy; 3108 // char *str; 3109 FieldTypes[2] = Context->getPointerType(Context->CharTy); 3110 // long length; 3111 FieldTypes[3] = Context->LongTy; 3112 3113 // Create fields 3114 for (unsigned i = 0; i < 4; ++i) { 3115 ConstantStringDecl->addDecl(FieldDecl::Create(*Context, 3116 ConstantStringDecl, 3117 SourceLocation(), 3118 SourceLocation(), 0, 3119 FieldTypes[i], 0, 3120 /*BitWidth=*/0, 3121 /*Mutable=*/true, 3122 ICIS_NoInit)); 3123 } 3124 3125 ConstantStringDecl->completeDefinition(); 3126 } 3127 return Context->getTagDeclType(ConstantStringDecl); 3128 } 3129 3130 /// getFunctionSourceLocation - returns start location of a function 3131 /// definition. Complication arises when function has declared as 3132 /// extern "C" or extern "C" {...} 3133 static SourceLocation getFunctionSourceLocation (RewriteModernObjC &R, 3134 FunctionDecl *FD) { 3135 if (FD->isExternC() && !FD->isMain()) { 3136 const DeclContext *DC = FD->getDeclContext(); 3137 if (const LinkageSpecDecl *LSD = dyn_cast<LinkageSpecDecl>(DC)) 3138 // if it is extern "C" {...}, return function decl's own location. 3139 if (!LSD->getRBraceLoc().isValid()) 3140 return LSD->getExternLoc(); 3141 } 3142 if (FD->getStorageClass() != SC_None) 3143 R.RewriteBlockLiteralFunctionDecl(FD); 3144 return FD->getTypeSpecStartLoc(); 3145 } 3146 3147 void RewriteModernObjC::RewriteLineDirective(const Decl *D) { 3148 3149 SourceLocation Location = D->getLocation(); 3150 3151 if (Location.isFileID() && GenerateLineInfo) { 3152 std::string LineString("\n#line "); 3153 PresumedLoc PLoc = SM->getPresumedLoc(Location); 3154 LineString += utostr(PLoc.getLine()); 3155 LineString += " \""; 3156 LineString += Lexer::Stringify(PLoc.getFilename()); 3157 if (isa<ObjCMethodDecl>(D)) 3158 LineString += "\""; 3159 else LineString += "\"\n"; 3160 3161 Location = D->getLocStart(); 3162 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { 3163 if (FD->isExternC() && !FD->isMain()) { 3164 const DeclContext *DC = FD->getDeclContext(); 3165 if (const LinkageSpecDecl *LSD = dyn_cast<LinkageSpecDecl>(DC)) 3166 // if it is extern "C" {...}, return function decl's own location. 3167 if (!LSD->getRBraceLoc().isValid()) 3168 Location = LSD->getExternLoc(); 3169 } 3170 } 3171 InsertText(Location, LineString); 3172 } 3173 } 3174 3175 /// SynthMsgSendStretCallExpr - This routine translates message expression 3176 /// into a call to objc_msgSend_stret() entry point. Tricky part is that 3177 /// nil check on receiver must be performed before calling objc_msgSend_stret. 3178 /// MsgSendStretFlavor - function declaration objc_msgSend_stret(...) 3179 /// msgSendType - function type of objc_msgSend_stret(...) 3180 /// returnType - Result type of the method being synthesized. 3181 /// ArgTypes - type of the arguments passed to objc_msgSend_stret, starting with receiver type. 3182 /// MsgExprs - list of argument expressions being passed to objc_msgSend_stret, 3183 /// starting with receiver. 3184 /// Method - Method being rewritten. 3185 Expr *RewriteModernObjC::SynthMsgSendStretCallExpr(FunctionDecl *MsgSendStretFlavor, 3186 QualType msgSendType, 3187 QualType returnType, 3188 SmallVectorImpl<QualType> &ArgTypes, 3189 SmallVectorImpl<Expr*> &MsgExprs, 3190 ObjCMethodDecl *Method) { 3191 // Now do the "normal" pointer to function cast. 3192 QualType castType = getSimpleFunctionType(returnType, ArgTypes, 3193 Method ? Method->isVariadic() 3194 : false); 3195 castType = Context->getPointerType(castType); 3196 3197 // build type for containing the objc_msgSend_stret object. 3198 static unsigned stretCount=0; 3199 std::string name = "__Stret"; name += utostr(stretCount); 3200 std::string str = 3201 "extern \"C\" void * __cdecl memset(void *_Dst, int _Val, size_t _Size);\n"; 3202 str += "struct "; str += name; 3203 str += " {\n\t"; 3204 str += name; 3205 str += "(id receiver, SEL sel"; 3206 for (unsigned i = 2; i < ArgTypes.size(); i++) { 3207 std::string ArgName = "arg"; ArgName += utostr(i); 3208 ArgTypes[i].getAsStringInternal(ArgName, Context->getPrintingPolicy()); 3209 str += ", "; str += ArgName; 3210 } 3211 // could be vararg. 3212 for (unsigned i = ArgTypes.size(); i < MsgExprs.size(); i++) { 3213 std::string ArgName = "arg"; ArgName += utostr(i); 3214 MsgExprs[i]->getType().getAsStringInternal(ArgName, 3215 Context->getPrintingPolicy()); 3216 str += ", "; str += ArgName; 3217 } 3218 3219 str += ") {\n"; 3220 str += "\t if (receiver == 0)\n"; 3221 str += "\t memset((void*)&s, 0, sizeof(s));\n"; 3222 str += "\t else\n"; 3223 str += "\t s = (("; str += castType.getAsString(Context->getPrintingPolicy()); 3224 str += ")(void *)objc_msgSend_stret)(receiver, sel"; 3225 for (unsigned i = 2; i < ArgTypes.size(); i++) { 3226 str += ", arg"; str += utostr(i); 3227 } 3228 // could be vararg. 3229 for (unsigned i = ArgTypes.size(); i < MsgExprs.size(); i++) { 3230 str += ", arg"; str += utostr(i); 3231 } 3232 3233 str += ");\n"; 3234 str += "\t}\n"; 3235 str += "\t"; str += returnType.getAsString(Context->getPrintingPolicy()); 3236 str += " s;\n"; 3237 str += "};\n\n"; 3238 SourceLocation FunLocStart; 3239 if (CurFunctionDef) 3240 FunLocStart = getFunctionSourceLocation(*this, CurFunctionDef); 3241 else { 3242 assert(CurMethodDef && "SynthMsgSendStretCallExpr - CurMethodDef is null"); 3243 FunLocStart = CurMethodDef->getLocStart(); 3244 } 3245 3246 InsertText(FunLocStart, str); 3247 ++stretCount; 3248 3249 // AST for __Stretn(receiver, args).s; 3250 IdentifierInfo *ID = &Context->Idents.get(name); 3251 FunctionDecl *FD = FunctionDecl::Create(*Context, TUDecl, SourceLocation(), 3252 SourceLocation(), ID, castType, 0, 3253 SC_Extern, false, false); 3254 DeclRefExpr *DRE = new (Context) DeclRefExpr(FD, false, castType, VK_RValue, 3255 SourceLocation()); 3256 CallExpr *STCE = new (Context) CallExpr(*Context, DRE, MsgExprs, 3257 castType, VK_LValue, SourceLocation()); 3258 3259 FieldDecl *FieldD = FieldDecl::Create(*Context, 0, SourceLocation(), 3260 SourceLocation(), 3261 &Context->Idents.get("s"), 3262 returnType, 0, 3263 /*BitWidth=*/0, /*Mutable=*/true, 3264 ICIS_NoInit); 3265 MemberExpr *ME = new (Context) MemberExpr(STCE, false, FieldD, SourceLocation(), 3266 FieldD->getType(), VK_LValue, 3267 OK_Ordinary); 3268 3269 return ME; 3270 } 3271 3272 Stmt *RewriteModernObjC::SynthMessageExpr(ObjCMessageExpr *Exp, 3273 SourceLocation StartLoc, 3274 SourceLocation EndLoc) { 3275 if (!SelGetUidFunctionDecl) 3276 SynthSelGetUidFunctionDecl(); 3277 if (!MsgSendFunctionDecl) 3278 SynthMsgSendFunctionDecl(); 3279 if (!MsgSendSuperFunctionDecl) 3280 SynthMsgSendSuperFunctionDecl(); 3281 if (!MsgSendStretFunctionDecl) 3282 SynthMsgSendStretFunctionDecl(); 3283 if (!MsgSendSuperStretFunctionDecl) 3284 SynthMsgSendSuperStretFunctionDecl(); 3285 if (!MsgSendFpretFunctionDecl) 3286 SynthMsgSendFpretFunctionDecl(); 3287 if (!GetClassFunctionDecl) 3288 SynthGetClassFunctionDecl(); 3289 if (!GetSuperClassFunctionDecl) 3290 SynthGetSuperClassFunctionDecl(); 3291 if (!GetMetaClassFunctionDecl) 3292 SynthGetMetaClassFunctionDecl(); 3293 3294 // default to objc_msgSend(). 3295 FunctionDecl *MsgSendFlavor = MsgSendFunctionDecl; 3296 // May need to use objc_msgSend_stret() as well. 3297 FunctionDecl *MsgSendStretFlavor = 0; 3298 if (ObjCMethodDecl *mDecl = Exp->getMethodDecl()) { 3299 QualType resultType = mDecl->getResultType(); 3300 if (resultType->isRecordType()) 3301 MsgSendStretFlavor = MsgSendStretFunctionDecl; 3302 else if (resultType->isRealFloatingType()) 3303 MsgSendFlavor = MsgSendFpretFunctionDecl; 3304 } 3305 3306 // Synthesize a call to objc_msgSend(). 3307 SmallVector<Expr*, 8> MsgExprs; 3308 switch (Exp->getReceiverKind()) { 3309 case ObjCMessageExpr::SuperClass: { 3310 MsgSendFlavor = MsgSendSuperFunctionDecl; 3311 if (MsgSendStretFlavor) 3312 MsgSendStretFlavor = MsgSendSuperStretFunctionDecl; 3313 assert(MsgSendFlavor && "MsgSendFlavor is NULL!"); 3314 3315 ObjCInterfaceDecl *ClassDecl = CurMethodDef->getClassInterface(); 3316 3317 SmallVector<Expr*, 4> InitExprs; 3318 3319 // set the receiver to self, the first argument to all methods. 3320 InitExprs.push_back( 3321 NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(), 3322 CK_BitCast, 3323 new (Context) DeclRefExpr(CurMethodDef->getSelfDecl(), 3324 false, 3325 Context->getObjCIdType(), 3326 VK_RValue, 3327 SourceLocation())) 3328 ); // set the 'receiver'. 3329 3330 // (id)class_getSuperclass((Class)objc_getClass("CurrentClass")) 3331 SmallVector<Expr*, 8> ClsExprs; 3332 QualType argType = Context->getPointerType(Context->CharTy); 3333 ClsExprs.push_back(StringLiteral::Create(*Context, 3334 ClassDecl->getIdentifier()->getName(), 3335 StringLiteral::Ascii, false, 3336 argType, SourceLocation())); 3337 // (Class)objc_getClass("CurrentClass") 3338 CallExpr *Cls = SynthesizeCallToFunctionDecl(GetMetaClassFunctionDecl, 3339 &ClsExprs[0], 3340 ClsExprs.size(), 3341 StartLoc, 3342 EndLoc); 3343 ClsExprs.clear(); 3344 ClsExprs.push_back(Cls); 3345 Cls = SynthesizeCallToFunctionDecl(GetSuperClassFunctionDecl, 3346 &ClsExprs[0], ClsExprs.size(), 3347 StartLoc, EndLoc); 3348 3349 // (id)class_getSuperclass((Class)objc_getClass("CurrentClass")) 3350 // To turn off a warning, type-cast to 'id' 3351 InitExprs.push_back( // set 'super class', using class_getSuperclass(). 3352 NoTypeInfoCStyleCastExpr(Context, 3353 Context->getObjCIdType(), 3354 CK_BitCast, Cls)); 3355 // struct __rw_objc_super 3356 QualType superType = getSuperStructType(); 3357 Expr *SuperRep; 3358 3359 if (LangOpts.MicrosoftExt) { 3360 SynthSuperContructorFunctionDecl(); 3361 // Simulate a contructor call... 3362 DeclRefExpr *DRE = new (Context) DeclRefExpr(SuperContructorFunctionDecl, 3363 false, superType, VK_LValue, 3364 SourceLocation()); 3365 SuperRep = new (Context) CallExpr(*Context, DRE, InitExprs, 3366 superType, VK_LValue, 3367 SourceLocation()); 3368 // The code for super is a little tricky to prevent collision with 3369 // the structure definition in the header. The rewriter has it's own 3370 // internal definition (__rw_objc_super) that is uses. This is why 3371 // we need the cast below. For example: 3372 // (struct __rw_objc_super *)&__rw_objc_super((id)self, (id)objc_getClass("SUPER")) 3373 // 3374 SuperRep = new (Context) UnaryOperator(SuperRep, UO_AddrOf, 3375 Context->getPointerType(SuperRep->getType()), 3376 VK_RValue, OK_Ordinary, 3377 SourceLocation()); 3378 SuperRep = NoTypeInfoCStyleCastExpr(Context, 3379 Context->getPointerType(superType), 3380 CK_BitCast, SuperRep); 3381 } else { 3382 // (struct __rw_objc_super) { <exprs from above> } 3383 InitListExpr *ILE = 3384 new (Context) InitListExpr(*Context, SourceLocation(), InitExprs, 3385 SourceLocation()); 3386 TypeSourceInfo *superTInfo 3387 = Context->getTrivialTypeSourceInfo(superType); 3388 SuperRep = new (Context) CompoundLiteralExpr(SourceLocation(), superTInfo, 3389 superType, VK_LValue, 3390 ILE, false); 3391 // struct __rw_objc_super * 3392 SuperRep = new (Context) UnaryOperator(SuperRep, UO_AddrOf, 3393 Context->getPointerType(SuperRep->getType()), 3394 VK_RValue, OK_Ordinary, 3395 SourceLocation()); 3396 } 3397 MsgExprs.push_back(SuperRep); 3398 break; 3399 } 3400 3401 case ObjCMessageExpr::Class: { 3402 SmallVector<Expr*, 8> ClsExprs; 3403 QualType argType = Context->getPointerType(Context->CharTy); 3404 ObjCInterfaceDecl *Class 3405 = Exp->getClassReceiver()->getAs<ObjCObjectType>()->getInterface(); 3406 IdentifierInfo *clsName = Class->getIdentifier(); 3407 ClsExprs.push_back(StringLiteral::Create(*Context, 3408 clsName->getName(), 3409 StringLiteral::Ascii, false, 3410 argType, SourceLocation())); 3411 CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl, 3412 &ClsExprs[0], 3413 ClsExprs.size(), 3414 StartLoc, EndLoc); 3415 CastExpr *ArgExpr = NoTypeInfoCStyleCastExpr(Context, 3416 Context->getObjCIdType(), 3417 CK_BitCast, Cls); 3418 MsgExprs.push_back(ArgExpr); 3419 break; 3420 } 3421 3422 case ObjCMessageExpr::SuperInstance:{ 3423 MsgSendFlavor = MsgSendSuperFunctionDecl; 3424 if (MsgSendStretFlavor) 3425 MsgSendStretFlavor = MsgSendSuperStretFunctionDecl; 3426 assert(MsgSendFlavor && "MsgSendFlavor is NULL!"); 3427 ObjCInterfaceDecl *ClassDecl = CurMethodDef->getClassInterface(); 3428 SmallVector<Expr*, 4> InitExprs; 3429 3430 InitExprs.push_back( 3431 NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(), 3432 CK_BitCast, 3433 new (Context) DeclRefExpr(CurMethodDef->getSelfDecl(), 3434 false, 3435 Context->getObjCIdType(), 3436 VK_RValue, SourceLocation())) 3437 ); // set the 'receiver'. 3438 3439 // (id)class_getSuperclass((Class)objc_getClass("CurrentClass")) 3440 SmallVector<Expr*, 8> ClsExprs; 3441 QualType argType = Context->getPointerType(Context->CharTy); 3442 ClsExprs.push_back(StringLiteral::Create(*Context, 3443 ClassDecl->getIdentifier()->getName(), 3444 StringLiteral::Ascii, false, argType, 3445 SourceLocation())); 3446 // (Class)objc_getClass("CurrentClass") 3447 CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl, 3448 &ClsExprs[0], 3449 ClsExprs.size(), 3450 StartLoc, EndLoc); 3451 ClsExprs.clear(); 3452 ClsExprs.push_back(Cls); 3453 Cls = SynthesizeCallToFunctionDecl(GetSuperClassFunctionDecl, 3454 &ClsExprs[0], ClsExprs.size(), 3455 StartLoc, EndLoc); 3456 3457 // (id)class_getSuperclass((Class)objc_getClass("CurrentClass")) 3458 // To turn off a warning, type-cast to 'id' 3459 InitExprs.push_back( 3460 // set 'super class', using class_getSuperclass(). 3461 NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(), 3462 CK_BitCast, Cls)); 3463 // struct __rw_objc_super 3464 QualType superType = getSuperStructType(); 3465 Expr *SuperRep; 3466 3467 if (LangOpts.MicrosoftExt) { 3468 SynthSuperContructorFunctionDecl(); 3469 // Simulate a contructor call... 3470 DeclRefExpr *DRE = new (Context) DeclRefExpr(SuperContructorFunctionDecl, 3471 false, superType, VK_LValue, 3472 SourceLocation()); 3473 SuperRep = new (Context) CallExpr(*Context, DRE, InitExprs, 3474 superType, VK_LValue, SourceLocation()); 3475 // The code for super is a little tricky to prevent collision with 3476 // the structure definition in the header. The rewriter has it's own 3477 // internal definition (__rw_objc_super) that is uses. This is why 3478 // we need the cast below. For example: 3479 // (struct __rw_objc_super *)&__rw_objc_super((id)self, (id)objc_getClass("SUPER")) 3480 // 3481 SuperRep = new (Context) UnaryOperator(SuperRep, UO_AddrOf, 3482 Context->getPointerType(SuperRep->getType()), 3483 VK_RValue, OK_Ordinary, 3484 SourceLocation()); 3485 SuperRep = NoTypeInfoCStyleCastExpr(Context, 3486 Context->getPointerType(superType), 3487 CK_BitCast, SuperRep); 3488 } else { 3489 // (struct __rw_objc_super) { <exprs from above> } 3490 InitListExpr *ILE = 3491 new (Context) InitListExpr(*Context, SourceLocation(), InitExprs, 3492 SourceLocation()); 3493 TypeSourceInfo *superTInfo 3494 = Context->getTrivialTypeSourceInfo(superType); 3495 SuperRep = new (Context) CompoundLiteralExpr(SourceLocation(), superTInfo, 3496 superType, VK_RValue, ILE, 3497 false); 3498 } 3499 MsgExprs.push_back(SuperRep); 3500 break; 3501 } 3502 3503 case ObjCMessageExpr::Instance: { 3504 // Remove all type-casts because it may contain objc-style types; e.g. 3505 // Foo<Proto> *. 3506 Expr *recExpr = Exp->getInstanceReceiver(); 3507 while (CStyleCastExpr *CE = dyn_cast<CStyleCastExpr>(recExpr)) 3508 recExpr = CE->getSubExpr(); 3509 CastKind CK = recExpr->getType()->isObjCObjectPointerType() 3510 ? CK_BitCast : recExpr->getType()->isBlockPointerType() 3511 ? CK_BlockPointerToObjCPointerCast 3512 : CK_CPointerToObjCPointerCast; 3513 3514 recExpr = NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(), 3515 CK, recExpr); 3516 MsgExprs.push_back(recExpr); 3517 break; 3518 } 3519 } 3520 3521 // Create a call to sel_registerName("selName"), it will be the 2nd argument. 3522 SmallVector<Expr*, 8> SelExprs; 3523 QualType argType = Context->getPointerType(Context->CharTy); 3524 SelExprs.push_back(StringLiteral::Create(*Context, 3525 Exp->getSelector().getAsString(), 3526 StringLiteral::Ascii, false, 3527 argType, SourceLocation())); 3528 CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl, 3529 &SelExprs[0], SelExprs.size(), 3530 StartLoc, 3531 EndLoc); 3532 MsgExprs.push_back(SelExp); 3533 3534 // Now push any user supplied arguments. 3535 for (unsigned i = 0; i < Exp->getNumArgs(); i++) { 3536 Expr *userExpr = Exp->getArg(i); 3537 // Make all implicit casts explicit...ICE comes in handy:-) 3538 if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(userExpr)) { 3539 // Reuse the ICE type, it is exactly what the doctor ordered. 3540 QualType type = ICE->getType(); 3541 if (needToScanForQualifiers(type)) 3542 type = Context->getObjCIdType(); 3543 // Make sure we convert "type (^)(...)" to "type (*)(...)". 3544 (void)convertBlockPointerToFunctionPointer(type); 3545 const Expr *SubExpr = ICE->IgnoreParenImpCasts(); 3546 CastKind CK; 3547 if (SubExpr->getType()->isIntegralType(*Context) && 3548 type->isBooleanType()) { 3549 CK = CK_IntegralToBoolean; 3550 } else if (type->isObjCObjectPointerType()) { 3551 if (SubExpr->getType()->isBlockPointerType()) { 3552 CK = CK_BlockPointerToObjCPointerCast; 3553 } else if (SubExpr->getType()->isPointerType()) { 3554 CK = CK_CPointerToObjCPointerCast; 3555 } else { 3556 CK = CK_BitCast; 3557 } 3558 } else { 3559 CK = CK_BitCast; 3560 } 3561 3562 userExpr = NoTypeInfoCStyleCastExpr(Context, type, CK, userExpr); 3563 } 3564 // Make id<P...> cast into an 'id' cast. 3565 else if (CStyleCastExpr *CE = dyn_cast<CStyleCastExpr>(userExpr)) { 3566 if (CE->getType()->isObjCQualifiedIdType()) { 3567 while ((CE = dyn_cast<CStyleCastExpr>(userExpr))) 3568 userExpr = CE->getSubExpr(); 3569 CastKind CK; 3570 if (userExpr->getType()->isIntegralType(*Context)) { 3571 CK = CK_IntegralToPointer; 3572 } else if (userExpr->getType()->isBlockPointerType()) { 3573 CK = CK_BlockPointerToObjCPointerCast; 3574 } else if (userExpr->getType()->isPointerType()) { 3575 CK = CK_CPointerToObjCPointerCast; 3576 } else { 3577 CK = CK_BitCast; 3578 } 3579 userExpr = NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(), 3580 CK, userExpr); 3581 } 3582 } 3583 MsgExprs.push_back(userExpr); 3584 // We've transferred the ownership to MsgExprs. For now, we *don't* null 3585 // out the argument in the original expression (since we aren't deleting 3586 // the ObjCMessageExpr). See RewritePropertyOrImplicitSetter() usage for more info. 3587 //Exp->setArg(i, 0); 3588 } 3589 // Generate the funky cast. 3590 CastExpr *cast; 3591 SmallVector<QualType, 8> ArgTypes; 3592 QualType returnType; 3593 3594 // Push 'id' and 'SEL', the 2 implicit arguments. 3595 if (MsgSendFlavor == MsgSendSuperFunctionDecl) 3596 ArgTypes.push_back(Context->getPointerType(getSuperStructType())); 3597 else 3598 ArgTypes.push_back(Context->getObjCIdType()); 3599 ArgTypes.push_back(Context->getObjCSelType()); 3600 if (ObjCMethodDecl *OMD = Exp->getMethodDecl()) { 3601 // Push any user argument types. 3602 for (ObjCMethodDecl::param_iterator PI = OMD->param_begin(), 3603 E = OMD->param_end(); PI != E; ++PI) { 3604 QualType t = (*PI)->getType()->isObjCQualifiedIdType() 3605 ? Context->getObjCIdType() 3606 : (*PI)->getType(); 3607 // Make sure we convert "t (^)(...)" to "t (*)(...)". 3608 (void)convertBlockPointerToFunctionPointer(t); 3609 ArgTypes.push_back(t); 3610 } 3611 returnType = Exp->getType(); 3612 convertToUnqualifiedObjCType(returnType); 3613 (void)convertBlockPointerToFunctionPointer(returnType); 3614 } else { 3615 returnType = Context->getObjCIdType(); 3616 } 3617 // Get the type, we will need to reference it in a couple spots. 3618 QualType msgSendType = MsgSendFlavor->getType(); 3619 3620 // Create a reference to the objc_msgSend() declaration. 3621 DeclRefExpr *DRE = new (Context) DeclRefExpr(MsgSendFlavor, false, msgSendType, 3622 VK_LValue, SourceLocation()); 3623 3624 // Need to cast objc_msgSend to "void *" (to workaround a GCC bandaid). 3625 // If we don't do this cast, we get the following bizarre warning/note: 3626 // xx.m:13: warning: function called through a non-compatible type 3627 // xx.m:13: note: if this code is reached, the program will abort 3628 cast = NoTypeInfoCStyleCastExpr(Context, 3629 Context->getPointerType(Context->VoidTy), 3630 CK_BitCast, DRE); 3631 3632 // Now do the "normal" pointer to function cast. 3633 // If we don't have a method decl, force a variadic cast. 3634 const ObjCMethodDecl *MD = Exp->getMethodDecl(); 3635 QualType castType = 3636 getSimpleFunctionType(returnType, ArgTypes, MD ? MD->isVariadic() : true); 3637 castType = Context->getPointerType(castType); 3638 cast = NoTypeInfoCStyleCastExpr(Context, castType, CK_BitCast, 3639 cast); 3640 3641 // Don't forget the parens to enforce the proper binding. 3642 ParenExpr *PE = new (Context) ParenExpr(StartLoc, EndLoc, cast); 3643 3644 const FunctionType *FT = msgSendType->getAs<FunctionType>(); 3645 CallExpr *CE = new (Context) CallExpr(*Context, PE, MsgExprs, 3646 FT->getResultType(), VK_RValue, EndLoc); 3647 Stmt *ReplacingStmt = CE; 3648 if (MsgSendStretFlavor) { 3649 // We have the method which returns a struct/union. Must also generate 3650 // call to objc_msgSend_stret and hang both varieties on a conditional 3651 // expression which dictate which one to envoke depending on size of 3652 // method's return type. 3653 3654 Expr *STCE = SynthMsgSendStretCallExpr(MsgSendStretFlavor, 3655 msgSendType, returnType, 3656 ArgTypes, MsgExprs, 3657 Exp->getMethodDecl()); 3658 3659 // Build sizeof(returnType) 3660 UnaryExprOrTypeTraitExpr *sizeofExpr = 3661 new (Context) UnaryExprOrTypeTraitExpr(UETT_SizeOf, 3662 Context->getTrivialTypeSourceInfo(returnType), 3663 Context->getSizeType(), SourceLocation(), 3664 SourceLocation()); 3665 // (sizeof(returnType) <= 8 ? objc_msgSend(...) : objc_msgSend_stret(...)) 3666 // FIXME: Value of 8 is base on ppc32/x86 ABI for the most common cases. 3667 // For X86 it is more complicated and some kind of target specific routine 3668 // is needed to decide what to do. 3669 unsigned IntSize = 3670 static_cast<unsigned>(Context->getTypeSize(Context->IntTy)); 3671 IntegerLiteral *limit = IntegerLiteral::Create(*Context, 3672 llvm::APInt(IntSize, 8), 3673 Context->IntTy, 3674 SourceLocation()); 3675 BinaryOperator *lessThanExpr = 3676 new (Context) BinaryOperator(sizeofExpr, limit, BO_LE, Context->IntTy, 3677 VK_RValue, OK_Ordinary, SourceLocation(), 3678 false); 3679 // (sizeof(returnType) <= 8 ? objc_msgSend(...) : objc_msgSend_stret(...)) 3680 ConditionalOperator *CondExpr = 3681 new (Context) ConditionalOperator(lessThanExpr, 3682 SourceLocation(), CE, 3683 SourceLocation(), STCE, 3684 returnType, VK_RValue, OK_Ordinary); 3685 ReplacingStmt = new (Context) ParenExpr(SourceLocation(), SourceLocation(), 3686 CondExpr); 3687 } 3688 // delete Exp; leak for now, see RewritePropertyOrImplicitSetter() usage for more info. 3689 return ReplacingStmt; 3690 } 3691 3692 Stmt *RewriteModernObjC::RewriteMessageExpr(ObjCMessageExpr *Exp) { 3693 Stmt *ReplacingStmt = SynthMessageExpr(Exp, Exp->getLocStart(), 3694 Exp->getLocEnd()); 3695 3696 // Now do the actual rewrite. 3697 ReplaceStmt(Exp, ReplacingStmt); 3698 3699 // delete Exp; leak for now, see RewritePropertyOrImplicitSetter() usage for more info. 3700 return ReplacingStmt; 3701 } 3702 3703 // typedef struct objc_object Protocol; 3704 QualType RewriteModernObjC::getProtocolType() { 3705 if (!ProtocolTypeDecl) { 3706 TypeSourceInfo *TInfo 3707 = Context->getTrivialTypeSourceInfo(Context->getObjCIdType()); 3708 ProtocolTypeDecl = TypedefDecl::Create(*Context, TUDecl, 3709 SourceLocation(), SourceLocation(), 3710 &Context->Idents.get("Protocol"), 3711 TInfo); 3712 } 3713 return Context->getTypeDeclType(ProtocolTypeDecl); 3714 } 3715 3716 /// RewriteObjCProtocolExpr - Rewrite a protocol expression into 3717 /// a synthesized/forward data reference (to the protocol's metadata). 3718 /// The forward references (and metadata) are generated in 3719 /// RewriteModernObjC::HandleTranslationUnit(). 3720 Stmt *RewriteModernObjC::RewriteObjCProtocolExpr(ObjCProtocolExpr *Exp) { 3721 std::string Name = "_OBJC_PROTOCOL_REFERENCE_$_" + 3722 Exp->getProtocol()->getNameAsString(); 3723 IdentifierInfo *ID = &Context->Idents.get(Name); 3724 VarDecl *VD = VarDecl::Create(*Context, TUDecl, SourceLocation(), 3725 SourceLocation(), ID, getProtocolType(), 0, 3726 SC_Extern); 3727 DeclRefExpr *DRE = new (Context) DeclRefExpr(VD, false, getProtocolType(), 3728 VK_LValue, SourceLocation()); 3729 Expr *DerefExpr = new (Context) UnaryOperator(DRE, UO_AddrOf, 3730 Context->getPointerType(DRE->getType()), 3731 VK_RValue, OK_Ordinary, SourceLocation()); 3732 CastExpr *castExpr = NoTypeInfoCStyleCastExpr(Context, DerefExpr->getType(), 3733 CK_BitCast, 3734 DerefExpr); 3735 ReplaceStmt(Exp, castExpr); 3736 ProtocolExprDecls.insert(Exp->getProtocol()->getCanonicalDecl()); 3737 // delete Exp; leak for now, see RewritePropertyOrImplicitSetter() usage for more info. 3738 return castExpr; 3739 3740 } 3741 3742 bool RewriteModernObjC::BufferContainsPPDirectives(const char *startBuf, 3743 const char *endBuf) { 3744 while (startBuf < endBuf) { 3745 if (*startBuf == '#') { 3746 // Skip whitespace. 3747 for (++startBuf; startBuf[0] == ' ' || startBuf[0] == '\t'; ++startBuf) 3748 ; 3749 if (!strncmp(startBuf, "if", strlen("if")) || 3750 !strncmp(startBuf, "ifdef", strlen("ifdef")) || 3751 !strncmp(startBuf, "ifndef", strlen("ifndef")) || 3752 !strncmp(startBuf, "define", strlen("define")) || 3753 !strncmp(startBuf, "undef", strlen("undef")) || 3754 !strncmp(startBuf, "else", strlen("else")) || 3755 !strncmp(startBuf, "elif", strlen("elif")) || 3756 !strncmp(startBuf, "endif", strlen("endif")) || 3757 !strncmp(startBuf, "pragma", strlen("pragma")) || 3758 !strncmp(startBuf, "include", strlen("include")) || 3759 !strncmp(startBuf, "import", strlen("import")) || 3760 !strncmp(startBuf, "include_next", strlen("include_next"))) 3761 return true; 3762 } 3763 startBuf++; 3764 } 3765 return false; 3766 } 3767 3768 /// IsTagDefinedInsideClass - This routine checks that a named tagged type 3769 /// is defined inside an objective-c class. If so, it returns true. 3770 bool RewriteModernObjC::IsTagDefinedInsideClass(ObjCContainerDecl *IDecl, 3771 TagDecl *Tag, 3772 bool &IsNamedDefinition) { 3773 if (!IDecl) 3774 return false; 3775 SourceLocation TagLocation; 3776 if (RecordDecl *RD = dyn_cast<RecordDecl>(Tag)) { 3777 RD = RD->getDefinition(); 3778 if (!RD || !RD->getDeclName().getAsIdentifierInfo()) 3779 return false; 3780 IsNamedDefinition = true; 3781 TagLocation = RD->getLocation(); 3782 return Context->getSourceManager().isBeforeInTranslationUnit( 3783 IDecl->getLocation(), TagLocation); 3784 } 3785 if (EnumDecl *ED = dyn_cast<EnumDecl>(Tag)) { 3786 if (!ED || !ED->getDeclName().getAsIdentifierInfo()) 3787 return false; 3788 IsNamedDefinition = true; 3789 TagLocation = ED->getLocation(); 3790 return Context->getSourceManager().isBeforeInTranslationUnit( 3791 IDecl->getLocation(), TagLocation); 3792 3793 } 3794 return false; 3795 } 3796 3797 /// RewriteObjCFieldDeclType - This routine rewrites a type into the buffer. 3798 /// It handles elaborated types, as well as enum types in the process. 3799 bool RewriteModernObjC::RewriteObjCFieldDeclType(QualType &Type, 3800 std::string &Result) { 3801 if (isa<TypedefType>(Type)) { 3802 Result += "\t"; 3803 return false; 3804 } 3805 3806 if (Type->isArrayType()) { 3807 QualType ElemTy = Context->getBaseElementType(Type); 3808 return RewriteObjCFieldDeclType(ElemTy, Result); 3809 } 3810 else if (Type->isRecordType()) { 3811 RecordDecl *RD = Type->getAs<RecordType>()->getDecl(); 3812 if (RD->isCompleteDefinition()) { 3813 if (RD->isStruct()) 3814 Result += "\n\tstruct "; 3815 else if (RD->isUnion()) 3816 Result += "\n\tunion "; 3817 else 3818 assert(false && "class not allowed as an ivar type"); 3819 3820 Result += RD->getName(); 3821 if (GlobalDefinedTags.count(RD)) { 3822 // struct/union is defined globally, use it. 3823 Result += " "; 3824 return true; 3825 } 3826 Result += " {\n"; 3827 for (RecordDecl::field_iterator i = RD->field_begin(), 3828 e = RD->field_end(); i != e; ++i) { 3829 FieldDecl *FD = *i; 3830 RewriteObjCFieldDecl(FD, Result); 3831 } 3832 Result += "\t} "; 3833 return true; 3834 } 3835 } 3836 else if (Type->isEnumeralType()) { 3837 EnumDecl *ED = Type->getAs<EnumType>()->getDecl(); 3838 if (ED->isCompleteDefinition()) { 3839 Result += "\n\tenum "; 3840 Result += ED->getName(); 3841 if (GlobalDefinedTags.count(ED)) { 3842 // Enum is globall defined, use it. 3843 Result += " "; 3844 return true; 3845 } 3846 3847 Result += " {\n"; 3848 for (EnumDecl::enumerator_iterator EC = ED->enumerator_begin(), 3849 ECEnd = ED->enumerator_end(); EC != ECEnd; ++EC) { 3850 Result += "\t"; Result += EC->getName(); Result += " = "; 3851 llvm::APSInt Val = EC->getInitVal(); 3852 Result += Val.toString(10); 3853 Result += ",\n"; 3854 } 3855 Result += "\t} "; 3856 return true; 3857 } 3858 } 3859 3860 Result += "\t"; 3861 convertObjCTypeToCStyleType(Type); 3862 return false; 3863 } 3864 3865 3866 /// RewriteObjCFieldDecl - This routine rewrites a field into the buffer. 3867 /// It handles elaborated types, as well as enum types in the process. 3868 void RewriteModernObjC::RewriteObjCFieldDecl(FieldDecl *fieldDecl, 3869 std::string &Result) { 3870 QualType Type = fieldDecl->getType(); 3871 std::string Name = fieldDecl->getNameAsString(); 3872 3873 bool EleboratedType = RewriteObjCFieldDeclType(Type, Result); 3874 if (!EleboratedType) 3875 Type.getAsStringInternal(Name, Context->getPrintingPolicy()); 3876 Result += Name; 3877 if (fieldDecl->isBitField()) { 3878 Result += " : "; Result += utostr(fieldDecl->getBitWidthValue(*Context)); 3879 } 3880 else if (EleboratedType && Type->isArrayType()) { 3881 const ArrayType *AT = Context->getAsArrayType(Type); 3882 do { 3883 if (const ConstantArrayType *CAT = dyn_cast<ConstantArrayType>(AT)) { 3884 Result += "["; 3885 llvm::APInt Dim = CAT->getSize(); 3886 Result += utostr(Dim.getZExtValue()); 3887 Result += "]"; 3888 } 3889 AT = Context->getAsArrayType(AT->getElementType()); 3890 } while (AT); 3891 } 3892 3893 Result += ";\n"; 3894 } 3895 3896 /// RewriteLocallyDefinedNamedAggregates - This routine rewrites locally defined 3897 /// named aggregate types into the input buffer. 3898 void RewriteModernObjC::RewriteLocallyDefinedNamedAggregates(FieldDecl *fieldDecl, 3899 std::string &Result) { 3900 QualType Type = fieldDecl->getType(); 3901 if (isa<TypedefType>(Type)) 3902 return; 3903 if (Type->isArrayType()) 3904 Type = Context->getBaseElementType(Type); 3905 ObjCContainerDecl *IDecl = 3906 dyn_cast<ObjCContainerDecl>(fieldDecl->getDeclContext()); 3907 3908 TagDecl *TD = 0; 3909 if (Type->isRecordType()) { 3910 TD = Type->getAs<RecordType>()->getDecl(); 3911 } 3912 else if (Type->isEnumeralType()) { 3913 TD = Type->getAs<EnumType>()->getDecl(); 3914 } 3915 3916 if (TD) { 3917 if (GlobalDefinedTags.count(TD)) 3918 return; 3919 3920 bool IsNamedDefinition = false; 3921 if (IsTagDefinedInsideClass(IDecl, TD, IsNamedDefinition)) { 3922 RewriteObjCFieldDeclType(Type, Result); 3923 Result += ";"; 3924 } 3925 if (IsNamedDefinition) 3926 GlobalDefinedTags.insert(TD); 3927 } 3928 3929 } 3930 3931 unsigned RewriteModernObjC::ObjCIvarBitfieldGroupNo(ObjCIvarDecl *IV) { 3932 const ObjCInterfaceDecl *CDecl = IV->getContainingInterface(); 3933 if (ObjCInterefaceHasBitfieldGroups.count(CDecl)) { 3934 return IvarGroupNumber[IV]; 3935 } 3936 unsigned GroupNo = 0; 3937 SmallVector<const ObjCIvarDecl *, 8> IVars; 3938 for (const ObjCIvarDecl *IVD = CDecl->all_declared_ivar_begin(); 3939 IVD; IVD = IVD->getNextIvar()) 3940 IVars.push_back(IVD); 3941 3942 for (unsigned i = 0, e = IVars.size(); i < e; i++) 3943 if (IVars[i]->isBitField()) { 3944 IvarGroupNumber[IVars[i++]] = ++GroupNo; 3945 while (i < e && IVars[i]->isBitField()) 3946 IvarGroupNumber[IVars[i++]] = GroupNo; 3947 if (i < e) 3948 --i; 3949 } 3950 3951 ObjCInterefaceHasBitfieldGroups.insert(CDecl); 3952 return IvarGroupNumber[IV]; 3953 } 3954 3955 QualType RewriteModernObjC::SynthesizeBitfieldGroupStructType( 3956 ObjCIvarDecl *IV, 3957 SmallVectorImpl<ObjCIvarDecl *> &IVars) { 3958 std::string StructTagName; 3959 ObjCIvarBitfieldGroupType(IV, StructTagName); 3960 RecordDecl *RD = RecordDecl::Create(*Context, TTK_Struct, 3961 Context->getTranslationUnitDecl(), 3962 SourceLocation(), SourceLocation(), 3963 &Context->Idents.get(StructTagName)); 3964 for (unsigned i=0, e = IVars.size(); i < e; i++) { 3965 ObjCIvarDecl *Ivar = IVars[i]; 3966 RD->addDecl(FieldDecl::Create(*Context, RD, SourceLocation(), SourceLocation(), 3967 &Context->Idents.get(Ivar->getName()), 3968 Ivar->getType(), 3969 0, /*Expr *BW */Ivar->getBitWidth(), false, 3970 ICIS_NoInit)); 3971 } 3972 RD->completeDefinition(); 3973 return Context->getTagDeclType(RD); 3974 } 3975 3976 QualType RewriteModernObjC::GetGroupRecordTypeForObjCIvarBitfield(ObjCIvarDecl *IV) { 3977 const ObjCInterfaceDecl *CDecl = IV->getContainingInterface(); 3978 unsigned GroupNo = ObjCIvarBitfieldGroupNo(IV); 3979 std::pair<const ObjCInterfaceDecl*, unsigned> tuple = std::make_pair(CDecl, GroupNo); 3980 if (GroupRecordType.count(tuple)) 3981 return GroupRecordType[tuple]; 3982 3983 SmallVector<ObjCIvarDecl *, 8> IVars; 3984 for (const ObjCIvarDecl *IVD = CDecl->all_declared_ivar_begin(); 3985 IVD; IVD = IVD->getNextIvar()) { 3986 if (IVD->isBitField()) 3987 IVars.push_back(const_cast<ObjCIvarDecl *>(IVD)); 3988 else { 3989 if (!IVars.empty()) { 3990 unsigned GroupNo = ObjCIvarBitfieldGroupNo(IVars[0]); 3991 // Generate the struct type for this group of bitfield ivars. 3992 GroupRecordType[std::make_pair(CDecl, GroupNo)] = 3993 SynthesizeBitfieldGroupStructType(IVars[0], IVars); 3994 IVars.clear(); 3995 } 3996 } 3997 } 3998 if (!IVars.empty()) { 3999 // Do the last one. 4000 unsigned GroupNo = ObjCIvarBitfieldGroupNo(IVars[0]); 4001 GroupRecordType[std::make_pair(CDecl, GroupNo)] = 4002 SynthesizeBitfieldGroupStructType(IVars[0], IVars); 4003 } 4004 QualType RetQT = GroupRecordType[tuple]; 4005 assert(!RetQT.isNull() && "GetGroupRecordTypeForObjCIvarBitfield struct type is NULL"); 4006 4007 return RetQT; 4008 } 4009 4010 /// ObjCIvarBitfieldGroupDecl - Names field decl. for ivar bitfield group. 4011 /// Name would be: classname__GRBF_n where n is the group number for this ivar. 4012 void RewriteModernObjC::ObjCIvarBitfieldGroupDecl(ObjCIvarDecl *IV, 4013 std::string &Result) { 4014 const ObjCInterfaceDecl *CDecl = IV->getContainingInterface(); 4015 Result += CDecl->getName(); 4016 Result += "__GRBF_"; 4017 unsigned GroupNo = ObjCIvarBitfieldGroupNo(IV); 4018 Result += utostr(GroupNo); 4019 return; 4020 } 4021 4022 /// ObjCIvarBitfieldGroupType - Names struct type for ivar bitfield group. 4023 /// Name of the struct would be: classname__T_n where n is the group number for 4024 /// this ivar. 4025 void RewriteModernObjC::ObjCIvarBitfieldGroupType(ObjCIvarDecl *IV, 4026 std::string &Result) { 4027 const ObjCInterfaceDecl *CDecl = IV->getContainingInterface(); 4028 Result += CDecl->getName(); 4029 Result += "__T_"; 4030 unsigned GroupNo = ObjCIvarBitfieldGroupNo(IV); 4031 Result += utostr(GroupNo); 4032 return; 4033 } 4034 4035 /// ObjCIvarBitfieldGroupOffset - Names symbol for ivar bitfield group field offset. 4036 /// Name would be: OBJC_IVAR_$_classname__GRBF_n where n is the group number for 4037 /// this ivar. 4038 void RewriteModernObjC::ObjCIvarBitfieldGroupOffset(ObjCIvarDecl *IV, 4039 std::string &Result) { 4040 Result += "OBJC_IVAR_$_"; 4041 ObjCIvarBitfieldGroupDecl(IV, Result); 4042 } 4043 4044 #define SKIP_BITFIELDS(IX, ENDIX, VEC) { \ 4045 while ((IX < ENDIX) && VEC[IX]->isBitField()) \ 4046 ++IX; \ 4047 if (IX < ENDIX) \ 4048 --IX; \ 4049 } 4050 4051 /// RewriteObjCInternalStruct - Rewrite one internal struct corresponding to 4052 /// an objective-c class with ivars. 4053 void RewriteModernObjC::RewriteObjCInternalStruct(ObjCInterfaceDecl *CDecl, 4054 std::string &Result) { 4055 assert(CDecl && "Class missing in SynthesizeObjCInternalStruct"); 4056 assert(CDecl->getName() != "" && 4057 "Name missing in SynthesizeObjCInternalStruct"); 4058 ObjCInterfaceDecl *RCDecl = CDecl->getSuperClass(); 4059 SmallVector<ObjCIvarDecl *, 8> IVars; 4060 for (ObjCIvarDecl *IVD = CDecl->all_declared_ivar_begin(); 4061 IVD; IVD = IVD->getNextIvar()) 4062 IVars.push_back(IVD); 4063 4064 SourceLocation LocStart = CDecl->getLocStart(); 4065 SourceLocation LocEnd = CDecl->getEndOfDefinitionLoc(); 4066 4067 const char *startBuf = SM->getCharacterData(LocStart); 4068 const char *endBuf = SM->getCharacterData(LocEnd); 4069 4070 // If no ivars and no root or if its root, directly or indirectly, 4071 // have no ivars (thus not synthesized) then no need to synthesize this class. 4072 if ((!CDecl->isThisDeclarationADefinition() || IVars.size() == 0) && 4073 (!RCDecl || !ObjCSynthesizedStructs.count(RCDecl))) { 4074 endBuf += Lexer::MeasureTokenLength(LocEnd, *SM, LangOpts); 4075 ReplaceText(LocStart, endBuf-startBuf, Result); 4076 return; 4077 } 4078 4079 // Insert named struct/union definitions inside class to 4080 // outer scope. This follows semantics of locally defined 4081 // struct/unions in objective-c classes. 4082 for (unsigned i = 0, e = IVars.size(); i < e; i++) 4083 RewriteLocallyDefinedNamedAggregates(IVars[i], Result); 4084 4085 // Insert named structs which are syntheized to group ivar bitfields 4086 // to outer scope as well. 4087 for (unsigned i = 0, e = IVars.size(); i < e; i++) 4088 if (IVars[i]->isBitField()) { 4089 ObjCIvarDecl *IV = IVars[i]; 4090 QualType QT = GetGroupRecordTypeForObjCIvarBitfield(IV); 4091 RewriteObjCFieldDeclType(QT, Result); 4092 Result += ";"; 4093 // skip over ivar bitfields in this group. 4094 SKIP_BITFIELDS(i , e, IVars); 4095 } 4096 4097 Result += "\nstruct "; 4098 Result += CDecl->getNameAsString(); 4099 Result += "_IMPL {\n"; 4100 4101 if (RCDecl && ObjCSynthesizedStructs.count(RCDecl)) { 4102 Result += "\tstruct "; Result += RCDecl->getNameAsString(); 4103 Result += "_IMPL "; Result += RCDecl->getNameAsString(); 4104 Result += "_IVARS;\n"; 4105 } 4106 4107 for (unsigned i = 0, e = IVars.size(); i < e; i++) { 4108 if (IVars[i]->isBitField()) { 4109 ObjCIvarDecl *IV = IVars[i]; 4110 Result += "\tstruct "; 4111 ObjCIvarBitfieldGroupType(IV, Result); Result += " "; 4112 ObjCIvarBitfieldGroupDecl(IV, Result); Result += ";\n"; 4113 // skip over ivar bitfields in this group. 4114 SKIP_BITFIELDS(i , e, IVars); 4115 } 4116 else 4117 RewriteObjCFieldDecl(IVars[i], Result); 4118 } 4119 4120 Result += "};\n"; 4121 endBuf += Lexer::MeasureTokenLength(LocEnd, *SM, LangOpts); 4122 ReplaceText(LocStart, endBuf-startBuf, Result); 4123 // Mark this struct as having been generated. 4124 if (!ObjCSynthesizedStructs.insert(CDecl)) 4125 llvm_unreachable("struct already synthesize- RewriteObjCInternalStruct"); 4126 } 4127 4128 /// RewriteIvarOffsetSymbols - Rewrite ivar offset symbols of those ivars which 4129 /// have been referenced in an ivar access expression. 4130 void RewriteModernObjC::RewriteIvarOffsetSymbols(ObjCInterfaceDecl *CDecl, 4131 std::string &Result) { 4132 // write out ivar offset symbols which have been referenced in an ivar 4133 // access expression. 4134 llvm::SmallPtrSet<ObjCIvarDecl *, 8> Ivars = ReferencedIvars[CDecl]; 4135 if (Ivars.empty()) 4136 return; 4137 4138 llvm::DenseSet<std::pair<const ObjCInterfaceDecl*, unsigned> > GroupSymbolOutput; 4139 for (llvm::SmallPtrSet<ObjCIvarDecl *, 8>::iterator i = Ivars.begin(), 4140 e = Ivars.end(); i != e; i++) { 4141 ObjCIvarDecl *IvarDecl = (*i); 4142 const ObjCInterfaceDecl *IDecl = IvarDecl->getContainingInterface(); 4143 unsigned GroupNo = 0; 4144 if (IvarDecl->isBitField()) { 4145 GroupNo = ObjCIvarBitfieldGroupNo(IvarDecl); 4146 if (GroupSymbolOutput.count(std::make_pair(IDecl, GroupNo))) 4147 continue; 4148 } 4149 Result += "\n"; 4150 if (LangOpts.MicrosoftExt) 4151 Result += "__declspec(allocate(\".objc_ivar$B\")) "; 4152 Result += "extern \"C\" "; 4153 if (LangOpts.MicrosoftExt && 4154 IvarDecl->getAccessControl() != ObjCIvarDecl::Private && 4155 IvarDecl->getAccessControl() != ObjCIvarDecl::Package) 4156 Result += "__declspec(dllimport) "; 4157 4158 Result += "unsigned long "; 4159 if (IvarDecl->isBitField()) { 4160 ObjCIvarBitfieldGroupOffset(IvarDecl, Result); 4161 GroupSymbolOutput.insert(std::make_pair(IDecl, GroupNo)); 4162 } 4163 else 4164 WriteInternalIvarName(CDecl, IvarDecl, Result); 4165 Result += ";"; 4166 } 4167 } 4168 4169 //===----------------------------------------------------------------------===// 4170 // Meta Data Emission 4171 //===----------------------------------------------------------------------===// 4172 4173 4174 /// RewriteImplementations - This routine rewrites all method implementations 4175 /// and emits meta-data. 4176 4177 void RewriteModernObjC::RewriteImplementations() { 4178 int ClsDefCount = ClassImplementation.size(); 4179 int CatDefCount = CategoryImplementation.size(); 4180 4181 // Rewrite implemented methods 4182 for (int i = 0; i < ClsDefCount; i++) { 4183 ObjCImplementationDecl *OIMP = ClassImplementation[i]; 4184 ObjCInterfaceDecl *CDecl = OIMP->getClassInterface(); 4185 if (CDecl->isImplicitInterfaceDecl()) 4186 assert(false && 4187 "Legacy implicit interface rewriting not supported in moder abi"); 4188 RewriteImplementationDecl(OIMP); 4189 } 4190 4191 for (int i = 0; i < CatDefCount; i++) { 4192 ObjCCategoryImplDecl *CIMP = CategoryImplementation[i]; 4193 ObjCInterfaceDecl *CDecl = CIMP->getClassInterface(); 4194 if (CDecl->isImplicitInterfaceDecl()) 4195 assert(false && 4196 "Legacy implicit interface rewriting not supported in moder abi"); 4197 RewriteImplementationDecl(CIMP); 4198 } 4199 } 4200 4201 void RewriteModernObjC::RewriteByRefString(std::string &ResultStr, 4202 const std::string &Name, 4203 ValueDecl *VD, bool def) { 4204 assert(BlockByRefDeclNo.count(VD) && 4205 "RewriteByRefString: ByRef decl missing"); 4206 if (def) 4207 ResultStr += "struct "; 4208 ResultStr += "__Block_byref_" + Name + 4209 "_" + utostr(BlockByRefDeclNo[VD]) ; 4210 } 4211 4212 static bool HasLocalVariableExternalStorage(ValueDecl *VD) { 4213 if (VarDecl *Var = dyn_cast<VarDecl>(VD)) 4214 return (Var->isFunctionOrMethodVarDecl() && !Var->hasLocalStorage()); 4215 return false; 4216 } 4217 4218 std::string RewriteModernObjC::SynthesizeBlockFunc(BlockExpr *CE, int i, 4219 StringRef funcName, 4220 std::string Tag) { 4221 const FunctionType *AFT = CE->getFunctionType(); 4222 QualType RT = AFT->getResultType(); 4223 std::string StructRef = "struct " + Tag; 4224 SourceLocation BlockLoc = CE->getExprLoc(); 4225 std::string S; 4226 ConvertSourceLocationToLineDirective(BlockLoc, S); 4227 4228 S += "static " + RT.getAsString(Context->getPrintingPolicy()) + " __" + 4229 funcName.str() + "_block_func_" + utostr(i); 4230 4231 BlockDecl *BD = CE->getBlockDecl(); 4232 4233 if (isa<FunctionNoProtoType>(AFT)) { 4234 // No user-supplied arguments. Still need to pass in a pointer to the 4235 // block (to reference imported block decl refs). 4236 S += "(" + StructRef + " *__cself)"; 4237 } else if (BD->param_empty()) { 4238 S += "(" + StructRef + " *__cself)"; 4239 } else { 4240 const FunctionProtoType *FT = cast<FunctionProtoType>(AFT); 4241 assert(FT && "SynthesizeBlockFunc: No function proto"); 4242 S += '('; 4243 // first add the implicit argument. 4244 S += StructRef + " *__cself, "; 4245 std::string ParamStr; 4246 for (BlockDecl::param_iterator AI = BD->param_begin(), 4247 E = BD->param_end(); AI != E; ++AI) { 4248 if (AI != BD->param_begin()) S += ", "; 4249 ParamStr = (*AI)->getNameAsString(); 4250 QualType QT = (*AI)->getType(); 4251 (void)convertBlockPointerToFunctionPointer(QT); 4252 QT.getAsStringInternal(ParamStr, Context->getPrintingPolicy()); 4253 S += ParamStr; 4254 } 4255 if (FT->isVariadic()) { 4256 if (!BD->param_empty()) S += ", "; 4257 S += "..."; 4258 } 4259 S += ')'; 4260 } 4261 S += " {\n"; 4262 4263 // Create local declarations to avoid rewriting all closure decl ref exprs. 4264 // First, emit a declaration for all "by ref" decls. 4265 for (SmallVectorImpl<ValueDecl *>::iterator I = BlockByRefDecls.begin(), 4266 E = BlockByRefDecls.end(); I != E; ++I) { 4267 S += " "; 4268 std::string Name = (*I)->getNameAsString(); 4269 std::string TypeString; 4270 RewriteByRefString(TypeString, Name, (*I)); 4271 TypeString += " *"; 4272 Name = TypeString + Name; 4273 S += Name + " = __cself->" + (*I)->getNameAsString() + "; // bound by ref\n"; 4274 } 4275 // Next, emit a declaration for all "by copy" declarations. 4276 for (SmallVectorImpl<ValueDecl *>::iterator I = BlockByCopyDecls.begin(), 4277 E = BlockByCopyDecls.end(); I != E; ++I) { 4278 S += " "; 4279 // Handle nested closure invocation. For example: 4280 // 4281 // void (^myImportedClosure)(void); 4282 // myImportedClosure = ^(void) { setGlobalInt(x + y); }; 4283 // 4284 // void (^anotherClosure)(void); 4285 // anotherClosure = ^(void) { 4286 // myImportedClosure(); // import and invoke the closure 4287 // }; 4288 // 4289 if (isTopLevelBlockPointerType((*I)->getType())) { 4290 RewriteBlockPointerTypeVariable(S, (*I)); 4291 S += " = ("; 4292 RewriteBlockPointerType(S, (*I)->getType()); 4293 S += ")"; 4294 S += "__cself->" + (*I)->getNameAsString() + "; // bound by copy\n"; 4295 } 4296 else { 4297 std::string Name = (*I)->getNameAsString(); 4298 QualType QT = (*I)->getType(); 4299 if (HasLocalVariableExternalStorage(*I)) 4300 QT = Context->getPointerType(QT); 4301 QT.getAsStringInternal(Name, Context->getPrintingPolicy()); 4302 S += Name + " = __cself->" + 4303 (*I)->getNameAsString() + "; // bound by copy\n"; 4304 } 4305 } 4306 std::string RewrittenStr = RewrittenBlockExprs[CE]; 4307 const char *cstr = RewrittenStr.c_str(); 4308 while (*cstr++ != '{') ; 4309 S += cstr; 4310 S += "\n"; 4311 return S; 4312 } 4313 4314 std::string RewriteModernObjC::SynthesizeBlockHelperFuncs(BlockExpr *CE, int i, 4315 StringRef funcName, 4316 std::string Tag) { 4317 std::string StructRef = "struct " + Tag; 4318 std::string S = "static void __"; 4319 4320 S += funcName; 4321 S += "_block_copy_" + utostr(i); 4322 S += "(" + StructRef; 4323 S += "*dst, " + StructRef; 4324 S += "*src) {"; 4325 for (llvm::SmallPtrSet<ValueDecl*,8>::iterator I = ImportedBlockDecls.begin(), 4326 E = ImportedBlockDecls.end(); I != E; ++I) { 4327 ValueDecl *VD = (*I); 4328 S += "_Block_object_assign((void*)&dst->"; 4329 S += (*I)->getNameAsString(); 4330 S += ", (void*)src->"; 4331 S += (*I)->getNameAsString(); 4332 if (BlockByRefDeclsPtrSet.count((*I))) 4333 S += ", " + utostr(BLOCK_FIELD_IS_BYREF) + "/*BLOCK_FIELD_IS_BYREF*/);"; 4334 else if (VD->getType()->isBlockPointerType()) 4335 S += ", " + utostr(BLOCK_FIELD_IS_BLOCK) + "/*BLOCK_FIELD_IS_BLOCK*/);"; 4336 else 4337 S += ", " + utostr(BLOCK_FIELD_IS_OBJECT) + "/*BLOCK_FIELD_IS_OBJECT*/);"; 4338 } 4339 S += "}\n"; 4340 4341 S += "\nstatic void __"; 4342 S += funcName; 4343 S += "_block_dispose_" + utostr(i); 4344 S += "(" + StructRef; 4345 S += "*src) {"; 4346 for (llvm::SmallPtrSet<ValueDecl*,8>::iterator I = ImportedBlockDecls.begin(), 4347 E = ImportedBlockDecls.end(); I != E; ++I) { 4348 ValueDecl *VD = (*I); 4349 S += "_Block_object_dispose((void*)src->"; 4350 S += (*I)->getNameAsString(); 4351 if (BlockByRefDeclsPtrSet.count((*I))) 4352 S += ", " + utostr(BLOCK_FIELD_IS_BYREF) + "/*BLOCK_FIELD_IS_BYREF*/);"; 4353 else if (VD->getType()->isBlockPointerType()) 4354 S += ", " + utostr(BLOCK_FIELD_IS_BLOCK) + "/*BLOCK_FIELD_IS_BLOCK*/);"; 4355 else 4356 S += ", " + utostr(BLOCK_FIELD_IS_OBJECT) + "/*BLOCK_FIELD_IS_OBJECT*/);"; 4357 } 4358 S += "}\n"; 4359 return S; 4360 } 4361 4362 std::string RewriteModernObjC::SynthesizeBlockImpl(BlockExpr *CE, std::string Tag, 4363 std::string Desc) { 4364 std::string S = "\nstruct " + Tag; 4365 std::string Constructor = " " + Tag; 4366 4367 S += " {\n struct __block_impl impl;\n"; 4368 S += " struct " + Desc; 4369 S += "* Desc;\n"; 4370 4371 Constructor += "(void *fp, "; // Invoke function pointer. 4372 Constructor += "struct " + Desc; // Descriptor pointer. 4373 Constructor += " *desc"; 4374 4375 if (BlockDeclRefs.size()) { 4376 // Output all "by copy" declarations. 4377 for (SmallVectorImpl<ValueDecl *>::iterator I = BlockByCopyDecls.begin(), 4378 E = BlockByCopyDecls.end(); I != E; ++I) { 4379 S += " "; 4380 std::string FieldName = (*I)->getNameAsString(); 4381 std::string ArgName = "_" + FieldName; 4382 // Handle nested closure invocation. For example: 4383 // 4384 // void (^myImportedBlock)(void); 4385 // myImportedBlock = ^(void) { setGlobalInt(x + y); }; 4386 // 4387 // void (^anotherBlock)(void); 4388 // anotherBlock = ^(void) { 4389 // myImportedBlock(); // import and invoke the closure 4390 // }; 4391 // 4392 if (isTopLevelBlockPointerType((*I)->getType())) { 4393 S += "struct __block_impl *"; 4394 Constructor += ", void *" + ArgName; 4395 } else { 4396 QualType QT = (*I)->getType(); 4397 if (HasLocalVariableExternalStorage(*I)) 4398 QT = Context->getPointerType(QT); 4399 QT.getAsStringInternal(FieldName, Context->getPrintingPolicy()); 4400 QT.getAsStringInternal(ArgName, Context->getPrintingPolicy()); 4401 Constructor += ", " + ArgName; 4402 } 4403 S += FieldName + ";\n"; 4404 } 4405 // Output all "by ref" declarations. 4406 for (SmallVectorImpl<ValueDecl *>::iterator I = BlockByRefDecls.begin(), 4407 E = BlockByRefDecls.end(); I != E; ++I) { 4408 S += " "; 4409 std::string FieldName = (*I)->getNameAsString(); 4410 std::string ArgName = "_" + FieldName; 4411 { 4412 std::string TypeString; 4413 RewriteByRefString(TypeString, FieldName, (*I)); 4414 TypeString += " *"; 4415 FieldName = TypeString + FieldName; 4416 ArgName = TypeString + ArgName; 4417 Constructor += ", " + ArgName; 4418 } 4419 S += FieldName + "; // by ref\n"; 4420 } 4421 // Finish writing the constructor. 4422 Constructor += ", int flags=0)"; 4423 // Initialize all "by copy" arguments. 4424 bool firsTime = true; 4425 for (SmallVectorImpl<ValueDecl *>::iterator I = BlockByCopyDecls.begin(), 4426 E = BlockByCopyDecls.end(); I != E; ++I) { 4427 std::string Name = (*I)->getNameAsString(); 4428 if (firsTime) { 4429 Constructor += " : "; 4430 firsTime = false; 4431 } 4432 else 4433 Constructor += ", "; 4434 if (isTopLevelBlockPointerType((*I)->getType())) 4435 Constructor += Name + "((struct __block_impl *)_" + Name + ")"; 4436 else 4437 Constructor += Name + "(_" + Name + ")"; 4438 } 4439 // Initialize all "by ref" arguments. 4440 for (SmallVectorImpl<ValueDecl *>::iterator I = BlockByRefDecls.begin(), 4441 E = BlockByRefDecls.end(); I != E; ++I) { 4442 std::string Name = (*I)->getNameAsString(); 4443 if (firsTime) { 4444 Constructor += " : "; 4445 firsTime = false; 4446 } 4447 else 4448 Constructor += ", "; 4449 Constructor += Name + "(_" + Name + "->__forwarding)"; 4450 } 4451 4452 Constructor += " {\n"; 4453 if (GlobalVarDecl) 4454 Constructor += " impl.isa = &_NSConcreteGlobalBlock;\n"; 4455 else 4456 Constructor += " impl.isa = &_NSConcreteStackBlock;\n"; 4457 Constructor += " impl.Flags = flags;\n impl.FuncPtr = fp;\n"; 4458 4459 Constructor += " Desc = desc;\n"; 4460 } else { 4461 // Finish writing the constructor. 4462 Constructor += ", int flags=0) {\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 Constructor += " Desc = desc;\n"; 4469 } 4470 Constructor += " "; 4471 Constructor += "}\n"; 4472 S += Constructor; 4473 S += "};\n"; 4474 return S; 4475 } 4476 4477 std::string RewriteModernObjC::SynthesizeBlockDescriptor(std::string DescTag, 4478 std::string ImplTag, int i, 4479 StringRef FunName, 4480 unsigned hasCopy) { 4481 std::string S = "\nstatic struct " + DescTag; 4482 4483 S += " {\n size_t reserved;\n"; 4484 S += " size_t Block_size;\n"; 4485 if (hasCopy) { 4486 S += " void (*copy)(struct "; 4487 S += ImplTag; S += "*, struct "; 4488 S += ImplTag; S += "*);\n"; 4489 4490 S += " void (*dispose)(struct "; 4491 S += ImplTag; S += "*);\n"; 4492 } 4493 S += "} "; 4494 4495 S += DescTag + "_DATA = { 0, sizeof(struct "; 4496 S += ImplTag + ")"; 4497 if (hasCopy) { 4498 S += ", __" + FunName.str() + "_block_copy_" + utostr(i); 4499 S += ", __" + FunName.str() + "_block_dispose_" + utostr(i); 4500 } 4501 S += "};\n"; 4502 return S; 4503 } 4504 4505 void RewriteModernObjC::SynthesizeBlockLiterals(SourceLocation FunLocStart, 4506 StringRef FunName) { 4507 bool RewriteSC = (GlobalVarDecl && 4508 !Blocks.empty() && 4509 GlobalVarDecl->getStorageClass() == SC_Static && 4510 GlobalVarDecl->getType().getCVRQualifiers()); 4511 if (RewriteSC) { 4512 std::string SC(" void __"); 4513 SC += GlobalVarDecl->getNameAsString(); 4514 SC += "() {}"; 4515 InsertText(FunLocStart, SC); 4516 } 4517 4518 // Insert closures that were part of the function. 4519 for (unsigned i = 0, count=0; i < Blocks.size(); i++) { 4520 CollectBlockDeclRefInfo(Blocks[i]); 4521 // Need to copy-in the inner copied-in variables not actually used in this 4522 // block. 4523 for (int j = 0; j < InnerDeclRefsCount[i]; j++) { 4524 DeclRefExpr *Exp = InnerDeclRefs[count++]; 4525 ValueDecl *VD = Exp->getDecl(); 4526 BlockDeclRefs.push_back(Exp); 4527 if (!VD->hasAttr<BlocksAttr>()) { 4528 if (!BlockByCopyDeclsPtrSet.count(VD)) { 4529 BlockByCopyDeclsPtrSet.insert(VD); 4530 BlockByCopyDecls.push_back(VD); 4531 } 4532 continue; 4533 } 4534 4535 if (!BlockByRefDeclsPtrSet.count(VD)) { 4536 BlockByRefDeclsPtrSet.insert(VD); 4537 BlockByRefDecls.push_back(VD); 4538 } 4539 4540 // imported objects in the inner blocks not used in the outer 4541 // blocks must be copied/disposed in the outer block as well. 4542 if (VD->getType()->isObjCObjectPointerType() || 4543 VD->getType()->isBlockPointerType()) 4544 ImportedBlockDecls.insert(VD); 4545 } 4546 4547 std::string ImplTag = "__" + FunName.str() + "_block_impl_" + utostr(i); 4548 std::string DescTag = "__" + FunName.str() + "_block_desc_" + utostr(i); 4549 4550 std::string CI = SynthesizeBlockImpl(Blocks[i], ImplTag, DescTag); 4551 4552 InsertText(FunLocStart, CI); 4553 4554 std::string CF = SynthesizeBlockFunc(Blocks[i], i, FunName, ImplTag); 4555 4556 InsertText(FunLocStart, CF); 4557 4558 if (ImportedBlockDecls.size()) { 4559 std::string HF = SynthesizeBlockHelperFuncs(Blocks[i], i, FunName, ImplTag); 4560 InsertText(FunLocStart, HF); 4561 } 4562 std::string BD = SynthesizeBlockDescriptor(DescTag, ImplTag, i, FunName, 4563 ImportedBlockDecls.size() > 0); 4564 InsertText(FunLocStart, BD); 4565 4566 BlockDeclRefs.clear(); 4567 BlockByRefDecls.clear(); 4568 BlockByRefDeclsPtrSet.clear(); 4569 BlockByCopyDecls.clear(); 4570 BlockByCopyDeclsPtrSet.clear(); 4571 ImportedBlockDecls.clear(); 4572 } 4573 if (RewriteSC) { 4574 // Must insert any 'const/volatile/static here. Since it has been 4575 // removed as result of rewriting of block literals. 4576 std::string SC; 4577 if (GlobalVarDecl->getStorageClass() == SC_Static) 4578 SC = "static "; 4579 if (GlobalVarDecl->getType().isConstQualified()) 4580 SC += "const "; 4581 if (GlobalVarDecl->getType().isVolatileQualified()) 4582 SC += "volatile "; 4583 if (GlobalVarDecl->getType().isRestrictQualified()) 4584 SC += "restrict "; 4585 InsertText(FunLocStart, SC); 4586 } 4587 if (GlobalConstructionExp) { 4588 // extra fancy dance for global literal expression. 4589 4590 // Always the latest block expression on the block stack. 4591 std::string Tag = "__"; 4592 Tag += FunName; 4593 Tag += "_block_impl_"; 4594 Tag += utostr(Blocks.size()-1); 4595 std::string globalBuf = "static "; 4596 globalBuf += Tag; globalBuf += " "; 4597 std::string SStr; 4598 4599 llvm::raw_string_ostream constructorExprBuf(SStr); 4600 GlobalConstructionExp->printPretty(constructorExprBuf, 0, 4601 PrintingPolicy(LangOpts)); 4602 globalBuf += constructorExprBuf.str(); 4603 globalBuf += ";\n"; 4604 InsertText(FunLocStart, globalBuf); 4605 GlobalConstructionExp = 0; 4606 } 4607 4608 Blocks.clear(); 4609 InnerDeclRefsCount.clear(); 4610 InnerDeclRefs.clear(); 4611 RewrittenBlockExprs.clear(); 4612 } 4613 4614 void RewriteModernObjC::InsertBlockLiteralsWithinFunction(FunctionDecl *FD) { 4615 SourceLocation FunLocStart = 4616 (!Blocks.empty()) ? getFunctionSourceLocation(*this, FD) 4617 : FD->getTypeSpecStartLoc(); 4618 StringRef FuncName = FD->getName(); 4619 4620 SynthesizeBlockLiterals(FunLocStart, FuncName); 4621 } 4622 4623 static void BuildUniqueMethodName(std::string &Name, 4624 ObjCMethodDecl *MD) { 4625 ObjCInterfaceDecl *IFace = MD->getClassInterface(); 4626 Name = IFace->getName(); 4627 Name += "__" + MD->getSelector().getAsString(); 4628 // Convert colons to underscores. 4629 std::string::size_type loc = 0; 4630 while ((loc = Name.find(":", loc)) != std::string::npos) 4631 Name.replace(loc, 1, "_"); 4632 } 4633 4634 void RewriteModernObjC::InsertBlockLiteralsWithinMethod(ObjCMethodDecl *MD) { 4635 //fprintf(stderr,"In InsertBlockLiteralsWitinMethod\n"); 4636 //SourceLocation FunLocStart = MD->getLocStart(); 4637 SourceLocation FunLocStart = MD->getLocStart(); 4638 std::string FuncName; 4639 BuildUniqueMethodName(FuncName, MD); 4640 SynthesizeBlockLiterals(FunLocStart, FuncName); 4641 } 4642 4643 void RewriteModernObjC::GetBlockDeclRefExprs(Stmt *S) { 4644 for (Stmt::child_range CI = S->children(); CI; ++CI) 4645 if (*CI) { 4646 if (BlockExpr *CBE = dyn_cast<BlockExpr>(*CI)) 4647 GetBlockDeclRefExprs(CBE->getBody()); 4648 else 4649 GetBlockDeclRefExprs(*CI); 4650 } 4651 // Handle specific things. 4652 if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(S)) { 4653 if (DRE->refersToEnclosingLocal()) { 4654 // FIXME: Handle enums. 4655 if (!isa<FunctionDecl>(DRE->getDecl())) 4656 BlockDeclRefs.push_back(DRE); 4657 if (HasLocalVariableExternalStorage(DRE->getDecl())) 4658 BlockDeclRefs.push_back(DRE); 4659 } 4660 } 4661 4662 return; 4663 } 4664 4665 void RewriteModernObjC::GetInnerBlockDeclRefExprs(Stmt *S, 4666 SmallVectorImpl<DeclRefExpr *> &InnerBlockDeclRefs, 4667 llvm::SmallPtrSet<const DeclContext *, 8> &InnerContexts) { 4668 for (Stmt::child_range CI = S->children(); CI; ++CI) 4669 if (*CI) { 4670 if (BlockExpr *CBE = dyn_cast<BlockExpr>(*CI)) { 4671 InnerContexts.insert(cast<DeclContext>(CBE->getBlockDecl())); 4672 GetInnerBlockDeclRefExprs(CBE->getBody(), 4673 InnerBlockDeclRefs, 4674 InnerContexts); 4675 } 4676 else 4677 GetInnerBlockDeclRefExprs(*CI, 4678 InnerBlockDeclRefs, 4679 InnerContexts); 4680 4681 } 4682 // Handle specific things. 4683 if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(S)) { 4684 if (DRE->refersToEnclosingLocal()) { 4685 if (!isa<FunctionDecl>(DRE->getDecl()) && 4686 !InnerContexts.count(DRE->getDecl()->getDeclContext())) 4687 InnerBlockDeclRefs.push_back(DRE); 4688 if (VarDecl *Var = dyn_cast<VarDecl>(DRE->getDecl())) 4689 if (Var->isFunctionOrMethodVarDecl()) 4690 ImportedLocalExternalDecls.insert(Var); 4691 } 4692 } 4693 4694 return; 4695 } 4696 4697 /// convertObjCTypeToCStyleType - This routine converts such objc types 4698 /// as qualified objects, and blocks to their closest c/c++ types that 4699 /// it can. It returns true if input type was modified. 4700 bool RewriteModernObjC::convertObjCTypeToCStyleType(QualType &T) { 4701 QualType oldT = T; 4702 convertBlockPointerToFunctionPointer(T); 4703 if (T->isFunctionPointerType()) { 4704 QualType PointeeTy; 4705 if (const PointerType* PT = T->getAs<PointerType>()) { 4706 PointeeTy = PT->getPointeeType(); 4707 if (const FunctionType *FT = PointeeTy->getAs<FunctionType>()) { 4708 T = convertFunctionTypeOfBlocks(FT); 4709 T = Context->getPointerType(T); 4710 } 4711 } 4712 } 4713 4714 convertToUnqualifiedObjCType(T); 4715 return T != oldT; 4716 } 4717 4718 /// convertFunctionTypeOfBlocks - This routine converts a function type 4719 /// whose result type may be a block pointer or whose argument type(s) 4720 /// might be block pointers to an equivalent function type replacing 4721 /// all block pointers to function pointers. 4722 QualType RewriteModernObjC::convertFunctionTypeOfBlocks(const FunctionType *FT) { 4723 const FunctionProtoType *FTP = dyn_cast<FunctionProtoType>(FT); 4724 // FTP will be null for closures that don't take arguments. 4725 // Generate a funky cast. 4726 SmallVector<QualType, 8> ArgTypes; 4727 QualType Res = FT->getResultType(); 4728 bool modified = convertObjCTypeToCStyleType(Res); 4729 4730 if (FTP) { 4731 for (FunctionProtoType::arg_type_iterator I = FTP->arg_type_begin(), 4732 E = FTP->arg_type_end(); I && (I != E); ++I) { 4733 QualType t = *I; 4734 // Make sure we convert "t (^)(...)" to "t (*)(...)". 4735 if (convertObjCTypeToCStyleType(t)) 4736 modified = true; 4737 ArgTypes.push_back(t); 4738 } 4739 } 4740 QualType FuncType; 4741 if (modified) 4742 FuncType = getSimpleFunctionType(Res, ArgTypes); 4743 else FuncType = QualType(FT, 0); 4744 return FuncType; 4745 } 4746 4747 Stmt *RewriteModernObjC::SynthesizeBlockCall(CallExpr *Exp, const Expr *BlockExp) { 4748 // Navigate to relevant type information. 4749 const BlockPointerType *CPT = 0; 4750 4751 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(BlockExp)) { 4752 CPT = DRE->getType()->getAs<BlockPointerType>(); 4753 } else if (const MemberExpr *MExpr = dyn_cast<MemberExpr>(BlockExp)) { 4754 CPT = MExpr->getType()->getAs<BlockPointerType>(); 4755 } 4756 else if (const ParenExpr *PRE = dyn_cast<ParenExpr>(BlockExp)) { 4757 return SynthesizeBlockCall(Exp, PRE->getSubExpr()); 4758 } 4759 else if (const ImplicitCastExpr *IEXPR = dyn_cast<ImplicitCastExpr>(BlockExp)) 4760 CPT = IEXPR->getType()->getAs<BlockPointerType>(); 4761 else if (const ConditionalOperator *CEXPR = 4762 dyn_cast<ConditionalOperator>(BlockExp)) { 4763 Expr *LHSExp = CEXPR->getLHS(); 4764 Stmt *LHSStmt = SynthesizeBlockCall(Exp, LHSExp); 4765 Expr *RHSExp = CEXPR->getRHS(); 4766 Stmt *RHSStmt = SynthesizeBlockCall(Exp, RHSExp); 4767 Expr *CONDExp = CEXPR->getCond(); 4768 ConditionalOperator *CondExpr = 4769 new (Context) ConditionalOperator(CONDExp, 4770 SourceLocation(), cast<Expr>(LHSStmt), 4771 SourceLocation(), cast<Expr>(RHSStmt), 4772 Exp->getType(), VK_RValue, OK_Ordinary); 4773 return CondExpr; 4774 } else if (const ObjCIvarRefExpr *IRE = dyn_cast<ObjCIvarRefExpr>(BlockExp)) { 4775 CPT = IRE->getType()->getAs<BlockPointerType>(); 4776 } else if (const PseudoObjectExpr *POE 4777 = dyn_cast<PseudoObjectExpr>(BlockExp)) { 4778 CPT = POE->getType()->castAs<BlockPointerType>(); 4779 } else { 4780 assert(1 && "RewriteBlockClass: Bad type"); 4781 } 4782 assert(CPT && "RewriteBlockClass: Bad type"); 4783 const FunctionType *FT = CPT->getPointeeType()->getAs<FunctionType>(); 4784 assert(FT && "RewriteBlockClass: Bad type"); 4785 const FunctionProtoType *FTP = dyn_cast<FunctionProtoType>(FT); 4786 // FTP will be null for closures that don't take arguments. 4787 4788 RecordDecl *RD = RecordDecl::Create(*Context, TTK_Struct, TUDecl, 4789 SourceLocation(), SourceLocation(), 4790 &Context->Idents.get("__block_impl")); 4791 QualType PtrBlock = Context->getPointerType(Context->getTagDeclType(RD)); 4792 4793 // Generate a funky cast. 4794 SmallVector<QualType, 8> ArgTypes; 4795 4796 // Push the block argument type. 4797 ArgTypes.push_back(PtrBlock); 4798 if (FTP) { 4799 for (FunctionProtoType::arg_type_iterator I = FTP->arg_type_begin(), 4800 E = FTP->arg_type_end(); I && (I != E); ++I) { 4801 QualType t = *I; 4802 // Make sure we convert "t (^)(...)" to "t (*)(...)". 4803 if (!convertBlockPointerToFunctionPointer(t)) 4804 convertToUnqualifiedObjCType(t); 4805 ArgTypes.push_back(t); 4806 } 4807 } 4808 // Now do the pointer to function cast. 4809 QualType PtrToFuncCastType = getSimpleFunctionType(Exp->getType(), ArgTypes); 4810 4811 PtrToFuncCastType = Context->getPointerType(PtrToFuncCastType); 4812 4813 CastExpr *BlkCast = NoTypeInfoCStyleCastExpr(Context, PtrBlock, 4814 CK_BitCast, 4815 const_cast<Expr*>(BlockExp)); 4816 // Don't forget the parens to enforce the proper binding. 4817 ParenExpr *PE = new (Context) ParenExpr(SourceLocation(), SourceLocation(), 4818 BlkCast); 4819 //PE->dump(); 4820 4821 FieldDecl *FD = FieldDecl::Create(*Context, 0, SourceLocation(), 4822 SourceLocation(), 4823 &Context->Idents.get("FuncPtr"), 4824 Context->VoidPtrTy, 0, 4825 /*BitWidth=*/0, /*Mutable=*/true, 4826 ICIS_NoInit); 4827 MemberExpr *ME = new (Context) MemberExpr(PE, true, FD, SourceLocation(), 4828 FD->getType(), VK_LValue, 4829 OK_Ordinary); 4830 4831 4832 CastExpr *FunkCast = NoTypeInfoCStyleCastExpr(Context, PtrToFuncCastType, 4833 CK_BitCast, ME); 4834 PE = new (Context) ParenExpr(SourceLocation(), SourceLocation(), FunkCast); 4835 4836 SmallVector<Expr*, 8> BlkExprs; 4837 // Add the implicit argument. 4838 BlkExprs.push_back(BlkCast); 4839 // Add the user arguments. 4840 for (CallExpr::arg_iterator I = Exp->arg_begin(), 4841 E = Exp->arg_end(); I != E; ++I) { 4842 BlkExprs.push_back(*I); 4843 } 4844 CallExpr *CE = new (Context) CallExpr(*Context, PE, BlkExprs, 4845 Exp->getType(), VK_RValue, 4846 SourceLocation()); 4847 return CE; 4848 } 4849 4850 // We need to return the rewritten expression to handle cases where the 4851 // DeclRefExpr is embedded in another expression being rewritten. 4852 // For example: 4853 // 4854 // int main() { 4855 // __block Foo *f; 4856 // __block int i; 4857 // 4858 // void (^myblock)() = ^() { 4859 // [f test]; // f is a DeclRefExpr embedded in a message (which is being rewritten). 4860 // i = 77; 4861 // }; 4862 //} 4863 Stmt *RewriteModernObjC::RewriteBlockDeclRefExpr(DeclRefExpr *DeclRefExp) { 4864 // Rewrite the byref variable into BYREFVAR->__forwarding->BYREFVAR 4865 // for each DeclRefExp where BYREFVAR is name of the variable. 4866 ValueDecl *VD = DeclRefExp->getDecl(); 4867 bool isArrow = DeclRefExp->refersToEnclosingLocal(); 4868 4869 FieldDecl *FD = FieldDecl::Create(*Context, 0, SourceLocation(), 4870 SourceLocation(), 4871 &Context->Idents.get("__forwarding"), 4872 Context->VoidPtrTy, 0, 4873 /*BitWidth=*/0, /*Mutable=*/true, 4874 ICIS_NoInit); 4875 MemberExpr *ME = new (Context) MemberExpr(DeclRefExp, isArrow, 4876 FD, SourceLocation(), 4877 FD->getType(), VK_LValue, 4878 OK_Ordinary); 4879 4880 StringRef Name = VD->getName(); 4881 FD = FieldDecl::Create(*Context, 0, SourceLocation(), SourceLocation(), 4882 &Context->Idents.get(Name), 4883 Context->VoidPtrTy, 0, 4884 /*BitWidth=*/0, /*Mutable=*/true, 4885 ICIS_NoInit); 4886 ME = new (Context) MemberExpr(ME, true, FD, SourceLocation(), 4887 DeclRefExp->getType(), VK_LValue, OK_Ordinary); 4888 4889 4890 4891 // Need parens to enforce precedence. 4892 ParenExpr *PE = new (Context) ParenExpr(DeclRefExp->getExprLoc(), 4893 DeclRefExp->getExprLoc(), 4894 ME); 4895 ReplaceStmt(DeclRefExp, PE); 4896 return PE; 4897 } 4898 4899 // Rewrites the imported local variable V with external storage 4900 // (static, extern, etc.) as *V 4901 // 4902 Stmt *RewriteModernObjC::RewriteLocalVariableExternalStorage(DeclRefExpr *DRE) { 4903 ValueDecl *VD = DRE->getDecl(); 4904 if (VarDecl *Var = dyn_cast<VarDecl>(VD)) 4905 if (!ImportedLocalExternalDecls.count(Var)) 4906 return DRE; 4907 Expr *Exp = new (Context) UnaryOperator(DRE, UO_Deref, DRE->getType(), 4908 VK_LValue, OK_Ordinary, 4909 DRE->getLocation()); 4910 // Need parens to enforce precedence. 4911 ParenExpr *PE = new (Context) ParenExpr(SourceLocation(), SourceLocation(), 4912 Exp); 4913 ReplaceStmt(DRE, PE); 4914 return PE; 4915 } 4916 4917 void RewriteModernObjC::RewriteCastExpr(CStyleCastExpr *CE) { 4918 SourceLocation LocStart = CE->getLParenLoc(); 4919 SourceLocation LocEnd = CE->getRParenLoc(); 4920 4921 // Need to avoid trying to rewrite synthesized casts. 4922 if (LocStart.isInvalid()) 4923 return; 4924 // Need to avoid trying to rewrite casts contained in macros. 4925 if (!Rewriter::isRewritable(LocStart) || !Rewriter::isRewritable(LocEnd)) 4926 return; 4927 4928 const char *startBuf = SM->getCharacterData(LocStart); 4929 const char *endBuf = SM->getCharacterData(LocEnd); 4930 QualType QT = CE->getType(); 4931 const Type* TypePtr = QT->getAs<Type>(); 4932 if (isa<TypeOfExprType>(TypePtr)) { 4933 const TypeOfExprType *TypeOfExprTypePtr = cast<TypeOfExprType>(TypePtr); 4934 QT = TypeOfExprTypePtr->getUnderlyingExpr()->getType(); 4935 std::string TypeAsString = "("; 4936 RewriteBlockPointerType(TypeAsString, QT); 4937 TypeAsString += ")"; 4938 ReplaceText(LocStart, endBuf-startBuf+1, TypeAsString); 4939 return; 4940 } 4941 // advance the location to startArgList. 4942 const char *argPtr = startBuf; 4943 4944 while (*argPtr++ && (argPtr < endBuf)) { 4945 switch (*argPtr) { 4946 case '^': 4947 // Replace the '^' with '*'. 4948 LocStart = LocStart.getLocWithOffset(argPtr-startBuf); 4949 ReplaceText(LocStart, 1, "*"); 4950 break; 4951 } 4952 } 4953 return; 4954 } 4955 4956 void RewriteModernObjC::RewriteImplicitCastObjCExpr(CastExpr *IC) { 4957 CastKind CastKind = IC->getCastKind(); 4958 if (CastKind != CK_BlockPointerToObjCPointerCast && 4959 CastKind != CK_AnyPointerToBlockPointerCast) 4960 return; 4961 4962 QualType QT = IC->getType(); 4963 (void)convertBlockPointerToFunctionPointer(QT); 4964 std::string TypeString(QT.getAsString(Context->getPrintingPolicy())); 4965 std::string Str = "("; 4966 Str += TypeString; 4967 Str += ")"; 4968 InsertText(IC->getSubExpr()->getLocStart(), &Str[0], Str.size()); 4969 4970 return; 4971 } 4972 4973 void RewriteModernObjC::RewriteBlockPointerFunctionArgs(FunctionDecl *FD) { 4974 SourceLocation DeclLoc = FD->getLocation(); 4975 unsigned parenCount = 0; 4976 4977 // We have 1 or more arguments that have closure pointers. 4978 const char *startBuf = SM->getCharacterData(DeclLoc); 4979 const char *startArgList = strchr(startBuf, '('); 4980 4981 assert((*startArgList == '(') && "Rewriter fuzzy parser confused"); 4982 4983 parenCount++; 4984 // advance the location to startArgList. 4985 DeclLoc = DeclLoc.getLocWithOffset(startArgList-startBuf); 4986 assert((DeclLoc.isValid()) && "Invalid DeclLoc"); 4987 4988 const char *argPtr = startArgList; 4989 4990 while (*argPtr++ && parenCount) { 4991 switch (*argPtr) { 4992 case '^': 4993 // Replace the '^' with '*'. 4994 DeclLoc = DeclLoc.getLocWithOffset(argPtr-startArgList); 4995 ReplaceText(DeclLoc, 1, "*"); 4996 break; 4997 case '(': 4998 parenCount++; 4999 break; 5000 case ')': 5001 parenCount--; 5002 break; 5003 } 5004 } 5005 return; 5006 } 5007 5008 bool RewriteModernObjC::PointerTypeTakesAnyBlockArguments(QualType QT) { 5009 const FunctionProtoType *FTP; 5010 const PointerType *PT = QT->getAs<PointerType>(); 5011 if (PT) { 5012 FTP = PT->getPointeeType()->getAs<FunctionProtoType>(); 5013 } else { 5014 const BlockPointerType *BPT = QT->getAs<BlockPointerType>(); 5015 assert(BPT && "BlockPointerTypeTakeAnyBlockArguments(): not a block pointer type"); 5016 FTP = BPT->getPointeeType()->getAs<FunctionProtoType>(); 5017 } 5018 if (FTP) { 5019 for (FunctionProtoType::arg_type_iterator I = FTP->arg_type_begin(), 5020 E = FTP->arg_type_end(); I != E; ++I) 5021 if (isTopLevelBlockPointerType(*I)) 5022 return true; 5023 } 5024 return false; 5025 } 5026 5027 bool RewriteModernObjC::PointerTypeTakesAnyObjCQualifiedType(QualType QT) { 5028 const FunctionProtoType *FTP; 5029 const PointerType *PT = QT->getAs<PointerType>(); 5030 if (PT) { 5031 FTP = PT->getPointeeType()->getAs<FunctionProtoType>(); 5032 } else { 5033 const BlockPointerType *BPT = QT->getAs<BlockPointerType>(); 5034 assert(BPT && "BlockPointerTypeTakeAnyBlockArguments(): not a block pointer type"); 5035 FTP = BPT->getPointeeType()->getAs<FunctionProtoType>(); 5036 } 5037 if (FTP) { 5038 for (FunctionProtoType::arg_type_iterator I = FTP->arg_type_begin(), 5039 E = FTP->arg_type_end(); I != E; ++I) { 5040 if ((*I)->isObjCQualifiedIdType()) 5041 return true; 5042 if ((*I)->isObjCObjectPointerType() && 5043 (*I)->getPointeeType()->isObjCQualifiedInterfaceType()) 5044 return true; 5045 } 5046 5047 } 5048 return false; 5049 } 5050 5051 void RewriteModernObjC::GetExtentOfArgList(const char *Name, const char *&LParen, 5052 const char *&RParen) { 5053 const char *argPtr = strchr(Name, '('); 5054 assert((*argPtr == '(') && "Rewriter fuzzy parser confused"); 5055 5056 LParen = argPtr; // output the start. 5057 argPtr++; // skip past the left paren. 5058 unsigned parenCount = 1; 5059 5060 while (*argPtr && parenCount) { 5061 switch (*argPtr) { 5062 case '(': parenCount++; break; 5063 case ')': parenCount--; break; 5064 default: break; 5065 } 5066 if (parenCount) argPtr++; 5067 } 5068 assert((*argPtr == ')') && "Rewriter fuzzy parser confused"); 5069 RParen = argPtr; // output the end 5070 } 5071 5072 void RewriteModernObjC::RewriteBlockPointerDecl(NamedDecl *ND) { 5073 if (FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) { 5074 RewriteBlockPointerFunctionArgs(FD); 5075 return; 5076 } 5077 // Handle Variables and Typedefs. 5078 SourceLocation DeclLoc = ND->getLocation(); 5079 QualType DeclT; 5080 if (VarDecl *VD = dyn_cast<VarDecl>(ND)) 5081 DeclT = VD->getType(); 5082 else if (TypedefNameDecl *TDD = dyn_cast<TypedefNameDecl>(ND)) 5083 DeclT = TDD->getUnderlyingType(); 5084 else if (FieldDecl *FD = dyn_cast<FieldDecl>(ND)) 5085 DeclT = FD->getType(); 5086 else 5087 llvm_unreachable("RewriteBlockPointerDecl(): Decl type not yet handled"); 5088 5089 const char *startBuf = SM->getCharacterData(DeclLoc); 5090 const char *endBuf = startBuf; 5091 // scan backward (from the decl location) for the end of the previous decl. 5092 while (*startBuf != '^' && *startBuf != ';' && startBuf != MainFileStart) 5093 startBuf--; 5094 SourceLocation Start = DeclLoc.getLocWithOffset(startBuf-endBuf); 5095 std::string buf; 5096 unsigned OrigLength=0; 5097 // *startBuf != '^' if we are dealing with a pointer to function that 5098 // may take block argument types (which will be handled below). 5099 if (*startBuf == '^') { 5100 // Replace the '^' with '*', computing a negative offset. 5101 buf = '*'; 5102 startBuf++; 5103 OrigLength++; 5104 } 5105 while (*startBuf != ')') { 5106 buf += *startBuf; 5107 startBuf++; 5108 OrigLength++; 5109 } 5110 buf += ')'; 5111 OrigLength++; 5112 5113 if (PointerTypeTakesAnyBlockArguments(DeclT) || 5114 PointerTypeTakesAnyObjCQualifiedType(DeclT)) { 5115 // Replace the '^' with '*' for arguments. 5116 // Replace id<P> with id/*<>*/ 5117 DeclLoc = ND->getLocation(); 5118 startBuf = SM->getCharacterData(DeclLoc); 5119 const char *argListBegin, *argListEnd; 5120 GetExtentOfArgList(startBuf, argListBegin, argListEnd); 5121 while (argListBegin < argListEnd) { 5122 if (*argListBegin == '^') 5123 buf += '*'; 5124 else if (*argListBegin == '<') { 5125 buf += "/*"; 5126 buf += *argListBegin++; 5127 OrigLength++; 5128 while (*argListBegin != '>') { 5129 buf += *argListBegin++; 5130 OrigLength++; 5131 } 5132 buf += *argListBegin; 5133 buf += "*/"; 5134 } 5135 else 5136 buf += *argListBegin; 5137 argListBegin++; 5138 OrigLength++; 5139 } 5140 buf += ')'; 5141 OrigLength++; 5142 } 5143 ReplaceText(Start, OrigLength, buf); 5144 5145 return; 5146 } 5147 5148 5149 /// SynthesizeByrefCopyDestroyHelper - This routine synthesizes: 5150 /// void __Block_byref_id_object_copy(struct Block_byref_id_object *dst, 5151 /// struct Block_byref_id_object *src) { 5152 /// _Block_object_assign (&_dest->object, _src->object, 5153 /// BLOCK_BYREF_CALLER | BLOCK_FIELD_IS_OBJECT 5154 /// [|BLOCK_FIELD_IS_WEAK]) // object 5155 /// _Block_object_assign(&_dest->object, _src->object, 5156 /// BLOCK_BYREF_CALLER | BLOCK_FIELD_IS_BLOCK 5157 /// [|BLOCK_FIELD_IS_WEAK]) // block 5158 /// } 5159 /// And: 5160 /// void __Block_byref_id_object_dispose(struct Block_byref_id_object *_src) { 5161 /// _Block_object_dispose(_src->object, 5162 /// BLOCK_BYREF_CALLER | BLOCK_FIELD_IS_OBJECT 5163 /// [|BLOCK_FIELD_IS_WEAK]) // object 5164 /// _Block_object_dispose(_src->object, 5165 /// BLOCK_BYREF_CALLER | BLOCK_FIELD_IS_BLOCK 5166 /// [|BLOCK_FIELD_IS_WEAK]) // block 5167 /// } 5168 5169 std::string RewriteModernObjC::SynthesizeByrefCopyDestroyHelper(VarDecl *VD, 5170 int flag) { 5171 std::string S; 5172 if (CopyDestroyCache.count(flag)) 5173 return S; 5174 CopyDestroyCache.insert(flag); 5175 S = "static void __Block_byref_id_object_copy_"; 5176 S += utostr(flag); 5177 S += "(void *dst, void *src) {\n"; 5178 5179 // offset into the object pointer is computed as: 5180 // void * + void* + int + int + void* + void * 5181 unsigned IntSize = 5182 static_cast<unsigned>(Context->getTypeSize(Context->IntTy)); 5183 unsigned VoidPtrSize = 5184 static_cast<unsigned>(Context->getTypeSize(Context->VoidPtrTy)); 5185 5186 unsigned offset = (VoidPtrSize*4 + IntSize + IntSize)/Context->getCharWidth(); 5187 S += " _Block_object_assign((char*)dst + "; 5188 S += utostr(offset); 5189 S += ", *(void * *) ((char*)src + "; 5190 S += utostr(offset); 5191 S += "), "; 5192 S += utostr(flag); 5193 S += ");\n}\n"; 5194 5195 S += "static void __Block_byref_id_object_dispose_"; 5196 S += utostr(flag); 5197 S += "(void *src) {\n"; 5198 S += " _Block_object_dispose(*(void * *) ((char*)src + "; 5199 S += utostr(offset); 5200 S += "), "; 5201 S += utostr(flag); 5202 S += ");\n}\n"; 5203 return S; 5204 } 5205 5206 /// RewriteByRefVar - For each __block typex ND variable this routine transforms 5207 /// the declaration into: 5208 /// struct __Block_byref_ND { 5209 /// void *__isa; // NULL for everything except __weak pointers 5210 /// struct __Block_byref_ND *__forwarding; 5211 /// int32_t __flags; 5212 /// int32_t __size; 5213 /// void *__Block_byref_id_object_copy; // If variable is __block ObjC object 5214 /// void *__Block_byref_id_object_dispose; // If variable is __block ObjC object 5215 /// typex ND; 5216 /// }; 5217 /// 5218 /// It then replaces declaration of ND variable with: 5219 /// struct __Block_byref_ND ND = {__isa=0B, __forwarding=&ND, __flags=some_flag, 5220 /// __size=sizeof(struct __Block_byref_ND), 5221 /// ND=initializer-if-any}; 5222 /// 5223 /// 5224 void RewriteModernObjC::RewriteByRefVar(VarDecl *ND, bool firstDecl, 5225 bool lastDecl) { 5226 int flag = 0; 5227 int isa = 0; 5228 SourceLocation DeclLoc = ND->getTypeSpecStartLoc(); 5229 if (DeclLoc.isInvalid()) 5230 // If type location is missing, it is because of missing type (a warning). 5231 // Use variable's location which is good for this case. 5232 DeclLoc = ND->getLocation(); 5233 const char *startBuf = SM->getCharacterData(DeclLoc); 5234 SourceLocation X = ND->getLocEnd(); 5235 X = SM->getExpansionLoc(X); 5236 const char *endBuf = SM->getCharacterData(X); 5237 std::string Name(ND->getNameAsString()); 5238 std::string ByrefType; 5239 RewriteByRefString(ByrefType, Name, ND, true); 5240 ByrefType += " {\n"; 5241 ByrefType += " void *__isa;\n"; 5242 RewriteByRefString(ByrefType, Name, ND); 5243 ByrefType += " *__forwarding;\n"; 5244 ByrefType += " int __flags;\n"; 5245 ByrefType += " int __size;\n"; 5246 // Add void *__Block_byref_id_object_copy; 5247 // void *__Block_byref_id_object_dispose; if needed. 5248 QualType Ty = ND->getType(); 5249 bool HasCopyAndDispose = Context->BlockRequiresCopying(Ty, ND); 5250 if (HasCopyAndDispose) { 5251 ByrefType += " void (*__Block_byref_id_object_copy)(void*, void*);\n"; 5252 ByrefType += " void (*__Block_byref_id_object_dispose)(void*);\n"; 5253 } 5254 5255 QualType T = Ty; 5256 (void)convertBlockPointerToFunctionPointer(T); 5257 T.getAsStringInternal(Name, Context->getPrintingPolicy()); 5258 5259 ByrefType += " " + Name + ";\n"; 5260 ByrefType += "};\n"; 5261 // Insert this type in global scope. It is needed by helper function. 5262 SourceLocation FunLocStart; 5263 if (CurFunctionDef) 5264 FunLocStart = getFunctionSourceLocation(*this, CurFunctionDef); 5265 else { 5266 assert(CurMethodDef && "RewriteByRefVar - CurMethodDef is null"); 5267 FunLocStart = CurMethodDef->getLocStart(); 5268 } 5269 InsertText(FunLocStart, ByrefType); 5270 5271 if (Ty.isObjCGCWeak()) { 5272 flag |= BLOCK_FIELD_IS_WEAK; 5273 isa = 1; 5274 } 5275 if (HasCopyAndDispose) { 5276 flag = BLOCK_BYREF_CALLER; 5277 QualType Ty = ND->getType(); 5278 // FIXME. Handle __weak variable (BLOCK_FIELD_IS_WEAK) as well. 5279 if (Ty->isBlockPointerType()) 5280 flag |= BLOCK_FIELD_IS_BLOCK; 5281 else 5282 flag |= BLOCK_FIELD_IS_OBJECT; 5283 std::string HF = SynthesizeByrefCopyDestroyHelper(ND, flag); 5284 if (!HF.empty()) 5285 Preamble += HF; 5286 } 5287 5288 // struct __Block_byref_ND ND = 5289 // {0, &ND, some_flag, __size=sizeof(struct __Block_byref_ND), 5290 // initializer-if-any}; 5291 bool hasInit = (ND->getInit() != 0); 5292 // FIXME. rewriter does not support __block c++ objects which 5293 // require construction. 5294 if (hasInit) 5295 if (CXXConstructExpr *CExp = dyn_cast<CXXConstructExpr>(ND->getInit())) { 5296 CXXConstructorDecl *CXXDecl = CExp->getConstructor(); 5297 if (CXXDecl && CXXDecl->isDefaultConstructor()) 5298 hasInit = false; 5299 } 5300 5301 unsigned flags = 0; 5302 if (HasCopyAndDispose) 5303 flags |= BLOCK_HAS_COPY_DISPOSE; 5304 Name = ND->getNameAsString(); 5305 ByrefType.clear(); 5306 RewriteByRefString(ByrefType, Name, ND); 5307 std::string ForwardingCastType("("); 5308 ForwardingCastType += ByrefType + " *)"; 5309 ByrefType += " " + Name + " = {(void*)"; 5310 ByrefType += utostr(isa); 5311 ByrefType += "," + ForwardingCastType + "&" + Name + ", "; 5312 ByrefType += utostr(flags); 5313 ByrefType += ", "; 5314 ByrefType += "sizeof("; 5315 RewriteByRefString(ByrefType, Name, ND); 5316 ByrefType += ")"; 5317 if (HasCopyAndDispose) { 5318 ByrefType += ", __Block_byref_id_object_copy_"; 5319 ByrefType += utostr(flag); 5320 ByrefType += ", __Block_byref_id_object_dispose_"; 5321 ByrefType += utostr(flag); 5322 } 5323 5324 if (!firstDecl) { 5325 // In multiple __block declarations, and for all but 1st declaration, 5326 // find location of the separating comma. This would be start location 5327 // where new text is to be inserted. 5328 DeclLoc = ND->getLocation(); 5329 const char *startDeclBuf = SM->getCharacterData(DeclLoc); 5330 const char *commaBuf = startDeclBuf; 5331 while (*commaBuf != ',') 5332 commaBuf--; 5333 assert((*commaBuf == ',') && "RewriteByRefVar: can't find ','"); 5334 DeclLoc = DeclLoc.getLocWithOffset(commaBuf - startDeclBuf); 5335 startBuf = commaBuf; 5336 } 5337 5338 if (!hasInit) { 5339 ByrefType += "};\n"; 5340 unsigned nameSize = Name.size(); 5341 // for block or function pointer declaration. Name is aleady 5342 // part of the declaration. 5343 if (Ty->isBlockPointerType() || Ty->isFunctionPointerType()) 5344 nameSize = 1; 5345 ReplaceText(DeclLoc, endBuf-startBuf+nameSize, ByrefType); 5346 } 5347 else { 5348 ByrefType += ", "; 5349 SourceLocation startLoc; 5350 Expr *E = ND->getInit(); 5351 if (const CStyleCastExpr *ECE = dyn_cast<CStyleCastExpr>(E)) 5352 startLoc = ECE->getLParenLoc(); 5353 else 5354 startLoc = E->getLocStart(); 5355 startLoc = SM->getExpansionLoc(startLoc); 5356 endBuf = SM->getCharacterData(startLoc); 5357 ReplaceText(DeclLoc, endBuf-startBuf, ByrefType); 5358 5359 const char separator = lastDecl ? ';' : ','; 5360 const char *startInitializerBuf = SM->getCharacterData(startLoc); 5361 const char *separatorBuf = strchr(startInitializerBuf, separator); 5362 assert((*separatorBuf == separator) && 5363 "RewriteByRefVar: can't find ';' or ','"); 5364 SourceLocation separatorLoc = 5365 startLoc.getLocWithOffset(separatorBuf-startInitializerBuf); 5366 5367 InsertText(separatorLoc, lastDecl ? "}" : "};\n"); 5368 } 5369 return; 5370 } 5371 5372 void RewriteModernObjC::CollectBlockDeclRefInfo(BlockExpr *Exp) { 5373 // Add initializers for any closure decl refs. 5374 GetBlockDeclRefExprs(Exp->getBody()); 5375 if (BlockDeclRefs.size()) { 5376 // Unique all "by copy" declarations. 5377 for (unsigned i = 0; i < BlockDeclRefs.size(); i++) 5378 if (!BlockDeclRefs[i]->getDecl()->hasAttr<BlocksAttr>()) { 5379 if (!BlockByCopyDeclsPtrSet.count(BlockDeclRefs[i]->getDecl())) { 5380 BlockByCopyDeclsPtrSet.insert(BlockDeclRefs[i]->getDecl()); 5381 BlockByCopyDecls.push_back(BlockDeclRefs[i]->getDecl()); 5382 } 5383 } 5384 // Unique all "by ref" declarations. 5385 for (unsigned i = 0; i < BlockDeclRefs.size(); i++) 5386 if (BlockDeclRefs[i]->getDecl()->hasAttr<BlocksAttr>()) { 5387 if (!BlockByRefDeclsPtrSet.count(BlockDeclRefs[i]->getDecl())) { 5388 BlockByRefDeclsPtrSet.insert(BlockDeclRefs[i]->getDecl()); 5389 BlockByRefDecls.push_back(BlockDeclRefs[i]->getDecl()); 5390 } 5391 } 5392 // Find any imported blocks...they will need special attention. 5393 for (unsigned i = 0; i < BlockDeclRefs.size(); i++) 5394 if (BlockDeclRefs[i]->getDecl()->hasAttr<BlocksAttr>() || 5395 BlockDeclRefs[i]->getType()->isObjCObjectPointerType() || 5396 BlockDeclRefs[i]->getType()->isBlockPointerType()) 5397 ImportedBlockDecls.insert(BlockDeclRefs[i]->getDecl()); 5398 } 5399 } 5400 5401 FunctionDecl *RewriteModernObjC::SynthBlockInitFunctionDecl(StringRef name) { 5402 IdentifierInfo *ID = &Context->Idents.get(name); 5403 QualType FType = Context->getFunctionNoProtoType(Context->VoidPtrTy); 5404 return FunctionDecl::Create(*Context, TUDecl, SourceLocation(), 5405 SourceLocation(), ID, FType, 0, SC_Extern, 5406 false, false); 5407 } 5408 5409 Stmt *RewriteModernObjC::SynthBlockInitExpr(BlockExpr *Exp, 5410 const SmallVectorImpl<DeclRefExpr *> &InnerBlockDeclRefs) { 5411 5412 const BlockDecl *block = Exp->getBlockDecl(); 5413 5414 Blocks.push_back(Exp); 5415 5416 CollectBlockDeclRefInfo(Exp); 5417 5418 // Add inner imported variables now used in current block. 5419 int countOfInnerDecls = 0; 5420 if (!InnerBlockDeclRefs.empty()) { 5421 for (unsigned i = 0; i < InnerBlockDeclRefs.size(); i++) { 5422 DeclRefExpr *Exp = InnerBlockDeclRefs[i]; 5423 ValueDecl *VD = Exp->getDecl(); 5424 if (!VD->hasAttr<BlocksAttr>() && !BlockByCopyDeclsPtrSet.count(VD)) { 5425 // We need to save the copied-in variables in nested 5426 // blocks because it is needed at the end for some of the API generations. 5427 // See SynthesizeBlockLiterals routine. 5428 InnerDeclRefs.push_back(Exp); countOfInnerDecls++; 5429 BlockDeclRefs.push_back(Exp); 5430 BlockByCopyDeclsPtrSet.insert(VD); 5431 BlockByCopyDecls.push_back(VD); 5432 } 5433 if (VD->hasAttr<BlocksAttr>() && !BlockByRefDeclsPtrSet.count(VD)) { 5434 InnerDeclRefs.push_back(Exp); countOfInnerDecls++; 5435 BlockDeclRefs.push_back(Exp); 5436 BlockByRefDeclsPtrSet.insert(VD); 5437 BlockByRefDecls.push_back(VD); 5438 } 5439 } 5440 // Find any imported blocks...they will need special attention. 5441 for (unsigned i = 0; i < InnerBlockDeclRefs.size(); i++) 5442 if (InnerBlockDeclRefs[i]->getDecl()->hasAttr<BlocksAttr>() || 5443 InnerBlockDeclRefs[i]->getType()->isObjCObjectPointerType() || 5444 InnerBlockDeclRefs[i]->getType()->isBlockPointerType()) 5445 ImportedBlockDecls.insert(InnerBlockDeclRefs[i]->getDecl()); 5446 } 5447 InnerDeclRefsCount.push_back(countOfInnerDecls); 5448 5449 std::string FuncName; 5450 5451 if (CurFunctionDef) 5452 FuncName = CurFunctionDef->getNameAsString(); 5453 else if (CurMethodDef) 5454 BuildUniqueMethodName(FuncName, CurMethodDef); 5455 else if (GlobalVarDecl) 5456 FuncName = std::string(GlobalVarDecl->getNameAsString()); 5457 5458 bool GlobalBlockExpr = 5459 block->getDeclContext()->getRedeclContext()->isFileContext(); 5460 5461 if (GlobalBlockExpr && !GlobalVarDecl) { 5462 Diags.Report(block->getLocation(), GlobalBlockRewriteFailedDiag); 5463 GlobalBlockExpr = false; 5464 } 5465 5466 std::string BlockNumber = utostr(Blocks.size()-1); 5467 5468 std::string Func = "__" + FuncName + "_block_func_" + BlockNumber; 5469 5470 // Get a pointer to the function type so we can cast appropriately. 5471 QualType BFT = convertFunctionTypeOfBlocks(Exp->getFunctionType()); 5472 QualType FType = Context->getPointerType(BFT); 5473 5474 FunctionDecl *FD; 5475 Expr *NewRep; 5476 5477 // Simulate a contructor call... 5478 std::string Tag; 5479 5480 if (GlobalBlockExpr) 5481 Tag = "__global_"; 5482 else 5483 Tag = "__"; 5484 Tag += FuncName + "_block_impl_" + BlockNumber; 5485 5486 FD = SynthBlockInitFunctionDecl(Tag); 5487 DeclRefExpr *DRE = new (Context) DeclRefExpr(FD, false, FType, VK_RValue, 5488 SourceLocation()); 5489 5490 SmallVector<Expr*, 4> InitExprs; 5491 5492 // Initialize the block function. 5493 FD = SynthBlockInitFunctionDecl(Func); 5494 DeclRefExpr *Arg = new (Context) DeclRefExpr(FD, false, FD->getType(), 5495 VK_LValue, SourceLocation()); 5496 CastExpr *castExpr = NoTypeInfoCStyleCastExpr(Context, Context->VoidPtrTy, 5497 CK_BitCast, Arg); 5498 InitExprs.push_back(castExpr); 5499 5500 // Initialize the block descriptor. 5501 std::string DescData = "__" + FuncName + "_block_desc_" + BlockNumber + "_DATA"; 5502 5503 VarDecl *NewVD = VarDecl::Create(*Context, TUDecl, 5504 SourceLocation(), SourceLocation(), 5505 &Context->Idents.get(DescData.c_str()), 5506 Context->VoidPtrTy, 0, 5507 SC_Static); 5508 UnaryOperator *DescRefExpr = 5509 new (Context) UnaryOperator(new (Context) DeclRefExpr(NewVD, false, 5510 Context->VoidPtrTy, 5511 VK_LValue, 5512 SourceLocation()), 5513 UO_AddrOf, 5514 Context->getPointerType(Context->VoidPtrTy), 5515 VK_RValue, OK_Ordinary, 5516 SourceLocation()); 5517 InitExprs.push_back(DescRefExpr); 5518 5519 // Add initializers for any closure decl refs. 5520 if (BlockDeclRefs.size()) { 5521 Expr *Exp; 5522 // Output all "by copy" declarations. 5523 for (SmallVectorImpl<ValueDecl *>::iterator I = BlockByCopyDecls.begin(), 5524 E = BlockByCopyDecls.end(); I != E; ++I) { 5525 if (isObjCType((*I)->getType())) { 5526 // FIXME: Conform to ABI ([[obj retain] autorelease]). 5527 FD = SynthBlockInitFunctionDecl((*I)->getName()); 5528 Exp = new (Context) DeclRefExpr(FD, false, FD->getType(), 5529 VK_LValue, SourceLocation()); 5530 if (HasLocalVariableExternalStorage(*I)) { 5531 QualType QT = (*I)->getType(); 5532 QT = Context->getPointerType(QT); 5533 Exp = new (Context) UnaryOperator(Exp, UO_AddrOf, QT, VK_RValue, 5534 OK_Ordinary, SourceLocation()); 5535 } 5536 } else if (isTopLevelBlockPointerType((*I)->getType())) { 5537 FD = SynthBlockInitFunctionDecl((*I)->getName()); 5538 Arg = new (Context) DeclRefExpr(FD, false, FD->getType(), 5539 VK_LValue, SourceLocation()); 5540 Exp = NoTypeInfoCStyleCastExpr(Context, Context->VoidPtrTy, 5541 CK_BitCast, Arg); 5542 } else { 5543 FD = SynthBlockInitFunctionDecl((*I)->getName()); 5544 Exp = new (Context) DeclRefExpr(FD, false, FD->getType(), 5545 VK_LValue, SourceLocation()); 5546 if (HasLocalVariableExternalStorage(*I)) { 5547 QualType QT = (*I)->getType(); 5548 QT = Context->getPointerType(QT); 5549 Exp = new (Context) UnaryOperator(Exp, UO_AddrOf, QT, VK_RValue, 5550 OK_Ordinary, SourceLocation()); 5551 } 5552 5553 } 5554 InitExprs.push_back(Exp); 5555 } 5556 // Output all "by ref" declarations. 5557 for (SmallVectorImpl<ValueDecl *>::iterator I = BlockByRefDecls.begin(), 5558 E = BlockByRefDecls.end(); I != E; ++I) { 5559 ValueDecl *ND = (*I); 5560 std::string Name(ND->getNameAsString()); 5561 std::string RecName; 5562 RewriteByRefString(RecName, Name, ND, true); 5563 IdentifierInfo *II = &Context->Idents.get(RecName.c_str() 5564 + sizeof("struct")); 5565 RecordDecl *RD = RecordDecl::Create(*Context, TTK_Struct, TUDecl, 5566 SourceLocation(), SourceLocation(), 5567 II); 5568 assert(RD && "SynthBlockInitExpr(): Can't find RecordDecl"); 5569 QualType castT = Context->getPointerType(Context->getTagDeclType(RD)); 5570 5571 FD = SynthBlockInitFunctionDecl((*I)->getName()); 5572 Exp = new (Context) DeclRefExpr(FD, false, FD->getType(), VK_LValue, 5573 SourceLocation()); 5574 bool isNestedCapturedVar = false; 5575 if (block) 5576 for (BlockDecl::capture_const_iterator ci = block->capture_begin(), 5577 ce = block->capture_end(); ci != ce; ++ci) { 5578 const VarDecl *variable = ci->getVariable(); 5579 if (variable == ND && ci->isNested()) { 5580 assert (ci->isByRef() && 5581 "SynthBlockInitExpr - captured block variable is not byref"); 5582 isNestedCapturedVar = true; 5583 break; 5584 } 5585 } 5586 // captured nested byref variable has its address passed. Do not take 5587 // its address again. 5588 if (!isNestedCapturedVar) 5589 Exp = new (Context) UnaryOperator(Exp, UO_AddrOf, 5590 Context->getPointerType(Exp->getType()), 5591 VK_RValue, OK_Ordinary, SourceLocation()); 5592 Exp = NoTypeInfoCStyleCastExpr(Context, castT, CK_BitCast, Exp); 5593 InitExprs.push_back(Exp); 5594 } 5595 } 5596 if (ImportedBlockDecls.size()) { 5597 // generate BLOCK_HAS_COPY_DISPOSE(have helper funcs) | BLOCK_HAS_DESCRIPTOR 5598 int flag = (BLOCK_HAS_COPY_DISPOSE | BLOCK_HAS_DESCRIPTOR); 5599 unsigned IntSize = 5600 static_cast<unsigned>(Context->getTypeSize(Context->IntTy)); 5601 Expr *FlagExp = IntegerLiteral::Create(*Context, llvm::APInt(IntSize, flag), 5602 Context->IntTy, SourceLocation()); 5603 InitExprs.push_back(FlagExp); 5604 } 5605 NewRep = new (Context) CallExpr(*Context, DRE, InitExprs, 5606 FType, VK_LValue, SourceLocation()); 5607 5608 if (GlobalBlockExpr) { 5609 assert (GlobalConstructionExp == 0 && 5610 "SynthBlockInitExpr - GlobalConstructionExp must be null"); 5611 GlobalConstructionExp = NewRep; 5612 NewRep = DRE; 5613 } 5614 5615 NewRep = new (Context) UnaryOperator(NewRep, UO_AddrOf, 5616 Context->getPointerType(NewRep->getType()), 5617 VK_RValue, OK_Ordinary, SourceLocation()); 5618 NewRep = NoTypeInfoCStyleCastExpr(Context, FType, CK_BitCast, 5619 NewRep); 5620 BlockDeclRefs.clear(); 5621 BlockByRefDecls.clear(); 5622 BlockByRefDeclsPtrSet.clear(); 5623 BlockByCopyDecls.clear(); 5624 BlockByCopyDeclsPtrSet.clear(); 5625 ImportedBlockDecls.clear(); 5626 return NewRep; 5627 } 5628 5629 bool RewriteModernObjC::IsDeclStmtInForeachHeader(DeclStmt *DS) { 5630 if (const ObjCForCollectionStmt * CS = 5631 dyn_cast<ObjCForCollectionStmt>(Stmts.back())) 5632 return CS->getElement() == DS; 5633 return false; 5634 } 5635 5636 //===----------------------------------------------------------------------===// 5637 // Function Body / Expression rewriting 5638 //===----------------------------------------------------------------------===// 5639 5640 Stmt *RewriteModernObjC::RewriteFunctionBodyOrGlobalInitializer(Stmt *S) { 5641 if (isa<SwitchStmt>(S) || isa<WhileStmt>(S) || 5642 isa<DoStmt>(S) || isa<ForStmt>(S)) 5643 Stmts.push_back(S); 5644 else if (isa<ObjCForCollectionStmt>(S)) { 5645 Stmts.push_back(S); 5646 ObjCBcLabelNo.push_back(++BcLabelCount); 5647 } 5648 5649 // Pseudo-object operations and ivar references need special 5650 // treatment because we're going to recursively rewrite them. 5651 if (PseudoObjectExpr *PseudoOp = dyn_cast<PseudoObjectExpr>(S)) { 5652 if (isa<BinaryOperator>(PseudoOp->getSyntacticForm())) { 5653 return RewritePropertyOrImplicitSetter(PseudoOp); 5654 } else { 5655 return RewritePropertyOrImplicitGetter(PseudoOp); 5656 } 5657 } else if (ObjCIvarRefExpr *IvarRefExpr = dyn_cast<ObjCIvarRefExpr>(S)) { 5658 return RewriteObjCIvarRefExpr(IvarRefExpr); 5659 } 5660 else if (isa<OpaqueValueExpr>(S)) 5661 S = cast<OpaqueValueExpr>(S)->getSourceExpr(); 5662 5663 SourceRange OrigStmtRange = S->getSourceRange(); 5664 5665 // Perform a bottom up rewrite of all children. 5666 for (Stmt::child_range CI = S->children(); CI; ++CI) 5667 if (*CI) { 5668 Stmt *childStmt = (*CI); 5669 Stmt *newStmt = RewriteFunctionBodyOrGlobalInitializer(childStmt); 5670 if (newStmt) { 5671 *CI = newStmt; 5672 } 5673 } 5674 5675 if (BlockExpr *BE = dyn_cast<BlockExpr>(S)) { 5676 SmallVector<DeclRefExpr *, 8> InnerBlockDeclRefs; 5677 llvm::SmallPtrSet<const DeclContext *, 8> InnerContexts; 5678 InnerContexts.insert(BE->getBlockDecl()); 5679 ImportedLocalExternalDecls.clear(); 5680 GetInnerBlockDeclRefExprs(BE->getBody(), 5681 InnerBlockDeclRefs, InnerContexts); 5682 // Rewrite the block body in place. 5683 Stmt *SaveCurrentBody = CurrentBody; 5684 CurrentBody = BE->getBody(); 5685 PropParentMap = 0; 5686 // block literal on rhs of a property-dot-sytax assignment 5687 // must be replaced by its synthesize ast so getRewrittenText 5688 // works as expected. In this case, what actually ends up on RHS 5689 // is the blockTranscribed which is the helper function for the 5690 // block literal; as in: self.c = ^() {[ace ARR];}; 5691 bool saveDisableReplaceStmt = DisableReplaceStmt; 5692 DisableReplaceStmt = false; 5693 RewriteFunctionBodyOrGlobalInitializer(BE->getBody()); 5694 DisableReplaceStmt = saveDisableReplaceStmt; 5695 CurrentBody = SaveCurrentBody; 5696 PropParentMap = 0; 5697 ImportedLocalExternalDecls.clear(); 5698 // Now we snarf the rewritten text and stash it away for later use. 5699 std::string Str = Rewrite.getRewrittenText(BE->getSourceRange()); 5700 RewrittenBlockExprs[BE] = Str; 5701 5702 Stmt *blockTranscribed = SynthBlockInitExpr(BE, InnerBlockDeclRefs); 5703 5704 //blockTranscribed->dump(); 5705 ReplaceStmt(S, blockTranscribed); 5706 return blockTranscribed; 5707 } 5708 // Handle specific things. 5709 if (ObjCEncodeExpr *AtEncode = dyn_cast<ObjCEncodeExpr>(S)) 5710 return RewriteAtEncode(AtEncode); 5711 5712 if (ObjCSelectorExpr *AtSelector = dyn_cast<ObjCSelectorExpr>(S)) 5713 return RewriteAtSelector(AtSelector); 5714 5715 if (ObjCStringLiteral *AtString = dyn_cast<ObjCStringLiteral>(S)) 5716 return RewriteObjCStringLiteral(AtString); 5717 5718 if (ObjCBoolLiteralExpr *BoolLitExpr = dyn_cast<ObjCBoolLiteralExpr>(S)) 5719 return RewriteObjCBoolLiteralExpr(BoolLitExpr); 5720 5721 if (ObjCBoxedExpr *BoxedExpr = dyn_cast<ObjCBoxedExpr>(S)) 5722 return RewriteObjCBoxedExpr(BoxedExpr); 5723 5724 if (ObjCArrayLiteral *ArrayLitExpr = dyn_cast<ObjCArrayLiteral>(S)) 5725 return RewriteObjCArrayLiteralExpr(ArrayLitExpr); 5726 5727 if (ObjCDictionaryLiteral *DictionaryLitExpr = 5728 dyn_cast<ObjCDictionaryLiteral>(S)) 5729 return RewriteObjCDictionaryLiteralExpr(DictionaryLitExpr); 5730 5731 if (ObjCMessageExpr *MessExpr = dyn_cast<ObjCMessageExpr>(S)) { 5732 #if 0 5733 // Before we rewrite it, put the original message expression in a comment. 5734 SourceLocation startLoc = MessExpr->getLocStart(); 5735 SourceLocation endLoc = MessExpr->getLocEnd(); 5736 5737 const char *startBuf = SM->getCharacterData(startLoc); 5738 const char *endBuf = SM->getCharacterData(endLoc); 5739 5740 std::string messString; 5741 messString += "// "; 5742 messString.append(startBuf, endBuf-startBuf+1); 5743 messString += "\n"; 5744 5745 // FIXME: Missing definition of 5746 // InsertText(clang::SourceLocation, char const*, unsigned int). 5747 // InsertText(startLoc, messString.c_str(), messString.size()); 5748 // Tried this, but it didn't work either... 5749 // ReplaceText(startLoc, 0, messString.c_str(), messString.size()); 5750 #endif 5751 return RewriteMessageExpr(MessExpr); 5752 } 5753 5754 if (ObjCAutoreleasePoolStmt *StmtAutoRelease = 5755 dyn_cast<ObjCAutoreleasePoolStmt>(S)) { 5756 return RewriteObjCAutoreleasePoolStmt(StmtAutoRelease); 5757 } 5758 5759 if (ObjCAtTryStmt *StmtTry = dyn_cast<ObjCAtTryStmt>(S)) 5760 return RewriteObjCTryStmt(StmtTry); 5761 5762 if (ObjCAtSynchronizedStmt *StmtTry = dyn_cast<ObjCAtSynchronizedStmt>(S)) 5763 return RewriteObjCSynchronizedStmt(StmtTry); 5764 5765 if (ObjCAtThrowStmt *StmtThrow = dyn_cast<ObjCAtThrowStmt>(S)) 5766 return RewriteObjCThrowStmt(StmtThrow); 5767 5768 if (ObjCProtocolExpr *ProtocolExp = dyn_cast<ObjCProtocolExpr>(S)) 5769 return RewriteObjCProtocolExpr(ProtocolExp); 5770 5771 if (ObjCForCollectionStmt *StmtForCollection = 5772 dyn_cast<ObjCForCollectionStmt>(S)) 5773 return RewriteObjCForCollectionStmt(StmtForCollection, 5774 OrigStmtRange.getEnd()); 5775 if (BreakStmt *StmtBreakStmt = 5776 dyn_cast<BreakStmt>(S)) 5777 return RewriteBreakStmt(StmtBreakStmt); 5778 if (ContinueStmt *StmtContinueStmt = 5779 dyn_cast<ContinueStmt>(S)) 5780 return RewriteContinueStmt(StmtContinueStmt); 5781 5782 // Need to check for protocol refs (id <P>, Foo <P> *) in variable decls 5783 // and cast exprs. 5784 if (DeclStmt *DS = dyn_cast<DeclStmt>(S)) { 5785 // FIXME: What we're doing here is modifying the type-specifier that 5786 // precedes the first Decl. In the future the DeclGroup should have 5787 // a separate type-specifier that we can rewrite. 5788 // NOTE: We need to avoid rewriting the DeclStmt if it is within 5789 // the context of an ObjCForCollectionStmt. For example: 5790 // NSArray *someArray; 5791 // for (id <FooProtocol> index in someArray) ; 5792 // This is because RewriteObjCForCollectionStmt() does textual rewriting 5793 // and it depends on the original text locations/positions. 5794 if (Stmts.empty() || !IsDeclStmtInForeachHeader(DS)) 5795 RewriteObjCQualifiedInterfaceTypes(*DS->decl_begin()); 5796 5797 // Blocks rewrite rules. 5798 for (DeclStmt::decl_iterator DI = DS->decl_begin(), DE = DS->decl_end(); 5799 DI != DE; ++DI) { 5800 Decl *SD = *DI; 5801 if (ValueDecl *ND = dyn_cast<ValueDecl>(SD)) { 5802 if (isTopLevelBlockPointerType(ND->getType())) 5803 RewriteBlockPointerDecl(ND); 5804 else if (ND->getType()->isFunctionPointerType()) 5805 CheckFunctionPointerDecl(ND->getType(), ND); 5806 if (VarDecl *VD = dyn_cast<VarDecl>(SD)) { 5807 if (VD->hasAttr<BlocksAttr>()) { 5808 static unsigned uniqueByrefDeclCount = 0; 5809 assert(!BlockByRefDeclNo.count(ND) && 5810 "RewriteFunctionBodyOrGlobalInitializer: Duplicate byref decl"); 5811 BlockByRefDeclNo[ND] = uniqueByrefDeclCount++; 5812 RewriteByRefVar(VD, (DI == DS->decl_begin()), ((DI+1) == DE)); 5813 } 5814 else 5815 RewriteTypeOfDecl(VD); 5816 } 5817 } 5818 if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(SD)) { 5819 if (isTopLevelBlockPointerType(TD->getUnderlyingType())) 5820 RewriteBlockPointerDecl(TD); 5821 else if (TD->getUnderlyingType()->isFunctionPointerType()) 5822 CheckFunctionPointerDecl(TD->getUnderlyingType(), TD); 5823 } 5824 } 5825 } 5826 5827 if (CStyleCastExpr *CE = dyn_cast<CStyleCastExpr>(S)) 5828 RewriteObjCQualifiedInterfaceTypes(CE); 5829 5830 if (isa<SwitchStmt>(S) || isa<WhileStmt>(S) || 5831 isa<DoStmt>(S) || isa<ForStmt>(S)) { 5832 assert(!Stmts.empty() && "Statement stack is empty"); 5833 assert ((isa<SwitchStmt>(Stmts.back()) || isa<WhileStmt>(Stmts.back()) || 5834 isa<DoStmt>(Stmts.back()) || isa<ForStmt>(Stmts.back())) 5835 && "Statement stack mismatch"); 5836 Stmts.pop_back(); 5837 } 5838 // Handle blocks rewriting. 5839 if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(S)) { 5840 ValueDecl *VD = DRE->getDecl(); 5841 if (VD->hasAttr<BlocksAttr>()) 5842 return RewriteBlockDeclRefExpr(DRE); 5843 if (HasLocalVariableExternalStorage(VD)) 5844 return RewriteLocalVariableExternalStorage(DRE); 5845 } 5846 5847 if (CallExpr *CE = dyn_cast<CallExpr>(S)) { 5848 if (CE->getCallee()->getType()->isBlockPointerType()) { 5849 Stmt *BlockCall = SynthesizeBlockCall(CE, CE->getCallee()); 5850 ReplaceStmt(S, BlockCall); 5851 return BlockCall; 5852 } 5853 } 5854 if (CStyleCastExpr *CE = dyn_cast<CStyleCastExpr>(S)) { 5855 RewriteCastExpr(CE); 5856 } 5857 if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(S)) { 5858 RewriteImplicitCastObjCExpr(ICE); 5859 } 5860 #if 0 5861 5862 if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(S)) { 5863 CastExpr *Replacement = new (Context) CastExpr(ICE->getType(), 5864 ICE->getSubExpr(), 5865 SourceLocation()); 5866 // Get the new text. 5867 std::string SStr; 5868 llvm::raw_string_ostream Buf(SStr); 5869 Replacement->printPretty(Buf); 5870 const std::string &Str = Buf.str(); 5871 5872 printf("CAST = %s\n", &Str[0]); 5873 InsertText(ICE->getSubExpr()->getLocStart(), &Str[0], Str.size()); 5874 delete S; 5875 return Replacement; 5876 } 5877 #endif 5878 // Return this stmt unmodified. 5879 return S; 5880 } 5881 5882 void RewriteModernObjC::RewriteRecordBody(RecordDecl *RD) { 5883 for (RecordDecl::field_iterator i = RD->field_begin(), 5884 e = RD->field_end(); i != e; ++i) { 5885 FieldDecl *FD = *i; 5886 if (isTopLevelBlockPointerType(FD->getType())) 5887 RewriteBlockPointerDecl(FD); 5888 if (FD->getType()->isObjCQualifiedIdType() || 5889 FD->getType()->isObjCQualifiedInterfaceType()) 5890 RewriteObjCQualifiedInterfaceTypes(FD); 5891 } 5892 } 5893 5894 /// HandleDeclInMainFile - This is called for each top-level decl defined in the 5895 /// main file of the input. 5896 void RewriteModernObjC::HandleDeclInMainFile(Decl *D) { 5897 switch (D->getKind()) { 5898 case Decl::Function: { 5899 FunctionDecl *FD = cast<FunctionDecl>(D); 5900 if (FD->isOverloadedOperator()) 5901 return; 5902 5903 // Since function prototypes don't have ParmDecl's, we check the function 5904 // prototype. This enables us to rewrite function declarations and 5905 // definitions using the same code. 5906 RewriteBlocksInFunctionProtoType(FD->getType(), FD); 5907 5908 if (!FD->isThisDeclarationADefinition()) 5909 break; 5910 5911 // FIXME: If this should support Obj-C++, support CXXTryStmt 5912 if (CompoundStmt *Body = dyn_cast_or_null<CompoundStmt>(FD->getBody())) { 5913 CurFunctionDef = FD; 5914 CurrentBody = Body; 5915 Body = 5916 cast_or_null<CompoundStmt>(RewriteFunctionBodyOrGlobalInitializer(Body)); 5917 FD->setBody(Body); 5918 CurrentBody = 0; 5919 if (PropParentMap) { 5920 delete PropParentMap; 5921 PropParentMap = 0; 5922 } 5923 // This synthesizes and inserts the block "impl" struct, invoke function, 5924 // and any copy/dispose helper functions. 5925 InsertBlockLiteralsWithinFunction(FD); 5926 RewriteLineDirective(D); 5927 CurFunctionDef = 0; 5928 } 5929 break; 5930 } 5931 case Decl::ObjCMethod: { 5932 ObjCMethodDecl *MD = cast<ObjCMethodDecl>(D); 5933 if (CompoundStmt *Body = MD->getCompoundBody()) { 5934 CurMethodDef = MD; 5935 CurrentBody = Body; 5936 Body = 5937 cast_or_null<CompoundStmt>(RewriteFunctionBodyOrGlobalInitializer(Body)); 5938 MD->setBody(Body); 5939 CurrentBody = 0; 5940 if (PropParentMap) { 5941 delete PropParentMap; 5942 PropParentMap = 0; 5943 } 5944 InsertBlockLiteralsWithinMethod(MD); 5945 RewriteLineDirective(D); 5946 CurMethodDef = 0; 5947 } 5948 break; 5949 } 5950 case Decl::ObjCImplementation: { 5951 ObjCImplementationDecl *CI = cast<ObjCImplementationDecl>(D); 5952 ClassImplementation.push_back(CI); 5953 break; 5954 } 5955 case Decl::ObjCCategoryImpl: { 5956 ObjCCategoryImplDecl *CI = cast<ObjCCategoryImplDecl>(D); 5957 CategoryImplementation.push_back(CI); 5958 break; 5959 } 5960 case Decl::Var: { 5961 VarDecl *VD = cast<VarDecl>(D); 5962 RewriteObjCQualifiedInterfaceTypes(VD); 5963 if (isTopLevelBlockPointerType(VD->getType())) 5964 RewriteBlockPointerDecl(VD); 5965 else if (VD->getType()->isFunctionPointerType()) { 5966 CheckFunctionPointerDecl(VD->getType(), VD); 5967 if (VD->getInit()) { 5968 if (CStyleCastExpr *CE = dyn_cast<CStyleCastExpr>(VD->getInit())) { 5969 RewriteCastExpr(CE); 5970 } 5971 } 5972 } else if (VD->getType()->isRecordType()) { 5973 RecordDecl *RD = VD->getType()->getAs<RecordType>()->getDecl(); 5974 if (RD->isCompleteDefinition()) 5975 RewriteRecordBody(RD); 5976 } 5977 if (VD->getInit()) { 5978 GlobalVarDecl = VD; 5979 CurrentBody = VD->getInit(); 5980 RewriteFunctionBodyOrGlobalInitializer(VD->getInit()); 5981 CurrentBody = 0; 5982 if (PropParentMap) { 5983 delete PropParentMap; 5984 PropParentMap = 0; 5985 } 5986 SynthesizeBlockLiterals(VD->getTypeSpecStartLoc(), VD->getName()); 5987 GlobalVarDecl = 0; 5988 5989 // This is needed for blocks. 5990 if (CStyleCastExpr *CE = dyn_cast<CStyleCastExpr>(VD->getInit())) { 5991 RewriteCastExpr(CE); 5992 } 5993 } 5994 break; 5995 } 5996 case Decl::TypeAlias: 5997 case Decl::Typedef: { 5998 if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D)) { 5999 if (isTopLevelBlockPointerType(TD->getUnderlyingType())) 6000 RewriteBlockPointerDecl(TD); 6001 else if (TD->getUnderlyingType()->isFunctionPointerType()) 6002 CheckFunctionPointerDecl(TD->getUnderlyingType(), TD); 6003 else 6004 RewriteObjCQualifiedInterfaceTypes(TD); 6005 } 6006 break; 6007 } 6008 case Decl::CXXRecord: 6009 case Decl::Record: { 6010 RecordDecl *RD = cast<RecordDecl>(D); 6011 if (RD->isCompleteDefinition()) 6012 RewriteRecordBody(RD); 6013 break; 6014 } 6015 default: 6016 break; 6017 } 6018 // Nothing yet. 6019 } 6020 6021 /// Write_ProtocolExprReferencedMetadata - This routine writer out the 6022 /// protocol reference symbols in the for of: 6023 /// struct _protocol_t *PROTOCOL_REF = &PROTOCOL_METADATA. 6024 static void Write_ProtocolExprReferencedMetadata(ASTContext *Context, 6025 ObjCProtocolDecl *PDecl, 6026 std::string &Result) { 6027 // Also output .objc_protorefs$B section and its meta-data. 6028 if (Context->getLangOpts().MicrosoftExt) 6029 Result += "static "; 6030 Result += "struct _protocol_t *"; 6031 Result += "_OBJC_PROTOCOL_REFERENCE_$_"; 6032 Result += PDecl->getNameAsString(); 6033 Result += " = &"; 6034 Result += "_OBJC_PROTOCOL_"; Result += PDecl->getNameAsString(); 6035 Result += ";\n"; 6036 } 6037 6038 void RewriteModernObjC::HandleTranslationUnit(ASTContext &C) { 6039 if (Diags.hasErrorOccurred()) 6040 return; 6041 6042 RewriteInclude(); 6043 6044 for (unsigned i = 0, e = FunctionDefinitionsSeen.size(); i < e; i++) { 6045 // translation of function bodies were postponed untill all class and 6046 // their extensions and implementations are seen. This is because, we 6047 // cannot build grouping structs for bitfields untill they are all seen. 6048 FunctionDecl *FDecl = FunctionDefinitionsSeen[i]; 6049 HandleTopLevelSingleDecl(FDecl); 6050 } 6051 6052 // Here's a great place to add any extra declarations that may be needed. 6053 // Write out meta data for each @protocol(<expr>). 6054 for (llvm::SmallPtrSet<ObjCProtocolDecl *,8>::iterator I = ProtocolExprDecls.begin(), 6055 E = ProtocolExprDecls.end(); I != E; ++I) { 6056 RewriteObjCProtocolMetaData(*I, Preamble); 6057 Write_ProtocolExprReferencedMetadata(Context, (*I), Preamble); 6058 } 6059 6060 InsertText(SM->getLocForStartOfFile(MainFileID), Preamble, false); 6061 6062 if (ClassImplementation.size() || CategoryImplementation.size()) 6063 RewriteImplementations(); 6064 6065 for (unsigned i = 0, e = ObjCInterfacesSeen.size(); i < e; i++) { 6066 ObjCInterfaceDecl *CDecl = ObjCInterfacesSeen[i]; 6067 // Write struct declaration for the class matching its ivar declarations. 6068 // Note that for modern abi, this is postponed until the end of TU 6069 // because class extensions and the implementation might declare their own 6070 // private ivars. 6071 RewriteInterfaceDecl(CDecl); 6072 } 6073 6074 // Get the buffer corresponding to MainFileID. If we haven't changed it, then 6075 // we are done. 6076 if (const RewriteBuffer *RewriteBuf = 6077 Rewrite.getRewriteBufferFor(MainFileID)) { 6078 //printf("Changed:\n"); 6079 *OutFile << std::string(RewriteBuf->begin(), RewriteBuf->end()); 6080 } else { 6081 llvm::errs() << "No changes\n"; 6082 } 6083 6084 if (ClassImplementation.size() || CategoryImplementation.size() || 6085 ProtocolExprDecls.size()) { 6086 // Rewrite Objective-c meta data* 6087 std::string ResultStr; 6088 RewriteMetaDataIntoBuffer(ResultStr); 6089 // Emit metadata. 6090 *OutFile << ResultStr; 6091 } 6092 // Emit ImageInfo; 6093 { 6094 std::string ResultStr; 6095 WriteImageInfo(ResultStr); 6096 *OutFile << ResultStr; 6097 } 6098 OutFile->flush(); 6099 } 6100 6101 void RewriteModernObjC::Initialize(ASTContext &context) { 6102 InitializeCommon(context); 6103 6104 Preamble += "#ifndef __OBJC2__\n"; 6105 Preamble += "#define __OBJC2__\n"; 6106 Preamble += "#endif\n"; 6107 6108 // declaring objc_selector outside the parameter list removes a silly 6109 // scope related warning... 6110 if (IsHeader) 6111 Preamble = "#pragma once\n"; 6112 Preamble += "struct objc_selector; struct objc_class;\n"; 6113 Preamble += "struct __rw_objc_super { \n\tstruct objc_object *object; "; 6114 Preamble += "\n\tstruct objc_object *superClass; "; 6115 // Add a constructor for creating temporary objects. 6116 Preamble += "\n\t__rw_objc_super(struct objc_object *o, struct objc_object *s) "; 6117 Preamble += ": object(o), superClass(s) {} "; 6118 Preamble += "\n};\n"; 6119 6120 if (LangOpts.MicrosoftExt) { 6121 // Define all sections using syntax that makes sense. 6122 // These are currently generated. 6123 Preamble += "\n#pragma section(\".objc_classlist$B\", long, read, write)\n"; 6124 Preamble += "#pragma section(\".objc_catlist$B\", long, read, write)\n"; 6125 Preamble += "#pragma section(\".objc_imageinfo$B\", long, read, write)\n"; 6126 Preamble += "#pragma section(\".objc_nlclslist$B\", long, read, write)\n"; 6127 Preamble += "#pragma section(\".objc_nlcatlist$B\", long, read, write)\n"; 6128 // These are generated but not necessary for functionality. 6129 Preamble += "#pragma section(\".cat_cls_meth$B\", long, read, write)\n"; 6130 Preamble += "#pragma section(\".inst_meth$B\", long, read, write)\n"; 6131 Preamble += "#pragma section(\".cls_meth$B\", long, read, write)\n"; 6132 Preamble += "#pragma section(\".objc_ivar$B\", long, read, write)\n"; 6133 6134 // These need be generated for performance. Currently they are not, 6135 // using API calls instead. 6136 Preamble += "#pragma section(\".objc_selrefs$B\", long, read, write)\n"; 6137 Preamble += "#pragma section(\".objc_classrefs$B\", long, read, write)\n"; 6138 Preamble += "#pragma section(\".objc_superrefs$B\", long, read, write)\n"; 6139 6140 } 6141 Preamble += "#ifndef _REWRITER_typedef_Protocol\n"; 6142 Preamble += "typedef struct objc_object Protocol;\n"; 6143 Preamble += "#define _REWRITER_typedef_Protocol\n"; 6144 Preamble += "#endif\n"; 6145 if (LangOpts.MicrosoftExt) { 6146 Preamble += "#define __OBJC_RW_DLLIMPORT extern \"C\" __declspec(dllimport)\n"; 6147 Preamble += "#define __OBJC_RW_STATICIMPORT extern \"C\"\n"; 6148 } 6149 else 6150 Preamble += "#define __OBJC_RW_DLLIMPORT extern\n"; 6151 6152 Preamble += "__OBJC_RW_DLLIMPORT void objc_msgSend(void);\n"; 6153 Preamble += "__OBJC_RW_DLLIMPORT void objc_msgSendSuper(void);\n"; 6154 Preamble += "__OBJC_RW_DLLIMPORT void objc_msgSend_stret(void);\n"; 6155 Preamble += "__OBJC_RW_DLLIMPORT void objc_msgSendSuper_stret(void);\n"; 6156 Preamble += "__OBJC_RW_DLLIMPORT void objc_msgSend_fpret(void);\n"; 6157 6158 Preamble += "__OBJC_RW_DLLIMPORT struct objc_class *objc_getClass"; 6159 Preamble += "(const char *);\n"; 6160 Preamble += "__OBJC_RW_DLLIMPORT struct objc_class *class_getSuperclass"; 6161 Preamble += "(struct objc_class *);\n"; 6162 Preamble += "__OBJC_RW_DLLIMPORT struct objc_class *objc_getMetaClass"; 6163 Preamble += "(const char *);\n"; 6164 Preamble += "__OBJC_RW_DLLIMPORT void objc_exception_throw( struct objc_object *);\n"; 6165 // @synchronized hooks. 6166 Preamble += "__OBJC_RW_DLLIMPORT int objc_sync_enter( struct objc_object *);\n"; 6167 Preamble += "__OBJC_RW_DLLIMPORT int objc_sync_exit( struct objc_object *);\n"; 6168 Preamble += "__OBJC_RW_DLLIMPORT Protocol *objc_getProtocol(const char *);\n"; 6169 Preamble += "#ifndef __FASTENUMERATIONSTATE\n"; 6170 Preamble += "struct __objcFastEnumerationState {\n\t"; 6171 Preamble += "unsigned long state;\n\t"; 6172 Preamble += "void **itemsPtr;\n\t"; 6173 Preamble += "unsigned long *mutationsPtr;\n\t"; 6174 Preamble += "unsigned long extra[5];\n};\n"; 6175 Preamble += "__OBJC_RW_DLLIMPORT void objc_enumerationMutation(struct objc_object *);\n"; 6176 Preamble += "#define __FASTENUMERATIONSTATE\n"; 6177 Preamble += "#endif\n"; 6178 Preamble += "#ifndef __NSCONSTANTSTRINGIMPL\n"; 6179 Preamble += "struct __NSConstantStringImpl {\n"; 6180 Preamble += " int *isa;\n"; 6181 Preamble += " int flags;\n"; 6182 Preamble += " char *str;\n"; 6183 Preamble += " long length;\n"; 6184 Preamble += "};\n"; 6185 Preamble += "#ifdef CF_EXPORT_CONSTANT_STRING\n"; 6186 Preamble += "extern \"C\" __declspec(dllexport) int __CFConstantStringClassReference[];\n"; 6187 Preamble += "#else\n"; 6188 Preamble += "__OBJC_RW_DLLIMPORT int __CFConstantStringClassReference[];\n"; 6189 Preamble += "#endif\n"; 6190 Preamble += "#define __NSCONSTANTSTRINGIMPL\n"; 6191 Preamble += "#endif\n"; 6192 // Blocks preamble. 6193 Preamble += "#ifndef BLOCK_IMPL\n"; 6194 Preamble += "#define BLOCK_IMPL\n"; 6195 Preamble += "struct __block_impl {\n"; 6196 Preamble += " void *isa;\n"; 6197 Preamble += " int Flags;\n"; 6198 Preamble += " int Reserved;\n"; 6199 Preamble += " void *FuncPtr;\n"; 6200 Preamble += "};\n"; 6201 Preamble += "// Runtime copy/destroy helper functions (from Block_private.h)\n"; 6202 Preamble += "#ifdef __OBJC_EXPORT_BLOCKS\n"; 6203 Preamble += "extern \"C\" __declspec(dllexport) " 6204 "void _Block_object_assign(void *, const void *, const int);\n"; 6205 Preamble += "extern \"C\" __declspec(dllexport) void _Block_object_dispose(const void *, const int);\n"; 6206 Preamble += "extern \"C\" __declspec(dllexport) void *_NSConcreteGlobalBlock[32];\n"; 6207 Preamble += "extern \"C\" __declspec(dllexport) void *_NSConcreteStackBlock[32];\n"; 6208 Preamble += "#else\n"; 6209 Preamble += "__OBJC_RW_DLLIMPORT void _Block_object_assign(void *, const void *, const int);\n"; 6210 Preamble += "__OBJC_RW_DLLIMPORT void _Block_object_dispose(const void *, const int);\n"; 6211 Preamble += "__OBJC_RW_DLLIMPORT void *_NSConcreteGlobalBlock[32];\n"; 6212 Preamble += "__OBJC_RW_DLLIMPORT void *_NSConcreteStackBlock[32];\n"; 6213 Preamble += "#endif\n"; 6214 Preamble += "#endif\n"; 6215 if (LangOpts.MicrosoftExt) { 6216 Preamble += "#undef __OBJC_RW_DLLIMPORT\n"; 6217 Preamble += "#undef __OBJC_RW_STATICIMPORT\n"; 6218 Preamble += "#ifndef KEEP_ATTRIBUTES\n"; // We use this for clang tests. 6219 Preamble += "#define __attribute__(X)\n"; 6220 Preamble += "#endif\n"; 6221 Preamble += "#ifndef __weak\n"; 6222 Preamble += "#define __weak\n"; 6223 Preamble += "#endif\n"; 6224 Preamble += "#ifndef __block\n"; 6225 Preamble += "#define __block\n"; 6226 Preamble += "#endif\n"; 6227 } 6228 else { 6229 Preamble += "#define __block\n"; 6230 Preamble += "#define __weak\n"; 6231 } 6232 6233 // Declarations required for modern objective-c array and dictionary literals. 6234 Preamble += "\n#include <stdarg.h>\n"; 6235 Preamble += "struct __NSContainer_literal {\n"; 6236 Preamble += " void * *arr;\n"; 6237 Preamble += " __NSContainer_literal (unsigned int count, ...) {\n"; 6238 Preamble += "\tva_list marker;\n"; 6239 Preamble += "\tva_start(marker, count);\n"; 6240 Preamble += "\tarr = new void *[count];\n"; 6241 Preamble += "\tfor (unsigned i = 0; i < count; i++)\n"; 6242 Preamble += "\t arr[i] = va_arg(marker, void *);\n"; 6243 Preamble += "\tva_end( marker );\n"; 6244 Preamble += " };\n"; 6245 Preamble += " ~__NSContainer_literal() {\n"; 6246 Preamble += "\tdelete[] arr;\n"; 6247 Preamble += " }\n"; 6248 Preamble += "};\n"; 6249 6250 // Declaration required for implementation of @autoreleasepool statement. 6251 Preamble += "extern \"C\" __declspec(dllimport) void * objc_autoreleasePoolPush(void);\n"; 6252 Preamble += "extern \"C\" __declspec(dllimport) void objc_autoreleasePoolPop(void *);\n\n"; 6253 Preamble += "struct __AtAutoreleasePool {\n"; 6254 Preamble += " __AtAutoreleasePool() {atautoreleasepoolobj = objc_autoreleasePoolPush();}\n"; 6255 Preamble += " ~__AtAutoreleasePool() {objc_autoreleasePoolPop(atautoreleasepoolobj);}\n"; 6256 Preamble += " void * atautoreleasepoolobj;\n"; 6257 Preamble += "};\n"; 6258 6259 // NOTE! Windows uses LLP64 for 64bit mode. So, cast pointer to long long 6260 // as this avoids warning in any 64bit/32bit compilation model. 6261 Preamble += "\n#define __OFFSETOFIVAR__(TYPE, MEMBER) ((long long) &((TYPE *)0)->MEMBER)\n"; 6262 } 6263 6264 /// RewriteIvarOffsetComputation - This rutine synthesizes computation of 6265 /// ivar offset. 6266 void RewriteModernObjC::RewriteIvarOffsetComputation(ObjCIvarDecl *ivar, 6267 std::string &Result) { 6268 Result += "__OFFSETOFIVAR__(struct "; 6269 Result += ivar->getContainingInterface()->getNameAsString(); 6270 if (LangOpts.MicrosoftExt) 6271 Result += "_IMPL"; 6272 Result += ", "; 6273 if (ivar->isBitField()) 6274 ObjCIvarBitfieldGroupDecl(ivar, Result); 6275 else 6276 Result += ivar->getNameAsString(); 6277 Result += ")"; 6278 } 6279 6280 /// WriteModernMetadataDeclarations - Writes out metadata declarations for modern ABI. 6281 /// struct _prop_t { 6282 /// const char *name; 6283 /// char *attributes; 6284 /// } 6285 6286 /// struct _prop_list_t { 6287 /// uint32_t entsize; // sizeof(struct _prop_t) 6288 /// uint32_t count_of_properties; 6289 /// struct _prop_t prop_list[count_of_properties]; 6290 /// } 6291 6292 /// struct _protocol_t; 6293 6294 /// struct _protocol_list_t { 6295 /// long protocol_count; // Note, this is 32/64 bit 6296 /// struct _protocol_t * protocol_list[protocol_count]; 6297 /// } 6298 6299 /// struct _objc_method { 6300 /// SEL _cmd; 6301 /// const char *method_type; 6302 /// char *_imp; 6303 /// } 6304 6305 /// struct _method_list_t { 6306 /// uint32_t entsize; // sizeof(struct _objc_method) 6307 /// uint32_t method_count; 6308 /// struct _objc_method method_list[method_count]; 6309 /// } 6310 6311 /// struct _protocol_t { 6312 /// id isa; // NULL 6313 /// const char *protocol_name; 6314 /// const struct _protocol_list_t * protocol_list; // super protocols 6315 /// const struct method_list_t *instance_methods; 6316 /// const struct method_list_t *class_methods; 6317 /// const struct method_list_t *optionalInstanceMethods; 6318 /// const struct method_list_t *optionalClassMethods; 6319 /// const struct _prop_list_t * properties; 6320 /// const uint32_t size; // sizeof(struct _protocol_t) 6321 /// const uint32_t flags; // = 0 6322 /// const char ** extendedMethodTypes; 6323 /// } 6324 6325 /// struct _ivar_t { 6326 /// unsigned long int *offset; // pointer to ivar offset location 6327 /// const char *name; 6328 /// const char *type; 6329 /// uint32_t alignment; 6330 /// uint32_t size; 6331 /// } 6332 6333 /// struct _ivar_list_t { 6334 /// uint32 entsize; // sizeof(struct _ivar_t) 6335 /// uint32 count; 6336 /// struct _ivar_t list[count]; 6337 /// } 6338 6339 /// struct _class_ro_t { 6340 /// uint32_t flags; 6341 /// uint32_t instanceStart; 6342 /// uint32_t instanceSize; 6343 /// uint32_t reserved; // only when building for 64bit targets 6344 /// const uint8_t *ivarLayout; 6345 /// const char *name; 6346 /// const struct _method_list_t *baseMethods; 6347 /// const struct _protocol_list_t *baseProtocols; 6348 /// const struct _ivar_list_t *ivars; 6349 /// const uint8_t *weakIvarLayout; 6350 /// const struct _prop_list_t *properties; 6351 /// } 6352 6353 /// struct _class_t { 6354 /// struct _class_t *isa; 6355 /// struct _class_t *superclass; 6356 /// void *cache; 6357 /// IMP *vtable; 6358 /// struct _class_ro_t *ro; 6359 /// } 6360 6361 /// struct _category_t { 6362 /// const char *name; 6363 /// struct _class_t *cls; 6364 /// const struct _method_list_t *instance_methods; 6365 /// const struct _method_list_t *class_methods; 6366 /// const struct _protocol_list_t *protocols; 6367 /// const struct _prop_list_t *properties; 6368 /// } 6369 6370 /// MessageRefTy - LLVM for: 6371 /// struct _message_ref_t { 6372 /// IMP messenger; 6373 /// SEL name; 6374 /// }; 6375 6376 /// SuperMessageRefTy - LLVM for: 6377 /// struct _super_message_ref_t { 6378 /// SUPER_IMP messenger; 6379 /// SEL name; 6380 /// }; 6381 6382 static void WriteModernMetadataDeclarations(ASTContext *Context, std::string &Result) { 6383 static bool meta_data_declared = false; 6384 if (meta_data_declared) 6385 return; 6386 6387 Result += "\nstruct _prop_t {\n"; 6388 Result += "\tconst char *name;\n"; 6389 Result += "\tconst char *attributes;\n"; 6390 Result += "};\n"; 6391 6392 Result += "\nstruct _protocol_t;\n"; 6393 6394 Result += "\nstruct _objc_method {\n"; 6395 Result += "\tstruct objc_selector * _cmd;\n"; 6396 Result += "\tconst char *method_type;\n"; 6397 Result += "\tvoid *_imp;\n"; 6398 Result += "};\n"; 6399 6400 Result += "\nstruct _protocol_t {\n"; 6401 Result += "\tvoid * isa; // NULL\n"; 6402 Result += "\tconst char *protocol_name;\n"; 6403 Result += "\tconst struct _protocol_list_t * protocol_list; // super protocols\n"; 6404 Result += "\tconst struct method_list_t *instance_methods;\n"; 6405 Result += "\tconst struct method_list_t *class_methods;\n"; 6406 Result += "\tconst struct method_list_t *optionalInstanceMethods;\n"; 6407 Result += "\tconst struct method_list_t *optionalClassMethods;\n"; 6408 Result += "\tconst struct _prop_list_t * properties;\n"; 6409 Result += "\tconst unsigned int size; // sizeof(struct _protocol_t)\n"; 6410 Result += "\tconst unsigned int flags; // = 0\n"; 6411 Result += "\tconst char ** extendedMethodTypes;\n"; 6412 Result += "};\n"; 6413 6414 Result += "\nstruct _ivar_t {\n"; 6415 Result += "\tunsigned long int *offset; // pointer to ivar offset location\n"; 6416 Result += "\tconst char *name;\n"; 6417 Result += "\tconst char *type;\n"; 6418 Result += "\tunsigned int alignment;\n"; 6419 Result += "\tunsigned int size;\n"; 6420 Result += "};\n"; 6421 6422 Result += "\nstruct _class_ro_t {\n"; 6423 Result += "\tunsigned int flags;\n"; 6424 Result += "\tunsigned int instanceStart;\n"; 6425 Result += "\tunsigned int instanceSize;\n"; 6426 const llvm::Triple &Triple(Context->getTargetInfo().getTriple()); 6427 if (Triple.getArch() == llvm::Triple::x86_64) 6428 Result += "\tunsigned int reserved;\n"; 6429 Result += "\tconst unsigned char *ivarLayout;\n"; 6430 Result += "\tconst char *name;\n"; 6431 Result += "\tconst struct _method_list_t *baseMethods;\n"; 6432 Result += "\tconst struct _objc_protocol_list *baseProtocols;\n"; 6433 Result += "\tconst struct _ivar_list_t *ivars;\n"; 6434 Result += "\tconst unsigned char *weakIvarLayout;\n"; 6435 Result += "\tconst struct _prop_list_t *properties;\n"; 6436 Result += "};\n"; 6437 6438 Result += "\nstruct _class_t {\n"; 6439 Result += "\tstruct _class_t *isa;\n"; 6440 Result += "\tstruct _class_t *superclass;\n"; 6441 Result += "\tvoid *cache;\n"; 6442 Result += "\tvoid *vtable;\n"; 6443 Result += "\tstruct _class_ro_t *ro;\n"; 6444 Result += "};\n"; 6445 6446 Result += "\nstruct _category_t {\n"; 6447 Result += "\tconst char *name;\n"; 6448 Result += "\tstruct _class_t *cls;\n"; 6449 Result += "\tconst struct _method_list_t *instance_methods;\n"; 6450 Result += "\tconst struct _method_list_t *class_methods;\n"; 6451 Result += "\tconst struct _protocol_list_t *protocols;\n"; 6452 Result += "\tconst struct _prop_list_t *properties;\n"; 6453 Result += "};\n"; 6454 6455 Result += "extern \"C\" __declspec(dllimport) struct objc_cache _objc_empty_cache;\n"; 6456 Result += "#pragma warning(disable:4273)\n"; 6457 meta_data_declared = true; 6458 } 6459 6460 static void Write_protocol_list_t_TypeDecl(std::string &Result, 6461 long super_protocol_count) { 6462 Result += "struct /*_protocol_list_t*/"; Result += " {\n"; 6463 Result += "\tlong protocol_count; // Note, this is 32/64 bit\n"; 6464 Result += "\tstruct _protocol_t *super_protocols["; 6465 Result += utostr(super_protocol_count); Result += "];\n"; 6466 Result += "}"; 6467 } 6468 6469 static void Write_method_list_t_TypeDecl(std::string &Result, 6470 unsigned int method_count) { 6471 Result += "struct /*_method_list_t*/"; Result += " {\n"; 6472 Result += "\tunsigned int entsize; // sizeof(struct _objc_method)\n"; 6473 Result += "\tunsigned int method_count;\n"; 6474 Result += "\tstruct _objc_method method_list["; 6475 Result += utostr(method_count); Result += "];\n"; 6476 Result += "}"; 6477 } 6478 6479 static void Write__prop_list_t_TypeDecl(std::string &Result, 6480 unsigned int property_count) { 6481 Result += "struct /*_prop_list_t*/"; Result += " {\n"; 6482 Result += "\tunsigned int entsize; // sizeof(struct _prop_t)\n"; 6483 Result += "\tunsigned int count_of_properties;\n"; 6484 Result += "\tstruct _prop_t prop_list["; 6485 Result += utostr(property_count); Result += "];\n"; 6486 Result += "}"; 6487 } 6488 6489 static void Write__ivar_list_t_TypeDecl(std::string &Result, 6490 unsigned int ivar_count) { 6491 Result += "struct /*_ivar_list_t*/"; Result += " {\n"; 6492 Result += "\tunsigned int entsize; // sizeof(struct _prop_t)\n"; 6493 Result += "\tunsigned int count;\n"; 6494 Result += "\tstruct _ivar_t ivar_list["; 6495 Result += utostr(ivar_count); Result += "];\n"; 6496 Result += "}"; 6497 } 6498 6499 static void Write_protocol_list_initializer(ASTContext *Context, std::string &Result, 6500 ArrayRef<ObjCProtocolDecl *> SuperProtocols, 6501 StringRef VarName, 6502 StringRef ProtocolName) { 6503 if (SuperProtocols.size() > 0) { 6504 Result += "\nstatic "; 6505 Write_protocol_list_t_TypeDecl(Result, SuperProtocols.size()); 6506 Result += " "; Result += VarName; 6507 Result += ProtocolName; 6508 Result += " __attribute__ ((used, section (\"__DATA,__objc_const\"))) = {\n"; 6509 Result += "\t"; Result += utostr(SuperProtocols.size()); Result += ",\n"; 6510 for (unsigned i = 0, e = SuperProtocols.size(); i < e; i++) { 6511 ObjCProtocolDecl *SuperPD = SuperProtocols[i]; 6512 Result += "\t&"; Result += "_OBJC_PROTOCOL_"; 6513 Result += SuperPD->getNameAsString(); 6514 if (i == e-1) 6515 Result += "\n};\n"; 6516 else 6517 Result += ",\n"; 6518 } 6519 } 6520 } 6521 6522 static void Write_method_list_t_initializer(RewriteModernObjC &RewriteObj, 6523 ASTContext *Context, std::string &Result, 6524 ArrayRef<ObjCMethodDecl *> Methods, 6525 StringRef VarName, 6526 StringRef TopLevelDeclName, 6527 bool MethodImpl) { 6528 if (Methods.size() > 0) { 6529 Result += "\nstatic "; 6530 Write_method_list_t_TypeDecl(Result, Methods.size()); 6531 Result += " "; Result += VarName; 6532 Result += TopLevelDeclName; 6533 Result += " __attribute__ ((used, section (\"__DATA,__objc_const\"))) = {\n"; 6534 Result += "\t"; Result += "sizeof(_objc_method)"; Result += ",\n"; 6535 Result += "\t"; Result += utostr(Methods.size()); Result += ",\n"; 6536 for (unsigned i = 0, e = Methods.size(); i < e; i++) { 6537 ObjCMethodDecl *MD = Methods[i]; 6538 if (i == 0) 6539 Result += "\t{{(struct objc_selector *)\""; 6540 else 6541 Result += "\t{(struct objc_selector *)\""; 6542 Result += (MD)->getSelector().getAsString(); Result += "\""; 6543 Result += ", "; 6544 std::string MethodTypeString; 6545 Context->getObjCEncodingForMethodDecl(MD, MethodTypeString); 6546 Result += "\""; Result += MethodTypeString; Result += "\""; 6547 Result += ", "; 6548 if (!MethodImpl) 6549 Result += "0"; 6550 else { 6551 Result += "(void *)"; 6552 Result += RewriteObj.MethodInternalNames[MD]; 6553 } 6554 if (i == e-1) 6555 Result += "}}\n"; 6556 else 6557 Result += "},\n"; 6558 } 6559 Result += "};\n"; 6560 } 6561 } 6562 6563 static void Write_prop_list_t_initializer(RewriteModernObjC &RewriteObj, 6564 ASTContext *Context, std::string &Result, 6565 ArrayRef<ObjCPropertyDecl *> Properties, 6566 const Decl *Container, 6567 StringRef VarName, 6568 StringRef ProtocolName) { 6569 if (Properties.size() > 0) { 6570 Result += "\nstatic "; 6571 Write__prop_list_t_TypeDecl(Result, Properties.size()); 6572 Result += " "; Result += VarName; 6573 Result += ProtocolName; 6574 Result += " __attribute__ ((used, section (\"__DATA,__objc_const\"))) = {\n"; 6575 Result += "\t"; Result += "sizeof(_prop_t)"; Result += ",\n"; 6576 Result += "\t"; Result += utostr(Properties.size()); Result += ",\n"; 6577 for (unsigned i = 0, e = Properties.size(); i < e; i++) { 6578 ObjCPropertyDecl *PropDecl = Properties[i]; 6579 if (i == 0) 6580 Result += "\t{{\""; 6581 else 6582 Result += "\t{\""; 6583 Result += PropDecl->getName(); Result += "\","; 6584 std::string PropertyTypeString, QuotePropertyTypeString; 6585 Context->getObjCEncodingForPropertyDecl(PropDecl, Container, PropertyTypeString); 6586 RewriteObj.QuoteDoublequotes(PropertyTypeString, QuotePropertyTypeString); 6587 Result += "\""; Result += QuotePropertyTypeString; Result += "\""; 6588 if (i == e-1) 6589 Result += "}}\n"; 6590 else 6591 Result += "},\n"; 6592 } 6593 Result += "};\n"; 6594 } 6595 } 6596 6597 // Metadata flags 6598 enum MetaDataDlags { 6599 CLS = 0x0, 6600 CLS_META = 0x1, 6601 CLS_ROOT = 0x2, 6602 OBJC2_CLS_HIDDEN = 0x10, 6603 CLS_EXCEPTION = 0x20, 6604 6605 /// (Obsolete) ARC-specific: this class has a .release_ivars method 6606 CLS_HAS_IVAR_RELEASER = 0x40, 6607 /// class was compiled with -fobjc-arr 6608 CLS_COMPILED_BY_ARC = 0x80 // (1<<7) 6609 }; 6610 6611 static void Write__class_ro_t_initializer(ASTContext *Context, std::string &Result, 6612 unsigned int flags, 6613 const std::string &InstanceStart, 6614 const std::string &InstanceSize, 6615 ArrayRef<ObjCMethodDecl *>baseMethods, 6616 ArrayRef<ObjCProtocolDecl *>baseProtocols, 6617 ArrayRef<ObjCIvarDecl *>ivars, 6618 ArrayRef<ObjCPropertyDecl *>Properties, 6619 StringRef VarName, 6620 StringRef ClassName) { 6621 Result += "\nstatic struct _class_ro_t "; 6622 Result += VarName; Result += ClassName; 6623 Result += " __attribute__ ((used, section (\"__DATA,__objc_const\"))) = {\n"; 6624 Result += "\t"; 6625 Result += llvm::utostr(flags); Result += ", "; 6626 Result += InstanceStart; Result += ", "; 6627 Result += InstanceSize; Result += ", \n"; 6628 Result += "\t"; 6629 const llvm::Triple &Triple(Context->getTargetInfo().getTriple()); 6630 if (Triple.getArch() == llvm::Triple::x86_64) 6631 // uint32_t const reserved; // only when building for 64bit targets 6632 Result += "(unsigned int)0, \n\t"; 6633 // const uint8_t * const ivarLayout; 6634 Result += "0, \n\t"; 6635 Result += "\""; Result += ClassName; Result += "\",\n\t"; 6636 bool metaclass = ((flags & CLS_META) != 0); 6637 if (baseMethods.size() > 0) { 6638 Result += "(const struct _method_list_t *)&"; 6639 if (metaclass) 6640 Result += "_OBJC_$_CLASS_METHODS_"; 6641 else 6642 Result += "_OBJC_$_INSTANCE_METHODS_"; 6643 Result += ClassName; 6644 Result += ",\n\t"; 6645 } 6646 else 6647 Result += "0, \n\t"; 6648 6649 if (!metaclass && baseProtocols.size() > 0) { 6650 Result += "(const struct _objc_protocol_list *)&"; 6651 Result += "_OBJC_CLASS_PROTOCOLS_$_"; Result += ClassName; 6652 Result += ",\n\t"; 6653 } 6654 else 6655 Result += "0, \n\t"; 6656 6657 if (!metaclass && ivars.size() > 0) { 6658 Result += "(const struct _ivar_list_t *)&"; 6659 Result += "_OBJC_$_INSTANCE_VARIABLES_"; Result += ClassName; 6660 Result += ",\n\t"; 6661 } 6662 else 6663 Result += "0, \n\t"; 6664 6665 // weakIvarLayout 6666 Result += "0, \n\t"; 6667 if (!metaclass && Properties.size() > 0) { 6668 Result += "(const struct _prop_list_t *)&"; 6669 Result += "_OBJC_$_PROP_LIST_"; Result += ClassName; 6670 Result += ",\n"; 6671 } 6672 else 6673 Result += "0, \n"; 6674 6675 Result += "};\n"; 6676 } 6677 6678 static void Write_class_t(ASTContext *Context, std::string &Result, 6679 StringRef VarName, 6680 const ObjCInterfaceDecl *CDecl, bool metaclass) { 6681 bool rootClass = (!CDecl->getSuperClass()); 6682 const ObjCInterfaceDecl *RootClass = CDecl; 6683 6684 if (!rootClass) { 6685 // Find the Root class 6686 RootClass = CDecl->getSuperClass(); 6687 while (RootClass->getSuperClass()) { 6688 RootClass = RootClass->getSuperClass(); 6689 } 6690 } 6691 6692 if (metaclass && rootClass) { 6693 // Need to handle a case of use of forward declaration. 6694 Result += "\n"; 6695 Result += "extern \"C\" "; 6696 if (CDecl->getImplementation()) 6697 Result += "__declspec(dllexport) "; 6698 else 6699 Result += "__declspec(dllimport) "; 6700 6701 Result += "struct _class_t OBJC_CLASS_$_"; 6702 Result += CDecl->getNameAsString(); 6703 Result += ";\n"; 6704 } 6705 // Also, for possibility of 'super' metadata class not having been defined yet. 6706 if (!rootClass) { 6707 ObjCInterfaceDecl *SuperClass = CDecl->getSuperClass(); 6708 Result += "\n"; 6709 Result += "extern \"C\" "; 6710 if (SuperClass->getImplementation()) 6711 Result += "__declspec(dllexport) "; 6712 else 6713 Result += "__declspec(dllimport) "; 6714 6715 Result += "struct _class_t "; 6716 Result += VarName; 6717 Result += SuperClass->getNameAsString(); 6718 Result += ";\n"; 6719 6720 if (metaclass && RootClass != SuperClass) { 6721 Result += "extern \"C\" "; 6722 if (RootClass->getImplementation()) 6723 Result += "__declspec(dllexport) "; 6724 else 6725 Result += "__declspec(dllimport) "; 6726 6727 Result += "struct _class_t "; 6728 Result += VarName; 6729 Result += RootClass->getNameAsString(); 6730 Result += ";\n"; 6731 } 6732 } 6733 6734 Result += "\nextern \"C\" __declspec(dllexport) struct _class_t "; 6735 Result += VarName; Result += CDecl->getNameAsString(); 6736 Result += " __attribute__ ((used, section (\"__DATA,__objc_data\"))) = {\n"; 6737 Result += "\t"; 6738 if (metaclass) { 6739 if (!rootClass) { 6740 Result += "0, // &"; Result += VarName; 6741 Result += RootClass->getNameAsString(); 6742 Result += ",\n\t"; 6743 Result += "0, // &"; Result += VarName; 6744 Result += CDecl->getSuperClass()->getNameAsString(); 6745 Result += ",\n\t"; 6746 } 6747 else { 6748 Result += "0, // &"; Result += VarName; 6749 Result += CDecl->getNameAsString(); 6750 Result += ",\n\t"; 6751 Result += "0, // &OBJC_CLASS_$_"; Result += CDecl->getNameAsString(); 6752 Result += ",\n\t"; 6753 } 6754 } 6755 else { 6756 Result += "0, // &OBJC_METACLASS_$_"; 6757 Result += CDecl->getNameAsString(); 6758 Result += ",\n\t"; 6759 if (!rootClass) { 6760 Result += "0, // &"; Result += VarName; 6761 Result += CDecl->getSuperClass()->getNameAsString(); 6762 Result += ",\n\t"; 6763 } 6764 else 6765 Result += "0,\n\t"; 6766 } 6767 Result += "0, // (void *)&_objc_empty_cache,\n\t"; 6768 Result += "0, // unused, was (void *)&_objc_empty_vtable,\n\t"; 6769 if (metaclass) 6770 Result += "&_OBJC_METACLASS_RO_$_"; 6771 else 6772 Result += "&_OBJC_CLASS_RO_$_"; 6773 Result += CDecl->getNameAsString(); 6774 Result += ",\n};\n"; 6775 6776 // Add static function to initialize some of the meta-data fields. 6777 // avoid doing it twice. 6778 if (metaclass) 6779 return; 6780 6781 const ObjCInterfaceDecl *SuperClass = 6782 rootClass ? CDecl : CDecl->getSuperClass(); 6783 6784 Result += "static void OBJC_CLASS_SETUP_$_"; 6785 Result += CDecl->getNameAsString(); 6786 Result += "(void ) {\n"; 6787 Result += "\tOBJC_METACLASS_$_"; Result += CDecl->getNameAsString(); 6788 Result += ".isa = "; Result += "&OBJC_METACLASS_$_"; 6789 Result += RootClass->getNameAsString(); Result += ";\n"; 6790 6791 Result += "\tOBJC_METACLASS_$_"; Result += CDecl->getNameAsString(); 6792 Result += ".superclass = "; 6793 if (rootClass) 6794 Result += "&OBJC_CLASS_$_"; 6795 else 6796 Result += "&OBJC_METACLASS_$_"; 6797 6798 Result += SuperClass->getNameAsString(); Result += ";\n"; 6799 6800 Result += "\tOBJC_METACLASS_$_"; Result += CDecl->getNameAsString(); 6801 Result += ".cache = "; Result += "&_objc_empty_cache"; Result += ";\n"; 6802 6803 Result += "\tOBJC_CLASS_$_"; Result += CDecl->getNameAsString(); 6804 Result += ".isa = "; Result += "&OBJC_METACLASS_$_"; 6805 Result += CDecl->getNameAsString(); Result += ";\n"; 6806 6807 if (!rootClass) { 6808 Result += "\tOBJC_CLASS_$_"; Result += CDecl->getNameAsString(); 6809 Result += ".superclass = "; Result += "&OBJC_CLASS_$_"; 6810 Result += SuperClass->getNameAsString(); Result += ";\n"; 6811 } 6812 6813 Result += "\tOBJC_CLASS_$_"; Result += CDecl->getNameAsString(); 6814 Result += ".cache = "; Result += "&_objc_empty_cache"; Result += ";\n"; 6815 Result += "}\n"; 6816 } 6817 6818 static void Write_category_t(RewriteModernObjC &RewriteObj, ASTContext *Context, 6819 std::string &Result, 6820 ObjCCategoryDecl *CatDecl, 6821 ObjCInterfaceDecl *ClassDecl, 6822 ArrayRef<ObjCMethodDecl *> InstanceMethods, 6823 ArrayRef<ObjCMethodDecl *> ClassMethods, 6824 ArrayRef<ObjCProtocolDecl *> RefedProtocols, 6825 ArrayRef<ObjCPropertyDecl *> ClassProperties) { 6826 StringRef CatName = CatDecl->getName(); 6827 StringRef ClassName = ClassDecl->getName(); 6828 // must declare an extern class object in case this class is not implemented 6829 // in this TU. 6830 Result += "\n"; 6831 Result += "extern \"C\" "; 6832 if (ClassDecl->getImplementation()) 6833 Result += "__declspec(dllexport) "; 6834 else 6835 Result += "__declspec(dllimport) "; 6836 6837 Result += "struct _class_t "; 6838 Result += "OBJC_CLASS_$_"; Result += ClassName; 6839 Result += ";\n"; 6840 6841 Result += "\nstatic struct _category_t "; 6842 Result += "_OBJC_$_CATEGORY_"; 6843 Result += ClassName; Result += "_$_"; Result += CatName; 6844 Result += " __attribute__ ((used, section (\"__DATA,__objc_const\"))) = \n"; 6845 Result += "{\n"; 6846 Result += "\t\""; Result += ClassName; Result += "\",\n"; 6847 Result += "\t0, // &"; Result += "OBJC_CLASS_$_"; Result += ClassName; 6848 Result += ",\n"; 6849 if (InstanceMethods.size() > 0) { 6850 Result += "\t(const struct _method_list_t *)&"; 6851 Result += "_OBJC_$_CATEGORY_INSTANCE_METHODS_"; 6852 Result += ClassName; Result += "_$_"; Result += CatName; 6853 Result += ",\n"; 6854 } 6855 else 6856 Result += "\t0,\n"; 6857 6858 if (ClassMethods.size() > 0) { 6859 Result += "\t(const struct _method_list_t *)&"; 6860 Result += "_OBJC_$_CATEGORY_CLASS_METHODS_"; 6861 Result += ClassName; Result += "_$_"; Result += CatName; 6862 Result += ",\n"; 6863 } 6864 else 6865 Result += "\t0,\n"; 6866 6867 if (RefedProtocols.size() > 0) { 6868 Result += "\t(const struct _protocol_list_t *)&"; 6869 Result += "_OBJC_CATEGORY_PROTOCOLS_$_"; 6870 Result += ClassName; Result += "_$_"; Result += CatName; 6871 Result += ",\n"; 6872 } 6873 else 6874 Result += "\t0,\n"; 6875 6876 if (ClassProperties.size() > 0) { 6877 Result += "\t(const struct _prop_list_t *)&"; Result += "_OBJC_$_PROP_LIST_"; 6878 Result += ClassName; Result += "_$_"; Result += CatName; 6879 Result += ",\n"; 6880 } 6881 else 6882 Result += "\t0,\n"; 6883 6884 Result += "};\n"; 6885 6886 // Add static function to initialize the class pointer in the category structure. 6887 Result += "static void OBJC_CATEGORY_SETUP_$_"; 6888 Result += ClassDecl->getNameAsString(); 6889 Result += "_$_"; 6890 Result += CatName; 6891 Result += "(void ) {\n"; 6892 Result += "\t_OBJC_$_CATEGORY_"; 6893 Result += ClassDecl->getNameAsString(); 6894 Result += "_$_"; 6895 Result += CatName; 6896 Result += ".cls = "; Result += "&OBJC_CLASS_$_"; Result += ClassName; 6897 Result += ";\n}\n"; 6898 } 6899 6900 static void Write__extendedMethodTypes_initializer(RewriteModernObjC &RewriteObj, 6901 ASTContext *Context, std::string &Result, 6902 ArrayRef<ObjCMethodDecl *> Methods, 6903 StringRef VarName, 6904 StringRef ProtocolName) { 6905 if (Methods.size() == 0) 6906 return; 6907 6908 Result += "\nstatic const char *"; 6909 Result += VarName; Result += ProtocolName; 6910 Result += " [] __attribute__ ((used, section (\"__DATA,__objc_const\"))) = \n"; 6911 Result += "{\n"; 6912 for (unsigned i = 0, e = Methods.size(); i < e; i++) { 6913 ObjCMethodDecl *MD = Methods[i]; 6914 std::string MethodTypeString, QuoteMethodTypeString; 6915 Context->getObjCEncodingForMethodDecl(MD, MethodTypeString, true); 6916 RewriteObj.QuoteDoublequotes(MethodTypeString, QuoteMethodTypeString); 6917 Result += "\t\""; Result += QuoteMethodTypeString; Result += "\""; 6918 if (i == e-1) 6919 Result += "\n};\n"; 6920 else { 6921 Result += ",\n"; 6922 } 6923 } 6924 } 6925 6926 static void Write_IvarOffsetVar(RewriteModernObjC &RewriteObj, 6927 ASTContext *Context, 6928 std::string &Result, 6929 ArrayRef<ObjCIvarDecl *> Ivars, 6930 ObjCInterfaceDecl *CDecl) { 6931 // FIXME. visibilty of offset symbols may have to be set; for Darwin 6932 // this is what happens: 6933 /** 6934 if (Ivar->getAccessControl() == ObjCIvarDecl::Private || 6935 Ivar->getAccessControl() == ObjCIvarDecl::Package || 6936 Class->getVisibility() == HiddenVisibility) 6937 Visibility shoud be: HiddenVisibility; 6938 else 6939 Visibility shoud be: DefaultVisibility; 6940 */ 6941 6942 Result += "\n"; 6943 for (unsigned i =0, e = Ivars.size(); i < e; i++) { 6944 ObjCIvarDecl *IvarDecl = Ivars[i]; 6945 if (Context->getLangOpts().MicrosoftExt) 6946 Result += "__declspec(allocate(\".objc_ivar$B\")) "; 6947 6948 if (!Context->getLangOpts().MicrosoftExt || 6949 IvarDecl->getAccessControl() == ObjCIvarDecl::Private || 6950 IvarDecl->getAccessControl() == ObjCIvarDecl::Package) 6951 Result += "extern \"C\" unsigned long int "; 6952 else 6953 Result += "extern \"C\" __declspec(dllexport) unsigned long int "; 6954 if (Ivars[i]->isBitField()) 6955 RewriteObj.ObjCIvarBitfieldGroupOffset(IvarDecl, Result); 6956 else 6957 WriteInternalIvarName(CDecl, IvarDecl, Result); 6958 Result += " __attribute__ ((used, section (\"__DATA,__objc_ivar\")))"; 6959 Result += " = "; 6960 RewriteObj.RewriteIvarOffsetComputation(IvarDecl, Result); 6961 Result += ";\n"; 6962 if (Ivars[i]->isBitField()) { 6963 // skip over rest of the ivar bitfields. 6964 SKIP_BITFIELDS(i , e, Ivars); 6965 } 6966 } 6967 } 6968 6969 static void Write__ivar_list_t_initializer(RewriteModernObjC &RewriteObj, 6970 ASTContext *Context, std::string &Result, 6971 ArrayRef<ObjCIvarDecl *> OriginalIvars, 6972 StringRef VarName, 6973 ObjCInterfaceDecl *CDecl) { 6974 if (OriginalIvars.size() > 0) { 6975 Write_IvarOffsetVar(RewriteObj, Context, Result, OriginalIvars, CDecl); 6976 SmallVector<ObjCIvarDecl *, 8> Ivars; 6977 // strip off all but the first ivar bitfield from each group of ivars. 6978 // Such ivars in the ivar list table will be replaced by their grouping struct 6979 // 'ivar'. 6980 for (unsigned i = 0, e = OriginalIvars.size(); i < e; i++) { 6981 if (OriginalIvars[i]->isBitField()) { 6982 Ivars.push_back(OriginalIvars[i]); 6983 // skip over rest of the ivar bitfields. 6984 SKIP_BITFIELDS(i , e, OriginalIvars); 6985 } 6986 else 6987 Ivars.push_back(OriginalIvars[i]); 6988 } 6989 6990 Result += "\nstatic "; 6991 Write__ivar_list_t_TypeDecl(Result, Ivars.size()); 6992 Result += " "; Result += VarName; 6993 Result += CDecl->getNameAsString(); 6994 Result += " __attribute__ ((used, section (\"__DATA,__objc_const\"))) = {\n"; 6995 Result += "\t"; Result += "sizeof(_ivar_t)"; Result += ",\n"; 6996 Result += "\t"; Result += utostr(Ivars.size()); Result += ",\n"; 6997 for (unsigned i =0, e = Ivars.size(); i < e; i++) { 6998 ObjCIvarDecl *IvarDecl = Ivars[i]; 6999 if (i == 0) 7000 Result += "\t{{"; 7001 else 7002 Result += "\t {"; 7003 Result += "(unsigned long int *)&"; 7004 if (Ivars[i]->isBitField()) 7005 RewriteObj.ObjCIvarBitfieldGroupOffset(IvarDecl, Result); 7006 else 7007 WriteInternalIvarName(CDecl, IvarDecl, Result); 7008 Result += ", "; 7009 7010 Result += "\""; 7011 if (Ivars[i]->isBitField()) 7012 RewriteObj.ObjCIvarBitfieldGroupDecl(Ivars[i], Result); 7013 else 7014 Result += IvarDecl->getName(); 7015 Result += "\", "; 7016 7017 QualType IVQT = IvarDecl->getType(); 7018 if (IvarDecl->isBitField()) 7019 IVQT = RewriteObj.GetGroupRecordTypeForObjCIvarBitfield(IvarDecl); 7020 7021 std::string IvarTypeString, QuoteIvarTypeString; 7022 Context->getObjCEncodingForType(IVQT, IvarTypeString, 7023 IvarDecl); 7024 RewriteObj.QuoteDoublequotes(IvarTypeString, QuoteIvarTypeString); 7025 Result += "\""; Result += QuoteIvarTypeString; Result += "\", "; 7026 7027 // FIXME. this alignment represents the host alignment and need be changed to 7028 // represent the target alignment. 7029 unsigned Align = Context->getTypeAlign(IVQT)/8; 7030 Align = llvm::Log2_32(Align); 7031 Result += llvm::utostr(Align); Result += ", "; 7032 CharUnits Size = Context->getTypeSizeInChars(IVQT); 7033 Result += llvm::utostr(Size.getQuantity()); 7034 if (i == e-1) 7035 Result += "}}\n"; 7036 else 7037 Result += "},\n"; 7038 } 7039 Result += "};\n"; 7040 } 7041 } 7042 7043 /// RewriteObjCProtocolMetaData - Rewrite protocols meta-data. 7044 void RewriteModernObjC::RewriteObjCProtocolMetaData(ObjCProtocolDecl *PDecl, 7045 std::string &Result) { 7046 7047 // Do not synthesize the protocol more than once. 7048 if (ObjCSynthesizedProtocols.count(PDecl->getCanonicalDecl())) 7049 return; 7050 WriteModernMetadataDeclarations(Context, Result); 7051 7052 if (ObjCProtocolDecl *Def = PDecl->getDefinition()) 7053 PDecl = Def; 7054 // Must write out all protocol definitions in current qualifier list, 7055 // and in their nested qualifiers before writing out current definition. 7056 for (ObjCProtocolDecl::protocol_iterator I = PDecl->protocol_begin(), 7057 E = PDecl->protocol_end(); I != E; ++I) 7058 RewriteObjCProtocolMetaData(*I, Result); 7059 7060 // Construct method lists. 7061 std::vector<ObjCMethodDecl *> InstanceMethods, ClassMethods; 7062 std::vector<ObjCMethodDecl *> OptInstanceMethods, OptClassMethods; 7063 for (ObjCProtocolDecl::instmeth_iterator 7064 I = PDecl->instmeth_begin(), E = PDecl->instmeth_end(); 7065 I != E; ++I) { 7066 ObjCMethodDecl *MD = *I; 7067 if (MD->getImplementationControl() == ObjCMethodDecl::Optional) { 7068 OptInstanceMethods.push_back(MD); 7069 } else { 7070 InstanceMethods.push_back(MD); 7071 } 7072 } 7073 7074 for (ObjCProtocolDecl::classmeth_iterator 7075 I = PDecl->classmeth_begin(), E = PDecl->classmeth_end(); 7076 I != E; ++I) { 7077 ObjCMethodDecl *MD = *I; 7078 if (MD->getImplementationControl() == ObjCMethodDecl::Optional) { 7079 OptClassMethods.push_back(MD); 7080 } else { 7081 ClassMethods.push_back(MD); 7082 } 7083 } 7084 std::vector<ObjCMethodDecl *> AllMethods; 7085 for (unsigned i = 0, e = InstanceMethods.size(); i < e; i++) 7086 AllMethods.push_back(InstanceMethods[i]); 7087 for (unsigned i = 0, e = ClassMethods.size(); i < e; i++) 7088 AllMethods.push_back(ClassMethods[i]); 7089 for (unsigned i = 0, e = OptInstanceMethods.size(); i < e; i++) 7090 AllMethods.push_back(OptInstanceMethods[i]); 7091 for (unsigned i = 0, e = OptClassMethods.size(); i < e; i++) 7092 AllMethods.push_back(OptClassMethods[i]); 7093 7094 Write__extendedMethodTypes_initializer(*this, Context, Result, 7095 AllMethods, 7096 "_OBJC_PROTOCOL_METHOD_TYPES_", 7097 PDecl->getNameAsString()); 7098 // Protocol's super protocol list 7099 std::vector<ObjCProtocolDecl *> SuperProtocols; 7100 for (ObjCProtocolDecl::protocol_iterator I = PDecl->protocol_begin(), 7101 E = PDecl->protocol_end(); I != E; ++I) 7102 SuperProtocols.push_back(*I); 7103 7104 Write_protocol_list_initializer(Context, Result, SuperProtocols, 7105 "_OBJC_PROTOCOL_REFS_", 7106 PDecl->getNameAsString()); 7107 7108 Write_method_list_t_initializer(*this, Context, Result, InstanceMethods, 7109 "_OBJC_PROTOCOL_INSTANCE_METHODS_", 7110 PDecl->getNameAsString(), false); 7111 7112 Write_method_list_t_initializer(*this, Context, Result, ClassMethods, 7113 "_OBJC_PROTOCOL_CLASS_METHODS_", 7114 PDecl->getNameAsString(), false); 7115 7116 Write_method_list_t_initializer(*this, Context, Result, OptInstanceMethods, 7117 "_OBJC_PROTOCOL_OPT_INSTANCE_METHODS_", 7118 PDecl->getNameAsString(), false); 7119 7120 Write_method_list_t_initializer(*this, Context, Result, OptClassMethods, 7121 "_OBJC_PROTOCOL_OPT_CLASS_METHODS_", 7122 PDecl->getNameAsString(), false); 7123 7124 // Protocol's property metadata. 7125 std::vector<ObjCPropertyDecl *> ProtocolProperties; 7126 for (ObjCContainerDecl::prop_iterator I = PDecl->prop_begin(), 7127 E = PDecl->prop_end(); I != E; ++I) 7128 ProtocolProperties.push_back(*I); 7129 7130 Write_prop_list_t_initializer(*this, Context, Result, ProtocolProperties, 7131 /* Container */0, 7132 "_OBJC_PROTOCOL_PROPERTIES_", 7133 PDecl->getNameAsString()); 7134 7135 // Writer out root metadata for current protocol: struct _protocol_t 7136 Result += "\n"; 7137 if (LangOpts.MicrosoftExt) 7138 Result += "static "; 7139 Result += "struct _protocol_t _OBJC_PROTOCOL_"; 7140 Result += PDecl->getNameAsString(); 7141 Result += " __attribute__ ((used, section (\"__DATA,__datacoal_nt,coalesced\"))) = {\n"; 7142 Result += "\t0,\n"; // id is; is null 7143 Result += "\t\""; Result += PDecl->getNameAsString(); Result += "\",\n"; 7144 if (SuperProtocols.size() > 0) { 7145 Result += "\t(const struct _protocol_list_t *)&"; Result += "_OBJC_PROTOCOL_REFS_"; 7146 Result += PDecl->getNameAsString(); Result += ",\n"; 7147 } 7148 else 7149 Result += "\t0,\n"; 7150 if (InstanceMethods.size() > 0) { 7151 Result += "\t(const struct method_list_t *)&_OBJC_PROTOCOL_INSTANCE_METHODS_"; 7152 Result += PDecl->getNameAsString(); Result += ",\n"; 7153 } 7154 else 7155 Result += "\t0,\n"; 7156 7157 if (ClassMethods.size() > 0) { 7158 Result += "\t(const struct method_list_t *)&_OBJC_PROTOCOL_CLASS_METHODS_"; 7159 Result += PDecl->getNameAsString(); Result += ",\n"; 7160 } 7161 else 7162 Result += "\t0,\n"; 7163 7164 if (OptInstanceMethods.size() > 0) { 7165 Result += "\t(const struct method_list_t *)&_OBJC_PROTOCOL_OPT_INSTANCE_METHODS_"; 7166 Result += PDecl->getNameAsString(); Result += ",\n"; 7167 } 7168 else 7169 Result += "\t0,\n"; 7170 7171 if (OptClassMethods.size() > 0) { 7172 Result += "\t(const struct method_list_t *)&_OBJC_PROTOCOL_OPT_CLASS_METHODS_"; 7173 Result += PDecl->getNameAsString(); Result += ",\n"; 7174 } 7175 else 7176 Result += "\t0,\n"; 7177 7178 if (ProtocolProperties.size() > 0) { 7179 Result += "\t(const struct _prop_list_t *)&_OBJC_PROTOCOL_PROPERTIES_"; 7180 Result += PDecl->getNameAsString(); Result += ",\n"; 7181 } 7182 else 7183 Result += "\t0,\n"; 7184 7185 Result += "\t"; Result += "sizeof(_protocol_t)"; Result += ",\n"; 7186 Result += "\t0,\n"; 7187 7188 if (AllMethods.size() > 0) { 7189 Result += "\t(const char **)&"; Result += "_OBJC_PROTOCOL_METHOD_TYPES_"; 7190 Result += PDecl->getNameAsString(); 7191 Result += "\n};\n"; 7192 } 7193 else 7194 Result += "\t0\n};\n"; 7195 7196 if (LangOpts.MicrosoftExt) 7197 Result += "static "; 7198 Result += "struct _protocol_t *"; 7199 Result += "_OBJC_LABEL_PROTOCOL_$_"; Result += PDecl->getNameAsString(); 7200 Result += " = &_OBJC_PROTOCOL_"; Result += PDecl->getNameAsString(); 7201 Result += ";\n"; 7202 7203 // Mark this protocol as having been generated. 7204 if (!ObjCSynthesizedProtocols.insert(PDecl->getCanonicalDecl())) 7205 llvm_unreachable("protocol already synthesized"); 7206 7207 } 7208 7209 void RewriteModernObjC::RewriteObjCProtocolListMetaData( 7210 const ObjCList<ObjCProtocolDecl> &Protocols, 7211 StringRef prefix, StringRef ClassName, 7212 std::string &Result) { 7213 if (Protocols.empty()) return; 7214 7215 for (unsigned i = 0; i != Protocols.size(); i++) 7216 RewriteObjCProtocolMetaData(Protocols[i], Result); 7217 7218 // Output the top lovel protocol meta-data for the class. 7219 /* struct _objc_protocol_list { 7220 struct _objc_protocol_list *next; 7221 int protocol_count; 7222 struct _objc_protocol *class_protocols[]; 7223 } 7224 */ 7225 Result += "\n"; 7226 if (LangOpts.MicrosoftExt) 7227 Result += "__declspec(allocate(\".cat_cls_meth$B\")) "; 7228 Result += "static struct {\n"; 7229 Result += "\tstruct _objc_protocol_list *next;\n"; 7230 Result += "\tint protocol_count;\n"; 7231 Result += "\tstruct _objc_protocol *class_protocols["; 7232 Result += utostr(Protocols.size()); 7233 Result += "];\n} _OBJC_"; 7234 Result += prefix; 7235 Result += "_PROTOCOLS_"; 7236 Result += ClassName; 7237 Result += " __attribute__ ((used, section (\"__OBJC, __cat_cls_meth\")))= " 7238 "{\n\t0, "; 7239 Result += utostr(Protocols.size()); 7240 Result += "\n"; 7241 7242 Result += "\t,{&_OBJC_PROTOCOL_"; 7243 Result += Protocols[0]->getNameAsString(); 7244 Result += " \n"; 7245 7246 for (unsigned i = 1; i != Protocols.size(); i++) { 7247 Result += "\t ,&_OBJC_PROTOCOL_"; 7248 Result += Protocols[i]->getNameAsString(); 7249 Result += "\n"; 7250 } 7251 Result += "\t }\n};\n"; 7252 } 7253 7254 /// hasObjCExceptionAttribute - Return true if this class or any super 7255 /// class has the __objc_exception__ attribute. 7256 /// FIXME. Move this to ASTContext.cpp as it is also used for IRGen. 7257 static bool hasObjCExceptionAttribute(ASTContext &Context, 7258 const ObjCInterfaceDecl *OID) { 7259 if (OID->hasAttr<ObjCExceptionAttr>()) 7260 return true; 7261 if (const ObjCInterfaceDecl *Super = OID->getSuperClass()) 7262 return hasObjCExceptionAttribute(Context, Super); 7263 return false; 7264 } 7265 7266 void RewriteModernObjC::RewriteObjCClassMetaData(ObjCImplementationDecl *IDecl, 7267 std::string &Result) { 7268 ObjCInterfaceDecl *CDecl = IDecl->getClassInterface(); 7269 7270 // Explicitly declared @interface's are already synthesized. 7271 if (CDecl->isImplicitInterfaceDecl()) 7272 assert(false && 7273 "Legacy implicit interface rewriting not supported in moder abi"); 7274 7275 WriteModernMetadataDeclarations(Context, Result); 7276 SmallVector<ObjCIvarDecl *, 8> IVars; 7277 7278 for (ObjCIvarDecl *IVD = CDecl->all_declared_ivar_begin(); 7279 IVD; IVD = IVD->getNextIvar()) { 7280 // Ignore unnamed bit-fields. 7281 if (!IVD->getDeclName()) 7282 continue; 7283 IVars.push_back(IVD); 7284 } 7285 7286 Write__ivar_list_t_initializer(*this, Context, Result, IVars, 7287 "_OBJC_$_INSTANCE_VARIABLES_", 7288 CDecl); 7289 7290 // Build _objc_method_list for class's instance methods if needed 7291 SmallVector<ObjCMethodDecl *, 32> 7292 InstanceMethods(IDecl->instmeth_begin(), IDecl->instmeth_end()); 7293 7294 // If any of our property implementations have associated getters or 7295 // setters, produce metadata for them as well. 7296 for (ObjCImplDecl::propimpl_iterator Prop = IDecl->propimpl_begin(), 7297 PropEnd = IDecl->propimpl_end(); 7298 Prop != PropEnd; ++Prop) { 7299 if (Prop->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic) 7300 continue; 7301 if (!Prop->getPropertyIvarDecl()) 7302 continue; 7303 ObjCPropertyDecl *PD = Prop->getPropertyDecl(); 7304 if (!PD) 7305 continue; 7306 if (ObjCMethodDecl *Getter = PD->getGetterMethodDecl()) 7307 if (mustSynthesizeSetterGetterMethod(IDecl, PD, true /*getter*/)) 7308 InstanceMethods.push_back(Getter); 7309 if (PD->isReadOnly()) 7310 continue; 7311 if (ObjCMethodDecl *Setter = PD->getSetterMethodDecl()) 7312 if (mustSynthesizeSetterGetterMethod(IDecl, PD, false /*setter*/)) 7313 InstanceMethods.push_back(Setter); 7314 } 7315 7316 Write_method_list_t_initializer(*this, Context, Result, InstanceMethods, 7317 "_OBJC_$_INSTANCE_METHODS_", 7318 IDecl->getNameAsString(), true); 7319 7320 SmallVector<ObjCMethodDecl *, 32> 7321 ClassMethods(IDecl->classmeth_begin(), IDecl->classmeth_end()); 7322 7323 Write_method_list_t_initializer(*this, Context, Result, ClassMethods, 7324 "_OBJC_$_CLASS_METHODS_", 7325 IDecl->getNameAsString(), true); 7326 7327 // Protocols referenced in class declaration? 7328 // Protocol's super protocol list 7329 std::vector<ObjCProtocolDecl *> RefedProtocols; 7330 const ObjCList<ObjCProtocolDecl> &Protocols = CDecl->getReferencedProtocols(); 7331 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(), 7332 E = Protocols.end(); 7333 I != E; ++I) { 7334 RefedProtocols.push_back(*I); 7335 // Must write out all protocol definitions in current qualifier list, 7336 // and in their nested qualifiers before writing out current definition. 7337 RewriteObjCProtocolMetaData(*I, Result); 7338 } 7339 7340 Write_protocol_list_initializer(Context, Result, 7341 RefedProtocols, 7342 "_OBJC_CLASS_PROTOCOLS_$_", 7343 IDecl->getNameAsString()); 7344 7345 // Protocol's property metadata. 7346 std::vector<ObjCPropertyDecl *> ClassProperties; 7347 for (ObjCContainerDecl::prop_iterator I = CDecl->prop_begin(), 7348 E = CDecl->prop_end(); I != E; ++I) 7349 ClassProperties.push_back(*I); 7350 7351 Write_prop_list_t_initializer(*this, Context, Result, ClassProperties, 7352 /* Container */IDecl, 7353 "_OBJC_$_PROP_LIST_", 7354 CDecl->getNameAsString()); 7355 7356 7357 // Data for initializing _class_ro_t metaclass meta-data 7358 uint32_t flags = CLS_META; 7359 std::string InstanceSize; 7360 std::string InstanceStart; 7361 7362 7363 bool classIsHidden = CDecl->getVisibility() == HiddenVisibility; 7364 if (classIsHidden) 7365 flags |= OBJC2_CLS_HIDDEN; 7366 7367 if (!CDecl->getSuperClass()) 7368 // class is root 7369 flags |= CLS_ROOT; 7370 InstanceSize = "sizeof(struct _class_t)"; 7371 InstanceStart = InstanceSize; 7372 Write__class_ro_t_initializer(Context, Result, flags, 7373 InstanceStart, InstanceSize, 7374 ClassMethods, 7375 0, 7376 0, 7377 0, 7378 "_OBJC_METACLASS_RO_$_", 7379 CDecl->getNameAsString()); 7380 7381 7382 // Data for initializing _class_ro_t meta-data 7383 flags = CLS; 7384 if (classIsHidden) 7385 flags |= OBJC2_CLS_HIDDEN; 7386 7387 if (hasObjCExceptionAttribute(*Context, CDecl)) 7388 flags |= CLS_EXCEPTION; 7389 7390 if (!CDecl->getSuperClass()) 7391 // class is root 7392 flags |= CLS_ROOT; 7393 7394 InstanceSize.clear(); 7395 InstanceStart.clear(); 7396 if (!ObjCSynthesizedStructs.count(CDecl)) { 7397 InstanceSize = "0"; 7398 InstanceStart = "0"; 7399 } 7400 else { 7401 InstanceSize = "sizeof(struct "; 7402 InstanceSize += CDecl->getNameAsString(); 7403 InstanceSize += "_IMPL)"; 7404 7405 ObjCIvarDecl *IVD = CDecl->all_declared_ivar_begin(); 7406 if (IVD) { 7407 RewriteIvarOffsetComputation(IVD, InstanceStart); 7408 } 7409 else 7410 InstanceStart = InstanceSize; 7411 } 7412 Write__class_ro_t_initializer(Context, Result, flags, 7413 InstanceStart, InstanceSize, 7414 InstanceMethods, 7415 RefedProtocols, 7416 IVars, 7417 ClassProperties, 7418 "_OBJC_CLASS_RO_$_", 7419 CDecl->getNameAsString()); 7420 7421 Write_class_t(Context, Result, 7422 "OBJC_METACLASS_$_", 7423 CDecl, /*metaclass*/true); 7424 7425 Write_class_t(Context, Result, 7426 "OBJC_CLASS_$_", 7427 CDecl, /*metaclass*/false); 7428 7429 if (ImplementationIsNonLazy(IDecl)) 7430 DefinedNonLazyClasses.push_back(CDecl); 7431 7432 } 7433 7434 void RewriteModernObjC::RewriteClassSetupInitHook(std::string &Result) { 7435 int ClsDefCount = ClassImplementation.size(); 7436 if (!ClsDefCount) 7437 return; 7438 Result += "#pragma section(\".objc_inithooks$B\", long, read, write)\n"; 7439 Result += "__declspec(allocate(\".objc_inithooks$B\")) "; 7440 Result += "static void *OBJC_CLASS_SETUP[] = {\n"; 7441 for (int i = 0; i < ClsDefCount; i++) { 7442 ObjCImplementationDecl *IDecl = ClassImplementation[i]; 7443 ObjCInterfaceDecl *CDecl = IDecl->getClassInterface(); 7444 Result += "\t(void *)&OBJC_CLASS_SETUP_$_"; 7445 Result += CDecl->getName(); Result += ",\n"; 7446 } 7447 Result += "};\n"; 7448 } 7449 7450 void RewriteModernObjC::RewriteMetaDataIntoBuffer(std::string &Result) { 7451 int ClsDefCount = ClassImplementation.size(); 7452 int CatDefCount = CategoryImplementation.size(); 7453 7454 // For each implemented class, write out all its meta data. 7455 for (int i = 0; i < ClsDefCount; i++) 7456 RewriteObjCClassMetaData(ClassImplementation[i], Result); 7457 7458 RewriteClassSetupInitHook(Result); 7459 7460 // For each implemented category, write out all its meta data. 7461 for (int i = 0; i < CatDefCount; i++) 7462 RewriteObjCCategoryImplDecl(CategoryImplementation[i], Result); 7463 7464 RewriteCategorySetupInitHook(Result); 7465 7466 if (ClsDefCount > 0) { 7467 if (LangOpts.MicrosoftExt) 7468 Result += "__declspec(allocate(\".objc_classlist$B\")) "; 7469 Result += "static struct _class_t *L_OBJC_LABEL_CLASS_$ ["; 7470 Result += llvm::utostr(ClsDefCount); Result += "]"; 7471 Result += 7472 " __attribute__((used, section (\"__DATA, __objc_classlist," 7473 "regular,no_dead_strip\")))= {\n"; 7474 for (int i = 0; i < ClsDefCount; i++) { 7475 Result += "\t&OBJC_CLASS_$_"; 7476 Result += ClassImplementation[i]->getNameAsString(); 7477 Result += ",\n"; 7478 } 7479 Result += "};\n"; 7480 7481 if (!DefinedNonLazyClasses.empty()) { 7482 if (LangOpts.MicrosoftExt) 7483 Result += "__declspec(allocate(\".objc_nlclslist$B\")) \n"; 7484 Result += "static struct _class_t *_OBJC_LABEL_NONLAZY_CLASS_$[] = {\n\t"; 7485 for (unsigned i = 0, e = DefinedNonLazyClasses.size(); i < e; i++) { 7486 Result += "\t&OBJC_CLASS_$_"; Result += DefinedNonLazyClasses[i]->getNameAsString(); 7487 Result += ",\n"; 7488 } 7489 Result += "};\n"; 7490 } 7491 } 7492 7493 if (CatDefCount > 0) { 7494 if (LangOpts.MicrosoftExt) 7495 Result += "__declspec(allocate(\".objc_catlist$B\")) "; 7496 Result += "static struct _category_t *L_OBJC_LABEL_CATEGORY_$ ["; 7497 Result += llvm::utostr(CatDefCount); Result += "]"; 7498 Result += 7499 " __attribute__((used, section (\"__DATA, __objc_catlist," 7500 "regular,no_dead_strip\")))= {\n"; 7501 for (int i = 0; i < CatDefCount; i++) { 7502 Result += "\t&_OBJC_$_CATEGORY_"; 7503 Result += 7504 CategoryImplementation[i]->getClassInterface()->getNameAsString(); 7505 Result += "_$_"; 7506 Result += CategoryImplementation[i]->getNameAsString(); 7507 Result += ",\n"; 7508 } 7509 Result += "};\n"; 7510 } 7511 7512 if (!DefinedNonLazyCategories.empty()) { 7513 if (LangOpts.MicrosoftExt) 7514 Result += "__declspec(allocate(\".objc_nlcatlist$B\")) \n"; 7515 Result += "static struct _category_t *_OBJC_LABEL_NONLAZY_CATEGORY_$[] = {\n\t"; 7516 for (unsigned i = 0, e = DefinedNonLazyCategories.size(); i < e; i++) { 7517 Result += "\t&_OBJC_$_CATEGORY_"; 7518 Result += 7519 DefinedNonLazyCategories[i]->getClassInterface()->getNameAsString(); 7520 Result += "_$_"; 7521 Result += DefinedNonLazyCategories[i]->getNameAsString(); 7522 Result += ",\n"; 7523 } 7524 Result += "};\n"; 7525 } 7526 } 7527 7528 void RewriteModernObjC::WriteImageInfo(std::string &Result) { 7529 if (LangOpts.MicrosoftExt) 7530 Result += "__declspec(allocate(\".objc_imageinfo$B\")) \n"; 7531 7532 Result += "static struct IMAGE_INFO { unsigned version; unsigned flag; } "; 7533 // version 0, ObjCABI is 2 7534 Result += "_OBJC_IMAGE_INFO = { 0, 2 };\n"; 7535 } 7536 7537 /// RewriteObjCCategoryImplDecl - Rewrite metadata for each category 7538 /// implementation. 7539 void RewriteModernObjC::RewriteObjCCategoryImplDecl(ObjCCategoryImplDecl *IDecl, 7540 std::string &Result) { 7541 WriteModernMetadataDeclarations(Context, Result); 7542 ObjCInterfaceDecl *ClassDecl = IDecl->getClassInterface(); 7543 // Find category declaration for this implementation. 7544 ObjCCategoryDecl *CDecl 7545 = ClassDecl->FindCategoryDeclaration(IDecl->getIdentifier()); 7546 7547 std::string FullCategoryName = ClassDecl->getNameAsString(); 7548 FullCategoryName += "_$_"; 7549 FullCategoryName += CDecl->getNameAsString(); 7550 7551 // Build _objc_method_list for class's instance methods if needed 7552 SmallVector<ObjCMethodDecl *, 32> 7553 InstanceMethods(IDecl->instmeth_begin(), IDecl->instmeth_end()); 7554 7555 // If any of our property implementations have associated getters or 7556 // setters, produce metadata for them as well. 7557 for (ObjCImplDecl::propimpl_iterator Prop = IDecl->propimpl_begin(), 7558 PropEnd = IDecl->propimpl_end(); 7559 Prop != PropEnd; ++Prop) { 7560 if (Prop->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic) 7561 continue; 7562 if (!Prop->getPropertyIvarDecl()) 7563 continue; 7564 ObjCPropertyDecl *PD = Prop->getPropertyDecl(); 7565 if (!PD) 7566 continue; 7567 if (ObjCMethodDecl *Getter = PD->getGetterMethodDecl()) 7568 InstanceMethods.push_back(Getter); 7569 if (PD->isReadOnly()) 7570 continue; 7571 if (ObjCMethodDecl *Setter = PD->getSetterMethodDecl()) 7572 InstanceMethods.push_back(Setter); 7573 } 7574 7575 Write_method_list_t_initializer(*this, Context, Result, InstanceMethods, 7576 "_OBJC_$_CATEGORY_INSTANCE_METHODS_", 7577 FullCategoryName, true); 7578 7579 SmallVector<ObjCMethodDecl *, 32> 7580 ClassMethods(IDecl->classmeth_begin(), IDecl->classmeth_end()); 7581 7582 Write_method_list_t_initializer(*this, Context, Result, ClassMethods, 7583 "_OBJC_$_CATEGORY_CLASS_METHODS_", 7584 FullCategoryName, true); 7585 7586 // Protocols referenced in class declaration? 7587 // Protocol's super protocol list 7588 std::vector<ObjCProtocolDecl *> RefedProtocols; 7589 for (ObjCInterfaceDecl::protocol_iterator I = CDecl->protocol_begin(), 7590 E = CDecl->protocol_end(); 7591 7592 I != E; ++I) { 7593 RefedProtocols.push_back(*I); 7594 // Must write out all protocol definitions in current qualifier list, 7595 // and in their nested qualifiers before writing out current definition. 7596 RewriteObjCProtocolMetaData(*I, Result); 7597 } 7598 7599 Write_protocol_list_initializer(Context, Result, 7600 RefedProtocols, 7601 "_OBJC_CATEGORY_PROTOCOLS_$_", 7602 FullCategoryName); 7603 7604 // Protocol's property metadata. 7605 std::vector<ObjCPropertyDecl *> ClassProperties; 7606 for (ObjCContainerDecl::prop_iterator I = CDecl->prop_begin(), 7607 E = CDecl->prop_end(); I != E; ++I) 7608 ClassProperties.push_back(*I); 7609 7610 Write_prop_list_t_initializer(*this, Context, Result, ClassProperties, 7611 /* Container */IDecl, 7612 "_OBJC_$_PROP_LIST_", 7613 FullCategoryName); 7614 7615 Write_category_t(*this, Context, Result, 7616 CDecl, 7617 ClassDecl, 7618 InstanceMethods, 7619 ClassMethods, 7620 RefedProtocols, 7621 ClassProperties); 7622 7623 // Determine if this category is also "non-lazy". 7624 if (ImplementationIsNonLazy(IDecl)) 7625 DefinedNonLazyCategories.push_back(CDecl); 7626 7627 } 7628 7629 void RewriteModernObjC::RewriteCategorySetupInitHook(std::string &Result) { 7630 int CatDefCount = CategoryImplementation.size(); 7631 if (!CatDefCount) 7632 return; 7633 Result += "#pragma section(\".objc_inithooks$B\", long, read, write)\n"; 7634 Result += "__declspec(allocate(\".objc_inithooks$B\")) "; 7635 Result += "static void *OBJC_CATEGORY_SETUP[] = {\n"; 7636 for (int i = 0; i < CatDefCount; i++) { 7637 ObjCCategoryImplDecl *IDecl = CategoryImplementation[i]; 7638 ObjCCategoryDecl *CatDecl= IDecl->getCategoryDecl(); 7639 ObjCInterfaceDecl *ClassDecl = IDecl->getClassInterface(); 7640 Result += "\t(void *)&OBJC_CATEGORY_SETUP_$_"; 7641 Result += ClassDecl->getName(); 7642 Result += "_$_"; 7643 Result += CatDecl->getName(); 7644 Result += ",\n"; 7645 } 7646 Result += "};\n"; 7647 } 7648 7649 // RewriteObjCMethodsMetaData - Rewrite methods metadata for instance or 7650 /// class methods. 7651 template<typename MethodIterator> 7652 void RewriteModernObjC::RewriteObjCMethodsMetaData(MethodIterator MethodBegin, 7653 MethodIterator MethodEnd, 7654 bool IsInstanceMethod, 7655 StringRef prefix, 7656 StringRef ClassName, 7657 std::string &Result) { 7658 if (MethodBegin == MethodEnd) return; 7659 7660 if (!objc_impl_method) { 7661 /* struct _objc_method { 7662 SEL _cmd; 7663 char *method_types; 7664 void *_imp; 7665 } 7666 */ 7667 Result += "\nstruct _objc_method {\n"; 7668 Result += "\tSEL _cmd;\n"; 7669 Result += "\tchar *method_types;\n"; 7670 Result += "\tvoid *_imp;\n"; 7671 Result += "};\n"; 7672 7673 objc_impl_method = true; 7674 } 7675 7676 // Build _objc_method_list for class's methods if needed 7677 7678 /* struct { 7679 struct _objc_method_list *next_method; 7680 int method_count; 7681 struct _objc_method method_list[]; 7682 } 7683 */ 7684 unsigned NumMethods = std::distance(MethodBegin, MethodEnd); 7685 Result += "\n"; 7686 if (LangOpts.MicrosoftExt) { 7687 if (IsInstanceMethod) 7688 Result += "__declspec(allocate(\".inst_meth$B\")) "; 7689 else 7690 Result += "__declspec(allocate(\".cls_meth$B\")) "; 7691 } 7692 Result += "static struct {\n"; 7693 Result += "\tstruct _objc_method_list *next_method;\n"; 7694 Result += "\tint method_count;\n"; 7695 Result += "\tstruct _objc_method method_list["; 7696 Result += utostr(NumMethods); 7697 Result += "];\n} _OBJC_"; 7698 Result += prefix; 7699 Result += IsInstanceMethod ? "INSTANCE" : "CLASS"; 7700 Result += "_METHODS_"; 7701 Result += ClassName; 7702 Result += " __attribute__ ((used, section (\"__OBJC, __"; 7703 Result += IsInstanceMethod ? "inst" : "cls"; 7704 Result += "_meth\")))= "; 7705 Result += "{\n\t0, " + utostr(NumMethods) + "\n"; 7706 7707 Result += "\t,{{(SEL)\""; 7708 Result += (*MethodBegin)->getSelector().getAsString().c_str(); 7709 std::string MethodTypeString; 7710 Context->getObjCEncodingForMethodDecl(*MethodBegin, MethodTypeString); 7711 Result += "\", \""; 7712 Result += MethodTypeString; 7713 Result += "\", (void *)"; 7714 Result += MethodInternalNames[*MethodBegin]; 7715 Result += "}\n"; 7716 for (++MethodBegin; MethodBegin != MethodEnd; ++MethodBegin) { 7717 Result += "\t ,{(SEL)\""; 7718 Result += (*MethodBegin)->getSelector().getAsString().c_str(); 7719 std::string MethodTypeString; 7720 Context->getObjCEncodingForMethodDecl(*MethodBegin, MethodTypeString); 7721 Result += "\", \""; 7722 Result += MethodTypeString; 7723 Result += "\", (void *)"; 7724 Result += MethodInternalNames[*MethodBegin]; 7725 Result += "}\n"; 7726 } 7727 Result += "\t }\n};\n"; 7728 } 7729 7730 Stmt *RewriteModernObjC::RewriteObjCIvarRefExpr(ObjCIvarRefExpr *IV) { 7731 SourceRange OldRange = IV->getSourceRange(); 7732 Expr *BaseExpr = IV->getBase(); 7733 7734 // Rewrite the base, but without actually doing replaces. 7735 { 7736 DisableReplaceStmtScope S(*this); 7737 BaseExpr = cast<Expr>(RewriteFunctionBodyOrGlobalInitializer(BaseExpr)); 7738 IV->setBase(BaseExpr); 7739 } 7740 7741 ObjCIvarDecl *D = IV->getDecl(); 7742 7743 Expr *Replacement = IV; 7744 7745 if (BaseExpr->getType()->isObjCObjectPointerType()) { 7746 const ObjCInterfaceType *iFaceDecl = 7747 dyn_cast<ObjCInterfaceType>(BaseExpr->getType()->getPointeeType()); 7748 assert(iFaceDecl && "RewriteObjCIvarRefExpr - iFaceDecl is null"); 7749 // lookup which class implements the instance variable. 7750 ObjCInterfaceDecl *clsDeclared = 0; 7751 iFaceDecl->getDecl()->lookupInstanceVariable(D->getIdentifier(), 7752 clsDeclared); 7753 assert(clsDeclared && "RewriteObjCIvarRefExpr(): Can't find class"); 7754 7755 // Build name of symbol holding ivar offset. 7756 std::string IvarOffsetName; 7757 if (D->isBitField()) 7758 ObjCIvarBitfieldGroupOffset(D, IvarOffsetName); 7759 else 7760 WriteInternalIvarName(clsDeclared, D, IvarOffsetName); 7761 7762 ReferencedIvars[clsDeclared].insert(D); 7763 7764 // cast offset to "char *". 7765 CastExpr *castExpr = NoTypeInfoCStyleCastExpr(Context, 7766 Context->getPointerType(Context->CharTy), 7767 CK_BitCast, 7768 BaseExpr); 7769 VarDecl *NewVD = VarDecl::Create(*Context, TUDecl, SourceLocation(), 7770 SourceLocation(), &Context->Idents.get(IvarOffsetName), 7771 Context->UnsignedLongTy, 0, SC_Extern); 7772 DeclRefExpr *DRE = new (Context) DeclRefExpr(NewVD, false, 7773 Context->UnsignedLongTy, VK_LValue, 7774 SourceLocation()); 7775 BinaryOperator *addExpr = 7776 new (Context) BinaryOperator(castExpr, DRE, BO_Add, 7777 Context->getPointerType(Context->CharTy), 7778 VK_RValue, OK_Ordinary, SourceLocation(), false); 7779 // Don't forget the parens to enforce the proper binding. 7780 ParenExpr *PE = new (Context) ParenExpr(SourceLocation(), 7781 SourceLocation(), 7782 addExpr); 7783 QualType IvarT = D->getType(); 7784 if (D->isBitField()) 7785 IvarT = GetGroupRecordTypeForObjCIvarBitfield(D); 7786 7787 if (!isa<TypedefType>(IvarT) && IvarT->isRecordType()) { 7788 RecordDecl *RD = IvarT->getAs<RecordType>()->getDecl(); 7789 RD = RD->getDefinition(); 7790 if (RD && !RD->getDeclName().getAsIdentifierInfo()) { 7791 // decltype(((Foo_IMPL*)0)->bar) * 7792 ObjCContainerDecl *CDecl = 7793 dyn_cast<ObjCContainerDecl>(D->getDeclContext()); 7794 // ivar in class extensions requires special treatment. 7795 if (ObjCCategoryDecl *CatDecl = dyn_cast<ObjCCategoryDecl>(CDecl)) 7796 CDecl = CatDecl->getClassInterface(); 7797 std::string RecName = CDecl->getName(); 7798 RecName += "_IMPL"; 7799 RecordDecl *RD = RecordDecl::Create(*Context, TTK_Struct, TUDecl, 7800 SourceLocation(), SourceLocation(), 7801 &Context->Idents.get(RecName.c_str())); 7802 QualType PtrStructIMPL = Context->getPointerType(Context->getTagDeclType(RD)); 7803 unsigned UnsignedIntSize = 7804 static_cast<unsigned>(Context->getTypeSize(Context->UnsignedIntTy)); 7805 Expr *Zero = IntegerLiteral::Create(*Context, 7806 llvm::APInt(UnsignedIntSize, 0), 7807 Context->UnsignedIntTy, SourceLocation()); 7808 Zero = NoTypeInfoCStyleCastExpr(Context, PtrStructIMPL, CK_BitCast, Zero); 7809 ParenExpr *PE = new (Context) ParenExpr(SourceLocation(), SourceLocation(), 7810 Zero); 7811 FieldDecl *FD = FieldDecl::Create(*Context, 0, SourceLocation(), 7812 SourceLocation(), 7813 &Context->Idents.get(D->getNameAsString()), 7814 IvarT, 0, 7815 /*BitWidth=*/0, /*Mutable=*/true, 7816 ICIS_NoInit); 7817 MemberExpr *ME = new (Context) MemberExpr(PE, true, FD, SourceLocation(), 7818 FD->getType(), VK_LValue, 7819 OK_Ordinary); 7820 IvarT = Context->getDecltypeType(ME, ME->getType()); 7821 } 7822 } 7823 convertObjCTypeToCStyleType(IvarT); 7824 QualType castT = Context->getPointerType(IvarT); 7825 7826 castExpr = NoTypeInfoCStyleCastExpr(Context, 7827 castT, 7828 CK_BitCast, 7829 PE); 7830 7831 7832 Expr *Exp = new (Context) UnaryOperator(castExpr, UO_Deref, IvarT, 7833 VK_LValue, OK_Ordinary, 7834 SourceLocation()); 7835 PE = new (Context) ParenExpr(OldRange.getBegin(), 7836 OldRange.getEnd(), 7837 Exp); 7838 7839 if (D->isBitField()) { 7840 FieldDecl *FD = FieldDecl::Create(*Context, 0, SourceLocation(), 7841 SourceLocation(), 7842 &Context->Idents.get(D->getNameAsString()), 7843 D->getType(), 0, 7844 /*BitWidth=*/D->getBitWidth(), 7845 /*Mutable=*/true, 7846 ICIS_NoInit); 7847 MemberExpr *ME = new (Context) MemberExpr(PE, /*isArrow*/false, FD, SourceLocation(), 7848 FD->getType(), VK_LValue, 7849 OK_Ordinary); 7850 Replacement = ME; 7851 7852 } 7853 else 7854 Replacement = PE; 7855 } 7856 7857 ReplaceStmtWithRange(IV, Replacement, OldRange); 7858 return Replacement; 7859 } 7860