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