clang API Documentation
00001 //===--- RewriteObjC.cpp - Playground for the code rewriter ---------------===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // Hacks and fun related to the code rewriter. 00011 // 00012 //===----------------------------------------------------------------------===// 00013 00014 #include "clang/Rewrite/Frontend/ASTConsumers.h" 00015 #include "clang/AST/AST.h" 00016 #include "clang/AST/ASTConsumer.h" 00017 #include "clang/AST/Attr.h" 00018 #include "clang/AST/ParentMap.h" 00019 #include "clang/Basic/CharInfo.h" 00020 #include "clang/Basic/Diagnostic.h" 00021 #include "clang/Basic/IdentifierTable.h" 00022 #include "clang/Basic/SourceManager.h" 00023 #include "clang/Lex/Lexer.h" 00024 #include "clang/Rewrite/Core/Rewriter.h" 00025 #include "llvm/ADT/DenseSet.h" 00026 #include "llvm/ADT/SmallPtrSet.h" 00027 #include "llvm/ADT/StringExtras.h" 00028 #include "llvm/Support/MemoryBuffer.h" 00029 #include "llvm/Support/raw_ostream.h" 00030 #include <memory> 00031 00032 #ifdef CLANG_ENABLE_OBJC_REWRITER 00033 00034 using namespace clang; 00035 using llvm::utostr; 00036 00037 namespace { 00038 class RewriteObjC : public ASTConsumer { 00039 protected: 00040 00041 enum { 00042 BLOCK_FIELD_IS_OBJECT = 3, /* id, NSObject, __attribute__((NSObject)), 00043 block, ... */ 00044 BLOCK_FIELD_IS_BLOCK = 7, /* a block variable */ 00045 BLOCK_FIELD_IS_BYREF = 8, /* the on stack structure holding the 00046 __block variable */ 00047 BLOCK_FIELD_IS_WEAK = 16, /* declared __weak, only used in byref copy 00048 helpers */ 00049 BLOCK_BYREF_CALLER = 128, /* called from __block (byref) copy/dispose 00050 support routines */ 00051 BLOCK_BYREF_CURRENT_MAX = 256 00052 }; 00053 00054 enum { 00055 BLOCK_NEEDS_FREE = (1 << 24), 00056 BLOCK_HAS_COPY_DISPOSE = (1 << 25), 00057 BLOCK_HAS_CXX_OBJ = (1 << 26), 00058 BLOCK_IS_GC = (1 << 27), 00059 BLOCK_IS_GLOBAL = (1 << 28), 00060 BLOCK_HAS_DESCRIPTOR = (1 << 29) 00061 }; 00062 static const int OBJC_ABI_VERSION = 7; 00063 00064 Rewriter Rewrite; 00065 DiagnosticsEngine &Diags; 00066 const LangOptions &LangOpts; 00067 ASTContext *Context; 00068 SourceManager *SM; 00069 TranslationUnitDecl *TUDecl; 00070 FileID MainFileID; 00071 const char *MainFileStart, *MainFileEnd; 00072 Stmt *CurrentBody; 00073 ParentMap *PropParentMap; // created lazily. 00074 std::string InFileName; 00075 raw_ostream* OutFile; 00076 std::string Preamble; 00077 00078 TypeDecl *ProtocolTypeDecl; 00079 VarDecl *GlobalVarDecl; 00080 unsigned RewriteFailedDiag; 00081 // ObjC string constant support. 00082 unsigned NumObjCStringLiterals; 00083 VarDecl *ConstantStringClassReference; 00084 RecordDecl *NSStringRecord; 00085 00086 // ObjC foreach break/continue generation support. 00087 int BcLabelCount; 00088 00089 unsigned TryFinallyContainsReturnDiag; 00090 // Needed for super. 00091 ObjCMethodDecl *CurMethodDef; 00092 RecordDecl *SuperStructDecl; 00093 RecordDecl *ConstantStringDecl; 00094 00095 FunctionDecl *MsgSendFunctionDecl; 00096 FunctionDecl *MsgSendSuperFunctionDecl; 00097 FunctionDecl *MsgSendStretFunctionDecl; 00098 FunctionDecl *MsgSendSuperStretFunctionDecl; 00099 FunctionDecl *MsgSendFpretFunctionDecl; 00100 FunctionDecl *GetClassFunctionDecl; 00101 FunctionDecl *GetMetaClassFunctionDecl; 00102 FunctionDecl *GetSuperClassFunctionDecl; 00103 FunctionDecl *SelGetUidFunctionDecl; 00104 FunctionDecl *CFStringFunctionDecl; 00105 FunctionDecl *SuperConstructorFunctionDecl; 00106 FunctionDecl *CurFunctionDef; 00107 FunctionDecl *CurFunctionDeclToDeclareForBlock; 00108 00109 /* Misc. containers needed for meta-data rewrite. */ 00110 SmallVector<ObjCImplementationDecl *, 8> ClassImplementation; 00111 SmallVector<ObjCCategoryImplDecl *, 8> CategoryImplementation; 00112 llvm::SmallPtrSet<ObjCInterfaceDecl*, 8> ObjCSynthesizedStructs; 00113 llvm::SmallPtrSet<ObjCProtocolDecl*, 8> ObjCSynthesizedProtocols; 00114 llvm::SmallPtrSet<ObjCInterfaceDecl*, 8> ObjCForwardDecls; 00115 llvm::DenseMap<ObjCMethodDecl*, std::string> MethodInternalNames; 00116 SmallVector<Stmt *, 32> Stmts; 00117 SmallVector<int, 8> ObjCBcLabelNo; 00118 // Remember all the @protocol(<expr>) expressions. 00119 llvm::SmallPtrSet<ObjCProtocolDecl *, 32> ProtocolExprDecls; 00120 00121 llvm::DenseSet<uint64_t> CopyDestroyCache; 00122 00123 // Block expressions. 00124 SmallVector<BlockExpr *, 32> Blocks; 00125 SmallVector<int, 32> InnerDeclRefsCount; 00126 SmallVector<DeclRefExpr *, 32> InnerDeclRefs; 00127 00128 SmallVector<DeclRefExpr *, 32> BlockDeclRefs; 00129 00130 // Block related declarations. 00131 SmallVector<ValueDecl *, 8> BlockByCopyDecls; 00132 llvm::SmallPtrSet<ValueDecl *, 8> BlockByCopyDeclsPtrSet; 00133 SmallVector<ValueDecl *, 8> BlockByRefDecls; 00134 llvm::SmallPtrSet<ValueDecl *, 8> BlockByRefDeclsPtrSet; 00135 llvm::DenseMap<ValueDecl *, unsigned> BlockByRefDeclNo; 00136 llvm::SmallPtrSet<ValueDecl *, 8> ImportedBlockDecls; 00137 llvm::SmallPtrSet<VarDecl *, 8> ImportedLocalExternalDecls; 00138 00139 llvm::DenseMap<BlockExpr *, std::string> RewrittenBlockExprs; 00140 00141 // This maps an original source AST to it's rewritten form. This allows 00142 // us to avoid rewriting the same node twice (which is very uncommon). 00143 // This is needed to support some of the exotic property rewriting. 00144 llvm::DenseMap<Stmt *, Stmt *> ReplacedNodes; 00145 00146 // Needed for header files being rewritten 00147 bool IsHeader; 00148 bool SilenceRewriteMacroWarning; 00149 bool objc_impl_method; 00150 00151 bool DisableReplaceStmt; 00152 class DisableReplaceStmtScope { 00153 RewriteObjC &R; 00154 bool SavedValue; 00155 00156 public: 00157 DisableReplaceStmtScope(RewriteObjC &R) 00158 : R(R), SavedValue(R.DisableReplaceStmt) { 00159 R.DisableReplaceStmt = true; 00160 } 00161 ~DisableReplaceStmtScope() { 00162 R.DisableReplaceStmt = SavedValue; 00163 } 00164 }; 00165 void InitializeCommon(ASTContext &context); 00166 00167 public: 00168 00169 // Top Level Driver code. 00170 bool HandleTopLevelDecl(DeclGroupRef D) override { 00171 for (DeclGroupRef::iterator I = D.begin(), E = D.end(); I != E; ++I) { 00172 if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(*I)) { 00173 if (!Class->isThisDeclarationADefinition()) { 00174 RewriteForwardClassDecl(D); 00175 break; 00176 } 00177 } 00178 00179 if (ObjCProtocolDecl *Proto = dyn_cast<ObjCProtocolDecl>(*I)) { 00180 if (!Proto->isThisDeclarationADefinition()) { 00181 RewriteForwardProtocolDecl(D); 00182 break; 00183 } 00184 } 00185 00186 HandleTopLevelSingleDecl(*I); 00187 } 00188 return true; 00189 } 00190 void HandleTopLevelSingleDecl(Decl *D); 00191 void HandleDeclInMainFile(Decl *D); 00192 RewriteObjC(std::string inFile, raw_ostream *OS, 00193 DiagnosticsEngine &D, const LangOptions &LOpts, 00194 bool silenceMacroWarn); 00195 00196 ~RewriteObjC() {} 00197 00198 void HandleTranslationUnit(ASTContext &C) override; 00199 00200 void ReplaceStmt(Stmt *Old, Stmt *New) { 00201 ReplaceStmtWithRange(Old, New, Old->getSourceRange()); 00202 } 00203 00204 void ReplaceStmtWithRange(Stmt *Old, Stmt *New, SourceRange SrcRange) { 00205 assert(Old != nullptr && New != nullptr && "Expected non-null Stmt's"); 00206 00207 Stmt *ReplacingStmt = ReplacedNodes[Old]; 00208 if (ReplacingStmt) 00209 return; // We can't rewrite the same node twice. 00210 00211 if (DisableReplaceStmt) 00212 return; 00213 00214 // Measure the old text. 00215 int Size = Rewrite.getRangeSize(SrcRange); 00216 if (Size == -1) { 00217 Diags.Report(Context->getFullLoc(Old->getLocStart()), RewriteFailedDiag) 00218 << Old->getSourceRange(); 00219 return; 00220 } 00221 // Get the new text. 00222 std::string SStr; 00223 llvm::raw_string_ostream S(SStr); 00224 New->printPretty(S, nullptr, PrintingPolicy(LangOpts)); 00225 const std::string &Str = S.str(); 00226 00227 // If replacement succeeded or warning disabled return with no warning. 00228 if (!Rewrite.ReplaceText(SrcRange.getBegin(), Size, Str)) { 00229 ReplacedNodes[Old] = New; 00230 return; 00231 } 00232 if (SilenceRewriteMacroWarning) 00233 return; 00234 Diags.Report(Context->getFullLoc(Old->getLocStart()), RewriteFailedDiag) 00235 << Old->getSourceRange(); 00236 } 00237 00238 void InsertText(SourceLocation Loc, StringRef Str, 00239 bool InsertAfter = true) { 00240 // If insertion succeeded or warning disabled return with no warning. 00241 if (!Rewrite.InsertText(Loc, Str, InsertAfter) || 00242 SilenceRewriteMacroWarning) 00243 return; 00244 00245 Diags.Report(Context->getFullLoc(Loc), RewriteFailedDiag); 00246 } 00247 00248 void ReplaceText(SourceLocation Start, unsigned OrigLength, 00249 StringRef Str) { 00250 // If removal succeeded or warning disabled return with no warning. 00251 if (!Rewrite.ReplaceText(Start, OrigLength, Str) || 00252 SilenceRewriteMacroWarning) 00253 return; 00254 00255 Diags.Report(Context->getFullLoc(Start), RewriteFailedDiag); 00256 } 00257 00258 // Syntactic Rewriting. 00259 void RewriteRecordBody(RecordDecl *RD); 00260 void RewriteInclude(); 00261 void RewriteForwardClassDecl(DeclGroupRef D); 00262 void RewriteForwardClassDecl(const SmallVectorImpl<Decl *> &DG); 00263 void RewriteForwardClassEpilogue(ObjCInterfaceDecl *ClassDecl, 00264 const std::string &typedefString); 00265 void RewriteImplementations(); 00266 void RewritePropertyImplDecl(ObjCPropertyImplDecl *PID, 00267 ObjCImplementationDecl *IMD, 00268 ObjCCategoryImplDecl *CID); 00269 void RewriteInterfaceDecl(ObjCInterfaceDecl *Dcl); 00270 void RewriteImplementationDecl(Decl *Dcl); 00271 void RewriteObjCMethodDecl(const ObjCInterfaceDecl *IDecl, 00272 ObjCMethodDecl *MDecl, std::string &ResultStr); 00273 void RewriteTypeIntoString(QualType T, std::string &ResultStr, 00274 const FunctionType *&FPRetType); 00275 void RewriteByRefString(std::string &ResultStr, const std::string &Name, 00276 ValueDecl *VD, bool def=false); 00277 void RewriteCategoryDecl(ObjCCategoryDecl *Dcl); 00278 void RewriteProtocolDecl(ObjCProtocolDecl *Dcl); 00279 void RewriteForwardProtocolDecl(DeclGroupRef D); 00280 void RewriteForwardProtocolDecl(const SmallVectorImpl<Decl *> &DG); 00281 void RewriteMethodDeclaration(ObjCMethodDecl *Method); 00282 void RewriteProperty(ObjCPropertyDecl *prop); 00283 void RewriteFunctionDecl(FunctionDecl *FD); 00284 void RewriteBlockPointerType(std::string& Str, QualType Type); 00285 void RewriteBlockPointerTypeVariable(std::string& Str, ValueDecl *VD); 00286 void RewriteBlockLiteralFunctionDecl(FunctionDecl *FD); 00287 void RewriteObjCQualifiedInterfaceTypes(Decl *Dcl); 00288 void RewriteTypeOfDecl(VarDecl *VD); 00289 void RewriteObjCQualifiedInterfaceTypes(Expr *E); 00290 00291 // Expression Rewriting. 00292 Stmt *RewriteFunctionBodyOrGlobalInitializer(Stmt *S); 00293 Stmt *RewriteAtEncode(ObjCEncodeExpr *Exp); 00294 Stmt *RewritePropertyOrImplicitGetter(PseudoObjectExpr *Pseudo); 00295 Stmt *RewritePropertyOrImplicitSetter(PseudoObjectExpr *Pseudo); 00296 Stmt *RewriteAtSelector(ObjCSelectorExpr *Exp); 00297 Stmt *RewriteMessageExpr(ObjCMessageExpr *Exp); 00298 Stmt *RewriteObjCStringLiteral(ObjCStringLiteral *Exp); 00299 Stmt *RewriteObjCProtocolExpr(ObjCProtocolExpr *Exp); 00300 void RewriteTryReturnStmts(Stmt *S); 00301 void RewriteSyncReturnStmts(Stmt *S, std::string buf); 00302 Stmt *RewriteObjCTryStmt(ObjCAtTryStmt *S); 00303 Stmt *RewriteObjCSynchronizedStmt(ObjCAtSynchronizedStmt *S); 00304 Stmt *RewriteObjCThrowStmt(ObjCAtThrowStmt *S); 00305 Stmt *RewriteObjCForCollectionStmt(ObjCForCollectionStmt *S, 00306 SourceLocation OrigEnd); 00307 Stmt *RewriteBreakStmt(BreakStmt *S); 00308 Stmt *RewriteContinueStmt(ContinueStmt *S); 00309 void RewriteCastExpr(CStyleCastExpr *CE); 00310 00311 // Block rewriting. 00312 void RewriteBlocksInFunctionProtoType(QualType funcType, NamedDecl *D); 00313 00314 // Block specific rewrite rules. 00315 void RewriteBlockPointerDecl(NamedDecl *VD); 00316 void RewriteByRefVar(VarDecl *VD); 00317 Stmt *RewriteBlockDeclRefExpr(DeclRefExpr *VD); 00318 Stmt *RewriteLocalVariableExternalStorage(DeclRefExpr *DRE); 00319 void RewriteBlockPointerFunctionArgs(FunctionDecl *FD); 00320 00321 void RewriteObjCInternalStruct(ObjCInterfaceDecl *CDecl, 00322 std::string &Result); 00323 00324 void Initialize(ASTContext &context) override = 0; 00325 00326 // Metadata Rewriting. 00327 virtual void RewriteMetaDataIntoBuffer(std::string &Result) = 0; 00328 virtual void RewriteObjCProtocolListMetaData(const ObjCList<ObjCProtocolDecl> &Prots, 00329 StringRef prefix, 00330 StringRef ClassName, 00331 std::string &Result) = 0; 00332 virtual void RewriteObjCCategoryImplDecl(ObjCCategoryImplDecl *CDecl, 00333 std::string &Result) = 0; 00334 virtual void RewriteObjCProtocolMetaData(ObjCProtocolDecl *Protocol, 00335 StringRef prefix, 00336 StringRef ClassName, 00337 std::string &Result) = 0; 00338 virtual void RewriteObjCClassMetaData(ObjCImplementationDecl *IDecl, 00339 std::string &Result) = 0; 00340 00341 // Rewriting ivar access 00342 virtual Stmt *RewriteObjCIvarRefExpr(ObjCIvarRefExpr *IV) = 0; 00343 virtual void RewriteIvarOffsetComputation(ObjCIvarDecl *ivar, 00344 std::string &Result) = 0; 00345 00346 // Misc. AST transformation routines. Sometimes they end up calling 00347 // rewriting routines on the new ASTs. 00348 CallExpr *SynthesizeCallToFunctionDecl(FunctionDecl *FD, 00349 Expr **args, unsigned nargs, 00350 SourceLocation StartLoc=SourceLocation(), 00351 SourceLocation EndLoc=SourceLocation()); 00352 CallExpr *SynthMsgSendStretCallExpr(FunctionDecl *MsgSendStretFlavor, 00353 QualType msgSendType, 00354 QualType returnType, 00355 SmallVectorImpl<QualType> &ArgTypes, 00356 SmallVectorImpl<Expr*> &MsgExprs, 00357 ObjCMethodDecl *Method); 00358 Stmt *SynthMessageExpr(ObjCMessageExpr *Exp, 00359 SourceLocation StartLoc=SourceLocation(), 00360 SourceLocation EndLoc=SourceLocation()); 00361 00362 void SynthCountByEnumWithState(std::string &buf); 00363 void SynthMsgSendFunctionDecl(); 00364 void SynthMsgSendSuperFunctionDecl(); 00365 void SynthMsgSendStretFunctionDecl(); 00366 void SynthMsgSendFpretFunctionDecl(); 00367 void SynthMsgSendSuperStretFunctionDecl(); 00368 void SynthGetClassFunctionDecl(); 00369 void SynthGetMetaClassFunctionDecl(); 00370 void SynthGetSuperClassFunctionDecl(); 00371 void SynthSelGetUidFunctionDecl(); 00372 void SynthSuperConstructorFunctionDecl(); 00373 00374 std::string SynthesizeByrefCopyDestroyHelper(VarDecl *VD, int flag); 00375 std::string SynthesizeBlockHelperFuncs(BlockExpr *CE, int i, 00376 StringRef funcName, std::string Tag); 00377 std::string SynthesizeBlockFunc(BlockExpr *CE, int i, 00378 StringRef funcName, std::string Tag); 00379 std::string SynthesizeBlockImpl(BlockExpr *CE, 00380 std::string Tag, std::string Desc); 00381 std::string SynthesizeBlockDescriptor(std::string DescTag, 00382 std::string ImplTag, 00383 int i, StringRef funcName, 00384 unsigned hasCopy); 00385 Stmt *SynthesizeBlockCall(CallExpr *Exp, const Expr* BlockExp); 00386 void SynthesizeBlockLiterals(SourceLocation FunLocStart, 00387 StringRef FunName); 00388 FunctionDecl *SynthBlockInitFunctionDecl(StringRef name); 00389 Stmt *SynthBlockInitExpr(BlockExpr *Exp, 00390 const SmallVectorImpl<DeclRefExpr *> &InnerBlockDeclRefs); 00391 00392 // Misc. helper routines. 00393 QualType getProtocolType(); 00394 void WarnAboutReturnGotoStmts(Stmt *S); 00395 void HasReturnStmts(Stmt *S, bool &hasReturns); 00396 void CheckFunctionPointerDecl(QualType dType, NamedDecl *ND); 00397 void InsertBlockLiteralsWithinFunction(FunctionDecl *FD); 00398 void InsertBlockLiteralsWithinMethod(ObjCMethodDecl *MD); 00399 00400 bool IsDeclStmtInForeachHeader(DeclStmt *DS); 00401 void CollectBlockDeclRefInfo(BlockExpr *Exp); 00402 void GetBlockDeclRefExprs(Stmt *S); 00403 void GetInnerBlockDeclRefExprs(Stmt *S, 00404 SmallVectorImpl<DeclRefExpr *> &InnerBlockDeclRefs, 00405 llvm::SmallPtrSetImpl<const DeclContext *> &InnerContexts); 00406 00407 // We avoid calling Type::isBlockPointerType(), since it operates on the 00408 // canonical type. We only care if the top-level type is a closure pointer. 00409 bool isTopLevelBlockPointerType(QualType T) { 00410 return isa<BlockPointerType>(T); 00411 } 00412 00413 /// convertBlockPointerToFunctionPointer - Converts a block-pointer type 00414 /// to a function pointer type and upon success, returns true; false 00415 /// otherwise. 00416 bool convertBlockPointerToFunctionPointer(QualType &T) { 00417 if (isTopLevelBlockPointerType(T)) { 00418 const BlockPointerType *BPT = T->getAs<BlockPointerType>(); 00419 T = Context->getPointerType(BPT->getPointeeType()); 00420 return true; 00421 } 00422 return false; 00423 } 00424 00425 bool needToScanForQualifiers(QualType T); 00426 QualType getSuperStructType(); 00427 QualType getConstantStringStructType(); 00428 QualType convertFunctionTypeOfBlocks(const FunctionType *FT); 00429 bool BufferContainsPPDirectives(const char *startBuf, const char *endBuf); 00430 00431 void convertToUnqualifiedObjCType(QualType &T) { 00432 if (T->isObjCQualifiedIdType()) 00433 T = Context->getObjCIdType(); 00434 else if (T->isObjCQualifiedClassType()) 00435 T = Context->getObjCClassType(); 00436 else if (T->isObjCObjectPointerType() && 00437 T->getPointeeType()->isObjCQualifiedInterfaceType()) { 00438 if (const ObjCObjectPointerType * OBJPT = 00439 T->getAsObjCInterfacePointerType()) { 00440 const ObjCInterfaceType *IFaceT = OBJPT->getInterfaceType(); 00441 T = QualType(IFaceT, 0); 00442 T = Context->getPointerType(T); 00443 } 00444 } 00445 } 00446 00447 // FIXME: This predicate seems like it would be useful to add to ASTContext. 00448 bool isObjCType(QualType T) { 00449 if (!LangOpts.ObjC1 && !LangOpts.ObjC2) 00450 return false; 00451 00452 QualType OCT = Context->getCanonicalType(T).getUnqualifiedType(); 00453 00454 if (OCT == Context->getCanonicalType(Context->getObjCIdType()) || 00455 OCT == Context->getCanonicalType(Context->getObjCClassType())) 00456 return true; 00457 00458 if (const PointerType *PT = OCT->getAs<PointerType>()) { 00459 if (isa<ObjCInterfaceType>(PT->getPointeeType()) || 00460 PT->getPointeeType()->isObjCQualifiedIdType()) 00461 return true; 00462 } 00463 return false; 00464 } 00465 bool PointerTypeTakesAnyBlockArguments(QualType QT); 00466 bool PointerTypeTakesAnyObjCQualifiedType(QualType QT); 00467 void GetExtentOfArgList(const char *Name, const char *&LParen, 00468 const char *&RParen); 00469 00470 void QuoteDoublequotes(std::string &From, std::string &To) { 00471 for (unsigned i = 0; i < From.length(); i++) { 00472 if (From[i] == '"') 00473 To += "\\\""; 00474 else 00475 To += From[i]; 00476 } 00477 } 00478 00479 QualType getSimpleFunctionType(QualType result, 00480 ArrayRef<QualType> args, 00481 bool variadic = false) { 00482 if (result == Context->getObjCInstanceType()) 00483 result = Context->getObjCIdType(); 00484 FunctionProtoType::ExtProtoInfo fpi; 00485 fpi.Variadic = variadic; 00486 return Context->getFunctionType(result, args, fpi); 00487 } 00488 00489 // Helper function: create a CStyleCastExpr with trivial type source info. 00490 CStyleCastExpr* NoTypeInfoCStyleCastExpr(ASTContext *Ctx, QualType Ty, 00491 CastKind Kind, Expr *E) { 00492 TypeSourceInfo *TInfo = Ctx->getTrivialTypeSourceInfo(Ty, SourceLocation()); 00493 return CStyleCastExpr::Create(*Ctx, Ty, VK_RValue, Kind, E, nullptr, 00494 TInfo, SourceLocation(), SourceLocation()); 00495 } 00496 00497 StringLiteral *getStringLiteral(StringRef Str) { 00498 QualType StrType = Context->getConstantArrayType( 00499 Context->CharTy, llvm::APInt(32, Str.size() + 1), ArrayType::Normal, 00500 0); 00501 return StringLiteral::Create(*Context, Str, StringLiteral::Ascii, 00502 /*Pascal=*/false, StrType, SourceLocation()); 00503 } 00504 }; 00505 00506 class RewriteObjCFragileABI : public RewriteObjC { 00507 public: 00508 00509 RewriteObjCFragileABI(std::string inFile, raw_ostream *OS, 00510 DiagnosticsEngine &D, const LangOptions &LOpts, 00511 bool silenceMacroWarn) : RewriteObjC(inFile, OS, 00512 D, LOpts, 00513 silenceMacroWarn) {} 00514 00515 ~RewriteObjCFragileABI() {} 00516 void Initialize(ASTContext &context) override; 00517 00518 // Rewriting metadata 00519 template<typename MethodIterator> 00520 void RewriteObjCMethodsMetaData(MethodIterator MethodBegin, 00521 MethodIterator MethodEnd, 00522 bool IsInstanceMethod, 00523 StringRef prefix, 00524 StringRef ClassName, 00525 std::string &Result); 00526 void RewriteObjCProtocolMetaData(ObjCProtocolDecl *Protocol, 00527 StringRef prefix, StringRef ClassName, 00528 std::string &Result) override; 00529 void RewriteObjCProtocolListMetaData( 00530 const ObjCList<ObjCProtocolDecl> &Prots, 00531 StringRef prefix, StringRef ClassName, std::string &Result) override; 00532 void RewriteObjCClassMetaData(ObjCImplementationDecl *IDecl, 00533 std::string &Result) override; 00534 void RewriteMetaDataIntoBuffer(std::string &Result) override; 00535 void RewriteObjCCategoryImplDecl(ObjCCategoryImplDecl *CDecl, 00536 std::string &Result) override; 00537 00538 // Rewriting ivar 00539 void RewriteIvarOffsetComputation(ObjCIvarDecl *ivar, 00540 std::string &Result) override; 00541 Stmt *RewriteObjCIvarRefExpr(ObjCIvarRefExpr *IV) override; 00542 }; 00543 } 00544 00545 void RewriteObjC::RewriteBlocksInFunctionProtoType(QualType funcType, 00546 NamedDecl *D) { 00547 if (const FunctionProtoType *fproto 00548 = dyn_cast<FunctionProtoType>(funcType.IgnoreParens())) { 00549 for (const auto &I : fproto->param_types()) 00550 if (isTopLevelBlockPointerType(I)) { 00551 // All the args are checked/rewritten. Don't call twice! 00552 RewriteBlockPointerDecl(D); 00553 break; 00554 } 00555 } 00556 } 00557 00558 void RewriteObjC::CheckFunctionPointerDecl(QualType funcType, NamedDecl *ND) { 00559 const PointerType *PT = funcType->getAs<PointerType>(); 00560 if (PT && PointerTypeTakesAnyBlockArguments(funcType)) 00561 RewriteBlocksInFunctionProtoType(PT->getPointeeType(), ND); 00562 } 00563 00564 static bool IsHeaderFile(const std::string &Filename) { 00565 std::string::size_type DotPos = Filename.rfind('.'); 00566 00567 if (DotPos == std::string::npos) { 00568 // no file extension 00569 return false; 00570 } 00571 00572 std::string Ext = std::string(Filename.begin()+DotPos+1, Filename.end()); 00573 // C header: .h 00574 // C++ header: .hh or .H; 00575 return Ext == "h" || Ext == "hh" || Ext == "H"; 00576 } 00577 00578 RewriteObjC::RewriteObjC(std::string inFile, raw_ostream* OS, 00579 DiagnosticsEngine &D, const LangOptions &LOpts, 00580 bool silenceMacroWarn) 00581 : Diags(D), LangOpts(LOpts), InFileName(inFile), OutFile(OS), 00582 SilenceRewriteMacroWarning(silenceMacroWarn) { 00583 IsHeader = IsHeaderFile(inFile); 00584 RewriteFailedDiag = Diags.getCustomDiagID(DiagnosticsEngine::Warning, 00585 "rewriting sub-expression within a macro (may not be correct)"); 00586 TryFinallyContainsReturnDiag = Diags.getCustomDiagID( 00587 DiagnosticsEngine::Warning, 00588 "rewriter doesn't support user-specified control flow semantics " 00589 "for @try/@finally (code may not execute properly)"); 00590 } 00591 00592 std::unique_ptr<ASTConsumer> 00593 clang::CreateObjCRewriter(const std::string &InFile, raw_ostream *OS, 00594 DiagnosticsEngine &Diags, const LangOptions &LOpts, 00595 bool SilenceRewriteMacroWarning) { 00596 return llvm::make_unique<RewriteObjCFragileABI>(InFile, OS, Diags, LOpts, 00597 SilenceRewriteMacroWarning); 00598 } 00599 00600 void RewriteObjC::InitializeCommon(ASTContext &context) { 00601 Context = &context; 00602 SM = &Context->getSourceManager(); 00603 TUDecl = Context->getTranslationUnitDecl(); 00604 MsgSendFunctionDecl = nullptr; 00605 MsgSendSuperFunctionDecl = nullptr; 00606 MsgSendStretFunctionDecl = nullptr; 00607 MsgSendSuperStretFunctionDecl = nullptr; 00608 MsgSendFpretFunctionDecl = nullptr; 00609 GetClassFunctionDecl = nullptr; 00610 GetMetaClassFunctionDecl = nullptr; 00611 GetSuperClassFunctionDecl = nullptr; 00612 SelGetUidFunctionDecl = nullptr; 00613 CFStringFunctionDecl = nullptr; 00614 ConstantStringClassReference = nullptr; 00615 NSStringRecord = nullptr; 00616 CurMethodDef = nullptr; 00617 CurFunctionDef = nullptr; 00618 CurFunctionDeclToDeclareForBlock = nullptr; 00619 GlobalVarDecl = nullptr; 00620 SuperStructDecl = nullptr; 00621 ProtocolTypeDecl = nullptr; 00622 ConstantStringDecl = nullptr; 00623 BcLabelCount = 0; 00624 SuperConstructorFunctionDecl = nullptr; 00625 NumObjCStringLiterals = 0; 00626 PropParentMap = nullptr; 00627 CurrentBody = nullptr; 00628 DisableReplaceStmt = false; 00629 objc_impl_method = false; 00630 00631 // Get the ID and start/end of the main file. 00632 MainFileID = SM->getMainFileID(); 00633 const llvm::MemoryBuffer *MainBuf = SM->getBuffer(MainFileID); 00634 MainFileStart = MainBuf->getBufferStart(); 00635 MainFileEnd = MainBuf->getBufferEnd(); 00636 00637 Rewrite.setSourceMgr(Context->getSourceManager(), Context->getLangOpts()); 00638 } 00639 00640 //===----------------------------------------------------------------------===// 00641 // Top Level Driver Code 00642 //===----------------------------------------------------------------------===// 00643 00644 void RewriteObjC::HandleTopLevelSingleDecl(Decl *D) { 00645 if (Diags.hasErrorOccurred()) 00646 return; 00647 00648 // Two cases: either the decl could be in the main file, or it could be in a 00649 // #included file. If the former, rewrite it now. If the later, check to see 00650 // if we rewrote the #include/#import. 00651 SourceLocation Loc = D->getLocation(); 00652 Loc = SM->getExpansionLoc(Loc); 00653 00654 // If this is for a builtin, ignore it. 00655 if (Loc.isInvalid()) return; 00656 00657 // Look for built-in declarations that we need to refer during the rewrite. 00658 if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { 00659 RewriteFunctionDecl(FD); 00660 } else if (VarDecl *FVD = dyn_cast<VarDecl>(D)) { 00661 // declared in <Foundation/NSString.h> 00662 if (FVD->getName() == "_NSConstantStringClassReference") { 00663 ConstantStringClassReference = FVD; 00664 return; 00665 } 00666 } else if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(D)) { 00667 if (ID->isThisDeclarationADefinition()) 00668 RewriteInterfaceDecl(ID); 00669 } else if (ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(D)) { 00670 RewriteCategoryDecl(CD); 00671 } else if (ObjCProtocolDecl *PD = dyn_cast<ObjCProtocolDecl>(D)) { 00672 if (PD->isThisDeclarationADefinition()) 00673 RewriteProtocolDecl(PD); 00674 } else if (LinkageSpecDecl *LSD = dyn_cast<LinkageSpecDecl>(D)) { 00675 // Recurse into linkage specifications 00676 for (DeclContext::decl_iterator DI = LSD->decls_begin(), 00677 DIEnd = LSD->decls_end(); 00678 DI != DIEnd; ) { 00679 if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>((*DI))) { 00680 if (!IFace->isThisDeclarationADefinition()) { 00681 SmallVector<Decl *, 8> DG; 00682 SourceLocation StartLoc = IFace->getLocStart(); 00683 do { 00684 if (isa<ObjCInterfaceDecl>(*DI) && 00685 !cast<ObjCInterfaceDecl>(*DI)->isThisDeclarationADefinition() && 00686 StartLoc == (*DI)->getLocStart()) 00687 DG.push_back(*DI); 00688 else 00689 break; 00690 00691 ++DI; 00692 } while (DI != DIEnd); 00693 RewriteForwardClassDecl(DG); 00694 continue; 00695 } 00696 } 00697 00698 if (ObjCProtocolDecl *Proto = dyn_cast<ObjCProtocolDecl>((*DI))) { 00699 if (!Proto->isThisDeclarationADefinition()) { 00700 SmallVector<Decl *, 8> DG; 00701 SourceLocation StartLoc = Proto->getLocStart(); 00702 do { 00703 if (isa<ObjCProtocolDecl>(*DI) && 00704 !cast<ObjCProtocolDecl>(*DI)->isThisDeclarationADefinition() && 00705 StartLoc == (*DI)->getLocStart()) 00706 DG.push_back(*DI); 00707 else 00708 break; 00709 00710 ++DI; 00711 } while (DI != DIEnd); 00712 RewriteForwardProtocolDecl(DG); 00713 continue; 00714 } 00715 } 00716 00717 HandleTopLevelSingleDecl(*DI); 00718 ++DI; 00719 } 00720 } 00721 // If we have a decl in the main file, see if we should rewrite it. 00722 if (SM->isWrittenInMainFile(Loc)) 00723 return HandleDeclInMainFile(D); 00724 } 00725 00726 //===----------------------------------------------------------------------===// 00727 // Syntactic (non-AST) Rewriting Code 00728 //===----------------------------------------------------------------------===// 00729 00730 void RewriteObjC::RewriteInclude() { 00731 SourceLocation LocStart = SM->getLocForStartOfFile(MainFileID); 00732 StringRef MainBuf = SM->getBufferData(MainFileID); 00733 const char *MainBufStart = MainBuf.begin(); 00734 const char *MainBufEnd = MainBuf.end(); 00735 size_t ImportLen = strlen("import"); 00736 00737 // Loop over the whole file, looking for includes. 00738 for (const char *BufPtr = MainBufStart; BufPtr < MainBufEnd; ++BufPtr) { 00739 if (*BufPtr == '#') { 00740 if (++BufPtr == MainBufEnd) 00741 return; 00742 while (*BufPtr == ' ' || *BufPtr == '\t') 00743 if (++BufPtr == MainBufEnd) 00744 return; 00745 if (!strncmp(BufPtr, "import", ImportLen)) { 00746 // replace import with include 00747 SourceLocation ImportLoc = 00748 LocStart.getLocWithOffset(BufPtr-MainBufStart); 00749 ReplaceText(ImportLoc, ImportLen, "include"); 00750 BufPtr += ImportLen; 00751 } 00752 } 00753 } 00754 } 00755 00756 static std::string getIvarAccessString(ObjCIvarDecl *OID) { 00757 const ObjCInterfaceDecl *ClassDecl = OID->getContainingInterface(); 00758 std::string S; 00759 S = "((struct "; 00760 S += ClassDecl->getIdentifier()->getName(); 00761 S += "_IMPL *)self)->"; 00762 S += OID->getName(); 00763 return S; 00764 } 00765 00766 void RewriteObjC::RewritePropertyImplDecl(ObjCPropertyImplDecl *PID, 00767 ObjCImplementationDecl *IMD, 00768 ObjCCategoryImplDecl *CID) { 00769 static bool objcGetPropertyDefined = false; 00770 static bool objcSetPropertyDefined = false; 00771 SourceLocation startLoc = PID->getLocStart(); 00772 InsertText(startLoc, "// "); 00773 const char *startBuf = SM->getCharacterData(startLoc); 00774 assert((*startBuf == '@') && "bogus @synthesize location"); 00775 const char *semiBuf = strchr(startBuf, ';'); 00776 assert((*semiBuf == ';') && "@synthesize: can't find ';'"); 00777 SourceLocation onePastSemiLoc = 00778 startLoc.getLocWithOffset(semiBuf-startBuf+1); 00779 00780 if (PID->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic) 00781 return; // FIXME: is this correct? 00782 00783 // Generate the 'getter' function. 00784 ObjCPropertyDecl *PD = PID->getPropertyDecl(); 00785 ObjCIvarDecl *OID = PID->getPropertyIvarDecl(); 00786 00787 if (!OID) 00788 return; 00789 unsigned Attributes = PD->getPropertyAttributes(); 00790 if (!PD->getGetterMethodDecl()->isDefined()) { 00791 bool GenGetProperty = !(Attributes & ObjCPropertyDecl::OBJC_PR_nonatomic) && 00792 (Attributes & (ObjCPropertyDecl::OBJC_PR_retain | 00793 ObjCPropertyDecl::OBJC_PR_copy)); 00794 std::string Getr; 00795 if (GenGetProperty && !objcGetPropertyDefined) { 00796 objcGetPropertyDefined = true; 00797 // FIXME. Is this attribute correct in all cases? 00798 Getr = "\nextern \"C\" __declspec(dllimport) " 00799 "id objc_getProperty(id, SEL, long, bool);\n"; 00800 } 00801 RewriteObjCMethodDecl(OID->getContainingInterface(), 00802 PD->getGetterMethodDecl(), Getr); 00803 Getr += "{ "; 00804 // Synthesize an explicit cast to gain access to the ivar. 00805 // See objc-act.c:objc_synthesize_new_getter() for details. 00806 if (GenGetProperty) { 00807 // return objc_getProperty(self, _cmd, offsetof(ClassDecl, OID), 1) 00808 Getr += "typedef "; 00809 const FunctionType *FPRetType = nullptr; 00810 RewriteTypeIntoString(PD->getGetterMethodDecl()->getReturnType(), Getr, 00811 FPRetType); 00812 Getr += " _TYPE"; 00813 if (FPRetType) { 00814 Getr += ")"; // close the precedence "scope" for "*". 00815 00816 // Now, emit the argument types (if any). 00817 if (const FunctionProtoType *FT = dyn_cast<FunctionProtoType>(FPRetType)){ 00818 Getr += "("; 00819 for (unsigned i = 0, e = FT->getNumParams(); i != e; ++i) { 00820 if (i) Getr += ", "; 00821 std::string ParamStr = 00822 FT->getParamType(i).getAsString(Context->getPrintingPolicy()); 00823 Getr += ParamStr; 00824 } 00825 if (FT->isVariadic()) { 00826 if (FT->getNumParams()) 00827 Getr += ", "; 00828 Getr += "..."; 00829 } 00830 Getr += ")"; 00831 } else 00832 Getr += "()"; 00833 } 00834 Getr += ";\n"; 00835 Getr += "return (_TYPE)"; 00836 Getr += "objc_getProperty(self, _cmd, "; 00837 RewriteIvarOffsetComputation(OID, Getr); 00838 Getr += ", 1)"; 00839 } 00840 else 00841 Getr += "return " + getIvarAccessString(OID); 00842 Getr += "; }"; 00843 InsertText(onePastSemiLoc, Getr); 00844 } 00845 00846 if (PD->isReadOnly() || PD->getSetterMethodDecl()->isDefined()) 00847 return; 00848 00849 // Generate the 'setter' function. 00850 std::string Setr; 00851 bool GenSetProperty = Attributes & (ObjCPropertyDecl::OBJC_PR_retain | 00852 ObjCPropertyDecl::OBJC_PR_copy); 00853 if (GenSetProperty && !objcSetPropertyDefined) { 00854 objcSetPropertyDefined = true; 00855 // FIXME. Is this attribute correct in all cases? 00856 Setr = "\nextern \"C\" __declspec(dllimport) " 00857 "void objc_setProperty (id, SEL, long, id, bool, bool);\n"; 00858 } 00859 00860 RewriteObjCMethodDecl(OID->getContainingInterface(), 00861 PD->getSetterMethodDecl(), Setr); 00862 Setr += "{ "; 00863 // Synthesize an explicit cast to initialize the ivar. 00864 // See objc-act.c:objc_synthesize_new_setter() for details. 00865 if (GenSetProperty) { 00866 Setr += "objc_setProperty (self, _cmd, "; 00867 RewriteIvarOffsetComputation(OID, Setr); 00868 Setr += ", (id)"; 00869 Setr += PD->getName(); 00870 Setr += ", "; 00871 if (Attributes & ObjCPropertyDecl::OBJC_PR_nonatomic) 00872 Setr += "0, "; 00873 else 00874 Setr += "1, "; 00875 if (Attributes & ObjCPropertyDecl::OBJC_PR_copy) 00876 Setr += "1)"; 00877 else 00878 Setr += "0)"; 00879 } 00880 else { 00881 Setr += getIvarAccessString(OID) + " = "; 00882 Setr += PD->getName(); 00883 } 00884 Setr += "; }"; 00885 InsertText(onePastSemiLoc, Setr); 00886 } 00887 00888 static void RewriteOneForwardClassDecl(ObjCInterfaceDecl *ForwardDecl, 00889 std::string &typedefString) { 00890 typedefString += "#ifndef _REWRITER_typedef_"; 00891 typedefString += ForwardDecl->getNameAsString(); 00892 typedefString += "\n"; 00893 typedefString += "#define _REWRITER_typedef_"; 00894 typedefString += ForwardDecl->getNameAsString(); 00895 typedefString += "\n"; 00896 typedefString += "typedef struct objc_object "; 00897 typedefString += ForwardDecl->getNameAsString(); 00898 typedefString += ";\n#endif\n"; 00899 } 00900 00901 void RewriteObjC::RewriteForwardClassEpilogue(ObjCInterfaceDecl *ClassDecl, 00902 const std::string &typedefString) { 00903 SourceLocation startLoc = ClassDecl->getLocStart(); 00904 const char *startBuf = SM->getCharacterData(startLoc); 00905 const char *semiPtr = strchr(startBuf, ';'); 00906 // Replace the @class with typedefs corresponding to the classes. 00907 ReplaceText(startLoc, semiPtr-startBuf+1, typedefString); 00908 } 00909 00910 void RewriteObjC::RewriteForwardClassDecl(DeclGroupRef D) { 00911 std::string typedefString; 00912 for (DeclGroupRef::iterator I = D.begin(), E = D.end(); I != E; ++I) { 00913 ObjCInterfaceDecl *ForwardDecl = cast<ObjCInterfaceDecl>(*I); 00914 if (I == D.begin()) { 00915 // Translate to typedef's that forward reference structs with the same name 00916 // as the class. As a convenience, we include the original declaration 00917 // as a comment. 00918 typedefString += "// @class "; 00919 typedefString += ForwardDecl->getNameAsString(); 00920 typedefString += ";\n"; 00921 } 00922 RewriteOneForwardClassDecl(ForwardDecl, typedefString); 00923 } 00924 DeclGroupRef::iterator I = D.begin(); 00925 RewriteForwardClassEpilogue(cast<ObjCInterfaceDecl>(*I), typedefString); 00926 } 00927 00928 void RewriteObjC::RewriteForwardClassDecl(const SmallVectorImpl<Decl *> &D) { 00929 std::string typedefString; 00930 for (unsigned i = 0; i < D.size(); i++) { 00931 ObjCInterfaceDecl *ForwardDecl = cast<ObjCInterfaceDecl>(D[i]); 00932 if (i == 0) { 00933 typedefString += "// @class "; 00934 typedefString += ForwardDecl->getNameAsString(); 00935 typedefString += ";\n"; 00936 } 00937 RewriteOneForwardClassDecl(ForwardDecl, typedefString); 00938 } 00939 RewriteForwardClassEpilogue(cast<ObjCInterfaceDecl>(D[0]), typedefString); 00940 } 00941 00942 void RewriteObjC::RewriteMethodDeclaration(ObjCMethodDecl *Method) { 00943 // When method is a synthesized one, such as a getter/setter there is 00944 // nothing to rewrite. 00945 if (Method->isImplicit()) 00946 return; 00947 SourceLocation LocStart = Method->getLocStart(); 00948 SourceLocation LocEnd = Method->getLocEnd(); 00949 00950 if (SM->getExpansionLineNumber(LocEnd) > 00951 SM->getExpansionLineNumber(LocStart)) { 00952 InsertText(LocStart, "#if 0\n"); 00953 ReplaceText(LocEnd, 1, ";\n#endif\n"); 00954 } else { 00955 InsertText(LocStart, "// "); 00956 } 00957 } 00958 00959 void RewriteObjC::RewriteProperty(ObjCPropertyDecl *prop) { 00960 SourceLocation Loc = prop->getAtLoc(); 00961 00962 ReplaceText(Loc, 0, "// "); 00963 // FIXME: handle properties that are declared across multiple lines. 00964 } 00965 00966 void RewriteObjC::RewriteCategoryDecl(ObjCCategoryDecl *CatDecl) { 00967 SourceLocation LocStart = CatDecl->getLocStart(); 00968 00969 // FIXME: handle category headers that are declared across multiple lines. 00970 ReplaceText(LocStart, 0, "// "); 00971 00972 for (auto *I : CatDecl->properties()) 00973 RewriteProperty(I); 00974 for (auto *I : CatDecl->instance_methods()) 00975 RewriteMethodDeclaration(I); 00976 for (auto *I : CatDecl->class_methods()) 00977 RewriteMethodDeclaration(I); 00978 00979 // Lastly, comment out the @end. 00980 ReplaceText(CatDecl->getAtEndRange().getBegin(), 00981 strlen("@end"), "/* @end */"); 00982 } 00983 00984 void RewriteObjC::RewriteProtocolDecl(ObjCProtocolDecl *PDecl) { 00985 SourceLocation LocStart = PDecl->getLocStart(); 00986 assert(PDecl->isThisDeclarationADefinition()); 00987 00988 // FIXME: handle protocol headers that are declared across multiple lines. 00989 ReplaceText(LocStart, 0, "// "); 00990 00991 for (auto *I : PDecl->instance_methods()) 00992 RewriteMethodDeclaration(I); 00993 for (auto *I : PDecl->class_methods()) 00994 RewriteMethodDeclaration(I); 00995 for (auto *I : PDecl->properties()) 00996 RewriteProperty(I); 00997 00998 // Lastly, comment out the @end. 00999 SourceLocation LocEnd = PDecl->getAtEndRange().getBegin(); 01000 ReplaceText(LocEnd, strlen("@end"), "/* @end */"); 01001 01002 // Must comment out @optional/@required 01003 const char *startBuf = SM->getCharacterData(LocStart); 01004 const char *endBuf = SM->getCharacterData(LocEnd); 01005 for (const char *p = startBuf; p < endBuf; p++) { 01006 if (*p == '@' && !strncmp(p+1, "optional", strlen("optional"))) { 01007 SourceLocation OptionalLoc = LocStart.getLocWithOffset(p-startBuf); 01008 ReplaceText(OptionalLoc, strlen("@optional"), "/* @optional */"); 01009 01010 } 01011 else if (*p == '@' && !strncmp(p+1, "required", strlen("required"))) { 01012 SourceLocation OptionalLoc = LocStart.getLocWithOffset(p-startBuf); 01013 ReplaceText(OptionalLoc, strlen("@required"), "/* @required */"); 01014 01015 } 01016 } 01017 } 01018 01019 void RewriteObjC::RewriteForwardProtocolDecl(DeclGroupRef D) { 01020 SourceLocation LocStart = (*D.begin())->getLocStart(); 01021 if (LocStart.isInvalid()) 01022 llvm_unreachable("Invalid SourceLocation"); 01023 // FIXME: handle forward protocol that are declared across multiple lines. 01024 ReplaceText(LocStart, 0, "// "); 01025 } 01026 01027 void 01028 RewriteObjC::RewriteForwardProtocolDecl(const SmallVectorImpl<Decl *> &DG) { 01029 SourceLocation LocStart = DG[0]->getLocStart(); 01030 if (LocStart.isInvalid()) 01031 llvm_unreachable("Invalid SourceLocation"); 01032 // FIXME: handle forward protocol that are declared across multiple lines. 01033 ReplaceText(LocStart, 0, "// "); 01034 } 01035 01036 void RewriteObjC::RewriteTypeIntoString(QualType T, std::string &ResultStr, 01037 const FunctionType *&FPRetType) { 01038 if (T->isObjCQualifiedIdType()) 01039 ResultStr += "id"; 01040 else if (T->isFunctionPointerType() || 01041 T->isBlockPointerType()) { 01042 // needs special handling, since pointer-to-functions have special 01043 // syntax (where a decaration models use). 01044 QualType retType = T; 01045 QualType PointeeTy; 01046 if (const PointerType* PT = retType->getAs<PointerType>()) 01047 PointeeTy = PT->getPointeeType(); 01048 else if (const BlockPointerType *BPT = retType->getAs<BlockPointerType>()) 01049 PointeeTy = BPT->getPointeeType(); 01050 if ((FPRetType = PointeeTy->getAs<FunctionType>())) { 01051 ResultStr += 01052 FPRetType->getReturnType().getAsString(Context->getPrintingPolicy()); 01053 ResultStr += "(*"; 01054 } 01055 } else 01056 ResultStr += T.getAsString(Context->getPrintingPolicy()); 01057 } 01058 01059 void RewriteObjC::RewriteObjCMethodDecl(const ObjCInterfaceDecl *IDecl, 01060 ObjCMethodDecl *OMD, 01061 std::string &ResultStr) { 01062 //fprintf(stderr,"In RewriteObjCMethodDecl\n"); 01063 const FunctionType *FPRetType = nullptr; 01064 ResultStr += "\nstatic "; 01065 RewriteTypeIntoString(OMD->getReturnType(), ResultStr, FPRetType); 01066 ResultStr += " "; 01067 01068 // Unique method name 01069 std::string NameStr; 01070 01071 if (OMD->isInstanceMethod()) 01072 NameStr += "_I_"; 01073 else 01074 NameStr += "_C_"; 01075 01076 NameStr += IDecl->getNameAsString(); 01077 NameStr += "_"; 01078 01079 if (ObjCCategoryImplDecl *CID = 01080 dyn_cast<ObjCCategoryImplDecl>(OMD->getDeclContext())) { 01081 NameStr += CID->getNameAsString(); 01082 NameStr += "_"; 01083 } 01084 // Append selector names, replacing ':' with '_' 01085 { 01086 std::string selString = OMD->getSelector().getAsString(); 01087 int len = selString.size(); 01088 for (int i = 0; i < len; i++) 01089 if (selString[i] == ':') 01090 selString[i] = '_'; 01091 NameStr += selString; 01092 } 01093 // Remember this name for metadata emission 01094 MethodInternalNames[OMD] = NameStr; 01095 ResultStr += NameStr; 01096 01097 // Rewrite arguments 01098 ResultStr += "("; 01099 01100 // invisible arguments 01101 if (OMD->isInstanceMethod()) { 01102 QualType selfTy = Context->getObjCInterfaceType(IDecl); 01103 selfTy = Context->getPointerType(selfTy); 01104 if (!LangOpts.MicrosoftExt) { 01105 if (ObjCSynthesizedStructs.count(const_cast<ObjCInterfaceDecl*>(IDecl))) 01106 ResultStr += "struct "; 01107 } 01108 // When rewriting for Microsoft, explicitly omit the structure name. 01109 ResultStr += IDecl->getNameAsString(); 01110 ResultStr += " *"; 01111 } 01112 else 01113 ResultStr += Context->getObjCClassType().getAsString( 01114 Context->getPrintingPolicy()); 01115 01116 ResultStr += " self, "; 01117 ResultStr += Context->getObjCSelType().getAsString(Context->getPrintingPolicy()); 01118 ResultStr += " _cmd"; 01119 01120 // Method arguments. 01121 for (const auto *PDecl : OMD->params()) { 01122 ResultStr += ", "; 01123 if (PDecl->getType()->isObjCQualifiedIdType()) { 01124 ResultStr += "id "; 01125 ResultStr += PDecl->getNameAsString(); 01126 } else { 01127 std::string Name = PDecl->getNameAsString(); 01128 QualType QT = PDecl->getType(); 01129 // Make sure we convert "t (^)(...)" to "t (*)(...)". 01130 (void)convertBlockPointerToFunctionPointer(QT); 01131 QT.getAsStringInternal(Name, Context->getPrintingPolicy()); 01132 ResultStr += Name; 01133 } 01134 } 01135 if (OMD->isVariadic()) 01136 ResultStr += ", ..."; 01137 ResultStr += ") "; 01138 01139 if (FPRetType) { 01140 ResultStr += ")"; // close the precedence "scope" for "*". 01141 01142 // Now, emit the argument types (if any). 01143 if (const FunctionProtoType *FT = dyn_cast<FunctionProtoType>(FPRetType)) { 01144 ResultStr += "("; 01145 for (unsigned i = 0, e = FT->getNumParams(); i != e; ++i) { 01146 if (i) ResultStr += ", "; 01147 std::string ParamStr = 01148 FT->getParamType(i).getAsString(Context->getPrintingPolicy()); 01149 ResultStr += ParamStr; 01150 } 01151 if (FT->isVariadic()) { 01152 if (FT->getNumParams()) 01153 ResultStr += ", "; 01154 ResultStr += "..."; 01155 } 01156 ResultStr += ")"; 01157 } else { 01158 ResultStr += "()"; 01159 } 01160 } 01161 } 01162 void RewriteObjC::RewriteImplementationDecl(Decl *OID) { 01163 ObjCImplementationDecl *IMD = dyn_cast<ObjCImplementationDecl>(OID); 01164 ObjCCategoryImplDecl *CID = dyn_cast<ObjCCategoryImplDecl>(OID); 01165 01166 InsertText(IMD ? IMD->getLocStart() : CID->getLocStart(), "// "); 01167 01168 for (auto *OMD : IMD ? IMD->instance_methods() : CID->instance_methods()) { 01169 std::string ResultStr; 01170 RewriteObjCMethodDecl(OMD->getClassInterface(), OMD, ResultStr); 01171 SourceLocation LocStart = OMD->getLocStart(); 01172 SourceLocation LocEnd = OMD->getCompoundBody()->getLocStart(); 01173 01174 const char *startBuf = SM->getCharacterData(LocStart); 01175 const char *endBuf = SM->getCharacterData(LocEnd); 01176 ReplaceText(LocStart, endBuf-startBuf, ResultStr); 01177 } 01178 01179 for (auto *OMD : IMD ? IMD->class_methods() : CID->class_methods()) { 01180 std::string ResultStr; 01181 RewriteObjCMethodDecl(OMD->getClassInterface(), OMD, ResultStr); 01182 SourceLocation LocStart = OMD->getLocStart(); 01183 SourceLocation LocEnd = OMD->getCompoundBody()->getLocStart(); 01184 01185 const char *startBuf = SM->getCharacterData(LocStart); 01186 const char *endBuf = SM->getCharacterData(LocEnd); 01187 ReplaceText(LocStart, endBuf-startBuf, ResultStr); 01188 } 01189 for (auto *I : IMD ? IMD->property_impls() : CID->property_impls()) 01190 RewritePropertyImplDecl(I, IMD, CID); 01191 01192 InsertText(IMD ? IMD->getLocEnd() : CID->getLocEnd(), "// "); 01193 } 01194 01195 void RewriteObjC::RewriteInterfaceDecl(ObjCInterfaceDecl *ClassDecl) { 01196 std::string ResultStr; 01197 if (!ObjCForwardDecls.count(ClassDecl->getCanonicalDecl())) { 01198 // we haven't seen a forward decl - generate a typedef. 01199 ResultStr = "#ifndef _REWRITER_typedef_"; 01200 ResultStr += ClassDecl->getNameAsString(); 01201 ResultStr += "\n"; 01202 ResultStr += "#define _REWRITER_typedef_"; 01203 ResultStr += ClassDecl->getNameAsString(); 01204 ResultStr += "\n"; 01205 ResultStr += "typedef struct objc_object "; 01206 ResultStr += ClassDecl->getNameAsString(); 01207 ResultStr += ";\n#endif\n"; 01208 // Mark this typedef as having been generated. 01209 ObjCForwardDecls.insert(ClassDecl->getCanonicalDecl()); 01210 } 01211 RewriteObjCInternalStruct(ClassDecl, ResultStr); 01212 01213 for (auto *I : ClassDecl->properties()) 01214 RewriteProperty(I); 01215 for (auto *I : ClassDecl->instance_methods()) 01216 RewriteMethodDeclaration(I); 01217 for (auto *I : ClassDecl->class_methods()) 01218 RewriteMethodDeclaration(I); 01219 01220 // Lastly, comment out the @end. 01221 ReplaceText(ClassDecl->getAtEndRange().getBegin(), strlen("@end"), 01222 "/* @end */"); 01223 } 01224 01225 Stmt *RewriteObjC::RewritePropertyOrImplicitSetter(PseudoObjectExpr *PseudoOp) { 01226 SourceRange OldRange = PseudoOp->getSourceRange(); 01227 01228 // We just magically know some things about the structure of this 01229 // expression. 01230 ObjCMessageExpr *OldMsg = 01231 cast<ObjCMessageExpr>(PseudoOp->getSemanticExpr( 01232 PseudoOp->getNumSemanticExprs() - 1)); 01233 01234 // Because the rewriter doesn't allow us to rewrite rewritten code, 01235 // we need to suppress rewriting the sub-statements. 01236 Expr *Base, *RHS; 01237 { 01238 DisableReplaceStmtScope S(*this); 01239 01240 // Rebuild the base expression if we have one. 01241 Base = nullptr; 01242 if (OldMsg->getReceiverKind() == ObjCMessageExpr::Instance) { 01243 Base = OldMsg->getInstanceReceiver(); 01244 Base = cast<OpaqueValueExpr>(Base)->getSourceExpr(); 01245 Base = cast<Expr>(RewriteFunctionBodyOrGlobalInitializer(Base)); 01246 } 01247 01248 // Rebuild the RHS. 01249 RHS = cast<BinaryOperator>(PseudoOp->getSyntacticForm())->getRHS(); 01250 RHS = cast<OpaqueValueExpr>(RHS)->getSourceExpr(); 01251 RHS = cast<Expr>(RewriteFunctionBodyOrGlobalInitializer(RHS)); 01252 } 01253 01254 // TODO: avoid this copy. 01255 SmallVector<SourceLocation, 1> SelLocs; 01256 OldMsg->getSelectorLocs(SelLocs); 01257 01258 ObjCMessageExpr *NewMsg = nullptr; 01259 switch (OldMsg->getReceiverKind()) { 01260 case ObjCMessageExpr::Class: 01261 NewMsg = ObjCMessageExpr::Create(*Context, OldMsg->getType(), 01262 OldMsg->getValueKind(), 01263 OldMsg->getLeftLoc(), 01264 OldMsg->getClassReceiverTypeInfo(), 01265 OldMsg->getSelector(), 01266 SelLocs, 01267 OldMsg->getMethodDecl(), 01268 RHS, 01269 OldMsg->getRightLoc(), 01270 OldMsg->isImplicit()); 01271 break; 01272 01273 case ObjCMessageExpr::Instance: 01274 NewMsg = ObjCMessageExpr::Create(*Context, OldMsg->getType(), 01275 OldMsg->getValueKind(), 01276 OldMsg->getLeftLoc(), 01277 Base, 01278 OldMsg->getSelector(), 01279 SelLocs, 01280 OldMsg->getMethodDecl(), 01281 RHS, 01282 OldMsg->getRightLoc(), 01283 OldMsg->isImplicit()); 01284 break; 01285 01286 case ObjCMessageExpr::SuperClass: 01287 case ObjCMessageExpr::SuperInstance: 01288 NewMsg = ObjCMessageExpr::Create(*Context, OldMsg->getType(), 01289 OldMsg->getValueKind(), 01290 OldMsg->getLeftLoc(), 01291 OldMsg->getSuperLoc(), 01292 OldMsg->getReceiverKind() == ObjCMessageExpr::SuperInstance, 01293 OldMsg->getSuperType(), 01294 OldMsg->getSelector(), 01295 SelLocs, 01296 OldMsg->getMethodDecl(), 01297 RHS, 01298 OldMsg->getRightLoc(), 01299 OldMsg->isImplicit()); 01300 break; 01301 } 01302 01303 Stmt *Replacement = SynthMessageExpr(NewMsg); 01304 ReplaceStmtWithRange(PseudoOp, Replacement, OldRange); 01305 return Replacement; 01306 } 01307 01308 Stmt *RewriteObjC::RewritePropertyOrImplicitGetter(PseudoObjectExpr *PseudoOp) { 01309 SourceRange OldRange = PseudoOp->getSourceRange(); 01310 01311 // We just magically know some things about the structure of this 01312 // expression. 01313 ObjCMessageExpr *OldMsg = 01314 cast<ObjCMessageExpr>(PseudoOp->getResultExpr()->IgnoreImplicit()); 01315 01316 // Because the rewriter doesn't allow us to rewrite rewritten code, 01317 // we need to suppress rewriting the sub-statements. 01318 Expr *Base = nullptr; 01319 { 01320 DisableReplaceStmtScope S(*this); 01321 01322 // Rebuild the base expression if we have one. 01323 if (OldMsg->getReceiverKind() == ObjCMessageExpr::Instance) { 01324 Base = OldMsg->getInstanceReceiver(); 01325 Base = cast<OpaqueValueExpr>(Base)->getSourceExpr(); 01326 Base = cast<Expr>(RewriteFunctionBodyOrGlobalInitializer(Base)); 01327 } 01328 } 01329 01330 // Intentionally empty. 01331 SmallVector<SourceLocation, 1> SelLocs; 01332 SmallVector<Expr*, 1> Args; 01333 01334 ObjCMessageExpr *NewMsg = nullptr; 01335 switch (OldMsg->getReceiverKind()) { 01336 case ObjCMessageExpr::Class: 01337 NewMsg = ObjCMessageExpr::Create(*Context, OldMsg->getType(), 01338 OldMsg->getValueKind(), 01339 OldMsg->getLeftLoc(), 01340 OldMsg->getClassReceiverTypeInfo(), 01341 OldMsg->getSelector(), 01342 SelLocs, 01343 OldMsg->getMethodDecl(), 01344 Args, 01345 OldMsg->getRightLoc(), 01346 OldMsg->isImplicit()); 01347 break; 01348 01349 case ObjCMessageExpr::Instance: 01350 NewMsg = ObjCMessageExpr::Create(*Context, OldMsg->getType(), 01351 OldMsg->getValueKind(), 01352 OldMsg->getLeftLoc(), 01353 Base, 01354 OldMsg->getSelector(), 01355 SelLocs, 01356 OldMsg->getMethodDecl(), 01357 Args, 01358 OldMsg->getRightLoc(), 01359 OldMsg->isImplicit()); 01360 break; 01361 01362 case ObjCMessageExpr::SuperClass: 01363 case ObjCMessageExpr::SuperInstance: 01364 NewMsg = ObjCMessageExpr::Create(*Context, OldMsg->getType(), 01365 OldMsg->getValueKind(), 01366 OldMsg->getLeftLoc(), 01367 OldMsg->getSuperLoc(), 01368 OldMsg->getReceiverKind() == ObjCMessageExpr::SuperInstance, 01369 OldMsg->getSuperType(), 01370 OldMsg->getSelector(), 01371 SelLocs, 01372 OldMsg->getMethodDecl(), 01373 Args, 01374 OldMsg->getRightLoc(), 01375 OldMsg->isImplicit()); 01376 break; 01377 } 01378 01379 Stmt *Replacement = SynthMessageExpr(NewMsg); 01380 ReplaceStmtWithRange(PseudoOp, Replacement, OldRange); 01381 return Replacement; 01382 } 01383 01384 /// SynthCountByEnumWithState - To print: 01385 /// ((unsigned int (*) 01386 /// (id, SEL, struct __objcFastEnumerationState *, id *, unsigned int)) 01387 /// (void *)objc_msgSend)((id)l_collection, 01388 /// sel_registerName( 01389 /// "countByEnumeratingWithState:objects:count:"), 01390 /// &enumState, 01391 /// (id *)__rw_items, (unsigned int)16) 01392 /// 01393 void RewriteObjC::SynthCountByEnumWithState(std::string &buf) { 01394 buf += "((unsigned int (*) (id, SEL, struct __objcFastEnumerationState *, " 01395 "id *, unsigned int))(void *)objc_msgSend)"; 01396 buf += "\n\t\t"; 01397 buf += "((id)l_collection,\n\t\t"; 01398 buf += "sel_registerName(\"countByEnumeratingWithState:objects:count:\"),"; 01399 buf += "\n\t\t"; 01400 buf += "&enumState, " 01401 "(id *)__rw_items, (unsigned int)16)"; 01402 } 01403 01404 /// RewriteBreakStmt - Rewrite for a break-stmt inside an ObjC2's foreach 01405 /// statement to exit to its outer synthesized loop. 01406 /// 01407 Stmt *RewriteObjC::RewriteBreakStmt(BreakStmt *S) { 01408 if (Stmts.empty() || !isa<ObjCForCollectionStmt>(Stmts.back())) 01409 return S; 01410 // replace break with goto __break_label 01411 std::string buf; 01412 01413 SourceLocation startLoc = S->getLocStart(); 01414 buf = "goto __break_label_"; 01415 buf += utostr(ObjCBcLabelNo.back()); 01416 ReplaceText(startLoc, strlen("break"), buf); 01417 01418 return nullptr; 01419 } 01420 01421 /// RewriteContinueStmt - Rewrite for a continue-stmt inside an ObjC2's foreach 01422 /// statement to continue with its inner synthesized loop. 01423 /// 01424 Stmt *RewriteObjC::RewriteContinueStmt(ContinueStmt *S) { 01425 if (Stmts.empty() || !isa<ObjCForCollectionStmt>(Stmts.back())) 01426 return S; 01427 // replace continue with goto __continue_label 01428 std::string buf; 01429 01430 SourceLocation startLoc = S->getLocStart(); 01431 buf = "goto __continue_label_"; 01432 buf += utostr(ObjCBcLabelNo.back()); 01433 ReplaceText(startLoc, strlen("continue"), buf); 01434 01435 return nullptr; 01436 } 01437 01438 /// RewriteObjCForCollectionStmt - Rewriter for ObjC2's foreach statement. 01439 /// It rewrites: 01440 /// for ( type elem in collection) { stmts; } 01441 01442 /// Into: 01443 /// { 01444 /// type elem; 01445 /// struct __objcFastEnumerationState enumState = { 0 }; 01446 /// id __rw_items[16]; 01447 /// id l_collection = (id)collection; 01448 /// unsigned long limit = [l_collection countByEnumeratingWithState:&enumState 01449 /// objects:__rw_items count:16]; 01450 /// if (limit) { 01451 /// unsigned long startMutations = *enumState.mutationsPtr; 01452 /// do { 01453 /// unsigned long counter = 0; 01454 /// do { 01455 /// if (startMutations != *enumState.mutationsPtr) 01456 /// objc_enumerationMutation(l_collection); 01457 /// elem = (type)enumState.itemsPtr[counter++]; 01458 /// stmts; 01459 /// __continue_label: ; 01460 /// } while (counter < limit); 01461 /// } while (limit = [l_collection countByEnumeratingWithState:&enumState 01462 /// objects:__rw_items count:16]); 01463 /// elem = nil; 01464 /// __break_label: ; 01465 /// } 01466 /// else 01467 /// elem = nil; 01468 /// } 01469 /// 01470 Stmt *RewriteObjC::RewriteObjCForCollectionStmt(ObjCForCollectionStmt *S, 01471 SourceLocation OrigEnd) { 01472 assert(!Stmts.empty() && "ObjCForCollectionStmt - Statement stack empty"); 01473 assert(isa<ObjCForCollectionStmt>(Stmts.back()) && 01474 "ObjCForCollectionStmt Statement stack mismatch"); 01475 assert(!ObjCBcLabelNo.empty() && 01476 "ObjCForCollectionStmt - Label No stack empty"); 01477 01478 SourceLocation startLoc = S->getLocStart(); 01479 const char *startBuf = SM->getCharacterData(startLoc); 01480 StringRef elementName; 01481 std::string elementTypeAsString; 01482 std::string buf; 01483 buf = "\n{\n\t"; 01484 if (DeclStmt *DS = dyn_cast<DeclStmt>(S->getElement())) { 01485 // type elem; 01486 NamedDecl* D = cast<NamedDecl>(DS->getSingleDecl()); 01487 QualType ElementType = cast<ValueDecl>(D)->getType(); 01488 if (ElementType->isObjCQualifiedIdType() || 01489 ElementType->isObjCQualifiedInterfaceType()) 01490 // Simply use 'id' for all qualified types. 01491 elementTypeAsString = "id"; 01492 else 01493 elementTypeAsString = ElementType.getAsString(Context->getPrintingPolicy()); 01494 buf += elementTypeAsString; 01495 buf += " "; 01496 elementName = D->getName(); 01497 buf += elementName; 01498 buf += ";\n\t"; 01499 } 01500 else { 01501 DeclRefExpr *DR = cast<DeclRefExpr>(S->getElement()); 01502 elementName = DR->getDecl()->getName(); 01503 ValueDecl *VD = cast<ValueDecl>(DR->getDecl()); 01504 if (VD->getType()->isObjCQualifiedIdType() || 01505 VD->getType()->isObjCQualifiedInterfaceType()) 01506 // Simply use 'id' for all qualified types. 01507 elementTypeAsString = "id"; 01508 else 01509 elementTypeAsString = VD->getType().getAsString(Context->getPrintingPolicy()); 01510 } 01511 01512 // struct __objcFastEnumerationState enumState = { 0 }; 01513 buf += "struct __objcFastEnumerationState enumState = { 0 };\n\t"; 01514 // id __rw_items[16]; 01515 buf += "id __rw_items[16];\n\t"; 01516 // id l_collection = (id) 01517 buf += "id l_collection = (id)"; 01518 // Find start location of 'collection' the hard way! 01519 const char *startCollectionBuf = startBuf; 01520 startCollectionBuf += 3; // skip 'for' 01521 startCollectionBuf = strchr(startCollectionBuf, '('); 01522 startCollectionBuf++; // skip '(' 01523 // find 'in' and skip it. 01524 while (*startCollectionBuf != ' ' || 01525 *(startCollectionBuf+1) != 'i' || *(startCollectionBuf+2) != 'n' || 01526 (*(startCollectionBuf+3) != ' ' && 01527 *(startCollectionBuf+3) != '[' && *(startCollectionBuf+3) != '(')) 01528 startCollectionBuf++; 01529 startCollectionBuf += 3; 01530 01531 // Replace: "for (type element in" with string constructed thus far. 01532 ReplaceText(startLoc, startCollectionBuf - startBuf, buf); 01533 // Replace ')' in for '(' type elem in collection ')' with ';' 01534 SourceLocation rightParenLoc = S->getRParenLoc(); 01535 const char *rparenBuf = SM->getCharacterData(rightParenLoc); 01536 SourceLocation lparenLoc = startLoc.getLocWithOffset(rparenBuf-startBuf); 01537 buf = ";\n\t"; 01538 01539 // unsigned long limit = [l_collection countByEnumeratingWithState:&enumState 01540 // objects:__rw_items count:16]; 01541 // which is synthesized into: 01542 // unsigned int limit = 01543 // ((unsigned int (*) 01544 // (id, SEL, struct __objcFastEnumerationState *, id *, unsigned int)) 01545 // (void *)objc_msgSend)((id)l_collection, 01546 // sel_registerName( 01547 // "countByEnumeratingWithState:objects:count:"), 01548 // (struct __objcFastEnumerationState *)&state, 01549 // (id *)__rw_items, (unsigned int)16); 01550 buf += "unsigned long limit =\n\t\t"; 01551 SynthCountByEnumWithState(buf); 01552 buf += ";\n\t"; 01553 /// if (limit) { 01554 /// unsigned long startMutations = *enumState.mutationsPtr; 01555 /// do { 01556 /// unsigned long counter = 0; 01557 /// do { 01558 /// if (startMutations != *enumState.mutationsPtr) 01559 /// objc_enumerationMutation(l_collection); 01560 /// elem = (type)enumState.itemsPtr[counter++]; 01561 buf += "if (limit) {\n\t"; 01562 buf += "unsigned long startMutations = *enumState.mutationsPtr;\n\t"; 01563 buf += "do {\n\t\t"; 01564 buf += "unsigned long counter = 0;\n\t\t"; 01565 buf += "do {\n\t\t\t"; 01566 buf += "if (startMutations != *enumState.mutationsPtr)\n\t\t\t\t"; 01567 buf += "objc_enumerationMutation(l_collection);\n\t\t\t"; 01568 buf += elementName; 01569 buf += " = ("; 01570 buf += elementTypeAsString; 01571 buf += ")enumState.itemsPtr[counter++];"; 01572 // Replace ')' in for '(' type elem in collection ')' with all of these. 01573 ReplaceText(lparenLoc, 1, buf); 01574 01575 /// __continue_label: ; 01576 /// } while (counter < limit); 01577 /// } while (limit = [l_collection countByEnumeratingWithState:&enumState 01578 /// objects:__rw_items count:16]); 01579 /// elem = nil; 01580 /// __break_label: ; 01581 /// } 01582 /// else 01583 /// elem = nil; 01584 /// } 01585 /// 01586 buf = ";\n\t"; 01587 buf += "__continue_label_"; 01588 buf += utostr(ObjCBcLabelNo.back()); 01589 buf += ": ;"; 01590 buf += "\n\t\t"; 01591 buf += "} while (counter < limit);\n\t"; 01592 buf += "} while (limit = "; 01593 SynthCountByEnumWithState(buf); 01594 buf += ");\n\t"; 01595 buf += elementName; 01596 buf += " = (("; 01597 buf += elementTypeAsString; 01598 buf += ")0);\n\t"; 01599 buf += "__break_label_"; 01600 buf += utostr(ObjCBcLabelNo.back()); 01601 buf += ": ;\n\t"; 01602 buf += "}\n\t"; 01603 buf += "else\n\t\t"; 01604 buf += elementName; 01605 buf += " = (("; 01606 buf += elementTypeAsString; 01607 buf += ")0);\n\t"; 01608 buf += "}\n"; 01609 01610 // Insert all these *after* the statement body. 01611 // FIXME: If this should support Obj-C++, support CXXTryStmt 01612 if (isa<CompoundStmt>(S->getBody())) { 01613 SourceLocation endBodyLoc = OrigEnd.getLocWithOffset(1); 01614 InsertText(endBodyLoc, buf); 01615 } else { 01616 /* Need to treat single statements specially. For example: 01617 * 01618 * for (A *a in b) if (stuff()) break; 01619 * for (A *a in b) xxxyy; 01620 * 01621 * The following code simply scans ahead to the semi to find the actual end. 01622 */ 01623 const char *stmtBuf = SM->getCharacterData(OrigEnd); 01624 const char *semiBuf = strchr(stmtBuf, ';'); 01625 assert(semiBuf && "Can't find ';'"); 01626 SourceLocation endBodyLoc = OrigEnd.getLocWithOffset(semiBuf-stmtBuf+1); 01627 InsertText(endBodyLoc, buf); 01628 } 01629 Stmts.pop_back(); 01630 ObjCBcLabelNo.pop_back(); 01631 return nullptr; 01632 } 01633 01634 /// RewriteObjCSynchronizedStmt - 01635 /// This routine rewrites @synchronized(expr) stmt; 01636 /// into: 01637 /// objc_sync_enter(expr); 01638 /// @try stmt @finally { objc_sync_exit(expr); } 01639 /// 01640 Stmt *RewriteObjC::RewriteObjCSynchronizedStmt(ObjCAtSynchronizedStmt *S) { 01641 // Get the start location and compute the semi location. 01642 SourceLocation startLoc = S->getLocStart(); 01643 const char *startBuf = SM->getCharacterData(startLoc); 01644 01645 assert((*startBuf == '@') && "bogus @synchronized location"); 01646 01647 std::string buf; 01648 buf = "objc_sync_enter((id)"; 01649 const char *lparenBuf = startBuf; 01650 while (*lparenBuf != '(') lparenBuf++; 01651 ReplaceText(startLoc, lparenBuf-startBuf+1, buf); 01652 // We can't use S->getSynchExpr()->getLocEnd() to find the end location, since 01653 // the sync expression is typically a message expression that's already 01654 // been rewritten! (which implies the SourceLocation's are invalid). 01655 SourceLocation endLoc = S->getSynchBody()->getLocStart(); 01656 const char *endBuf = SM->getCharacterData(endLoc); 01657 while (*endBuf != ')') endBuf--; 01658 SourceLocation rparenLoc = startLoc.getLocWithOffset(endBuf-startBuf); 01659 buf = ");\n"; 01660 // declare a new scope with two variables, _stack and _rethrow. 01661 buf += "/* @try scope begin */ \n{ struct _objc_exception_data {\n"; 01662 buf += "int buf[18/*32-bit i386*/];\n"; 01663 buf += "char *pointers[4];} _stack;\n"; 01664 buf += "id volatile _rethrow = 0;\n"; 01665 buf += "objc_exception_try_enter(&_stack);\n"; 01666 buf += "if (!_setjmp(_stack.buf)) /* @try block continue */\n"; 01667 ReplaceText(rparenLoc, 1, buf); 01668 startLoc = S->getSynchBody()->getLocEnd(); 01669 startBuf = SM->getCharacterData(startLoc); 01670 01671 assert((*startBuf == '}') && "bogus @synchronized block"); 01672 SourceLocation lastCurlyLoc = startLoc; 01673 buf = "}\nelse {\n"; 01674 buf += " _rethrow = objc_exception_extract(&_stack);\n"; 01675 buf += "}\n"; 01676 buf += "{ /* implicit finally clause */\n"; 01677 buf += " if (!_rethrow) objc_exception_try_exit(&_stack);\n"; 01678 01679 std::string syncBuf; 01680 syncBuf += " objc_sync_exit("; 01681 01682 Expr *syncExpr = S->getSynchExpr(); 01683 CastKind CK = syncExpr->getType()->isObjCObjectPointerType() 01684 ? CK_BitCast : 01685 syncExpr->getType()->isBlockPointerType() 01686 ? CK_BlockPointerToObjCPointerCast 01687 : CK_CPointerToObjCPointerCast; 01688 syncExpr = NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(), 01689 CK, syncExpr); 01690 std::string syncExprBufS; 01691 llvm::raw_string_ostream syncExprBuf(syncExprBufS); 01692 assert(syncExpr != nullptr && "Expected non-null Expr"); 01693 syncExpr->printPretty(syncExprBuf, nullptr, PrintingPolicy(LangOpts)); 01694 syncBuf += syncExprBuf.str(); 01695 syncBuf += ");"; 01696 01697 buf += syncBuf; 01698 buf += "\n if (_rethrow) objc_exception_throw(_rethrow);\n"; 01699 buf += "}\n"; 01700 buf += "}"; 01701 01702 ReplaceText(lastCurlyLoc, 1, buf); 01703 01704 bool hasReturns = false; 01705 HasReturnStmts(S->getSynchBody(), hasReturns); 01706 if (hasReturns) 01707 RewriteSyncReturnStmts(S->getSynchBody(), syncBuf); 01708 01709 return nullptr; 01710 } 01711 01712 void RewriteObjC::WarnAboutReturnGotoStmts(Stmt *S) 01713 { 01714 // Perform a bottom up traversal of all children. 01715 for (Stmt::child_range CI = S->children(); CI; ++CI) 01716 if (*CI) 01717 WarnAboutReturnGotoStmts(*CI); 01718 01719 if (isa<ReturnStmt>(S) || isa<GotoStmt>(S)) { 01720 Diags.Report(Context->getFullLoc(S->getLocStart()), 01721 TryFinallyContainsReturnDiag); 01722 } 01723 return; 01724 } 01725 01726 void RewriteObjC::HasReturnStmts(Stmt *S, bool &hasReturns) 01727 { 01728 // Perform a bottom up traversal of all children. 01729 for (Stmt::child_range CI = S->children(); CI; ++CI) 01730 if (*CI) 01731 HasReturnStmts(*CI, hasReturns); 01732 01733 if (isa<ReturnStmt>(S)) 01734 hasReturns = true; 01735 return; 01736 } 01737 01738 void RewriteObjC::RewriteTryReturnStmts(Stmt *S) { 01739 // Perform a bottom up traversal of all children. 01740 for (Stmt::child_range CI = S->children(); CI; ++CI) 01741 if (*CI) { 01742 RewriteTryReturnStmts(*CI); 01743 } 01744 if (isa<ReturnStmt>(S)) { 01745 SourceLocation startLoc = S->getLocStart(); 01746 const char *startBuf = SM->getCharacterData(startLoc); 01747 01748 const char *semiBuf = strchr(startBuf, ';'); 01749 assert((*semiBuf == ';') && "RewriteTryReturnStmts: can't find ';'"); 01750 SourceLocation onePastSemiLoc = startLoc.getLocWithOffset(semiBuf-startBuf+1); 01751 01752 std::string buf; 01753 buf = "{ objc_exception_try_exit(&_stack); return"; 01754 01755 ReplaceText(startLoc, 6, buf); 01756 InsertText(onePastSemiLoc, "}"); 01757 } 01758 return; 01759 } 01760 01761 void RewriteObjC::RewriteSyncReturnStmts(Stmt *S, std::string syncExitBuf) { 01762 // Perform a bottom up traversal of all children. 01763 for (Stmt::child_range CI = S->children(); CI; ++CI) 01764 if (*CI) { 01765 RewriteSyncReturnStmts(*CI, syncExitBuf); 01766 } 01767 if (isa<ReturnStmt>(S)) { 01768 SourceLocation startLoc = S->getLocStart(); 01769 const char *startBuf = SM->getCharacterData(startLoc); 01770 01771 const char *semiBuf = strchr(startBuf, ';'); 01772 assert((*semiBuf == ';') && "RewriteSyncReturnStmts: can't find ';'"); 01773 SourceLocation onePastSemiLoc = startLoc.getLocWithOffset(semiBuf-startBuf+1); 01774 01775 std::string buf; 01776 buf = "{ objc_exception_try_exit(&_stack);"; 01777 buf += syncExitBuf; 01778 buf += " return"; 01779 01780 ReplaceText(startLoc, 6, buf); 01781 InsertText(onePastSemiLoc, "}"); 01782 } 01783 return; 01784 } 01785 01786 Stmt *RewriteObjC::RewriteObjCTryStmt(ObjCAtTryStmt *S) { 01787 // Get the start location and compute the semi location. 01788 SourceLocation startLoc = S->getLocStart(); 01789 const char *startBuf = SM->getCharacterData(startLoc); 01790 01791 assert((*startBuf == '@') && "bogus @try location"); 01792 01793 std::string buf; 01794 // declare a new scope with two variables, _stack and _rethrow. 01795 buf = "/* @try scope begin */ { struct _objc_exception_data {\n"; 01796 buf += "int buf[18/*32-bit i386*/];\n"; 01797 buf += "char *pointers[4];} _stack;\n"; 01798 buf += "id volatile _rethrow = 0;\n"; 01799 buf += "objc_exception_try_enter(&_stack);\n"; 01800 buf += "if (!_setjmp(_stack.buf)) /* @try block continue */\n"; 01801 01802 ReplaceText(startLoc, 4, buf); 01803 01804 startLoc = S->getTryBody()->getLocEnd(); 01805 startBuf = SM->getCharacterData(startLoc); 01806 01807 assert((*startBuf == '}') && "bogus @try block"); 01808 01809 SourceLocation lastCurlyLoc = startLoc; 01810 if (S->getNumCatchStmts()) { 01811 startLoc = startLoc.getLocWithOffset(1); 01812 buf = " /* @catch begin */ else {\n"; 01813 buf += " id _caught = objc_exception_extract(&_stack);\n"; 01814 buf += " objc_exception_try_enter (&_stack);\n"; 01815 buf += " if (_setjmp(_stack.buf))\n"; 01816 buf += " _rethrow = objc_exception_extract(&_stack);\n"; 01817 buf += " else { /* @catch continue */"; 01818 01819 InsertText(startLoc, buf); 01820 } else { /* no catch list */ 01821 buf = "}\nelse {\n"; 01822 buf += " _rethrow = objc_exception_extract(&_stack);\n"; 01823 buf += "}"; 01824 ReplaceText(lastCurlyLoc, 1, buf); 01825 } 01826 Stmt *lastCatchBody = nullptr; 01827 for (unsigned I = 0, N = S->getNumCatchStmts(); I != N; ++I) { 01828 ObjCAtCatchStmt *Catch = S->getCatchStmt(I); 01829 VarDecl *catchDecl = Catch->getCatchParamDecl(); 01830 01831 if (I == 0) 01832 buf = "if ("; // we are generating code for the first catch clause 01833 else 01834 buf = "else if ("; 01835 startLoc = Catch->getLocStart(); 01836 startBuf = SM->getCharacterData(startLoc); 01837 01838 assert((*startBuf == '@') && "bogus @catch location"); 01839 01840 const char *lParenLoc = strchr(startBuf, '('); 01841 01842 if (Catch->hasEllipsis()) { 01843 // Now rewrite the body... 01844 lastCatchBody = Catch->getCatchBody(); 01845 SourceLocation bodyLoc = lastCatchBody->getLocStart(); 01846 const char *bodyBuf = SM->getCharacterData(bodyLoc); 01847 assert(*SM->getCharacterData(Catch->getRParenLoc()) == ')' && 01848 "bogus @catch paren location"); 01849 assert((*bodyBuf == '{') && "bogus @catch body location"); 01850 01851 buf += "1) { id _tmp = _caught;"; 01852 Rewrite.ReplaceText(startLoc, bodyBuf-startBuf+1, buf); 01853 } else if (catchDecl) { 01854 QualType t = catchDecl->getType(); 01855 if (t == Context->getObjCIdType()) { 01856 buf += "1) { "; 01857 ReplaceText(startLoc, lParenLoc-startBuf+1, buf); 01858 } else if (const ObjCObjectPointerType *Ptr = 01859 t->getAs<ObjCObjectPointerType>()) { 01860 // Should be a pointer to a class. 01861 ObjCInterfaceDecl *IDecl = Ptr->getObjectType()->getInterface(); 01862 if (IDecl) { 01863 buf += "objc_exception_match((struct objc_class *)objc_getClass(\""; 01864 buf += IDecl->getNameAsString(); 01865 buf += "\"), (struct objc_object *)_caught)) { "; 01866 ReplaceText(startLoc, lParenLoc-startBuf+1, buf); 01867 } 01868 } 01869 // Now rewrite the body... 01870 lastCatchBody = Catch->getCatchBody(); 01871 SourceLocation rParenLoc = Catch->getRParenLoc(); 01872 SourceLocation bodyLoc = lastCatchBody->getLocStart(); 01873 const char *bodyBuf = SM->getCharacterData(bodyLoc); 01874 const char *rParenBuf = SM->getCharacterData(rParenLoc); 01875 assert((*rParenBuf == ')') && "bogus @catch paren location"); 01876 assert((*bodyBuf == '{') && "bogus @catch body location"); 01877 01878 // Here we replace ") {" with "= _caught;" (which initializes and 01879 // declares the @catch parameter). 01880 ReplaceText(rParenLoc, bodyBuf-rParenBuf+1, " = _caught;"); 01881 } else { 01882 llvm_unreachable("@catch rewrite bug"); 01883 } 01884 } 01885 // Complete the catch list... 01886 if (lastCatchBody) { 01887 SourceLocation bodyLoc = lastCatchBody->getLocEnd(); 01888 assert(*SM->getCharacterData(bodyLoc) == '}' && 01889 "bogus @catch body location"); 01890 01891 // Insert the last (implicit) else clause *before* the right curly brace. 01892 bodyLoc = bodyLoc.getLocWithOffset(-1); 01893 buf = "} /* last catch end */\n"; 01894 buf += "else {\n"; 01895 buf += " _rethrow = _caught;\n"; 01896 buf += " objc_exception_try_exit(&_stack);\n"; 01897 buf += "} } /* @catch end */\n"; 01898 if (!S->getFinallyStmt()) 01899 buf += "}\n"; 01900 InsertText(bodyLoc, buf); 01901 01902 // Set lastCurlyLoc 01903 lastCurlyLoc = lastCatchBody->getLocEnd(); 01904 } 01905 if (ObjCAtFinallyStmt *finalStmt = S->getFinallyStmt()) { 01906 startLoc = finalStmt->getLocStart(); 01907 startBuf = SM->getCharacterData(startLoc); 01908 assert((*startBuf == '@') && "bogus @finally start"); 01909 01910 ReplaceText(startLoc, 8, "/* @finally */"); 01911 01912 Stmt *body = finalStmt->getFinallyBody(); 01913 SourceLocation startLoc = body->getLocStart(); 01914 SourceLocation endLoc = body->getLocEnd(); 01915 assert(*SM->getCharacterData(startLoc) == '{' && 01916 "bogus @finally body location"); 01917 assert(*SM->getCharacterData(endLoc) == '}' && 01918 "bogus @finally body location"); 01919 01920 startLoc = startLoc.getLocWithOffset(1); 01921 InsertText(startLoc, " if (!_rethrow) objc_exception_try_exit(&_stack);\n"); 01922 endLoc = endLoc.getLocWithOffset(-1); 01923 InsertText(endLoc, " if (_rethrow) objc_exception_throw(_rethrow);\n"); 01924 01925 // Set lastCurlyLoc 01926 lastCurlyLoc = body->getLocEnd(); 01927 01928 // Now check for any return/continue/go statements within the @try. 01929 WarnAboutReturnGotoStmts(S->getTryBody()); 01930 } else { /* no finally clause - make sure we synthesize an implicit one */ 01931 buf = "{ /* implicit finally clause */\n"; 01932 buf += " if (!_rethrow) objc_exception_try_exit(&_stack);\n"; 01933 buf += " if (_rethrow) objc_exception_throw(_rethrow);\n"; 01934 buf += "}"; 01935 ReplaceText(lastCurlyLoc, 1, buf); 01936 01937 // Now check for any return/continue/go statements within the @try. 01938 // The implicit finally clause won't called if the @try contains any 01939 // jump statements. 01940 bool hasReturns = false; 01941 HasReturnStmts(S->getTryBody(), hasReturns); 01942 if (hasReturns) 01943 RewriteTryReturnStmts(S->getTryBody()); 01944 } 01945 // Now emit the final closing curly brace... 01946 lastCurlyLoc = lastCurlyLoc.getLocWithOffset(1); 01947 InsertText(lastCurlyLoc, " } /* @try scope end */\n"); 01948 return nullptr; 01949 } 01950 01951 // This can't be done with ReplaceStmt(S, ThrowExpr), since 01952 // the throw expression is typically a message expression that's already 01953 // been rewritten! (which implies the SourceLocation's are invalid). 01954 Stmt *RewriteObjC::RewriteObjCThrowStmt(ObjCAtThrowStmt *S) { 01955 // Get the start location and compute the semi location. 01956 SourceLocation startLoc = S->getLocStart(); 01957 const char *startBuf = SM->getCharacterData(startLoc); 01958 01959 assert((*startBuf == '@') && "bogus @throw location"); 01960 01961 std::string buf; 01962 /* void objc_exception_throw(id) __attribute__((noreturn)); */ 01963 if (S->getThrowExpr()) 01964 buf = "objc_exception_throw("; 01965 else // add an implicit argument 01966 buf = "objc_exception_throw(_caught"; 01967 01968 // handle "@ throw" correctly. 01969 const char *wBuf = strchr(startBuf, 'w'); 01970 assert((*wBuf == 'w') && "@throw: can't find 'w'"); 01971 ReplaceText(startLoc, wBuf-startBuf+1, buf); 01972 01973 const char *semiBuf = strchr(startBuf, ';'); 01974 assert((*semiBuf == ';') && "@throw: can't find ';'"); 01975 SourceLocation semiLoc = startLoc.getLocWithOffset(semiBuf-startBuf); 01976 ReplaceText(semiLoc, 1, ");"); 01977 return nullptr; 01978 } 01979 01980 Stmt *RewriteObjC::RewriteAtEncode(ObjCEncodeExpr *Exp) { 01981 // Create a new string expression. 01982 std::string StrEncoding; 01983 Context->getObjCEncodingForType(Exp->getEncodedType(), StrEncoding); 01984 Expr *Replacement = getStringLiteral(StrEncoding); 01985 ReplaceStmt(Exp, Replacement); 01986 01987 // Replace this subexpr in the parent. 01988 // delete Exp; leak for now, see RewritePropertyOrImplicitSetter() usage for more info. 01989 return Replacement; 01990 } 01991 01992 Stmt *RewriteObjC::RewriteAtSelector(ObjCSelectorExpr *Exp) { 01993 if (!SelGetUidFunctionDecl) 01994 SynthSelGetUidFunctionDecl(); 01995 assert(SelGetUidFunctionDecl && "Can't find sel_registerName() decl"); 01996 // Create a call to sel_registerName("selName"). 01997 SmallVector<Expr*, 8> SelExprs; 01998 SelExprs.push_back(getStringLiteral(Exp->getSelector().getAsString())); 01999 CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl, 02000 &SelExprs[0], SelExprs.size()); 02001 ReplaceStmt(Exp, SelExp); 02002 // delete Exp; leak for now, see RewritePropertyOrImplicitSetter() usage for more info. 02003 return SelExp; 02004 } 02005 02006 CallExpr *RewriteObjC::SynthesizeCallToFunctionDecl( 02007 FunctionDecl *FD, Expr **args, unsigned nargs, SourceLocation StartLoc, 02008 SourceLocation EndLoc) { 02009 // Get the type, we will need to reference it in a couple spots. 02010 QualType msgSendType = FD->getType(); 02011 02012 // Create a reference to the objc_msgSend() declaration. 02013 DeclRefExpr *DRE = new (Context) DeclRefExpr(FD, false, msgSendType, 02014 VK_LValue, SourceLocation()); 02015 02016 // Now, we cast the reference to a pointer to the objc_msgSend type. 02017 QualType pToFunc = Context->getPointerType(msgSendType); 02018 ImplicitCastExpr *ICE = 02019 ImplicitCastExpr::Create(*Context, pToFunc, CK_FunctionToPointerDecay, 02020 DRE, nullptr, VK_RValue); 02021 02022 const FunctionType *FT = msgSendType->getAs<FunctionType>(); 02023 02024 CallExpr *Exp = 02025 new (Context) CallExpr(*Context, ICE, llvm::makeArrayRef(args, nargs), 02026 FT->getCallResultType(*Context), 02027 VK_RValue, EndLoc); 02028 return Exp; 02029 } 02030 02031 static bool scanForProtocolRefs(const char *startBuf, const char *endBuf, 02032 const char *&startRef, const char *&endRef) { 02033 while (startBuf < endBuf) { 02034 if (*startBuf == '<') 02035 startRef = startBuf; // mark the start. 02036 if (*startBuf == '>') { 02037 if (startRef && *startRef == '<') { 02038 endRef = startBuf; // mark the end. 02039 return true; 02040 } 02041 return false; 02042 } 02043 startBuf++; 02044 } 02045 return false; 02046 } 02047 02048 static void scanToNextArgument(const char *&argRef) { 02049 int angle = 0; 02050 while (*argRef != ')' && (*argRef != ',' || angle > 0)) { 02051 if (*argRef == '<') 02052 angle++; 02053 else if (*argRef == '>') 02054 angle--; 02055 argRef++; 02056 } 02057 assert(angle == 0 && "scanToNextArgument - bad protocol type syntax"); 02058 } 02059 02060 bool RewriteObjC::needToScanForQualifiers(QualType T) { 02061 if (T->isObjCQualifiedIdType()) 02062 return true; 02063 if (const PointerType *PT = T->getAs<PointerType>()) { 02064 if (PT->getPointeeType()->isObjCQualifiedIdType()) 02065 return true; 02066 } 02067 if (T->isObjCObjectPointerType()) { 02068 T = T->getPointeeType(); 02069 return T->isObjCQualifiedInterfaceType(); 02070 } 02071 if (T->isArrayType()) { 02072 QualType ElemTy = Context->getBaseElementType(T); 02073 return needToScanForQualifiers(ElemTy); 02074 } 02075 return false; 02076 } 02077 02078 void RewriteObjC::RewriteObjCQualifiedInterfaceTypes(Expr *E) { 02079 QualType Type = E->getType(); 02080 if (needToScanForQualifiers(Type)) { 02081 SourceLocation Loc, EndLoc; 02082 02083 if (const CStyleCastExpr *ECE = dyn_cast<CStyleCastExpr>(E)) { 02084 Loc = ECE->getLParenLoc(); 02085 EndLoc = ECE->getRParenLoc(); 02086 } else { 02087 Loc = E->getLocStart(); 02088 EndLoc = E->getLocEnd(); 02089 } 02090 // This will defend against trying to rewrite synthesized expressions. 02091 if (Loc.isInvalid() || EndLoc.isInvalid()) 02092 return; 02093 02094 const char *startBuf = SM->getCharacterData(Loc); 02095 const char *endBuf = SM->getCharacterData(EndLoc); 02096 const char *startRef = nullptr, *endRef = nullptr; 02097 if (scanForProtocolRefs(startBuf, endBuf, startRef, endRef)) { 02098 // Get the locations of the startRef, endRef. 02099 SourceLocation LessLoc = Loc.getLocWithOffset(startRef-startBuf); 02100 SourceLocation GreaterLoc = Loc.getLocWithOffset(endRef-startBuf+1); 02101 // Comment out the protocol references. 02102 InsertText(LessLoc, "/*"); 02103 InsertText(GreaterLoc, "*/"); 02104 } 02105 } 02106 } 02107 02108 void RewriteObjC::RewriteObjCQualifiedInterfaceTypes(Decl *Dcl) { 02109 SourceLocation Loc; 02110 QualType Type; 02111 const FunctionProtoType *proto = nullptr; 02112 if (VarDecl *VD = dyn_cast<VarDecl>(Dcl)) { 02113 Loc = VD->getLocation(); 02114 Type = VD->getType(); 02115 } 02116 else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(Dcl)) { 02117 Loc = FD->getLocation(); 02118 // Check for ObjC 'id' and class types that have been adorned with protocol 02119 // information (id<p>, C<p>*). The protocol references need to be rewritten! 02120 const FunctionType *funcType = FD->getType()->getAs<FunctionType>(); 02121 assert(funcType && "missing function type"); 02122 proto = dyn_cast<FunctionProtoType>(funcType); 02123 if (!proto) 02124 return; 02125 Type = proto->getReturnType(); 02126 } 02127 else if (FieldDecl *FD = dyn_cast<FieldDecl>(Dcl)) { 02128 Loc = FD->getLocation(); 02129 Type = FD->getType(); 02130 } 02131 else 02132 return; 02133 02134 if (needToScanForQualifiers(Type)) { 02135 // Since types are unique, we need to scan the buffer. 02136 02137 const char *endBuf = SM->getCharacterData(Loc); 02138 const char *startBuf = endBuf; 02139 while (*startBuf != ';' && *startBuf != '<' && startBuf != MainFileStart) 02140 startBuf--; // scan backward (from the decl location) for return type. 02141 const char *startRef = nullptr, *endRef = nullptr; 02142 if (scanForProtocolRefs(startBuf, endBuf, startRef, endRef)) { 02143 // Get the locations of the startRef, endRef. 02144 SourceLocation LessLoc = Loc.getLocWithOffset(startRef-endBuf); 02145 SourceLocation GreaterLoc = Loc.getLocWithOffset(endRef-endBuf+1); 02146 // Comment out the protocol references. 02147 InsertText(LessLoc, "/*"); 02148 InsertText(GreaterLoc, "*/"); 02149 } 02150 } 02151 if (!proto) 02152 return; // most likely, was a variable 02153 // Now check arguments. 02154 const char *startBuf = SM->getCharacterData(Loc); 02155 const char *startFuncBuf = startBuf; 02156 for (unsigned i = 0; i < proto->getNumParams(); i++) { 02157 if (needToScanForQualifiers(proto->getParamType(i))) { 02158 // Since types are unique, we need to scan the buffer. 02159 02160 const char *endBuf = startBuf; 02161 // scan forward (from the decl location) for argument types. 02162 scanToNextArgument(endBuf); 02163 const char *startRef = nullptr, *endRef = nullptr; 02164 if (scanForProtocolRefs(startBuf, endBuf, startRef, endRef)) { 02165 // Get the locations of the startRef, endRef. 02166 SourceLocation LessLoc = 02167 Loc.getLocWithOffset(startRef-startFuncBuf); 02168 SourceLocation GreaterLoc = 02169 Loc.getLocWithOffset(endRef-startFuncBuf+1); 02170 // Comment out the protocol references. 02171 InsertText(LessLoc, "/*"); 02172 InsertText(GreaterLoc, "*/"); 02173 } 02174 startBuf = ++endBuf; 02175 } 02176 else { 02177 // If the function name is derived from a macro expansion, then the 02178 // argument buffer will not follow the name. Need to speak with Chris. 02179 while (*startBuf && *startBuf != ')' && *startBuf != ',') 02180 startBuf++; // scan forward (from the decl location) for argument types. 02181 startBuf++; 02182 } 02183 } 02184 } 02185 02186 void RewriteObjC::RewriteTypeOfDecl(VarDecl *ND) { 02187 QualType QT = ND->getType(); 02188 const Type* TypePtr = QT->getAs<Type>(); 02189 if (!isa<TypeOfExprType>(TypePtr)) 02190 return; 02191 while (isa<TypeOfExprType>(TypePtr)) { 02192 const TypeOfExprType *TypeOfExprTypePtr = cast<TypeOfExprType>(TypePtr); 02193 QT = TypeOfExprTypePtr->getUnderlyingExpr()->getType(); 02194 TypePtr = QT->getAs<Type>(); 02195 } 02196 // FIXME. This will not work for multiple declarators; as in: 02197 // __typeof__(a) b,c,d; 02198 std::string TypeAsString(QT.getAsString(Context->getPrintingPolicy())); 02199 SourceLocation DeclLoc = ND->getTypeSpecStartLoc(); 02200 const char *startBuf = SM->getCharacterData(DeclLoc); 02201 if (ND->getInit()) { 02202 std::string Name(ND->getNameAsString()); 02203 TypeAsString += " " + Name + " = "; 02204 Expr *E = ND->getInit(); 02205 SourceLocation startLoc; 02206 if (const CStyleCastExpr *ECE = dyn_cast<CStyleCastExpr>(E)) 02207 startLoc = ECE->getLParenLoc(); 02208 else 02209 startLoc = E->getLocStart(); 02210 startLoc = SM->getExpansionLoc(startLoc); 02211 const char *endBuf = SM->getCharacterData(startLoc); 02212 ReplaceText(DeclLoc, endBuf-startBuf-1, TypeAsString); 02213 } 02214 else { 02215 SourceLocation X = ND->getLocEnd(); 02216 X = SM->getExpansionLoc(X); 02217 const char *endBuf = SM->getCharacterData(X); 02218 ReplaceText(DeclLoc, endBuf-startBuf-1, TypeAsString); 02219 } 02220 } 02221 02222 // SynthSelGetUidFunctionDecl - SEL sel_registerName(const char *str); 02223 void RewriteObjC::SynthSelGetUidFunctionDecl() { 02224 IdentifierInfo *SelGetUidIdent = &Context->Idents.get("sel_registerName"); 02225 SmallVector<QualType, 16> ArgTys; 02226 ArgTys.push_back(Context->getPointerType(Context->CharTy.withConst())); 02227 QualType getFuncType = 02228 getSimpleFunctionType(Context->getObjCSelType(), ArgTys); 02229 SelGetUidFunctionDecl = FunctionDecl::Create(*Context, TUDecl, 02230 SourceLocation(), 02231 SourceLocation(), 02232 SelGetUidIdent, getFuncType, 02233 nullptr, SC_Extern); 02234 } 02235 02236 void RewriteObjC::RewriteFunctionDecl(FunctionDecl *FD) { 02237 // declared in <objc/objc.h> 02238 if (FD->getIdentifier() && 02239 FD->getName() == "sel_registerName") { 02240 SelGetUidFunctionDecl = FD; 02241 return; 02242 } 02243 RewriteObjCQualifiedInterfaceTypes(FD); 02244 } 02245 02246 void RewriteObjC::RewriteBlockPointerType(std::string& Str, QualType Type) { 02247 std::string TypeString(Type.getAsString(Context->getPrintingPolicy())); 02248 const char *argPtr = TypeString.c_str(); 02249 if (!strchr(argPtr, '^')) { 02250 Str += TypeString; 02251 return; 02252 } 02253 while (*argPtr) { 02254 Str += (*argPtr == '^' ? '*' : *argPtr); 02255 argPtr++; 02256 } 02257 } 02258 02259 // FIXME. Consolidate this routine with RewriteBlockPointerType. 02260 void RewriteObjC::RewriteBlockPointerTypeVariable(std::string& Str, 02261 ValueDecl *VD) { 02262 QualType Type = VD->getType(); 02263 std::string TypeString(Type.getAsString(Context->getPrintingPolicy())); 02264 const char *argPtr = TypeString.c_str(); 02265 int paren = 0; 02266 while (*argPtr) { 02267 switch (*argPtr) { 02268 case '(': 02269 Str += *argPtr; 02270 paren++; 02271 break; 02272 case ')': 02273 Str += *argPtr; 02274 paren--; 02275 break; 02276 case '^': 02277 Str += '*'; 02278 if (paren == 1) 02279 Str += VD->getNameAsString(); 02280 break; 02281 default: 02282 Str += *argPtr; 02283 break; 02284 } 02285 argPtr++; 02286 } 02287 } 02288 02289 02290 void RewriteObjC::RewriteBlockLiteralFunctionDecl(FunctionDecl *FD) { 02291 SourceLocation FunLocStart = FD->getTypeSpecStartLoc(); 02292 const FunctionType *funcType = FD->getType()->getAs<FunctionType>(); 02293 const FunctionProtoType *proto = dyn_cast<FunctionProtoType>(funcType); 02294 if (!proto) 02295 return; 02296 QualType Type = proto->getReturnType(); 02297 std::string FdStr = Type.getAsString(Context->getPrintingPolicy()); 02298 FdStr += " "; 02299 FdStr += FD->getName(); 02300 FdStr += "("; 02301 unsigned numArgs = proto->getNumParams(); 02302 for (unsigned i = 0; i < numArgs; i++) { 02303 QualType ArgType = proto->getParamType(i); 02304 RewriteBlockPointerType(FdStr, ArgType); 02305 if (i+1 < numArgs) 02306 FdStr += ", "; 02307 } 02308 FdStr += ");\n"; 02309 InsertText(FunLocStart, FdStr); 02310 CurFunctionDeclToDeclareForBlock = nullptr; 02311 } 02312 02313 // SynthSuperConstructorFunctionDecl - id objc_super(id obj, id super); 02314 void RewriteObjC::SynthSuperConstructorFunctionDecl() { 02315 if (SuperConstructorFunctionDecl) 02316 return; 02317 IdentifierInfo *msgSendIdent = &Context->Idents.get("__rw_objc_super"); 02318 SmallVector<QualType, 16> ArgTys; 02319 QualType argT = Context->getObjCIdType(); 02320 assert(!argT.isNull() && "Can't find 'id' type"); 02321 ArgTys.push_back(argT); 02322 ArgTys.push_back(argT); 02323 QualType msgSendType = getSimpleFunctionType(Context->getObjCIdType(), 02324 ArgTys); 02325 SuperConstructorFunctionDecl = FunctionDecl::Create(*Context, TUDecl, 02326 SourceLocation(), 02327 SourceLocation(), 02328 msgSendIdent, msgSendType, 02329 nullptr, SC_Extern); 02330 } 02331 02332 // SynthMsgSendFunctionDecl - id objc_msgSend(id self, SEL op, ...); 02333 void RewriteObjC::SynthMsgSendFunctionDecl() { 02334 IdentifierInfo *msgSendIdent = &Context->Idents.get("objc_msgSend"); 02335 SmallVector<QualType, 16> ArgTys; 02336 QualType argT = Context->getObjCIdType(); 02337 assert(!argT.isNull() && "Can't find 'id' type"); 02338 ArgTys.push_back(argT); 02339 argT = Context->getObjCSelType(); 02340 assert(!argT.isNull() && "Can't find 'SEL' type"); 02341 ArgTys.push_back(argT); 02342 QualType msgSendType = getSimpleFunctionType(Context->getObjCIdType(), 02343 ArgTys, /*isVariadic=*/true); 02344 MsgSendFunctionDecl = FunctionDecl::Create(*Context, TUDecl, 02345 SourceLocation(), 02346 SourceLocation(), 02347 msgSendIdent, msgSendType, 02348 nullptr, SC_Extern); 02349 } 02350 02351 // SynthMsgSendSuperFunctionDecl - id objc_msgSendSuper(struct objc_super *, SEL op, ...); 02352 void RewriteObjC::SynthMsgSendSuperFunctionDecl() { 02353 IdentifierInfo *msgSendIdent = &Context->Idents.get("objc_msgSendSuper"); 02354 SmallVector<QualType, 16> ArgTys; 02355 RecordDecl *RD = RecordDecl::Create(*Context, TTK_Struct, TUDecl, 02356 SourceLocation(), SourceLocation(), 02357 &Context->Idents.get("objc_super")); 02358 QualType argT = Context->getPointerType(Context->getTagDeclType(RD)); 02359 assert(!argT.isNull() && "Can't build 'struct objc_super *' type"); 02360 ArgTys.push_back(argT); 02361 argT = Context->getObjCSelType(); 02362 assert(!argT.isNull() && "Can't find 'SEL' type"); 02363 ArgTys.push_back(argT); 02364 QualType msgSendType = getSimpleFunctionType(Context->getObjCIdType(), 02365 ArgTys, /*isVariadic=*/true); 02366 MsgSendSuperFunctionDecl = FunctionDecl::Create(*Context, TUDecl, 02367 SourceLocation(), 02368 SourceLocation(), 02369 msgSendIdent, msgSendType, 02370 nullptr, SC_Extern); 02371 } 02372 02373 // SynthMsgSendStretFunctionDecl - id objc_msgSend_stret(id self, SEL op, ...); 02374 void RewriteObjC::SynthMsgSendStretFunctionDecl() { 02375 IdentifierInfo *msgSendIdent = &Context->Idents.get("objc_msgSend_stret"); 02376 SmallVector<QualType, 16> ArgTys; 02377 QualType argT = Context->getObjCIdType(); 02378 assert(!argT.isNull() && "Can't find 'id' type"); 02379 ArgTys.push_back(argT); 02380 argT = Context->getObjCSelType(); 02381 assert(!argT.isNull() && "Can't find 'SEL' type"); 02382 ArgTys.push_back(argT); 02383 QualType msgSendType = getSimpleFunctionType(Context->getObjCIdType(), 02384 ArgTys, /*isVariadic=*/true); 02385 MsgSendStretFunctionDecl = FunctionDecl::Create(*Context, TUDecl, 02386 SourceLocation(), 02387 SourceLocation(), 02388 msgSendIdent, msgSendType, 02389 nullptr, SC_Extern); 02390 } 02391 02392 // SynthMsgSendSuperStretFunctionDecl - 02393 // id objc_msgSendSuper_stret(struct objc_super *, SEL op, ...); 02394 void RewriteObjC::SynthMsgSendSuperStretFunctionDecl() { 02395 IdentifierInfo *msgSendIdent = 02396 &Context->Idents.get("objc_msgSendSuper_stret"); 02397 SmallVector<QualType, 16> ArgTys; 02398 RecordDecl *RD = RecordDecl::Create(*Context, TTK_Struct, TUDecl, 02399 SourceLocation(), SourceLocation(), 02400 &Context->Idents.get("objc_super")); 02401 QualType argT = Context->getPointerType(Context->getTagDeclType(RD)); 02402 assert(!argT.isNull() && "Can't build 'struct objc_super *' type"); 02403 ArgTys.push_back(argT); 02404 argT = Context->getObjCSelType(); 02405 assert(!argT.isNull() && "Can't find 'SEL' type"); 02406 ArgTys.push_back(argT); 02407 QualType msgSendType = getSimpleFunctionType(Context->getObjCIdType(), 02408 ArgTys, /*isVariadic=*/true); 02409 MsgSendSuperStretFunctionDecl = FunctionDecl::Create(*Context, TUDecl, 02410 SourceLocation(), 02411 SourceLocation(), 02412 msgSendIdent, 02413 msgSendType, nullptr, 02414 SC_Extern); 02415 } 02416 02417 // SynthMsgSendFpretFunctionDecl - double objc_msgSend_fpret(id self, SEL op, ...); 02418 void RewriteObjC::SynthMsgSendFpretFunctionDecl() { 02419 IdentifierInfo *msgSendIdent = &Context->Idents.get("objc_msgSend_fpret"); 02420 SmallVector<QualType, 16> ArgTys; 02421 QualType argT = Context->getObjCIdType(); 02422 assert(!argT.isNull() && "Can't find 'id' type"); 02423 ArgTys.push_back(argT); 02424 argT = Context->getObjCSelType(); 02425 assert(!argT.isNull() && "Can't find 'SEL' type"); 02426 ArgTys.push_back(argT); 02427 QualType msgSendType = getSimpleFunctionType(Context->DoubleTy, 02428 ArgTys, /*isVariadic=*/true); 02429 MsgSendFpretFunctionDecl = FunctionDecl::Create(*Context, TUDecl, 02430 SourceLocation(), 02431 SourceLocation(), 02432 msgSendIdent, msgSendType, 02433 nullptr, SC_Extern); 02434 } 02435 02436 // SynthGetClassFunctionDecl - id objc_getClass(const char *name); 02437 void RewriteObjC::SynthGetClassFunctionDecl() { 02438 IdentifierInfo *getClassIdent = &Context->Idents.get("objc_getClass"); 02439 SmallVector<QualType, 16> ArgTys; 02440 ArgTys.push_back(Context->getPointerType(Context->CharTy.withConst())); 02441 QualType getClassType = getSimpleFunctionType(Context->getObjCIdType(), 02442 ArgTys); 02443 GetClassFunctionDecl = FunctionDecl::Create(*Context, TUDecl, 02444 SourceLocation(), 02445 SourceLocation(), 02446 getClassIdent, getClassType, 02447 nullptr, SC_Extern); 02448 } 02449 02450 // SynthGetSuperClassFunctionDecl - Class class_getSuperclass(Class cls); 02451 void RewriteObjC::SynthGetSuperClassFunctionDecl() { 02452 IdentifierInfo *getSuperClassIdent = 02453 &Context->Idents.get("class_getSuperclass"); 02454 SmallVector<QualType, 16> ArgTys; 02455 ArgTys.push_back(Context->getObjCClassType()); 02456 QualType getClassType = getSimpleFunctionType(Context->getObjCClassType(), 02457 ArgTys); 02458 GetSuperClassFunctionDecl = FunctionDecl::Create(*Context, TUDecl, 02459 SourceLocation(), 02460 SourceLocation(), 02461 getSuperClassIdent, 02462 getClassType, nullptr, 02463 SC_Extern); 02464 } 02465 02466 // SynthGetMetaClassFunctionDecl - id objc_getMetaClass(const char *name); 02467 void RewriteObjC::SynthGetMetaClassFunctionDecl() { 02468 IdentifierInfo *getClassIdent = &Context->Idents.get("objc_getMetaClass"); 02469 SmallVector<QualType, 16> ArgTys; 02470 ArgTys.push_back(Context->getPointerType(Context->CharTy.withConst())); 02471 QualType getClassType = getSimpleFunctionType(Context->getObjCIdType(), 02472 ArgTys); 02473 GetMetaClassFunctionDecl = FunctionDecl::Create(*Context, TUDecl, 02474 SourceLocation(), 02475 SourceLocation(), 02476 getClassIdent, getClassType, 02477 nullptr, SC_Extern); 02478 } 02479 02480 Stmt *RewriteObjC::RewriteObjCStringLiteral(ObjCStringLiteral *Exp) { 02481 assert(Exp != nullptr && "Expected non-null ObjCStringLiteral"); 02482 QualType strType = getConstantStringStructType(); 02483 02484 std::string S = "__NSConstantStringImpl_"; 02485 02486 std::string tmpName = InFileName; 02487 unsigned i; 02488 for (i=0; i < tmpName.length(); i++) { 02489 char c = tmpName.at(i); 02490 // replace any non-alphanumeric characters with '_'. 02491 if (!isAlphanumeric(c)) 02492 tmpName[i] = '_'; 02493 } 02494 S += tmpName; 02495 S += "_"; 02496 S += utostr(NumObjCStringLiterals++); 02497 02498 Preamble += "static __NSConstantStringImpl " + S; 02499 Preamble += " __attribute__ ((section (\"__DATA, __cfstring\"))) = {__CFConstantStringClassReference,"; 02500 Preamble += "0x000007c8,"; // utf8_str 02501 // The pretty printer for StringLiteral handles escape characters properly. 02502 std::string prettyBufS; 02503 llvm::raw_string_ostream prettyBuf(prettyBufS); 02504 Exp->getString()->printPretty(prettyBuf, nullptr, PrintingPolicy(LangOpts)); 02505 Preamble += prettyBuf.str(); 02506 Preamble += ","; 02507 Preamble += utostr(Exp->getString()->getByteLength()) + "};\n"; 02508 02509 VarDecl *NewVD = VarDecl::Create(*Context, TUDecl, SourceLocation(), 02510 SourceLocation(), &Context->Idents.get(S), 02511 strType, nullptr, SC_Static); 02512 DeclRefExpr *DRE = new (Context) DeclRefExpr(NewVD, false, strType, VK_LValue, 02513 SourceLocation()); 02514 Expr *Unop = new (Context) UnaryOperator(DRE, UO_AddrOf, 02515 Context->getPointerType(DRE->getType()), 02516 VK_RValue, OK_Ordinary, 02517 SourceLocation()); 02518 // cast to NSConstantString * 02519 CastExpr *cast = NoTypeInfoCStyleCastExpr(Context, Exp->getType(), 02520 CK_CPointerToObjCPointerCast, Unop); 02521 ReplaceStmt(Exp, cast); 02522 // delete Exp; leak for now, see RewritePropertyOrImplicitSetter() usage for more info. 02523 return cast; 02524 } 02525 02526 // struct objc_super { struct objc_object *receiver; struct objc_class *super; }; 02527 QualType RewriteObjC::getSuperStructType() { 02528 if (!SuperStructDecl) { 02529 SuperStructDecl = RecordDecl::Create(*Context, TTK_Struct, TUDecl, 02530 SourceLocation(), SourceLocation(), 02531 &Context->Idents.get("objc_super")); 02532 QualType FieldTypes[2]; 02533 02534 // struct objc_object *receiver; 02535 FieldTypes[0] = Context->getObjCIdType(); 02536 // struct objc_class *super; 02537 FieldTypes[1] = Context->getObjCClassType(); 02538 02539 // Create fields 02540 for (unsigned i = 0; i < 2; ++i) { 02541 SuperStructDecl->addDecl(FieldDecl::Create(*Context, SuperStructDecl, 02542 SourceLocation(), 02543 SourceLocation(), nullptr, 02544 FieldTypes[i], nullptr, 02545 /*BitWidth=*/nullptr, 02546 /*Mutable=*/false, 02547 ICIS_NoInit)); 02548 } 02549 02550 SuperStructDecl->completeDefinition(); 02551 } 02552 return Context->getTagDeclType(SuperStructDecl); 02553 } 02554 02555 QualType RewriteObjC::getConstantStringStructType() { 02556 if (!ConstantStringDecl) { 02557 ConstantStringDecl = RecordDecl::Create(*Context, TTK_Struct, TUDecl, 02558 SourceLocation(), SourceLocation(), 02559 &Context->Idents.get("__NSConstantStringImpl")); 02560 QualType FieldTypes[4]; 02561 02562 // struct objc_object *receiver; 02563 FieldTypes[0] = Context->getObjCIdType(); 02564 // int flags; 02565 FieldTypes[1] = Context->IntTy; 02566 // char *str; 02567 FieldTypes[2] = Context->getPointerType(Context->CharTy); 02568 // long length; 02569 FieldTypes[3] = Context->LongTy; 02570 02571 // Create fields 02572 for (unsigned i = 0; i < 4; ++i) { 02573 ConstantStringDecl->addDecl(FieldDecl::Create(*Context, 02574 ConstantStringDecl, 02575 SourceLocation(), 02576 SourceLocation(), nullptr, 02577 FieldTypes[i], nullptr, 02578 /*BitWidth=*/nullptr, 02579 /*Mutable=*/true, 02580 ICIS_NoInit)); 02581 } 02582 02583 ConstantStringDecl->completeDefinition(); 02584 } 02585 return Context->getTagDeclType(ConstantStringDecl); 02586 } 02587 02588 CallExpr *RewriteObjC::SynthMsgSendStretCallExpr(FunctionDecl *MsgSendStretFlavor, 02589 QualType msgSendType, 02590 QualType returnType, 02591 SmallVectorImpl<QualType> &ArgTypes, 02592 SmallVectorImpl<Expr*> &MsgExprs, 02593 ObjCMethodDecl *Method) { 02594 // Create a reference to the objc_msgSend_stret() declaration. 02595 DeclRefExpr *STDRE = new (Context) DeclRefExpr(MsgSendStretFlavor, 02596 false, msgSendType, 02597 VK_LValue, SourceLocation()); 02598 // Need to cast objc_msgSend_stret to "void *" (see above comment). 02599 CastExpr *cast = NoTypeInfoCStyleCastExpr(Context, 02600 Context->getPointerType(Context->VoidTy), 02601 CK_BitCast, STDRE); 02602 // Now do the "normal" pointer to function cast. 02603 QualType castType = getSimpleFunctionType(returnType, ArgTypes, 02604 Method ? Method->isVariadic() 02605 : false); 02606 castType = Context->getPointerType(castType); 02607 cast = NoTypeInfoCStyleCastExpr(Context, castType, CK_BitCast, 02608 cast); 02609 02610 // Don't forget the parens to enforce the proper binding. 02611 ParenExpr *PE = new (Context) ParenExpr(SourceLocation(), SourceLocation(), cast); 02612 02613 const FunctionType *FT = msgSendType->getAs<FunctionType>(); 02614 CallExpr *STCE = new (Context) CallExpr( 02615 *Context, PE, MsgExprs, FT->getReturnType(), VK_RValue, SourceLocation()); 02616 return STCE; 02617 02618 } 02619 02620 02621 Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp, 02622 SourceLocation StartLoc, 02623 SourceLocation EndLoc) { 02624 if (!SelGetUidFunctionDecl) 02625 SynthSelGetUidFunctionDecl(); 02626 if (!MsgSendFunctionDecl) 02627 SynthMsgSendFunctionDecl(); 02628 if (!MsgSendSuperFunctionDecl) 02629 SynthMsgSendSuperFunctionDecl(); 02630 if (!MsgSendStretFunctionDecl) 02631 SynthMsgSendStretFunctionDecl(); 02632 if (!MsgSendSuperStretFunctionDecl) 02633 SynthMsgSendSuperStretFunctionDecl(); 02634 if (!MsgSendFpretFunctionDecl) 02635 SynthMsgSendFpretFunctionDecl(); 02636 if (!GetClassFunctionDecl) 02637 SynthGetClassFunctionDecl(); 02638 if (!GetSuperClassFunctionDecl) 02639 SynthGetSuperClassFunctionDecl(); 02640 if (!GetMetaClassFunctionDecl) 02641 SynthGetMetaClassFunctionDecl(); 02642 02643 // default to objc_msgSend(). 02644 FunctionDecl *MsgSendFlavor = MsgSendFunctionDecl; 02645 // May need to use objc_msgSend_stret() as well. 02646 FunctionDecl *MsgSendStretFlavor = nullptr; 02647 if (ObjCMethodDecl *mDecl = Exp->getMethodDecl()) { 02648 QualType resultType = mDecl->getReturnType(); 02649 if (resultType->isRecordType()) 02650 MsgSendStretFlavor = MsgSendStretFunctionDecl; 02651 else if (resultType->isRealFloatingType()) 02652 MsgSendFlavor = MsgSendFpretFunctionDecl; 02653 } 02654 02655 // Synthesize a call to objc_msgSend(). 02656 SmallVector<Expr*, 8> MsgExprs; 02657 switch (Exp->getReceiverKind()) { 02658 case ObjCMessageExpr::SuperClass: { 02659 MsgSendFlavor = MsgSendSuperFunctionDecl; 02660 if (MsgSendStretFlavor) 02661 MsgSendStretFlavor = MsgSendSuperStretFunctionDecl; 02662 assert(MsgSendFlavor && "MsgSendFlavor is NULL!"); 02663 02664 ObjCInterfaceDecl *ClassDecl = CurMethodDef->getClassInterface(); 02665 02666 SmallVector<Expr*, 4> InitExprs; 02667 02668 // set the receiver to self, the first argument to all methods. 02669 InitExprs.push_back( 02670 NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(), 02671 CK_BitCast, 02672 new (Context) DeclRefExpr(CurMethodDef->getSelfDecl(), 02673 false, 02674 Context->getObjCIdType(), 02675 VK_RValue, 02676 SourceLocation())) 02677 ); // set the 'receiver'. 02678 02679 // (id)class_getSuperclass((Class)objc_getClass("CurrentClass")) 02680 SmallVector<Expr*, 8> ClsExprs; 02681 ClsExprs.push_back(getStringLiteral(ClassDecl->getIdentifier()->getName())); 02682 CallExpr *Cls = SynthesizeCallToFunctionDecl(GetMetaClassFunctionDecl, 02683 &ClsExprs[0], 02684 ClsExprs.size(), 02685 StartLoc, 02686 EndLoc); 02687 // (Class)objc_getClass("CurrentClass") 02688 CastExpr *ArgExpr = NoTypeInfoCStyleCastExpr(Context, 02689 Context->getObjCClassType(), 02690 CK_BitCast, Cls); 02691 ClsExprs.clear(); 02692 ClsExprs.push_back(ArgExpr); 02693 Cls = SynthesizeCallToFunctionDecl(GetSuperClassFunctionDecl, 02694 &ClsExprs[0], ClsExprs.size(), 02695 StartLoc, EndLoc); 02696 02697 // (id)class_getSuperclass((Class)objc_getClass("CurrentClass")) 02698 // To turn off a warning, type-cast to 'id' 02699 InitExprs.push_back( // set 'super class', using class_getSuperclass(). 02700 NoTypeInfoCStyleCastExpr(Context, 02701 Context->getObjCIdType(), 02702 CK_BitCast, Cls)); 02703 // struct objc_super 02704 QualType superType = getSuperStructType(); 02705 Expr *SuperRep; 02706 02707 if (LangOpts.MicrosoftExt) { 02708 SynthSuperConstructorFunctionDecl(); 02709 // Simulate a constructor call... 02710 DeclRefExpr *DRE = new (Context) DeclRefExpr(SuperConstructorFunctionDecl, 02711 false, superType, VK_LValue, 02712 SourceLocation()); 02713 SuperRep = new (Context) CallExpr(*Context, DRE, InitExprs, 02714 superType, VK_LValue, 02715 SourceLocation()); 02716 // The code for super is a little tricky to prevent collision with 02717 // the structure definition in the header. The rewriter has it's own 02718 // internal definition (__rw_objc_super) that is uses. This is why 02719 // we need the cast below. For example: 02720 // (struct objc_super *)&__rw_objc_super((id)self, (id)objc_getClass("SUPER")) 02721 // 02722 SuperRep = new (Context) UnaryOperator(SuperRep, UO_AddrOf, 02723 Context->getPointerType(SuperRep->getType()), 02724 VK_RValue, OK_Ordinary, 02725 SourceLocation()); 02726 SuperRep = NoTypeInfoCStyleCastExpr(Context, 02727 Context->getPointerType(superType), 02728 CK_BitCast, SuperRep); 02729 } else { 02730 // (struct objc_super) { <exprs from above> } 02731 InitListExpr *ILE = 02732 new (Context) InitListExpr(*Context, SourceLocation(), InitExprs, 02733 SourceLocation()); 02734 TypeSourceInfo *superTInfo 02735 = Context->getTrivialTypeSourceInfo(superType); 02736 SuperRep = new (Context) CompoundLiteralExpr(SourceLocation(), superTInfo, 02737 superType, VK_LValue, 02738 ILE, false); 02739 // struct objc_super * 02740 SuperRep = new (Context) UnaryOperator(SuperRep, UO_AddrOf, 02741 Context->getPointerType(SuperRep->getType()), 02742 VK_RValue, OK_Ordinary, 02743 SourceLocation()); 02744 } 02745 MsgExprs.push_back(SuperRep); 02746 break; 02747 } 02748 02749 case ObjCMessageExpr::Class: { 02750 SmallVector<Expr*, 8> ClsExprs; 02751 ObjCInterfaceDecl *Class 02752 = Exp->getClassReceiver()->getAs<ObjCObjectType>()->getInterface(); 02753 IdentifierInfo *clsName = Class->getIdentifier(); 02754 ClsExprs.push_back(getStringLiteral(clsName->getName())); 02755 CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl, 02756 &ClsExprs[0], 02757 ClsExprs.size(), 02758 StartLoc, EndLoc); 02759 MsgExprs.push_back(Cls); 02760 break; 02761 } 02762 02763 case ObjCMessageExpr::SuperInstance:{ 02764 MsgSendFlavor = MsgSendSuperFunctionDecl; 02765 if (MsgSendStretFlavor) 02766 MsgSendStretFlavor = MsgSendSuperStretFunctionDecl; 02767 assert(MsgSendFlavor && "MsgSendFlavor is NULL!"); 02768 ObjCInterfaceDecl *ClassDecl = CurMethodDef->getClassInterface(); 02769 SmallVector<Expr*, 4> InitExprs; 02770 02771 InitExprs.push_back( 02772 NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(), 02773 CK_BitCast, 02774 new (Context) DeclRefExpr(CurMethodDef->getSelfDecl(), 02775 false, 02776 Context->getObjCIdType(), 02777 VK_RValue, SourceLocation())) 02778 ); // set the 'receiver'. 02779 02780 // (id)class_getSuperclass((Class)objc_getClass("CurrentClass")) 02781 SmallVector<Expr*, 8> ClsExprs; 02782 ClsExprs.push_back(getStringLiteral(ClassDecl->getIdentifier()->getName())); 02783 CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl, 02784 &ClsExprs[0], 02785 ClsExprs.size(), 02786 StartLoc, EndLoc); 02787 // (Class)objc_getClass("CurrentClass") 02788 CastExpr *ArgExpr = NoTypeInfoCStyleCastExpr(Context, 02789 Context->getObjCClassType(), 02790 CK_BitCast, Cls); 02791 ClsExprs.clear(); 02792 ClsExprs.push_back(ArgExpr); 02793 Cls = SynthesizeCallToFunctionDecl(GetSuperClassFunctionDecl, 02794 &ClsExprs[0], ClsExprs.size(), 02795 StartLoc, EndLoc); 02796 02797 // (id)class_getSuperclass((Class)objc_getClass("CurrentClass")) 02798 // To turn off a warning, type-cast to 'id' 02799 InitExprs.push_back( 02800 // set 'super class', using class_getSuperclass(). 02801 NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(), 02802 CK_BitCast, Cls)); 02803 // struct objc_super 02804 QualType superType = getSuperStructType(); 02805 Expr *SuperRep; 02806 02807 if (LangOpts.MicrosoftExt) { 02808 SynthSuperConstructorFunctionDecl(); 02809 // Simulate a constructor call... 02810 DeclRefExpr *DRE = new (Context) DeclRefExpr(SuperConstructorFunctionDecl, 02811 false, superType, VK_LValue, 02812 SourceLocation()); 02813 SuperRep = new (Context) CallExpr(*Context, DRE, InitExprs, 02814 superType, VK_LValue, SourceLocation()); 02815 // The code for super is a little tricky to prevent collision with 02816 // the structure definition in the header. The rewriter has it's own 02817 // internal definition (__rw_objc_super) that is uses. This is why 02818 // we need the cast below. For example: 02819 // (struct objc_super *)&__rw_objc_super((id)self, (id)objc_getClass("SUPER")) 02820 // 02821 SuperRep = new (Context) UnaryOperator(SuperRep, UO_AddrOf, 02822 Context->getPointerType(SuperRep->getType()), 02823 VK_RValue, OK_Ordinary, 02824 SourceLocation()); 02825 SuperRep = NoTypeInfoCStyleCastExpr(Context, 02826 Context->getPointerType(superType), 02827 CK_BitCast, SuperRep); 02828 } else { 02829 // (struct objc_super) { <exprs from above> } 02830 InitListExpr *ILE = 02831 new (Context) InitListExpr(*Context, SourceLocation(), InitExprs, 02832 SourceLocation()); 02833 TypeSourceInfo *superTInfo 02834 = Context->getTrivialTypeSourceInfo(superType); 02835 SuperRep = new (Context) CompoundLiteralExpr(SourceLocation(), superTInfo, 02836 superType, VK_RValue, ILE, 02837 false); 02838 } 02839 MsgExprs.push_back(SuperRep); 02840 break; 02841 } 02842 02843 case ObjCMessageExpr::Instance: { 02844 // Remove all type-casts because it may contain objc-style types; e.g. 02845 // Foo<Proto> *. 02846 Expr *recExpr = Exp->getInstanceReceiver(); 02847 while (CStyleCastExpr *CE = dyn_cast<CStyleCastExpr>(recExpr)) 02848 recExpr = CE->getSubExpr(); 02849 CastKind CK = recExpr->getType()->isObjCObjectPointerType() 02850 ? CK_BitCast : recExpr->getType()->isBlockPointerType() 02851 ? CK_BlockPointerToObjCPointerCast 02852 : CK_CPointerToObjCPointerCast; 02853 02854 recExpr = NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(), 02855 CK, recExpr); 02856 MsgExprs.push_back(recExpr); 02857 break; 02858 } 02859 } 02860 02861 // Create a call to sel_registerName("selName"), it will be the 2nd argument. 02862 SmallVector<Expr*, 8> SelExprs; 02863 SelExprs.push_back(getStringLiteral(Exp->getSelector().getAsString())); 02864 CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl, 02865 &SelExprs[0], SelExprs.size(), 02866 StartLoc, 02867 EndLoc); 02868 MsgExprs.push_back(SelExp); 02869 02870 // Now push any user supplied arguments. 02871 for (unsigned i = 0; i < Exp->getNumArgs(); i++) { 02872 Expr *userExpr = Exp->getArg(i); 02873 // Make all implicit casts explicit...ICE comes in handy:-) 02874 if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(userExpr)) { 02875 // Reuse the ICE type, it is exactly what the doctor ordered. 02876 QualType type = ICE->getType(); 02877 if (needToScanForQualifiers(type)) 02878 type = Context->getObjCIdType(); 02879 // Make sure we convert "type (^)(...)" to "type (*)(...)". 02880 (void)convertBlockPointerToFunctionPointer(type); 02881 const Expr *SubExpr = ICE->IgnoreParenImpCasts(); 02882 CastKind CK; 02883 if (SubExpr->getType()->isIntegralType(*Context) && 02884 type->isBooleanType()) { 02885 CK = CK_IntegralToBoolean; 02886 } else if (type->isObjCObjectPointerType()) { 02887 if (SubExpr->getType()->isBlockPointerType()) { 02888 CK = CK_BlockPointerToObjCPointerCast; 02889 } else if (SubExpr->getType()->isPointerType()) { 02890 CK = CK_CPointerToObjCPointerCast; 02891 } else { 02892 CK = CK_BitCast; 02893 } 02894 } else { 02895 CK = CK_BitCast; 02896 } 02897 02898 userExpr = NoTypeInfoCStyleCastExpr(Context, type, CK, userExpr); 02899 } 02900 // Make id<P...> cast into an 'id' cast. 02901 else if (CStyleCastExpr *CE = dyn_cast<CStyleCastExpr>(userExpr)) { 02902 if (CE->getType()->isObjCQualifiedIdType()) { 02903 while ((CE = dyn_cast<CStyleCastExpr>(userExpr))) 02904 userExpr = CE->getSubExpr(); 02905 CastKind CK; 02906 if (userExpr->getType()->isIntegralType(*Context)) { 02907 CK = CK_IntegralToPointer; 02908 } else if (userExpr->getType()->isBlockPointerType()) { 02909 CK = CK_BlockPointerToObjCPointerCast; 02910 } else if (userExpr->getType()->isPointerType()) { 02911 CK = CK_CPointerToObjCPointerCast; 02912 } else { 02913 CK = CK_BitCast; 02914 } 02915 userExpr = NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(), 02916 CK, userExpr); 02917 } 02918 } 02919 MsgExprs.push_back(userExpr); 02920 // We've transferred the ownership to MsgExprs. For now, we *don't* null 02921 // out the argument in the original expression (since we aren't deleting 02922 // the ObjCMessageExpr). See RewritePropertyOrImplicitSetter() usage for more info. 02923 //Exp->setArg(i, 0); 02924 } 02925 // Generate the funky cast. 02926 CastExpr *cast; 02927 SmallVector<QualType, 8> ArgTypes; 02928 QualType returnType; 02929 02930 // Push 'id' and 'SEL', the 2 implicit arguments. 02931 if (MsgSendFlavor == MsgSendSuperFunctionDecl) 02932 ArgTypes.push_back(Context->getPointerType(getSuperStructType())); 02933 else 02934 ArgTypes.push_back(Context->getObjCIdType()); 02935 ArgTypes.push_back(Context->getObjCSelType()); 02936 if (ObjCMethodDecl *OMD = Exp->getMethodDecl()) { 02937 // Push any user argument types. 02938 for (const auto *PI : OMD->params()) { 02939 QualType t = PI->getType()->isObjCQualifiedIdType() 02940 ? Context->getObjCIdType() 02941 : PI->getType(); 02942 // Make sure we convert "t (^)(...)" to "t (*)(...)". 02943 (void)convertBlockPointerToFunctionPointer(t); 02944 ArgTypes.push_back(t); 02945 } 02946 returnType = Exp->getType(); 02947 convertToUnqualifiedObjCType(returnType); 02948 (void)convertBlockPointerToFunctionPointer(returnType); 02949 } else { 02950 returnType = Context->getObjCIdType(); 02951 } 02952 // Get the type, we will need to reference it in a couple spots. 02953 QualType msgSendType = MsgSendFlavor->getType(); 02954 02955 // Create a reference to the objc_msgSend() declaration. 02956 DeclRefExpr *DRE = new (Context) DeclRefExpr(MsgSendFlavor, false, msgSendType, 02957 VK_LValue, SourceLocation()); 02958 02959 // Need to cast objc_msgSend to "void *" (to workaround a GCC bandaid). 02960 // If we don't do this cast, we get the following bizarre warning/note: 02961 // xx.m:13: warning: function called through a non-compatible type 02962 // xx.m:13: note: if this code is reached, the program will abort 02963 cast = NoTypeInfoCStyleCastExpr(Context, 02964 Context->getPointerType(Context->VoidTy), 02965 CK_BitCast, DRE); 02966 02967 // Now do the "normal" pointer to function cast. 02968 // If we don't have a method decl, force a variadic cast. 02969 const ObjCMethodDecl *MD = Exp->getMethodDecl(); 02970 QualType castType = 02971 getSimpleFunctionType(returnType, ArgTypes, MD ? MD->isVariadic() : true); 02972 castType = Context->getPointerType(castType); 02973 cast = NoTypeInfoCStyleCastExpr(Context, castType, CK_BitCast, 02974 cast); 02975 02976 // Don't forget the parens to enforce the proper binding. 02977 ParenExpr *PE = new (Context) ParenExpr(StartLoc, EndLoc, cast); 02978 02979 const FunctionType *FT = msgSendType->getAs<FunctionType>(); 02980 CallExpr *CE = new (Context) 02981 CallExpr(*Context, PE, MsgExprs, FT->getReturnType(), VK_RValue, EndLoc); 02982 Stmt *ReplacingStmt = CE; 02983 if (MsgSendStretFlavor) { 02984 // We have the method which returns a struct/union. Must also generate 02985 // call to objc_msgSend_stret and hang both varieties on a conditional 02986 // expression which dictate which one to envoke depending on size of 02987 // method's return type. 02988 02989 CallExpr *STCE = SynthMsgSendStretCallExpr(MsgSendStretFlavor, 02990 msgSendType, returnType, 02991 ArgTypes, MsgExprs, 02992 Exp->getMethodDecl()); 02993 02994 // Build sizeof(returnType) 02995 UnaryExprOrTypeTraitExpr *sizeofExpr = 02996 new (Context) UnaryExprOrTypeTraitExpr(UETT_SizeOf, 02997 Context->getTrivialTypeSourceInfo(returnType), 02998 Context->getSizeType(), SourceLocation(), 02999 SourceLocation()); 03000 // (sizeof(returnType) <= 8 ? objc_msgSend(...) : objc_msgSend_stret(...)) 03001 // FIXME: Value of 8 is base on ppc32/x86 ABI for the most common cases. 03002 // For X86 it is more complicated and some kind of target specific routine 03003 // is needed to decide what to do. 03004 unsigned IntSize = 03005 static_cast<unsigned>(Context->getTypeSize(Context->IntTy)); 03006 IntegerLiteral *limit = IntegerLiteral::Create(*Context, 03007 llvm::APInt(IntSize, 8), 03008 Context->IntTy, 03009 SourceLocation()); 03010 BinaryOperator *lessThanExpr = 03011 new (Context) BinaryOperator(sizeofExpr, limit, BO_LE, Context->IntTy, 03012 VK_RValue, OK_Ordinary, SourceLocation(), 03013 false); 03014 // (sizeof(returnType) <= 8 ? objc_msgSend(...) : objc_msgSend_stret(...)) 03015 ConditionalOperator *CondExpr = 03016 new (Context) ConditionalOperator(lessThanExpr, 03017 SourceLocation(), CE, 03018 SourceLocation(), STCE, 03019 returnType, VK_RValue, OK_Ordinary); 03020 ReplacingStmt = new (Context) ParenExpr(SourceLocation(), SourceLocation(), 03021 CondExpr); 03022 } 03023 // delete Exp; leak for now, see RewritePropertyOrImplicitSetter() usage for more info. 03024 return ReplacingStmt; 03025 } 03026 03027 Stmt *RewriteObjC::RewriteMessageExpr(ObjCMessageExpr *Exp) { 03028 Stmt *ReplacingStmt = SynthMessageExpr(Exp, Exp->getLocStart(), 03029 Exp->getLocEnd()); 03030 03031 // Now do the actual rewrite. 03032 ReplaceStmt(Exp, ReplacingStmt); 03033 03034 // delete Exp; leak for now, see RewritePropertyOrImplicitSetter() usage for more info. 03035 return ReplacingStmt; 03036 } 03037 03038 // typedef struct objc_object Protocol; 03039 QualType RewriteObjC::getProtocolType() { 03040 if (!ProtocolTypeDecl) { 03041 TypeSourceInfo *TInfo 03042 = Context->getTrivialTypeSourceInfo(Context->getObjCIdType()); 03043 ProtocolTypeDecl = TypedefDecl::Create(*Context, TUDecl, 03044 SourceLocation(), SourceLocation(), 03045 &Context->Idents.get("Protocol"), 03046 TInfo); 03047 } 03048 return Context->getTypeDeclType(ProtocolTypeDecl); 03049 } 03050 03051 /// RewriteObjCProtocolExpr - Rewrite a protocol expression into 03052 /// a synthesized/forward data reference (to the protocol's metadata). 03053 /// The forward references (and metadata) are generated in 03054 /// RewriteObjC::HandleTranslationUnit(). 03055 Stmt *RewriteObjC::RewriteObjCProtocolExpr(ObjCProtocolExpr *Exp) { 03056 std::string Name = "_OBJC_PROTOCOL_" + Exp->getProtocol()->getNameAsString(); 03057 IdentifierInfo *ID = &Context->Idents.get(Name); 03058 VarDecl *VD = VarDecl::Create(*Context, TUDecl, SourceLocation(), 03059 SourceLocation(), ID, getProtocolType(), 03060 nullptr, SC_Extern); 03061 DeclRefExpr *DRE = new (Context) DeclRefExpr(VD, false, getProtocolType(), 03062 VK_LValue, SourceLocation()); 03063 Expr *DerefExpr = new (Context) UnaryOperator(DRE, UO_AddrOf, 03064 Context->getPointerType(DRE->getType()), 03065 VK_RValue, OK_Ordinary, SourceLocation()); 03066 CastExpr *castExpr = NoTypeInfoCStyleCastExpr(Context, DerefExpr->getType(), 03067 CK_BitCast, 03068 DerefExpr); 03069 ReplaceStmt(Exp, castExpr); 03070 ProtocolExprDecls.insert(Exp->getProtocol()->getCanonicalDecl()); 03071 // delete Exp; leak for now, see RewritePropertyOrImplicitSetter() usage for more info. 03072 return castExpr; 03073 03074 } 03075 03076 bool RewriteObjC::BufferContainsPPDirectives(const char *startBuf, 03077 const char *endBuf) { 03078 while (startBuf < endBuf) { 03079 if (*startBuf == '#') { 03080 // Skip whitespace. 03081 for (++startBuf; startBuf[0] == ' ' || startBuf[0] == '\t'; ++startBuf) 03082 ; 03083 if (!strncmp(startBuf, "if", strlen("if")) || 03084 !strncmp(startBuf, "ifdef", strlen("ifdef")) || 03085 !strncmp(startBuf, "ifndef", strlen("ifndef")) || 03086 !strncmp(startBuf, "define", strlen("define")) || 03087 !strncmp(startBuf, "undef", strlen("undef")) || 03088 !strncmp(startBuf, "else", strlen("else")) || 03089 !strncmp(startBuf, "elif", strlen("elif")) || 03090 !strncmp(startBuf, "endif", strlen("endif")) || 03091 !strncmp(startBuf, "pragma", strlen("pragma")) || 03092 !strncmp(startBuf, "include", strlen("include")) || 03093 !strncmp(startBuf, "import", strlen("import")) || 03094 !strncmp(startBuf, "include_next", strlen("include_next"))) 03095 return true; 03096 } 03097 startBuf++; 03098 } 03099 return false; 03100 } 03101 03102 /// RewriteObjCInternalStruct - Rewrite one internal struct corresponding to 03103 /// an objective-c class with ivars. 03104 void RewriteObjC::RewriteObjCInternalStruct(ObjCInterfaceDecl *CDecl, 03105 std::string &Result) { 03106 assert(CDecl && "Class missing in SynthesizeObjCInternalStruct"); 03107 assert(CDecl->getName() != "" && 03108 "Name missing in SynthesizeObjCInternalStruct"); 03109 // Do not synthesize more than once. 03110 if (ObjCSynthesizedStructs.count(CDecl)) 03111 return; 03112 ObjCInterfaceDecl *RCDecl = CDecl->getSuperClass(); 03113 int NumIvars = CDecl->ivar_size(); 03114 SourceLocation LocStart = CDecl->getLocStart(); 03115 SourceLocation LocEnd = CDecl->getEndOfDefinitionLoc(); 03116 03117 const char *startBuf = SM->getCharacterData(LocStart); 03118 const char *endBuf = SM->getCharacterData(LocEnd); 03119 03120 // If no ivars and no root or if its root, directly or indirectly, 03121 // have no ivars (thus not synthesized) then no need to synthesize this class. 03122 if ((!CDecl->isThisDeclarationADefinition() || NumIvars == 0) && 03123 (!RCDecl || !ObjCSynthesizedStructs.count(RCDecl))) { 03124 endBuf += Lexer::MeasureTokenLength(LocEnd, *SM, LangOpts); 03125 ReplaceText(LocStart, endBuf-startBuf, Result); 03126 return; 03127 } 03128 03129 // FIXME: This has potential of causing problem. If 03130 // SynthesizeObjCInternalStruct is ever called recursively. 03131 Result += "\nstruct "; 03132 Result += CDecl->getNameAsString(); 03133 if (LangOpts.MicrosoftExt) 03134 Result += "_IMPL"; 03135 03136 if (NumIvars > 0) { 03137 const char *cursor = strchr(startBuf, '{'); 03138 assert((cursor && endBuf) 03139 && "SynthesizeObjCInternalStruct - malformed @interface"); 03140 // If the buffer contains preprocessor directives, we do more fine-grained 03141 // rewrites. This is intended to fix code that looks like (which occurs in 03142 // NSURL.h, for example): 03143 // 03144 // #ifdef XYZ 03145 // @interface Foo : NSObject 03146 // #else 03147 // @interface FooBar : NSObject 03148 // #endif 03149 // { 03150 // int i; 03151 // } 03152 // @end 03153 // 03154 // This clause is segregated to avoid breaking the common case. 03155 if (BufferContainsPPDirectives(startBuf, cursor)) { 03156 SourceLocation L = RCDecl ? CDecl->getSuperClassLoc() : 03157 CDecl->getAtStartLoc(); 03158 const char *endHeader = SM->getCharacterData(L); 03159 endHeader += Lexer::MeasureTokenLength(L, *SM, LangOpts); 03160 03161 if (CDecl->protocol_begin() != CDecl->protocol_end()) { 03162 // advance to the end of the referenced protocols. 03163 while (endHeader < cursor && *endHeader != '>') endHeader++; 03164 endHeader++; 03165 } 03166 // rewrite the original header 03167 ReplaceText(LocStart, endHeader-startBuf, Result); 03168 } else { 03169 // rewrite the original header *without* disturbing the '{' 03170 ReplaceText(LocStart, cursor-startBuf, Result); 03171 } 03172 if (RCDecl && ObjCSynthesizedStructs.count(RCDecl)) { 03173 Result = "\n struct "; 03174 Result += RCDecl->getNameAsString(); 03175 Result += "_IMPL "; 03176 Result += RCDecl->getNameAsString(); 03177 Result += "_IVARS;\n"; 03178 03179 // insert the super class structure definition. 03180 SourceLocation OnePastCurly = 03181 LocStart.getLocWithOffset(cursor-startBuf+1); 03182 InsertText(OnePastCurly, Result); 03183 } 03184 cursor++; // past '{' 03185 03186 // Now comment out any visibility specifiers. 03187 while (cursor < endBuf) { 03188 if (*cursor == '@') { 03189 SourceLocation atLoc = LocStart.getLocWithOffset(cursor-startBuf); 03190 // Skip whitespace. 03191 for (++cursor; cursor[0] == ' ' || cursor[0] == '\t'; ++cursor) 03192 /*scan*/; 03193 03194 // FIXME: presence of @public, etc. inside comment results in 03195 // this transformation as well, which is still correct c-code. 03196 if (!strncmp(cursor, "public", strlen("public")) || 03197 !strncmp(cursor, "private", strlen("private")) || 03198 !strncmp(cursor, "package", strlen("package")) || 03199 !strncmp(cursor, "protected", strlen("protected"))) 03200 InsertText(atLoc, "// "); 03201 } 03202 // FIXME: If there are cases where '<' is used in ivar declaration part 03203 // of user code, then scan the ivar list and use needToScanForQualifiers 03204 // for type checking. 03205 else if (*cursor == '<') { 03206 SourceLocation atLoc = LocStart.getLocWithOffset(cursor-startBuf); 03207 InsertText(atLoc, "/* "); 03208 cursor = strchr(cursor, '>'); 03209 cursor++; 03210 atLoc = LocStart.getLocWithOffset(cursor-startBuf); 03211 InsertText(atLoc, " */"); 03212 } else if (*cursor == '^') { // rewrite block specifier. 03213 SourceLocation caretLoc = LocStart.getLocWithOffset(cursor-startBuf); 03214 ReplaceText(caretLoc, 1, "*"); 03215 } 03216 cursor++; 03217 } 03218 // Don't forget to add a ';'!! 03219 InsertText(LocEnd.getLocWithOffset(1), ";"); 03220 } else { // we don't have any instance variables - insert super struct. 03221 endBuf += Lexer::MeasureTokenLength(LocEnd, *SM, LangOpts); 03222 Result += " {\n struct "; 03223 Result += RCDecl->getNameAsString(); 03224 Result += "_IMPL "; 03225 Result += RCDecl->getNameAsString(); 03226 Result += "_IVARS;\n};\n"; 03227 ReplaceText(LocStart, endBuf-startBuf, Result); 03228 } 03229 // Mark this struct as having been generated. 03230 if (!ObjCSynthesizedStructs.insert(CDecl)) 03231 llvm_unreachable("struct already synthesize- SynthesizeObjCInternalStruct"); 03232 } 03233 03234 //===----------------------------------------------------------------------===// 03235 // Meta Data Emission 03236 //===----------------------------------------------------------------------===// 03237 03238 03239 /// RewriteImplementations - This routine rewrites all method implementations 03240 /// and emits meta-data. 03241 03242 void RewriteObjC::RewriteImplementations() { 03243 int ClsDefCount = ClassImplementation.size(); 03244 int CatDefCount = CategoryImplementation.size(); 03245 03246 // Rewrite implemented methods 03247 for (int i = 0; i < ClsDefCount; i++) 03248 RewriteImplementationDecl(ClassImplementation[i]); 03249 03250 for (int i = 0; i < CatDefCount; i++) 03251 RewriteImplementationDecl(CategoryImplementation[i]); 03252 } 03253 03254 void RewriteObjC::RewriteByRefString(std::string &ResultStr, 03255 const std::string &Name, 03256 ValueDecl *VD, bool def) { 03257 assert(BlockByRefDeclNo.count(VD) && 03258 "RewriteByRefString: ByRef decl missing"); 03259 if (def) 03260 ResultStr += "struct "; 03261 ResultStr += "__Block_byref_" + Name + 03262 "_" + utostr(BlockByRefDeclNo[VD]) ; 03263 } 03264 03265 static bool HasLocalVariableExternalStorage(ValueDecl *VD) { 03266 if (VarDecl *Var = dyn_cast<VarDecl>(VD)) 03267 return (Var->isFunctionOrMethodVarDecl() && !Var->hasLocalStorage()); 03268 return false; 03269 } 03270 03271 std::string RewriteObjC::SynthesizeBlockFunc(BlockExpr *CE, int i, 03272 StringRef funcName, 03273 std::string Tag) { 03274 const FunctionType *AFT = CE->getFunctionType(); 03275 QualType RT = AFT->getReturnType(); 03276 std::string StructRef = "struct " + Tag; 03277 std::string S = "static " + RT.getAsString(Context->getPrintingPolicy()) + " __" + 03278 funcName.str() + "_" + "block_func_" + utostr(i); 03279 03280 BlockDecl *BD = CE->getBlockDecl(); 03281 03282 if (isa<FunctionNoProtoType>(AFT)) { 03283 // No user-supplied arguments. Still need to pass in a pointer to the 03284 // block (to reference imported block decl refs). 03285 S += "(" + StructRef + " *__cself)"; 03286 } else if (BD->param_empty()) { 03287 S += "(" + StructRef + " *__cself)"; 03288 } else { 03289 const FunctionProtoType *FT = cast<FunctionProtoType>(AFT); 03290 assert(FT && "SynthesizeBlockFunc: No function proto"); 03291 S += '('; 03292 // first add the implicit argument. 03293 S += StructRef + " *__cself, "; 03294 std::string ParamStr; 03295 for (BlockDecl::param_iterator AI = BD->param_begin(), 03296 E = BD->param_end(); AI != E; ++AI) { 03297 if (AI != BD->param_begin()) S += ", "; 03298 ParamStr = (*AI)->getNameAsString(); 03299 QualType QT = (*AI)->getType(); 03300 (void)convertBlockPointerToFunctionPointer(QT); 03301 QT.getAsStringInternal(ParamStr, Context->getPrintingPolicy()); 03302 S += ParamStr; 03303 } 03304 if (FT->isVariadic()) { 03305 if (!BD->param_empty()) S += ", "; 03306 S += "..."; 03307 } 03308 S += ')'; 03309 } 03310 S += " {\n"; 03311 03312 // Create local declarations to avoid rewriting all closure decl ref exprs. 03313 // First, emit a declaration for all "by ref" decls. 03314 for (SmallVectorImpl<ValueDecl *>::iterator I = BlockByRefDecls.begin(), 03315 E = BlockByRefDecls.end(); I != E; ++I) { 03316 S += " "; 03317 std::string Name = (*I)->getNameAsString(); 03318 std::string TypeString; 03319 RewriteByRefString(TypeString, Name, (*I)); 03320 TypeString += " *"; 03321 Name = TypeString + Name; 03322 S += Name + " = __cself->" + (*I)->getNameAsString() + "; // bound by ref\n"; 03323 } 03324 // Next, emit a declaration for all "by copy" declarations. 03325 for (SmallVectorImpl<ValueDecl *>::iterator I = BlockByCopyDecls.begin(), 03326 E = BlockByCopyDecls.end(); I != E; ++I) { 03327 S += " "; 03328 // Handle nested closure invocation. For example: 03329 // 03330 // void (^myImportedClosure)(void); 03331 // myImportedClosure = ^(void) { setGlobalInt(x + y); }; 03332 // 03333 // void (^anotherClosure)(void); 03334 // anotherClosure = ^(void) { 03335 // myImportedClosure(); // import and invoke the closure 03336 // }; 03337 // 03338 if (isTopLevelBlockPointerType((*I)->getType())) { 03339 RewriteBlockPointerTypeVariable(S, (*I)); 03340 S += " = ("; 03341 RewriteBlockPointerType(S, (*I)->getType()); 03342 S += ")"; 03343 S += "__cself->" + (*I)->getNameAsString() + "; // bound by copy\n"; 03344 } 03345 else { 03346 std::string Name = (*I)->getNameAsString(); 03347 QualType QT = (*I)->getType(); 03348 if (HasLocalVariableExternalStorage(*I)) 03349 QT = Context->getPointerType(QT); 03350 QT.getAsStringInternal(Name, Context->getPrintingPolicy()); 03351 S += Name + " = __cself->" + 03352 (*I)->getNameAsString() + "; // bound by copy\n"; 03353 } 03354 } 03355 std::string RewrittenStr = RewrittenBlockExprs[CE]; 03356 const char *cstr = RewrittenStr.c_str(); 03357 while (*cstr++ != '{') ; 03358 S += cstr; 03359 S += "\n"; 03360 return S; 03361 } 03362 03363 std::string RewriteObjC::SynthesizeBlockHelperFuncs(BlockExpr *CE, int i, 03364 StringRef funcName, 03365 std::string Tag) { 03366 std::string StructRef = "struct " + Tag; 03367 std::string S = "static void __"; 03368 03369 S += funcName; 03370 S += "_block_copy_" + utostr(i); 03371 S += "(" + StructRef; 03372 S += "*dst, " + StructRef; 03373 S += "*src) {"; 03374 for (ValueDecl *VD : ImportedBlockDecls) { 03375 S += "_Block_object_assign((void*)&dst->"; 03376 S += VD->getNameAsString(); 03377 S += ", (void*)src->"; 03378 S += VD->getNameAsString(); 03379 if (BlockByRefDeclsPtrSet.count(VD)) 03380 S += ", " + utostr(BLOCK_FIELD_IS_BYREF) + "/*BLOCK_FIELD_IS_BYREF*/);"; 03381 else if (VD->getType()->isBlockPointerType()) 03382 S += ", " + utostr(BLOCK_FIELD_IS_BLOCK) + "/*BLOCK_FIELD_IS_BLOCK*/);"; 03383 else 03384 S += ", " + utostr(BLOCK_FIELD_IS_OBJECT) + "/*BLOCK_FIELD_IS_OBJECT*/);"; 03385 } 03386 S += "}\n"; 03387 03388 S += "\nstatic void __"; 03389 S += funcName; 03390 S += "_block_dispose_" + utostr(i); 03391 S += "(" + StructRef; 03392 S += "*src) {"; 03393 for (ValueDecl *VD : ImportedBlockDecls) { 03394 S += "_Block_object_dispose((void*)src->"; 03395 S += VD->getNameAsString(); 03396 if (BlockByRefDeclsPtrSet.count(VD)) 03397 S += ", " + utostr(BLOCK_FIELD_IS_BYREF) + "/*BLOCK_FIELD_IS_BYREF*/);"; 03398 else if (VD->getType()->isBlockPointerType()) 03399 S += ", " + utostr(BLOCK_FIELD_IS_BLOCK) + "/*BLOCK_FIELD_IS_BLOCK*/);"; 03400 else 03401 S += ", " + utostr(BLOCK_FIELD_IS_OBJECT) + "/*BLOCK_FIELD_IS_OBJECT*/);"; 03402 } 03403 S += "}\n"; 03404 return S; 03405 } 03406 03407 std::string RewriteObjC::SynthesizeBlockImpl(BlockExpr *CE, std::string Tag, 03408 std::string Desc) { 03409 std::string S = "\nstruct " + Tag; 03410 std::string Constructor = " " + Tag; 03411 03412 S += " {\n struct __block_impl impl;\n"; 03413 S += " struct " + Desc; 03414 S += "* Desc;\n"; 03415 03416 Constructor += "(void *fp, "; // Invoke function pointer. 03417 Constructor += "struct " + Desc; // Descriptor pointer. 03418 Constructor += " *desc"; 03419 03420 if (BlockDeclRefs.size()) { 03421 // Output all "by copy" declarations. 03422 for (SmallVectorImpl<ValueDecl *>::iterator I = BlockByCopyDecls.begin(), 03423 E = BlockByCopyDecls.end(); I != E; ++I) { 03424 S += " "; 03425 std::string FieldName = (*I)->getNameAsString(); 03426 std::string ArgName = "_" + FieldName; 03427 // Handle nested closure invocation. For example: 03428 // 03429 // void (^myImportedBlock)(void); 03430 // myImportedBlock = ^(void) { setGlobalInt(x + y); }; 03431 // 03432 // void (^anotherBlock)(void); 03433 // anotherBlock = ^(void) { 03434 // myImportedBlock(); // import and invoke the closure 03435 // }; 03436 // 03437 if (isTopLevelBlockPointerType((*I)->getType())) { 03438 S += "struct __block_impl *"; 03439 Constructor += ", void *" + ArgName; 03440 } else { 03441 QualType QT = (*I)->getType(); 03442 if (HasLocalVariableExternalStorage(*I)) 03443 QT = Context->getPointerType(QT); 03444 QT.getAsStringInternal(FieldName, Context->getPrintingPolicy()); 03445 QT.getAsStringInternal(ArgName, Context->getPrintingPolicy()); 03446 Constructor += ", " + ArgName; 03447 } 03448 S += FieldName + ";\n"; 03449 } 03450 // Output all "by ref" declarations. 03451 for (SmallVectorImpl<ValueDecl *>::iterator I = BlockByRefDecls.begin(), 03452 E = BlockByRefDecls.end(); I != E; ++I) { 03453 S += " "; 03454 std::string FieldName = (*I)->getNameAsString(); 03455 std::string ArgName = "_" + FieldName; 03456 { 03457 std::string TypeString; 03458 RewriteByRefString(TypeString, FieldName, (*I)); 03459 TypeString += " *"; 03460 FieldName = TypeString + FieldName; 03461 ArgName = TypeString + ArgName; 03462 Constructor += ", " + ArgName; 03463 } 03464 S += FieldName + "; // by ref\n"; 03465 } 03466 // Finish writing the constructor. 03467 Constructor += ", int flags=0)"; 03468 // Initialize all "by copy" arguments. 03469 bool firsTime = true; 03470 for (SmallVectorImpl<ValueDecl *>::iterator I = BlockByCopyDecls.begin(), 03471 E = BlockByCopyDecls.end(); I != E; ++I) { 03472 std::string Name = (*I)->getNameAsString(); 03473 if (firsTime) { 03474 Constructor += " : "; 03475 firsTime = false; 03476 } 03477 else 03478 Constructor += ", "; 03479 if (isTopLevelBlockPointerType((*I)->getType())) 03480 Constructor += Name + "((struct __block_impl *)_" + Name + ")"; 03481 else 03482 Constructor += Name + "(_" + Name + ")"; 03483 } 03484 // Initialize all "by ref" arguments. 03485 for (SmallVectorImpl<ValueDecl *>::iterator I = BlockByRefDecls.begin(), 03486 E = BlockByRefDecls.end(); I != E; ++I) { 03487 std::string Name = (*I)->getNameAsString(); 03488 if (firsTime) { 03489 Constructor += " : "; 03490 firsTime = false; 03491 } 03492 else 03493 Constructor += ", "; 03494 Constructor += Name + "(_" + Name + "->__forwarding)"; 03495 } 03496 03497 Constructor += " {\n"; 03498 if (GlobalVarDecl) 03499 Constructor += " impl.isa = &_NSConcreteGlobalBlock;\n"; 03500 else 03501 Constructor += " impl.isa = &_NSConcreteStackBlock;\n"; 03502 Constructor += " impl.Flags = flags;\n impl.FuncPtr = fp;\n"; 03503 03504 Constructor += " Desc = desc;\n"; 03505 } else { 03506 // Finish writing the constructor. 03507 Constructor += ", int flags=0) {\n"; 03508 if (GlobalVarDecl) 03509 Constructor += " impl.isa = &_NSConcreteGlobalBlock;\n"; 03510 else 03511 Constructor += " impl.isa = &_NSConcreteStackBlock;\n"; 03512 Constructor += " impl.Flags = flags;\n impl.FuncPtr = fp;\n"; 03513 Constructor += " Desc = desc;\n"; 03514 } 03515 Constructor += " "; 03516 Constructor += "}\n"; 03517 S += Constructor; 03518 S += "};\n"; 03519 return S; 03520 } 03521 03522 std::string RewriteObjC::SynthesizeBlockDescriptor(std::string DescTag, 03523 std::string ImplTag, int i, 03524 StringRef FunName, 03525 unsigned hasCopy) { 03526 std::string S = "\nstatic struct " + DescTag; 03527 03528 S += " {\n unsigned long reserved;\n"; 03529 S += " unsigned long Block_size;\n"; 03530 if (hasCopy) { 03531 S += " void (*copy)(struct "; 03532 S += ImplTag; S += "*, struct "; 03533 S += ImplTag; S += "*);\n"; 03534 03535 S += " void (*dispose)(struct "; 03536 S += ImplTag; S += "*);\n"; 03537 } 03538 S += "} "; 03539 03540 S += DescTag + "_DATA = { 0, sizeof(struct "; 03541 S += ImplTag + ")"; 03542 if (hasCopy) { 03543 S += ", __" + FunName.str() + "_block_copy_" + utostr(i); 03544 S += ", __" + FunName.str() + "_block_dispose_" + utostr(i); 03545 } 03546 S += "};\n"; 03547 return S; 03548 } 03549 03550 void RewriteObjC::SynthesizeBlockLiterals(SourceLocation FunLocStart, 03551 StringRef FunName) { 03552 // Insert declaration for the function in which block literal is used. 03553 if (CurFunctionDeclToDeclareForBlock && !Blocks.empty()) 03554 RewriteBlockLiteralFunctionDecl(CurFunctionDeclToDeclareForBlock); 03555 bool RewriteSC = (GlobalVarDecl && 03556 !Blocks.empty() && 03557 GlobalVarDecl->getStorageClass() == SC_Static && 03558 GlobalVarDecl->getType().getCVRQualifiers()); 03559 if (RewriteSC) { 03560 std::string SC(" void __"); 03561 SC += GlobalVarDecl->getNameAsString(); 03562 SC += "() {}"; 03563 InsertText(FunLocStart, SC); 03564 } 03565 03566 // Insert closures that were part of the function. 03567 for (unsigned i = 0, count=0; i < Blocks.size(); i++) { 03568 CollectBlockDeclRefInfo(Blocks[i]); 03569 // Need to copy-in the inner copied-in variables not actually used in this 03570 // block. 03571 for (int j = 0; j < InnerDeclRefsCount[i]; j++) { 03572 DeclRefExpr *Exp = InnerDeclRefs[count++]; 03573 ValueDecl *VD = Exp->getDecl(); 03574 BlockDeclRefs.push_back(Exp); 03575 if (!VD->hasAttr<BlocksAttr>() && !BlockByCopyDeclsPtrSet.count(VD)) { 03576 BlockByCopyDeclsPtrSet.insert(VD); 03577 BlockByCopyDecls.push_back(VD); 03578 } 03579 if (VD->hasAttr<BlocksAttr>() && !BlockByRefDeclsPtrSet.count(VD)) { 03580 BlockByRefDeclsPtrSet.insert(VD); 03581 BlockByRefDecls.push_back(VD); 03582 } 03583 // imported objects in the inner blocks not used in the outer 03584 // blocks must be copied/disposed in the outer block as well. 03585 if (VD->hasAttr<BlocksAttr>() || 03586 VD->getType()->isObjCObjectPointerType() || 03587 VD->getType()->isBlockPointerType()) 03588 ImportedBlockDecls.insert(VD); 03589 } 03590 03591 std::string ImplTag = "__" + FunName.str() + "_block_impl_" + utostr(i); 03592 std::string DescTag = "__" + FunName.str() + "_block_desc_" + utostr(i); 03593 03594 std::string CI = SynthesizeBlockImpl(Blocks[i], ImplTag, DescTag); 03595 03596 InsertText(FunLocStart, CI); 03597 03598 std::string CF = SynthesizeBlockFunc(Blocks[i], i, FunName, ImplTag); 03599 03600 InsertText(FunLocStart, CF); 03601 03602 if (ImportedBlockDecls.size()) { 03603 std::string HF = SynthesizeBlockHelperFuncs(Blocks[i], i, FunName, ImplTag); 03604 InsertText(FunLocStart, HF); 03605 } 03606 std::string BD = SynthesizeBlockDescriptor(DescTag, ImplTag, i, FunName, 03607 ImportedBlockDecls.size() > 0); 03608 InsertText(FunLocStart, BD); 03609 03610 BlockDeclRefs.clear(); 03611 BlockByRefDecls.clear(); 03612 BlockByRefDeclsPtrSet.clear(); 03613 BlockByCopyDecls.clear(); 03614 BlockByCopyDeclsPtrSet.clear(); 03615 ImportedBlockDecls.clear(); 03616 } 03617 if (RewriteSC) { 03618 // Must insert any 'const/volatile/static here. Since it has been 03619 // removed as result of rewriting of block literals. 03620 std::string SC; 03621 if (GlobalVarDecl->getStorageClass() == SC_Static) 03622 SC = "static "; 03623 if (GlobalVarDecl->getType().isConstQualified()) 03624 SC += "const "; 03625 if (GlobalVarDecl->getType().isVolatileQualified()) 03626 SC += "volatile "; 03627 if (GlobalVarDecl->getType().isRestrictQualified()) 03628 SC += "restrict "; 03629 InsertText(FunLocStart, SC); 03630 } 03631 03632 Blocks.clear(); 03633 InnerDeclRefsCount.clear(); 03634 InnerDeclRefs.clear(); 03635 RewrittenBlockExprs.clear(); 03636 } 03637 03638 void RewriteObjC::InsertBlockLiteralsWithinFunction(FunctionDecl *FD) { 03639 SourceLocation FunLocStart = FD->getTypeSpecStartLoc(); 03640 StringRef FuncName = FD->getName(); 03641 03642 SynthesizeBlockLiterals(FunLocStart, FuncName); 03643 } 03644 03645 static void BuildUniqueMethodName(std::string &Name, 03646 ObjCMethodDecl *MD) { 03647 ObjCInterfaceDecl *IFace = MD->getClassInterface(); 03648 Name = IFace->getName(); 03649 Name += "__" + MD->getSelector().getAsString(); 03650 // Convert colons to underscores. 03651 std::string::size_type loc = 0; 03652 while ((loc = Name.find(":", loc)) != std::string::npos) 03653 Name.replace(loc, 1, "_"); 03654 } 03655 03656 void RewriteObjC::InsertBlockLiteralsWithinMethod(ObjCMethodDecl *MD) { 03657 //fprintf(stderr,"In InsertBlockLiteralsWitinMethod\n"); 03658 //SourceLocation FunLocStart = MD->getLocStart(); 03659 SourceLocation FunLocStart = MD->getLocStart(); 03660 std::string FuncName; 03661 BuildUniqueMethodName(FuncName, MD); 03662 SynthesizeBlockLiterals(FunLocStart, FuncName); 03663 } 03664 03665 void RewriteObjC::GetBlockDeclRefExprs(Stmt *S) { 03666 for (Stmt::child_range CI = S->children(); CI; ++CI) 03667 if (*CI) { 03668 if (BlockExpr *CBE = dyn_cast<BlockExpr>(*CI)) 03669 GetBlockDeclRefExprs(CBE->getBody()); 03670 else 03671 GetBlockDeclRefExprs(*CI); 03672 } 03673 // Handle specific things. 03674 if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(S)) { 03675 if (DRE->refersToEnclosingLocal()) { 03676 // FIXME: Handle enums. 03677 if (!isa<FunctionDecl>(DRE->getDecl())) 03678 BlockDeclRefs.push_back(DRE); 03679 if (HasLocalVariableExternalStorage(DRE->getDecl())) 03680 BlockDeclRefs.push_back(DRE); 03681 } 03682 } 03683 03684 return; 03685 } 03686 03687 void RewriteObjC::GetInnerBlockDeclRefExprs(Stmt *S, 03688 SmallVectorImpl<DeclRefExpr *> &InnerBlockDeclRefs, 03689 llvm::SmallPtrSetImpl<const DeclContext *> &InnerContexts) { 03690 for (Stmt::child_range CI = S->children(); CI; ++CI) 03691 if (*CI) { 03692 if (BlockExpr *CBE = dyn_cast<BlockExpr>(*CI)) { 03693 InnerContexts.insert(cast<DeclContext>(CBE->getBlockDecl())); 03694 GetInnerBlockDeclRefExprs(CBE->getBody(), 03695 InnerBlockDeclRefs, 03696 InnerContexts); 03697 } 03698 else 03699 GetInnerBlockDeclRefExprs(*CI, 03700 InnerBlockDeclRefs, 03701 InnerContexts); 03702 03703 } 03704 // Handle specific things. 03705 if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(S)) { 03706 if (DRE->refersToEnclosingLocal()) { 03707 if (!isa<FunctionDecl>(DRE->getDecl()) && 03708 !InnerContexts.count(DRE->getDecl()->getDeclContext())) 03709 InnerBlockDeclRefs.push_back(DRE); 03710 if (VarDecl *Var = dyn_cast<VarDecl>(DRE->getDecl())) 03711 if (Var->isFunctionOrMethodVarDecl()) 03712 ImportedLocalExternalDecls.insert(Var); 03713 } 03714 } 03715 03716 return; 03717 } 03718 03719 /// convertFunctionTypeOfBlocks - This routine converts a function type 03720 /// whose result type may be a block pointer or whose argument type(s) 03721 /// might be block pointers to an equivalent function type replacing 03722 /// all block pointers to function pointers. 03723 QualType RewriteObjC::convertFunctionTypeOfBlocks(const FunctionType *FT) { 03724 const FunctionProtoType *FTP = dyn_cast<FunctionProtoType>(FT); 03725 // FTP will be null for closures that don't take arguments. 03726 // Generate a funky cast. 03727 SmallVector<QualType, 8> ArgTypes; 03728 QualType Res = FT->getReturnType(); 03729 bool HasBlockType = convertBlockPointerToFunctionPointer(Res); 03730 03731 if (FTP) { 03732 for (auto &I : FTP->param_types()) { 03733 QualType t = I; 03734 // Make sure we convert "t (^)(...)" to "t (*)(...)". 03735 if (convertBlockPointerToFunctionPointer(t)) 03736 HasBlockType = true; 03737 ArgTypes.push_back(t); 03738 } 03739 } 03740 QualType FuncType; 03741 // FIXME. Does this work if block takes no argument but has a return type 03742 // which is of block type? 03743 if (HasBlockType) 03744 FuncType = getSimpleFunctionType(Res, ArgTypes); 03745 else FuncType = QualType(FT, 0); 03746 return FuncType; 03747 } 03748 03749 Stmt *RewriteObjC::SynthesizeBlockCall(CallExpr *Exp, const Expr *BlockExp) { 03750 // Navigate to relevant type information. 03751 const BlockPointerType *CPT = nullptr; 03752 03753 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(BlockExp)) { 03754 CPT = DRE->getType()->getAs<BlockPointerType>(); 03755 } else if (const MemberExpr *MExpr = dyn_cast<MemberExpr>(BlockExp)) { 03756 CPT = MExpr->getType()->getAs<BlockPointerType>(); 03757 } 03758 else if (const ParenExpr *PRE = dyn_cast<ParenExpr>(BlockExp)) { 03759 return SynthesizeBlockCall(Exp, PRE->getSubExpr()); 03760 } 03761 else if (const ImplicitCastExpr *IEXPR = dyn_cast<ImplicitCastExpr>(BlockExp)) 03762 CPT = IEXPR->getType()->getAs<BlockPointerType>(); 03763 else if (const ConditionalOperator *CEXPR = 03764 dyn_cast<ConditionalOperator>(BlockExp)) { 03765 Expr *LHSExp = CEXPR->getLHS(); 03766 Stmt *LHSStmt = SynthesizeBlockCall(Exp, LHSExp); 03767 Expr *RHSExp = CEXPR->getRHS(); 03768 Stmt *RHSStmt = SynthesizeBlockCall(Exp, RHSExp); 03769 Expr *CONDExp = CEXPR->getCond(); 03770 ConditionalOperator *CondExpr = 03771 new (Context) ConditionalOperator(CONDExp, 03772 SourceLocation(), cast<Expr>(LHSStmt), 03773 SourceLocation(), cast<Expr>(RHSStmt), 03774 Exp->getType(), VK_RValue, OK_Ordinary); 03775 return CondExpr; 03776 } else if (const ObjCIvarRefExpr *IRE = dyn_cast<ObjCIvarRefExpr>(BlockExp)) { 03777 CPT = IRE->getType()->getAs<BlockPointerType>(); 03778 } else if (const PseudoObjectExpr *POE 03779 = dyn_cast<PseudoObjectExpr>(BlockExp)) { 03780 CPT = POE->getType()->castAs<BlockPointerType>(); 03781 } else { 03782 assert(1 && "RewriteBlockClass: Bad type"); 03783 } 03784 assert(CPT && "RewriteBlockClass: Bad type"); 03785 const FunctionType *FT = CPT->getPointeeType()->getAs<FunctionType>(); 03786 assert(FT && "RewriteBlockClass: Bad type"); 03787 const FunctionProtoType *FTP = dyn_cast<FunctionProtoType>(FT); 03788 // FTP will be null for closures that don't take arguments. 03789 03790 RecordDecl *RD = RecordDecl::Create(*Context, TTK_Struct, TUDecl, 03791 SourceLocation(), SourceLocation(), 03792 &Context->Idents.get("__block_impl")); 03793 QualType PtrBlock = Context->getPointerType(Context->getTagDeclType(RD)); 03794 03795 // Generate a funky cast. 03796 SmallVector<QualType, 8> ArgTypes; 03797 03798 // Push the block argument type. 03799 ArgTypes.push_back(PtrBlock); 03800 if (FTP) { 03801 for (auto &I : FTP->param_types()) { 03802 QualType t = I; 03803 // Make sure we convert "t (^)(...)" to "t (*)(...)". 03804 if (!convertBlockPointerToFunctionPointer(t)) 03805 convertToUnqualifiedObjCType(t); 03806 ArgTypes.push_back(t); 03807 } 03808 } 03809 // Now do the pointer to function cast. 03810 QualType PtrToFuncCastType = getSimpleFunctionType(Exp->getType(), ArgTypes); 03811 03812 PtrToFuncCastType = Context->getPointerType(PtrToFuncCastType); 03813 03814 CastExpr *BlkCast = NoTypeInfoCStyleCastExpr(Context, PtrBlock, 03815 CK_BitCast, 03816 const_cast<Expr*>(BlockExp)); 03817 // Don't forget the parens to enforce the proper binding. 03818 ParenExpr *PE = new (Context) ParenExpr(SourceLocation(), SourceLocation(), 03819 BlkCast); 03820 //PE->dump(); 03821 03822 FieldDecl *FD = FieldDecl::Create(*Context, nullptr, SourceLocation(), 03823 SourceLocation(), 03824 &Context->Idents.get("FuncPtr"), 03825 Context->VoidPtrTy, nullptr, 03826 /*BitWidth=*/nullptr, /*Mutable=*/true, 03827 ICIS_NoInit); 03828 MemberExpr *ME = new (Context) MemberExpr(PE, true, FD, SourceLocation(), 03829 FD->getType(), VK_LValue, 03830 OK_Ordinary); 03831 03832 03833 CastExpr *FunkCast = NoTypeInfoCStyleCastExpr(Context, PtrToFuncCastType, 03834 CK_BitCast, ME); 03835 PE = new (Context) ParenExpr(SourceLocation(), SourceLocation(), FunkCast); 03836 03837 SmallVector<Expr*, 8> BlkExprs; 03838 // Add the implicit argument. 03839 BlkExprs.push_back(BlkCast); 03840 // Add the user arguments. 03841 for (CallExpr::arg_iterator I = Exp->arg_begin(), 03842 E = Exp->arg_end(); I != E; ++I) { 03843 BlkExprs.push_back(*I); 03844 } 03845 CallExpr *CE = new (Context) CallExpr(*Context, PE, BlkExprs, 03846 Exp->getType(), VK_RValue, 03847 SourceLocation()); 03848 return CE; 03849 } 03850 03851 // We need to return the rewritten expression to handle cases where the 03852 // BlockDeclRefExpr is embedded in another expression being rewritten. 03853 // For example: 03854 // 03855 // int main() { 03856 // __block Foo *f; 03857 // __block int i; 03858 // 03859 // void (^myblock)() = ^() { 03860 // [f test]; // f is a BlockDeclRefExpr embedded in a message (which is being rewritten). 03861 // i = 77; 03862 // }; 03863 //} 03864 Stmt *RewriteObjC::RewriteBlockDeclRefExpr(DeclRefExpr *DeclRefExp) { 03865 // Rewrite the byref variable into BYREFVAR->__forwarding->BYREFVAR 03866 // for each DeclRefExp where BYREFVAR is name of the variable. 03867 ValueDecl *VD = DeclRefExp->getDecl(); 03868 bool isArrow = DeclRefExp->refersToEnclosingLocal(); 03869 03870 FieldDecl *FD = FieldDecl::Create(*Context, nullptr, SourceLocation(), 03871 SourceLocation(), 03872 &Context->Idents.get("__forwarding"), 03873 Context->VoidPtrTy, nullptr, 03874 /*BitWidth=*/nullptr, /*Mutable=*/true, 03875 ICIS_NoInit); 03876 MemberExpr *ME = new (Context) MemberExpr(DeclRefExp, isArrow, 03877 FD, SourceLocation(), 03878 FD->getType(), VK_LValue, 03879 OK_Ordinary); 03880 03881 StringRef Name = VD->getName(); 03882 FD = FieldDecl::Create(*Context, nullptr, SourceLocation(), SourceLocation(), 03883 &Context->Idents.get(Name), 03884 Context->VoidPtrTy, nullptr, 03885 /*BitWidth=*/nullptr, /*Mutable=*/true, 03886 ICIS_NoInit); 03887 ME = new (Context) MemberExpr(ME, true, FD, SourceLocation(), 03888 DeclRefExp->getType(), VK_LValue, OK_Ordinary); 03889 03890 03891 03892 // Need parens to enforce precedence. 03893 ParenExpr *PE = new (Context) ParenExpr(DeclRefExp->getExprLoc(), 03894 DeclRefExp->getExprLoc(), 03895 ME); 03896 ReplaceStmt(DeclRefExp, PE); 03897 return PE; 03898 } 03899 03900 // Rewrites the imported local variable V with external storage 03901 // (static, extern, etc.) as *V 03902 // 03903 Stmt *RewriteObjC::RewriteLocalVariableExternalStorage(DeclRefExpr *DRE) { 03904 ValueDecl *VD = DRE->getDecl(); 03905 if (VarDecl *Var = dyn_cast<VarDecl>(VD)) 03906 if (!ImportedLocalExternalDecls.count(Var)) 03907 return DRE; 03908 Expr *Exp = new (Context) UnaryOperator(DRE, UO_Deref, DRE->getType(), 03909 VK_LValue, OK_Ordinary, 03910 DRE->getLocation()); 03911 // Need parens to enforce precedence. 03912 ParenExpr *PE = new (Context) ParenExpr(SourceLocation(), SourceLocation(), 03913 Exp); 03914 ReplaceStmt(DRE, PE); 03915 return PE; 03916 } 03917 03918 void RewriteObjC::RewriteCastExpr(CStyleCastExpr *CE) { 03919 SourceLocation LocStart = CE->getLParenLoc(); 03920 SourceLocation LocEnd = CE->getRParenLoc(); 03921 03922 // Need to avoid trying to rewrite synthesized casts. 03923 if (LocStart.isInvalid()) 03924 return; 03925 // Need to avoid trying to rewrite casts contained in macros. 03926 if (!Rewriter::isRewritable(LocStart) || !Rewriter::isRewritable(LocEnd)) 03927 return; 03928 03929 const char *startBuf = SM->getCharacterData(LocStart); 03930 const char *endBuf = SM->getCharacterData(LocEnd); 03931 QualType QT = CE->getType(); 03932 const Type* TypePtr = QT->getAs<Type>(); 03933 if (isa<TypeOfExprType>(TypePtr)) { 03934 const TypeOfExprType *TypeOfExprTypePtr = cast<TypeOfExprType>(TypePtr); 03935 QT = TypeOfExprTypePtr->getUnderlyingExpr()->getType(); 03936 std::string TypeAsString = "("; 03937 RewriteBlockPointerType(TypeAsString, QT); 03938 TypeAsString += ")"; 03939 ReplaceText(LocStart, endBuf-startBuf+1, TypeAsString); 03940 return; 03941 } 03942 // advance the location to startArgList. 03943 const char *argPtr = startBuf; 03944 03945 while (*argPtr++ && (argPtr < endBuf)) { 03946 switch (*argPtr) { 03947 case '^': 03948 // Replace the '^' with '*'. 03949 LocStart = LocStart.getLocWithOffset(argPtr-startBuf); 03950 ReplaceText(LocStart, 1, "*"); 03951 break; 03952 } 03953 } 03954 return; 03955 } 03956 03957 void RewriteObjC::RewriteBlockPointerFunctionArgs(FunctionDecl *FD) { 03958 SourceLocation DeclLoc = FD->getLocation(); 03959 unsigned parenCount = 0; 03960 03961 // We have 1 or more arguments that have closure pointers. 03962 const char *startBuf = SM->getCharacterData(DeclLoc); 03963 const char *startArgList = strchr(startBuf, '('); 03964 03965 assert((*startArgList == '(') && "Rewriter fuzzy parser confused"); 03966 03967 parenCount++; 03968 // advance the location to startArgList. 03969 DeclLoc = DeclLoc.getLocWithOffset(startArgList-startBuf); 03970 assert((DeclLoc.isValid()) && "Invalid DeclLoc"); 03971 03972 const char *argPtr = startArgList; 03973 03974 while (*argPtr++ && parenCount) { 03975 switch (*argPtr) { 03976 case '^': 03977 // Replace the '^' with '*'. 03978 DeclLoc = DeclLoc.getLocWithOffset(argPtr-startArgList); 03979 ReplaceText(DeclLoc, 1, "*"); 03980 break; 03981 case '(': 03982 parenCount++; 03983 break; 03984 case ')': 03985 parenCount--; 03986 break; 03987 } 03988 } 03989 return; 03990 } 03991 03992 bool RewriteObjC::PointerTypeTakesAnyBlockArguments(QualType QT) { 03993 const FunctionProtoType *FTP; 03994 const PointerType *PT = QT->getAs<PointerType>(); 03995 if (PT) { 03996 FTP = PT->getPointeeType()->getAs<FunctionProtoType>(); 03997 } else { 03998 const BlockPointerType *BPT = QT->getAs<BlockPointerType>(); 03999 assert(BPT && "BlockPointerTypeTakeAnyBlockArguments(): not a block pointer type"); 04000 FTP = BPT->getPointeeType()->getAs<FunctionProtoType>(); 04001 } 04002 if (FTP) { 04003 for (const auto &I : FTP->param_types()) 04004 if (isTopLevelBlockPointerType(I)) 04005 return true; 04006 } 04007 return false; 04008 } 04009 04010 bool RewriteObjC::PointerTypeTakesAnyObjCQualifiedType(QualType QT) { 04011 const FunctionProtoType *FTP; 04012 const PointerType *PT = QT->getAs<PointerType>(); 04013 if (PT) { 04014 FTP = PT->getPointeeType()->getAs<FunctionProtoType>(); 04015 } else { 04016 const BlockPointerType *BPT = QT->getAs<BlockPointerType>(); 04017 assert(BPT && "BlockPointerTypeTakeAnyBlockArguments(): not a block pointer type"); 04018 FTP = BPT->getPointeeType()->getAs<FunctionProtoType>(); 04019 } 04020 if (FTP) { 04021 for (const auto &I : FTP->param_types()) { 04022 if (I->isObjCQualifiedIdType()) 04023 return true; 04024 if (I->isObjCObjectPointerType() && 04025 I->getPointeeType()->isObjCQualifiedInterfaceType()) 04026 return true; 04027 } 04028 04029 } 04030 return false; 04031 } 04032 04033 void RewriteObjC::GetExtentOfArgList(const char *Name, const char *&LParen, 04034 const char *&RParen) { 04035 const char *argPtr = strchr(Name, '('); 04036 assert((*argPtr == '(') && "Rewriter fuzzy parser confused"); 04037 04038 LParen = argPtr; // output the start. 04039 argPtr++; // skip past the left paren. 04040 unsigned parenCount = 1; 04041 04042 while (*argPtr && parenCount) { 04043 switch (*argPtr) { 04044 case '(': parenCount++; break; 04045 case ')': parenCount--; break; 04046 default: break; 04047 } 04048 if (parenCount) argPtr++; 04049 } 04050 assert((*argPtr == ')') && "Rewriter fuzzy parser confused"); 04051 RParen = argPtr; // output the end 04052 } 04053 04054 void RewriteObjC::RewriteBlockPointerDecl(NamedDecl *ND) { 04055 if (FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) { 04056 RewriteBlockPointerFunctionArgs(FD); 04057 return; 04058 } 04059 // Handle Variables and Typedefs. 04060 SourceLocation DeclLoc = ND->getLocation(); 04061 QualType DeclT; 04062 if (VarDecl *VD = dyn_cast<VarDecl>(ND)) 04063 DeclT = VD->getType(); 04064 else if (TypedefNameDecl *TDD = dyn_cast<TypedefNameDecl>(ND)) 04065 DeclT = TDD->getUnderlyingType(); 04066 else if (FieldDecl *FD = dyn_cast<FieldDecl>(ND)) 04067 DeclT = FD->getType(); 04068 else 04069 llvm_unreachable("RewriteBlockPointerDecl(): Decl type not yet handled"); 04070 04071 const char *startBuf = SM->getCharacterData(DeclLoc); 04072 const char *endBuf = startBuf; 04073 // scan backward (from the decl location) for the end of the previous decl. 04074 while (*startBuf != '^' && *startBuf != ';' && startBuf != MainFileStart) 04075 startBuf--; 04076 SourceLocation Start = DeclLoc.getLocWithOffset(startBuf-endBuf); 04077 std::string buf; 04078 unsigned OrigLength=0; 04079 // *startBuf != '^' if we are dealing with a pointer to function that 04080 // may take block argument types (which will be handled below). 04081 if (*startBuf == '^') { 04082 // Replace the '^' with '*', computing a negative offset. 04083 buf = '*'; 04084 startBuf++; 04085 OrigLength++; 04086 } 04087 while (*startBuf != ')') { 04088 buf += *startBuf; 04089 startBuf++; 04090 OrigLength++; 04091 } 04092 buf += ')'; 04093 OrigLength++; 04094 04095 if (PointerTypeTakesAnyBlockArguments(DeclT) || 04096 PointerTypeTakesAnyObjCQualifiedType(DeclT)) { 04097 // Replace the '^' with '*' for arguments. 04098 // Replace id<P> with id/*<>*/ 04099 DeclLoc = ND->getLocation(); 04100 startBuf = SM->getCharacterData(DeclLoc); 04101 const char *argListBegin, *argListEnd; 04102 GetExtentOfArgList(startBuf, argListBegin, argListEnd); 04103 while (argListBegin < argListEnd) { 04104 if (*argListBegin == '^') 04105 buf += '*'; 04106 else if (*argListBegin == '<') { 04107 buf += "/*"; 04108 buf += *argListBegin++; 04109 OrigLength++; 04110 while (*argListBegin != '>') { 04111 buf += *argListBegin++; 04112 OrigLength++; 04113 } 04114 buf += *argListBegin; 04115 buf += "*/"; 04116 } 04117 else 04118 buf += *argListBegin; 04119 argListBegin++; 04120 OrigLength++; 04121 } 04122 buf += ')'; 04123 OrigLength++; 04124 } 04125 ReplaceText(Start, OrigLength, buf); 04126 04127 return; 04128 } 04129 04130 04131 /// SynthesizeByrefCopyDestroyHelper - This routine synthesizes: 04132 /// void __Block_byref_id_object_copy(struct Block_byref_id_object *dst, 04133 /// struct Block_byref_id_object *src) { 04134 /// _Block_object_assign (&_dest->object, _src->object, 04135 /// BLOCK_BYREF_CALLER | BLOCK_FIELD_IS_OBJECT 04136 /// [|BLOCK_FIELD_IS_WEAK]) // object 04137 /// _Block_object_assign(&_dest->object, _src->object, 04138 /// BLOCK_BYREF_CALLER | BLOCK_FIELD_IS_BLOCK 04139 /// [|BLOCK_FIELD_IS_WEAK]) // block 04140 /// } 04141 /// And: 04142 /// void __Block_byref_id_object_dispose(struct Block_byref_id_object *_src) { 04143 /// _Block_object_dispose(_src->object, 04144 /// BLOCK_BYREF_CALLER | BLOCK_FIELD_IS_OBJECT 04145 /// [|BLOCK_FIELD_IS_WEAK]) // object 04146 /// _Block_object_dispose(_src->object, 04147 /// BLOCK_BYREF_CALLER | BLOCK_FIELD_IS_BLOCK 04148 /// [|BLOCK_FIELD_IS_WEAK]) // block 04149 /// } 04150 04151 std::string RewriteObjC::SynthesizeByrefCopyDestroyHelper(VarDecl *VD, 04152 int flag) { 04153 std::string S; 04154 if (CopyDestroyCache.count(flag)) 04155 return S; 04156 CopyDestroyCache.insert(flag); 04157 S = "static void __Block_byref_id_object_copy_"; 04158 S += utostr(flag); 04159 S += "(void *dst, void *src) {\n"; 04160 04161 // offset into the object pointer is computed as: 04162 // void * + void* + int + int + void* + void * 04163 unsigned IntSize = 04164 static_cast<unsigned>(Context->getTypeSize(Context->IntTy)); 04165 unsigned VoidPtrSize = 04166 static_cast<unsigned>(Context->getTypeSize(Context->VoidPtrTy)); 04167 04168 unsigned offset = (VoidPtrSize*4 + IntSize + IntSize)/Context->getCharWidth(); 04169 S += " _Block_object_assign((char*)dst + "; 04170 S += utostr(offset); 04171 S += ", *(void * *) ((char*)src + "; 04172 S += utostr(offset); 04173 S += "), "; 04174 S += utostr(flag); 04175 S += ");\n}\n"; 04176 04177 S += "static void __Block_byref_id_object_dispose_"; 04178 S += utostr(flag); 04179 S += "(void *src) {\n"; 04180 S += " _Block_object_dispose(*(void * *) ((char*)src + "; 04181 S += utostr(offset); 04182 S += "), "; 04183 S += utostr(flag); 04184 S += ");\n}\n"; 04185 return S; 04186 } 04187 04188 /// RewriteByRefVar - For each __block typex ND variable this routine transforms 04189 /// the declaration into: 04190 /// struct __Block_byref_ND { 04191 /// void *__isa; // NULL for everything except __weak pointers 04192 /// struct __Block_byref_ND *__forwarding; 04193 /// int32_t __flags; 04194 /// int32_t __size; 04195 /// void *__Block_byref_id_object_copy; // If variable is __block ObjC object 04196 /// void *__Block_byref_id_object_dispose; // If variable is __block ObjC object 04197 /// typex ND; 04198 /// }; 04199 /// 04200 /// It then replaces declaration of ND variable with: 04201 /// struct __Block_byref_ND ND = {__isa=0B, __forwarding=&ND, __flags=some_flag, 04202 /// __size=sizeof(struct __Block_byref_ND), 04203 /// ND=initializer-if-any}; 04204 /// 04205 /// 04206 void RewriteObjC::RewriteByRefVar(VarDecl *ND) { 04207 // Insert declaration for the function in which block literal is 04208 // used. 04209 if (CurFunctionDeclToDeclareForBlock) 04210 RewriteBlockLiteralFunctionDecl(CurFunctionDeclToDeclareForBlock); 04211 int flag = 0; 04212 int isa = 0; 04213 SourceLocation DeclLoc = ND->getTypeSpecStartLoc(); 04214 if (DeclLoc.isInvalid()) 04215 // If type location is missing, it is because of missing type (a warning). 04216 // Use variable's location which is good for this case. 04217 DeclLoc = ND->getLocation(); 04218 const char *startBuf = SM->getCharacterData(DeclLoc); 04219 SourceLocation X = ND->getLocEnd(); 04220 X = SM->getExpansionLoc(X); 04221 const char *endBuf = SM->getCharacterData(X); 04222 std::string Name(ND->getNameAsString()); 04223 std::string ByrefType; 04224 RewriteByRefString(ByrefType, Name, ND, true); 04225 ByrefType += " {\n"; 04226 ByrefType += " void *__isa;\n"; 04227 RewriteByRefString(ByrefType, Name, ND); 04228 ByrefType += " *__forwarding;\n"; 04229 ByrefType += " int __flags;\n"; 04230 ByrefType += " int __size;\n"; 04231 // Add void *__Block_byref_id_object_copy; 04232 // void *__Block_byref_id_object_dispose; if needed. 04233 QualType Ty = ND->getType(); 04234 bool HasCopyAndDispose = Context->BlockRequiresCopying(Ty, ND); 04235 if (HasCopyAndDispose) { 04236 ByrefType += " void (*__Block_byref_id_object_copy)(void*, void*);\n"; 04237 ByrefType += " void (*__Block_byref_id_object_dispose)(void*);\n"; 04238 } 04239 04240 QualType T = Ty; 04241 (void)convertBlockPointerToFunctionPointer(T); 04242 T.getAsStringInternal(Name, Context->getPrintingPolicy()); 04243 04244 ByrefType += " " + Name + ";\n"; 04245 ByrefType += "};\n"; 04246 // Insert this type in global scope. It is needed by helper function. 04247 SourceLocation FunLocStart; 04248 if (CurFunctionDef) 04249 FunLocStart = CurFunctionDef->getTypeSpecStartLoc(); 04250 else { 04251 assert(CurMethodDef && "RewriteByRefVar - CurMethodDef is null"); 04252 FunLocStart = CurMethodDef->getLocStart(); 04253 } 04254 InsertText(FunLocStart, ByrefType); 04255 if (Ty.isObjCGCWeak()) { 04256 flag |= BLOCK_FIELD_IS_WEAK; 04257 isa = 1; 04258 } 04259 04260 if (HasCopyAndDispose) { 04261 flag = BLOCK_BYREF_CALLER; 04262 QualType Ty = ND->getType(); 04263 // FIXME. Handle __weak variable (BLOCK_FIELD_IS_WEAK) as well. 04264 if (Ty->isBlockPointerType()) 04265 flag |= BLOCK_FIELD_IS_BLOCK; 04266 else 04267 flag |= BLOCK_FIELD_IS_OBJECT; 04268 std::string HF = SynthesizeByrefCopyDestroyHelper(ND, flag); 04269 if (!HF.empty()) 04270 InsertText(FunLocStart, HF); 04271 } 04272 04273 // struct __Block_byref_ND ND = 04274 // {0, &ND, some_flag, __size=sizeof(struct __Block_byref_ND), 04275 // initializer-if-any}; 04276 bool hasInit = (ND->getInit() != nullptr); 04277 unsigned flags = 0; 04278 if (HasCopyAndDispose) 04279 flags |= BLOCK_HAS_COPY_DISPOSE; 04280 Name = ND->getNameAsString(); 04281 ByrefType.clear(); 04282 RewriteByRefString(ByrefType, Name, ND); 04283 std::string ForwardingCastType("("); 04284 ForwardingCastType += ByrefType + " *)"; 04285 if (!hasInit) { 04286 ByrefType += " " + Name + " = {(void*)"; 04287 ByrefType += utostr(isa); 04288 ByrefType += "," + ForwardingCastType + "&" + Name + ", "; 04289 ByrefType += utostr(flags); 04290 ByrefType += ", "; 04291 ByrefType += "sizeof("; 04292 RewriteByRefString(ByrefType, Name, ND); 04293 ByrefType += ")"; 04294 if (HasCopyAndDispose) { 04295 ByrefType += ", __Block_byref_id_object_copy_"; 04296 ByrefType += utostr(flag); 04297 ByrefType += ", __Block_byref_id_object_dispose_"; 04298 ByrefType += utostr(flag); 04299 } 04300 ByrefType += "};\n"; 04301 unsigned nameSize = Name.size(); 04302 // for block or function pointer declaration. Name is aleady 04303 // part of the declaration. 04304 if (Ty->isBlockPointerType() || Ty->isFunctionPointerType()) 04305 nameSize = 1; 04306 ReplaceText(DeclLoc, endBuf-startBuf+nameSize, ByrefType); 04307 } 04308 else { 04309 SourceLocation startLoc; 04310 Expr *E = ND->getInit(); 04311 if (const CStyleCastExpr *ECE = dyn_cast<CStyleCastExpr>(E)) 04312 startLoc = ECE->getLParenLoc(); 04313 else 04314 startLoc = E->getLocStart(); 04315 startLoc = SM->getExpansionLoc(startLoc); 04316 endBuf = SM->getCharacterData(startLoc); 04317 ByrefType += " " + Name; 04318 ByrefType += " = {(void*)"; 04319 ByrefType += utostr(isa); 04320 ByrefType += "," + ForwardingCastType + "&" + Name + ", "; 04321 ByrefType += utostr(flags); 04322 ByrefType += ", "; 04323 ByrefType += "sizeof("; 04324 RewriteByRefString(ByrefType, Name, ND); 04325 ByrefType += "), "; 04326 if (HasCopyAndDispose) { 04327 ByrefType += "__Block_byref_id_object_copy_"; 04328 ByrefType += utostr(flag); 04329 ByrefType += ", __Block_byref_id_object_dispose_"; 04330 ByrefType += utostr(flag); 04331 ByrefType += ", "; 04332 } 04333 ReplaceText(DeclLoc, endBuf-startBuf, ByrefType); 04334 04335 // Complete the newly synthesized compound expression by inserting a right 04336 // curly brace before the end of the declaration. 04337 // FIXME: This approach avoids rewriting the initializer expression. It 04338 // also assumes there is only one declarator. For example, the following 04339 // isn't currently supported by this routine (in general): 04340 // 04341 // double __block BYREFVAR = 1.34, BYREFVAR2 = 1.37; 04342 // 04343 const char *startInitializerBuf = SM->getCharacterData(startLoc); 04344 const char *semiBuf = strchr(startInitializerBuf, ';'); 04345 assert((*semiBuf == ';') && "RewriteByRefVar: can't find ';'"); 04346 SourceLocation semiLoc = 04347 startLoc.getLocWithOffset(semiBuf-startInitializerBuf); 04348 04349 InsertText(semiLoc, "}"); 04350 } 04351 return; 04352 } 04353 04354 void RewriteObjC::CollectBlockDeclRefInfo(BlockExpr *Exp) { 04355 // Add initializers for any closure decl refs. 04356 GetBlockDeclRefExprs(Exp->getBody()); 04357 if (BlockDeclRefs.size()) { 04358 // Unique all "by copy" declarations. 04359 for (unsigned i = 0; i < BlockDeclRefs.size(); i++) 04360 if (!BlockDeclRefs[i]->getDecl()->hasAttr<BlocksAttr>()) { 04361 if (!BlockByCopyDeclsPtrSet.count(BlockDeclRefs[i]->getDecl())) { 04362 BlockByCopyDeclsPtrSet.insert(BlockDeclRefs[i]->getDecl()); 04363 BlockByCopyDecls.push_back(BlockDeclRefs[i]->getDecl()); 04364 } 04365 } 04366 // Unique all "by ref" declarations. 04367 for (unsigned i = 0; i < BlockDeclRefs.size(); i++) 04368 if (BlockDeclRefs[i]->getDecl()->hasAttr<BlocksAttr>()) { 04369 if (!BlockByRefDeclsPtrSet.count(BlockDeclRefs[i]->getDecl())) { 04370 BlockByRefDeclsPtrSet.insert(BlockDeclRefs[i]->getDecl()); 04371 BlockByRefDecls.push_back(BlockDeclRefs[i]->getDecl()); 04372 } 04373 } 04374 // Find any imported blocks...they will need special attention. 04375 for (unsigned i = 0; i < BlockDeclRefs.size(); i++) 04376 if (BlockDeclRefs[i]->getDecl()->hasAttr<BlocksAttr>() || 04377 BlockDeclRefs[i]->getType()->isObjCObjectPointerType() || 04378 BlockDeclRefs[i]->getType()->isBlockPointerType()) 04379 ImportedBlockDecls.insert(BlockDeclRefs[i]->getDecl()); 04380 } 04381 } 04382 04383 FunctionDecl *RewriteObjC::SynthBlockInitFunctionDecl(StringRef name) { 04384 IdentifierInfo *ID = &Context->Idents.get(name); 04385 QualType FType = Context->getFunctionNoProtoType(Context->VoidPtrTy); 04386 return FunctionDecl::Create(*Context, TUDecl, SourceLocation(), 04387 SourceLocation(), ID, FType, nullptr, SC_Extern, 04388 false, false); 04389 } 04390 04391 Stmt *RewriteObjC::SynthBlockInitExpr(BlockExpr *Exp, 04392 const SmallVectorImpl<DeclRefExpr *> &InnerBlockDeclRefs) { 04393 const BlockDecl *block = Exp->getBlockDecl(); 04394 Blocks.push_back(Exp); 04395 04396 CollectBlockDeclRefInfo(Exp); 04397 04398 // Add inner imported variables now used in current block. 04399 int countOfInnerDecls = 0; 04400 if (!InnerBlockDeclRefs.empty()) { 04401 for (unsigned i = 0; i < InnerBlockDeclRefs.size(); i++) { 04402 DeclRefExpr *Exp = InnerBlockDeclRefs[i]; 04403 ValueDecl *VD = Exp->getDecl(); 04404 if (!VD->hasAttr<BlocksAttr>() && !BlockByCopyDeclsPtrSet.count(VD)) { 04405 // We need to save the copied-in variables in nested 04406 // blocks because it is needed at the end for some of the API generations. 04407 // See SynthesizeBlockLiterals routine. 04408 InnerDeclRefs.push_back(Exp); countOfInnerDecls++; 04409 BlockDeclRefs.push_back(Exp); 04410 BlockByCopyDeclsPtrSet.insert(VD); 04411 BlockByCopyDecls.push_back(VD); 04412 } 04413 if (VD->hasAttr<BlocksAttr>() && !BlockByRefDeclsPtrSet.count(VD)) { 04414 InnerDeclRefs.push_back(Exp); countOfInnerDecls++; 04415 BlockDeclRefs.push_back(Exp); 04416 BlockByRefDeclsPtrSet.insert(VD); 04417 BlockByRefDecls.push_back(VD); 04418 } 04419 } 04420 // Find any imported blocks...they will need special attention. 04421 for (unsigned i = 0; i < InnerBlockDeclRefs.size(); i++) 04422 if (InnerBlockDeclRefs[i]->getDecl()->hasAttr<BlocksAttr>() || 04423 InnerBlockDeclRefs[i]->getType()->isObjCObjectPointerType() || 04424 InnerBlockDeclRefs[i]->getType()->isBlockPointerType()) 04425 ImportedBlockDecls.insert(InnerBlockDeclRefs[i]->getDecl()); 04426 } 04427 InnerDeclRefsCount.push_back(countOfInnerDecls); 04428 04429 std::string FuncName; 04430 04431 if (CurFunctionDef) 04432 FuncName = CurFunctionDef->getNameAsString(); 04433 else if (CurMethodDef) 04434 BuildUniqueMethodName(FuncName, CurMethodDef); 04435 else if (GlobalVarDecl) 04436 FuncName = std::string(GlobalVarDecl->getNameAsString()); 04437 04438 std::string BlockNumber = utostr(Blocks.size()-1); 04439 04440 std::string Tag = "__" + FuncName + "_block_impl_" + BlockNumber; 04441 std::string Func = "__" + FuncName + "_block_func_" + BlockNumber; 04442 04443 // Get a pointer to the function type so we can cast appropriately. 04444 QualType BFT = convertFunctionTypeOfBlocks(Exp->getFunctionType()); 04445 QualType FType = Context->getPointerType(BFT); 04446 04447 FunctionDecl *FD; 04448 Expr *NewRep; 04449 04450 // Simulate a constructor call... 04451 FD = SynthBlockInitFunctionDecl(Tag); 04452 DeclRefExpr *DRE = new (Context) DeclRefExpr(FD, false, FType, VK_RValue, 04453 SourceLocation()); 04454 04455 SmallVector<Expr*, 4> InitExprs; 04456 04457 // Initialize the block function. 04458 FD = SynthBlockInitFunctionDecl(Func); 04459 DeclRefExpr *Arg = new (Context) DeclRefExpr(FD, false, FD->getType(), 04460 VK_LValue, SourceLocation()); 04461 CastExpr *castExpr = NoTypeInfoCStyleCastExpr(Context, Context->VoidPtrTy, 04462 CK_BitCast, Arg); 04463 InitExprs.push_back(castExpr); 04464 04465 // Initialize the block descriptor. 04466 std::string DescData = "__" + FuncName + "_block_desc_" + BlockNumber + "_DATA"; 04467 04468 VarDecl *NewVD = VarDecl::Create(*Context, TUDecl, 04469 SourceLocation(), SourceLocation(), 04470 &Context->Idents.get(DescData.c_str()), 04471 Context->VoidPtrTy, nullptr, 04472 SC_Static); 04473 UnaryOperator *DescRefExpr = 04474 new (Context) UnaryOperator(new (Context) DeclRefExpr(NewVD, false, 04475 Context->VoidPtrTy, 04476 VK_LValue, 04477 SourceLocation()), 04478 UO_AddrOf, 04479 Context->getPointerType(Context->VoidPtrTy), 04480 VK_RValue, OK_Ordinary, 04481 SourceLocation()); 04482 InitExprs.push_back(DescRefExpr); 04483 04484 // Add initializers for any closure decl refs. 04485 if (BlockDeclRefs.size()) { 04486 Expr *Exp; 04487 // Output all "by copy" declarations. 04488 for (SmallVectorImpl<ValueDecl *>::iterator I = BlockByCopyDecls.begin(), 04489 E = BlockByCopyDecls.end(); I != E; ++I) { 04490 if (isObjCType((*I)->getType())) { 04491 // FIXME: Conform to ABI ([[obj retain] autorelease]). 04492 FD = SynthBlockInitFunctionDecl((*I)->getName()); 04493 Exp = new (Context) DeclRefExpr(FD, false, FD->getType(), VK_LValue, 04494 SourceLocation()); 04495 if (HasLocalVariableExternalStorage(*I)) { 04496 QualType QT = (*I)->getType(); 04497 QT = Context->getPointerType(QT); 04498 Exp = new (Context) UnaryOperator(Exp, UO_AddrOf, QT, VK_RValue, 04499 OK_Ordinary, SourceLocation()); 04500 } 04501 } else if (isTopLevelBlockPointerType((*I)->getType())) { 04502 FD = SynthBlockInitFunctionDecl((*I)->getName()); 04503 Arg = new (Context) DeclRefExpr(FD, false, FD->getType(), VK_LValue, 04504 SourceLocation()); 04505 Exp = NoTypeInfoCStyleCastExpr(Context, Context->VoidPtrTy, 04506 CK_BitCast, Arg); 04507 } else { 04508 FD = SynthBlockInitFunctionDecl((*I)->getName()); 04509 Exp = new (Context) DeclRefExpr(FD, false, FD->getType(), VK_LValue, 04510 SourceLocation()); 04511 if (HasLocalVariableExternalStorage(*I)) { 04512 QualType QT = (*I)->getType(); 04513 QT = Context->getPointerType(QT); 04514 Exp = new (Context) UnaryOperator(Exp, UO_AddrOf, QT, VK_RValue, 04515 OK_Ordinary, SourceLocation()); 04516 } 04517 04518 } 04519 InitExprs.push_back(Exp); 04520 } 04521 // Output all "by ref" declarations. 04522 for (SmallVectorImpl<ValueDecl *>::iterator I = BlockByRefDecls.begin(), 04523 E = BlockByRefDecls.end(); I != E; ++I) { 04524 ValueDecl *ND = (*I); 04525 std::string Name(ND->getNameAsString()); 04526 std::string RecName; 04527 RewriteByRefString(RecName, Name, ND, true); 04528 IdentifierInfo *II = &Context->Idents.get(RecName.c_str() 04529 + sizeof("struct")); 04530 RecordDecl *RD = RecordDecl::Create(*Context, TTK_Struct, TUDecl, 04531 SourceLocation(), SourceLocation(), 04532 II); 04533 assert(RD && "SynthBlockInitExpr(): Can't find RecordDecl"); 04534 QualType castT = Context->getPointerType(Context->getTagDeclType(RD)); 04535 04536 FD = SynthBlockInitFunctionDecl((*I)->getName()); 04537 Exp = new (Context) DeclRefExpr(FD, false, FD->getType(), VK_LValue, 04538 SourceLocation()); 04539 bool isNestedCapturedVar = false; 04540 if (block) 04541 for (const auto &CI : block->captures()) { 04542 const VarDecl *variable = CI.getVariable(); 04543 if (variable == ND && CI.isNested()) { 04544 assert (CI.isByRef() && 04545 "SynthBlockInitExpr - captured block variable is not byref"); 04546 isNestedCapturedVar = true; 04547 break; 04548 } 04549 } 04550 // captured nested byref variable has its address passed. Do not take 04551 // its address again. 04552 if (!isNestedCapturedVar) 04553 Exp = new (Context) UnaryOperator(Exp, UO_AddrOf, 04554 Context->getPointerType(Exp->getType()), 04555 VK_RValue, OK_Ordinary, SourceLocation()); 04556 Exp = NoTypeInfoCStyleCastExpr(Context, castT, CK_BitCast, Exp); 04557 InitExprs.push_back(Exp); 04558 } 04559 } 04560 if (ImportedBlockDecls.size()) { 04561 // generate BLOCK_HAS_COPY_DISPOSE(have helper funcs) | BLOCK_HAS_DESCRIPTOR 04562 int flag = (BLOCK_HAS_COPY_DISPOSE | BLOCK_HAS_DESCRIPTOR); 04563 unsigned IntSize = 04564 static_cast<unsigned>(Context->getTypeSize(Context->IntTy)); 04565 Expr *FlagExp = IntegerLiteral::Create(*Context, llvm::APInt(IntSize, flag), 04566 Context->IntTy, SourceLocation()); 04567 InitExprs.push_back(FlagExp); 04568 } 04569 NewRep = new (Context) CallExpr(*Context, DRE, InitExprs, 04570 FType, VK_LValue, SourceLocation()); 04571 NewRep = new (Context) UnaryOperator(NewRep, UO_AddrOf, 04572 Context->getPointerType(NewRep->getType()), 04573 VK_RValue, OK_Ordinary, SourceLocation()); 04574 NewRep = NoTypeInfoCStyleCastExpr(Context, FType, CK_BitCast, 04575 NewRep); 04576 BlockDeclRefs.clear(); 04577 BlockByRefDecls.clear(); 04578 BlockByRefDeclsPtrSet.clear(); 04579 BlockByCopyDecls.clear(); 04580 BlockByCopyDeclsPtrSet.clear(); 04581 ImportedBlockDecls.clear(); 04582 return NewRep; 04583 } 04584 04585 bool RewriteObjC::IsDeclStmtInForeachHeader(DeclStmt *DS) { 04586 if (const ObjCForCollectionStmt * CS = 04587 dyn_cast<ObjCForCollectionStmt>(Stmts.back())) 04588 return CS->getElement() == DS; 04589 return false; 04590 } 04591 04592 //===----------------------------------------------------------------------===// 04593 // Function Body / Expression rewriting 04594 //===----------------------------------------------------------------------===// 04595 04596 Stmt *RewriteObjC::RewriteFunctionBodyOrGlobalInitializer(Stmt *S) { 04597 if (isa<SwitchStmt>(S) || isa<WhileStmt>(S) || 04598 isa<DoStmt>(S) || isa<ForStmt>(S)) 04599 Stmts.push_back(S); 04600 else if (isa<ObjCForCollectionStmt>(S)) { 04601 Stmts.push_back(S); 04602 ObjCBcLabelNo.push_back(++BcLabelCount); 04603 } 04604 04605 // Pseudo-object operations and ivar references need special 04606 // treatment because we're going to recursively rewrite them. 04607 if (PseudoObjectExpr *PseudoOp = dyn_cast<PseudoObjectExpr>(S)) { 04608 if (isa<BinaryOperator>(PseudoOp->getSyntacticForm())) { 04609 return RewritePropertyOrImplicitSetter(PseudoOp); 04610 } else { 04611 return RewritePropertyOrImplicitGetter(PseudoOp); 04612 } 04613 } else if (ObjCIvarRefExpr *IvarRefExpr = dyn_cast<ObjCIvarRefExpr>(S)) { 04614 return RewriteObjCIvarRefExpr(IvarRefExpr); 04615 } 04616 04617 SourceRange OrigStmtRange = S->getSourceRange(); 04618 04619 // Perform a bottom up rewrite of all children. 04620 for (Stmt::child_range CI = S->children(); CI; ++CI) 04621 if (*CI) { 04622 Stmt *childStmt = (*CI); 04623 Stmt *newStmt = RewriteFunctionBodyOrGlobalInitializer(childStmt); 04624 if (newStmt) { 04625 *CI = newStmt; 04626 } 04627 } 04628 04629 if (BlockExpr *BE = dyn_cast<BlockExpr>(S)) { 04630 SmallVector<DeclRefExpr *, 8> InnerBlockDeclRefs; 04631 llvm::SmallPtrSet<const DeclContext *, 8> InnerContexts; 04632 InnerContexts.insert(BE->getBlockDecl()); 04633 ImportedLocalExternalDecls.clear(); 04634 GetInnerBlockDeclRefExprs(BE->getBody(), 04635 InnerBlockDeclRefs, InnerContexts); 04636 // Rewrite the block body in place. 04637 Stmt *SaveCurrentBody = CurrentBody; 04638 CurrentBody = BE->getBody(); 04639 PropParentMap = nullptr; 04640 // block literal on rhs of a property-dot-sytax assignment 04641 // must be replaced by its synthesize ast so getRewrittenText 04642 // works as expected. In this case, what actually ends up on RHS 04643 // is the blockTranscribed which is the helper function for the 04644 // block literal; as in: self.c = ^() {[ace ARR];}; 04645 bool saveDisableReplaceStmt = DisableReplaceStmt; 04646 DisableReplaceStmt = false; 04647 RewriteFunctionBodyOrGlobalInitializer(BE->getBody()); 04648 DisableReplaceStmt = saveDisableReplaceStmt; 04649 CurrentBody = SaveCurrentBody; 04650 PropParentMap = nullptr; 04651 ImportedLocalExternalDecls.clear(); 04652 // Now we snarf the rewritten text and stash it away for later use. 04653 std::string Str = Rewrite.getRewrittenText(BE->getSourceRange()); 04654 RewrittenBlockExprs[BE] = Str; 04655 04656 Stmt *blockTranscribed = SynthBlockInitExpr(BE, InnerBlockDeclRefs); 04657 04658 //blockTranscribed->dump(); 04659 ReplaceStmt(S, blockTranscribed); 04660 return blockTranscribed; 04661 } 04662 // Handle specific things. 04663 if (ObjCEncodeExpr *AtEncode = dyn_cast<ObjCEncodeExpr>(S)) 04664 return RewriteAtEncode(AtEncode); 04665 04666 if (ObjCSelectorExpr *AtSelector = dyn_cast<ObjCSelectorExpr>(S)) 04667 return RewriteAtSelector(AtSelector); 04668 04669 if (ObjCStringLiteral *AtString = dyn_cast<ObjCStringLiteral>(S)) 04670 return RewriteObjCStringLiteral(AtString); 04671 04672 if (ObjCMessageExpr *MessExpr = dyn_cast<ObjCMessageExpr>(S)) { 04673 #if 0 04674 // Before we rewrite it, put the original message expression in a comment. 04675 SourceLocation startLoc = MessExpr->getLocStart(); 04676 SourceLocation endLoc = MessExpr->getLocEnd(); 04677 04678 const char *startBuf = SM->getCharacterData(startLoc); 04679 const char *endBuf = SM->getCharacterData(endLoc); 04680 04681 std::string messString; 04682 messString += "// "; 04683 messString.append(startBuf, endBuf-startBuf+1); 04684 messString += "\n"; 04685 04686 // FIXME: Missing definition of 04687 // InsertText(clang::SourceLocation, char const*, unsigned int). 04688 // InsertText(startLoc, messString.c_str(), messString.size()); 04689 // Tried this, but it didn't work either... 04690 // ReplaceText(startLoc, 0, messString.c_str(), messString.size()); 04691 #endif 04692 return RewriteMessageExpr(MessExpr); 04693 } 04694 04695 if (ObjCAtTryStmt *StmtTry = dyn_cast<ObjCAtTryStmt>(S)) 04696 return RewriteObjCTryStmt(StmtTry); 04697 04698 if (ObjCAtSynchronizedStmt *StmtTry = dyn_cast<ObjCAtSynchronizedStmt>(S)) 04699 return RewriteObjCSynchronizedStmt(StmtTry); 04700 04701 if (ObjCAtThrowStmt *StmtThrow = dyn_cast<ObjCAtThrowStmt>(S)) 04702 return RewriteObjCThrowStmt(StmtThrow); 04703 04704 if (ObjCProtocolExpr *ProtocolExp = dyn_cast<ObjCProtocolExpr>(S)) 04705 return RewriteObjCProtocolExpr(ProtocolExp); 04706 04707 if (ObjCForCollectionStmt *StmtForCollection = 04708 dyn_cast<ObjCForCollectionStmt>(S)) 04709 return RewriteObjCForCollectionStmt(StmtForCollection, 04710 OrigStmtRange.getEnd()); 04711 if (BreakStmt *StmtBreakStmt = 04712 dyn_cast<BreakStmt>(S)) 04713 return RewriteBreakStmt(StmtBreakStmt); 04714 if (ContinueStmt *StmtContinueStmt = 04715 dyn_cast<ContinueStmt>(S)) 04716 return RewriteContinueStmt(StmtContinueStmt); 04717 04718 // Need to check for protocol refs (id <P>, Foo <P> *) in variable decls 04719 // and cast exprs. 04720 if (DeclStmt *DS = dyn_cast<DeclStmt>(S)) { 04721 // FIXME: What we're doing here is modifying the type-specifier that 04722 // precedes the first Decl. In the future the DeclGroup should have 04723 // a separate type-specifier that we can rewrite. 04724 // NOTE: We need to avoid rewriting the DeclStmt if it is within 04725 // the context of an ObjCForCollectionStmt. For example: 04726 // NSArray *someArray; 04727 // for (id <FooProtocol> index in someArray) ; 04728 // This is because RewriteObjCForCollectionStmt() does textual rewriting 04729 // and it depends on the original text locations/positions. 04730 if (Stmts.empty() || !IsDeclStmtInForeachHeader(DS)) 04731 RewriteObjCQualifiedInterfaceTypes(*DS->decl_begin()); 04732 04733 // Blocks rewrite rules. 04734 for (auto *SD : DS->decls()) { 04735 if (ValueDecl *ND = dyn_cast<ValueDecl>(SD)) { 04736 if (isTopLevelBlockPointerType(ND->getType())) 04737 RewriteBlockPointerDecl(ND); 04738 else if (ND->getType()->isFunctionPointerType()) 04739 CheckFunctionPointerDecl(ND->getType(), ND); 04740 if (VarDecl *VD = dyn_cast<VarDecl>(SD)) { 04741 if (VD->hasAttr<BlocksAttr>()) { 04742 static unsigned uniqueByrefDeclCount = 0; 04743 assert(!BlockByRefDeclNo.count(ND) && 04744 "RewriteFunctionBodyOrGlobalInitializer: Duplicate byref decl"); 04745 BlockByRefDeclNo[ND] = uniqueByrefDeclCount++; 04746 RewriteByRefVar(VD); 04747 } 04748 else 04749 RewriteTypeOfDecl(VD); 04750 } 04751 } 04752 if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(SD)) { 04753 if (isTopLevelBlockPointerType(TD->getUnderlyingType())) 04754 RewriteBlockPointerDecl(TD); 04755 else if (TD->getUnderlyingType()->isFunctionPointerType()) 04756 CheckFunctionPointerDecl(TD->getUnderlyingType(), TD); 04757 } 04758 } 04759 } 04760 04761 if (CStyleCastExpr *CE = dyn_cast<CStyleCastExpr>(S)) 04762 RewriteObjCQualifiedInterfaceTypes(CE); 04763 04764 if (isa<SwitchStmt>(S) || isa<WhileStmt>(S) || 04765 isa<DoStmt>(S) || isa<ForStmt>(S)) { 04766 assert(!Stmts.empty() && "Statement stack is empty"); 04767 assert ((isa<SwitchStmt>(Stmts.back()) || isa<WhileStmt>(Stmts.back()) || 04768 isa<DoStmt>(Stmts.back()) || isa<ForStmt>(Stmts.back())) 04769 && "Statement stack mismatch"); 04770 Stmts.pop_back(); 04771 } 04772 // Handle blocks rewriting. 04773 if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(S)) { 04774 ValueDecl *VD = DRE->getDecl(); 04775 if (VD->hasAttr<BlocksAttr>()) 04776 return RewriteBlockDeclRefExpr(DRE); 04777 if (HasLocalVariableExternalStorage(VD)) 04778 return RewriteLocalVariableExternalStorage(DRE); 04779 } 04780 04781 if (CallExpr *CE = dyn_cast<CallExpr>(S)) { 04782 if (CE->getCallee()->getType()->isBlockPointerType()) { 04783 Stmt *BlockCall = SynthesizeBlockCall(CE, CE->getCallee()); 04784 ReplaceStmt(S, BlockCall); 04785 return BlockCall; 04786 } 04787 } 04788 if (CStyleCastExpr *CE = dyn_cast<CStyleCastExpr>(S)) { 04789 RewriteCastExpr(CE); 04790 } 04791 #if 0 04792 if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(S)) { 04793 CastExpr *Replacement = new (Context) CastExpr(ICE->getType(), 04794 ICE->getSubExpr(), 04795 SourceLocation()); 04796 // Get the new text. 04797 std::string SStr; 04798 llvm::raw_string_ostream Buf(SStr); 04799 Replacement->printPretty(Buf); 04800 const std::string &Str = Buf.str(); 04801 04802 printf("CAST = %s\n", &Str[0]); 04803 InsertText(ICE->getSubExpr()->getLocStart(), &Str[0], Str.size()); 04804 delete S; 04805 return Replacement; 04806 } 04807 #endif 04808 // Return this stmt unmodified. 04809 return S; 04810 } 04811 04812 void RewriteObjC::RewriteRecordBody(RecordDecl *RD) { 04813 for (auto *FD : RD->fields()) { 04814 if (isTopLevelBlockPointerType(FD->getType())) 04815 RewriteBlockPointerDecl(FD); 04816 if (FD->getType()->isObjCQualifiedIdType() || 04817 FD->getType()->isObjCQualifiedInterfaceType()) 04818 RewriteObjCQualifiedInterfaceTypes(FD); 04819 } 04820 } 04821 04822 /// HandleDeclInMainFile - This is called for each top-level decl defined in the 04823 /// main file of the input. 04824 void RewriteObjC::HandleDeclInMainFile(Decl *D) { 04825 switch (D->getKind()) { 04826 case Decl::Function: { 04827 FunctionDecl *FD = cast<FunctionDecl>(D); 04828 if (FD->isOverloadedOperator()) 04829 return; 04830 04831 // Since function prototypes don't have ParmDecl's, we check the function 04832 // prototype. This enables us to rewrite function declarations and 04833 // definitions using the same code. 04834 RewriteBlocksInFunctionProtoType(FD->getType(), FD); 04835 04836 if (!FD->isThisDeclarationADefinition()) 04837 break; 04838 04839 // FIXME: If this should support Obj-C++, support CXXTryStmt 04840 if (CompoundStmt *Body = dyn_cast_or_null<CompoundStmt>(FD->getBody())) { 04841 CurFunctionDef = FD; 04842 CurFunctionDeclToDeclareForBlock = FD; 04843 CurrentBody = Body; 04844 Body = 04845 cast_or_null<CompoundStmt>(RewriteFunctionBodyOrGlobalInitializer(Body)); 04846 FD->setBody(Body); 04847 CurrentBody = nullptr; 04848 if (PropParentMap) { 04849 delete PropParentMap; 04850 PropParentMap = nullptr; 04851 } 04852 // This synthesizes and inserts the block "impl" struct, invoke function, 04853 // and any copy/dispose helper functions. 04854 InsertBlockLiteralsWithinFunction(FD); 04855 CurFunctionDef = nullptr; 04856 CurFunctionDeclToDeclareForBlock = nullptr; 04857 } 04858 break; 04859 } 04860 case Decl::ObjCMethod: { 04861 ObjCMethodDecl *MD = cast<ObjCMethodDecl>(D); 04862 if (CompoundStmt *Body = MD->getCompoundBody()) { 04863 CurMethodDef = MD; 04864 CurrentBody = Body; 04865 Body = 04866 cast_or_null<CompoundStmt>(RewriteFunctionBodyOrGlobalInitializer(Body)); 04867 MD->setBody(Body); 04868 CurrentBody = nullptr; 04869 if (PropParentMap) { 04870 delete PropParentMap; 04871 PropParentMap = nullptr; 04872 } 04873 InsertBlockLiteralsWithinMethod(MD); 04874 CurMethodDef = nullptr; 04875 } 04876 break; 04877 } 04878 case Decl::ObjCImplementation: { 04879 ObjCImplementationDecl *CI = cast<ObjCImplementationDecl>(D); 04880 ClassImplementation.push_back(CI); 04881 break; 04882 } 04883 case Decl::ObjCCategoryImpl: { 04884 ObjCCategoryImplDecl *CI = cast<ObjCCategoryImplDecl>(D); 04885 CategoryImplementation.push_back(CI); 04886 break; 04887 } 04888 case Decl::Var: { 04889 VarDecl *VD = cast<VarDecl>(D); 04890 RewriteObjCQualifiedInterfaceTypes(VD); 04891 if (isTopLevelBlockPointerType(VD->getType())) 04892 RewriteBlockPointerDecl(VD); 04893 else if (VD->getType()->isFunctionPointerType()) { 04894 CheckFunctionPointerDecl(VD->getType(), VD); 04895 if (VD->getInit()) { 04896 if (CStyleCastExpr *CE = dyn_cast<CStyleCastExpr>(VD->getInit())) { 04897 RewriteCastExpr(CE); 04898 } 04899 } 04900 } else if (VD->getType()->isRecordType()) { 04901 RecordDecl *RD = VD->getType()->getAs<RecordType>()->getDecl(); 04902 if (RD->isCompleteDefinition()) 04903 RewriteRecordBody(RD); 04904 } 04905 if (VD->getInit()) { 04906 GlobalVarDecl = VD; 04907 CurrentBody = VD->getInit(); 04908 RewriteFunctionBodyOrGlobalInitializer(VD->getInit()); 04909 CurrentBody = nullptr; 04910 if (PropParentMap) { 04911 delete PropParentMap; 04912 PropParentMap = nullptr; 04913 } 04914 SynthesizeBlockLiterals(VD->getTypeSpecStartLoc(), VD->getName()); 04915 GlobalVarDecl = nullptr; 04916 04917 // This is needed for blocks. 04918 if (CStyleCastExpr *CE = dyn_cast<CStyleCastExpr>(VD->getInit())) { 04919 RewriteCastExpr(CE); 04920 } 04921 } 04922 break; 04923 } 04924 case Decl::TypeAlias: 04925 case Decl::Typedef: { 04926 if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D)) { 04927 if (isTopLevelBlockPointerType(TD->getUnderlyingType())) 04928 RewriteBlockPointerDecl(TD); 04929 else if (TD->getUnderlyingType()->isFunctionPointerType()) 04930 CheckFunctionPointerDecl(TD->getUnderlyingType(), TD); 04931 } 04932 break; 04933 } 04934 case Decl::CXXRecord: 04935 case Decl::Record: { 04936 RecordDecl *RD = cast<RecordDecl>(D); 04937 if (RD->isCompleteDefinition()) 04938 RewriteRecordBody(RD); 04939 break; 04940 } 04941 default: 04942 break; 04943 } 04944 // Nothing yet. 04945 } 04946 04947 void RewriteObjC::HandleTranslationUnit(ASTContext &C) { 04948 if (Diags.hasErrorOccurred()) 04949 return; 04950 04951 RewriteInclude(); 04952 04953 // Here's a great place to add any extra declarations that may be needed. 04954 // Write out meta data for each @protocol(<expr>). 04955 for (ObjCProtocolDecl *ProtDecl : ProtocolExprDecls) 04956 RewriteObjCProtocolMetaData(ProtDecl, "", "", Preamble); 04957 04958 InsertText(SM->getLocForStartOfFile(MainFileID), Preamble, false); 04959 if (ClassImplementation.size() || CategoryImplementation.size()) 04960 RewriteImplementations(); 04961 04962 // Get the buffer corresponding to MainFileID. If we haven't changed it, then 04963 // we are done. 04964 if (const RewriteBuffer *RewriteBuf = 04965 Rewrite.getRewriteBufferFor(MainFileID)) { 04966 //printf("Changed:\n"); 04967 *OutFile << std::string(RewriteBuf->begin(), RewriteBuf->end()); 04968 } else { 04969 llvm::errs() << "No changes\n"; 04970 } 04971 04972 if (ClassImplementation.size() || CategoryImplementation.size() || 04973 ProtocolExprDecls.size()) { 04974 // Rewrite Objective-c meta data* 04975 std::string ResultStr; 04976 RewriteMetaDataIntoBuffer(ResultStr); 04977 // Emit metadata. 04978 *OutFile << ResultStr; 04979 } 04980 OutFile->flush(); 04981 } 04982 04983 void RewriteObjCFragileABI::Initialize(ASTContext &context) { 04984 InitializeCommon(context); 04985 04986 // declaring objc_selector outside the parameter list removes a silly 04987 // scope related warning... 04988 if (IsHeader) 04989 Preamble = "#pragma once\n"; 04990 Preamble += "struct objc_selector; struct objc_class;\n"; 04991 Preamble += "struct __rw_objc_super { struct objc_object *object; "; 04992 Preamble += "struct objc_object *superClass; "; 04993 if (LangOpts.MicrosoftExt) { 04994 // Add a constructor for creating temporary objects. 04995 Preamble += "__rw_objc_super(struct objc_object *o, struct objc_object *s) " 04996 ": "; 04997 Preamble += "object(o), superClass(s) {} "; 04998 } 04999 Preamble += "};\n"; 05000 Preamble += "#ifndef _REWRITER_typedef_Protocol\n"; 05001 Preamble += "typedef struct objc_object Protocol;\n"; 05002 Preamble += "#define _REWRITER_typedef_Protocol\n"; 05003 Preamble += "#endif\n"; 05004 if (LangOpts.MicrosoftExt) { 05005 Preamble += "#define __OBJC_RW_DLLIMPORT extern \"C\" __declspec(dllimport)\n"; 05006 Preamble += "#define __OBJC_RW_STATICIMPORT extern \"C\"\n"; 05007 } else 05008 Preamble += "#define __OBJC_RW_DLLIMPORT extern\n"; 05009 Preamble += "__OBJC_RW_DLLIMPORT struct objc_object *objc_msgSend"; 05010 Preamble += "(struct objc_object *, struct objc_selector *, ...);\n"; 05011 Preamble += "__OBJC_RW_DLLIMPORT struct objc_object *objc_msgSendSuper"; 05012 Preamble += "(struct objc_super *, struct objc_selector *, ...);\n"; 05013 Preamble += "__OBJC_RW_DLLIMPORT struct objc_object* objc_msgSend_stret"; 05014 Preamble += "(struct objc_object *, struct objc_selector *, ...);\n"; 05015 Preamble += "__OBJC_RW_DLLIMPORT struct objc_object* objc_msgSendSuper_stret"; 05016 Preamble += "(struct objc_super *, struct objc_selector *, ...);\n"; 05017 Preamble += "__OBJC_RW_DLLIMPORT double objc_msgSend_fpret"; 05018 Preamble += "(struct objc_object *, struct objc_selector *, ...);\n"; 05019 Preamble += "__OBJC_RW_DLLIMPORT struct objc_object *objc_getClass"; 05020 Preamble += "(const char *);\n"; 05021 Preamble += "__OBJC_RW_DLLIMPORT struct objc_class *class_getSuperclass"; 05022 Preamble += "(struct objc_class *);\n"; 05023 Preamble += "__OBJC_RW_DLLIMPORT struct objc_object *objc_getMetaClass"; 05024 Preamble += "(const char *);\n"; 05025 Preamble += "__OBJC_RW_DLLIMPORT void objc_exception_throw(struct objc_object *);\n"; 05026 Preamble += "__OBJC_RW_DLLIMPORT void objc_exception_try_enter(void *);\n"; 05027 Preamble += "__OBJC_RW_DLLIMPORT void objc_exception_try_exit(void *);\n"; 05028 Preamble += "__OBJC_RW_DLLIMPORT struct objc_object *objc_exception_extract(void *);\n"; 05029 Preamble += "__OBJC_RW_DLLIMPORT int objc_exception_match"; 05030 Preamble += "(struct objc_class *, struct objc_object *);\n"; 05031 // @synchronized hooks. 05032 Preamble += "__OBJC_RW_DLLIMPORT int objc_sync_enter(struct objc_object *);\n"; 05033 Preamble += "__OBJC_RW_DLLIMPORT int objc_sync_exit(struct objc_object *);\n"; 05034 Preamble += "__OBJC_RW_DLLIMPORT Protocol *objc_getProtocol(const char *);\n"; 05035 Preamble += "#ifndef __FASTENUMERATIONSTATE\n"; 05036 Preamble += "struct __objcFastEnumerationState {\n\t"; 05037 Preamble += "unsigned long state;\n\t"; 05038 Preamble += "void **itemsPtr;\n\t"; 05039 Preamble += "unsigned long *mutationsPtr;\n\t"; 05040 Preamble += "unsigned long extra[5];\n};\n"; 05041 Preamble += "__OBJC_RW_DLLIMPORT void objc_enumerationMutation(struct objc_object *);\n"; 05042 Preamble += "#define __FASTENUMERATIONSTATE\n"; 05043 Preamble += "#endif\n"; 05044 Preamble += "#ifndef __NSCONSTANTSTRINGIMPL\n"; 05045 Preamble += "struct __NSConstantStringImpl {\n"; 05046 Preamble += " int *isa;\n"; 05047 Preamble += " int flags;\n"; 05048 Preamble += " char *str;\n"; 05049 Preamble += " long length;\n"; 05050 Preamble += "};\n"; 05051 Preamble += "#ifdef CF_EXPORT_CONSTANT_STRING\n"; 05052 Preamble += "extern \"C\" __declspec(dllexport) int __CFConstantStringClassReference[];\n"; 05053 Preamble += "#else\n"; 05054 Preamble += "__OBJC_RW_DLLIMPORT int __CFConstantStringClassReference[];\n"; 05055 Preamble += "#endif\n"; 05056 Preamble += "#define __NSCONSTANTSTRINGIMPL\n"; 05057 Preamble += "#endif\n"; 05058 // Blocks preamble. 05059 Preamble += "#ifndef BLOCK_IMPL\n"; 05060 Preamble += "#define BLOCK_IMPL\n"; 05061 Preamble += "struct __block_impl {\n"; 05062 Preamble += " void *isa;\n"; 05063 Preamble += " int Flags;\n"; 05064 Preamble += " int Reserved;\n"; 05065 Preamble += " void *FuncPtr;\n"; 05066 Preamble += "};\n"; 05067 Preamble += "// Runtime copy/destroy helper functions (from Block_private.h)\n"; 05068 Preamble += "#ifdef __OBJC_EXPORT_BLOCKS\n"; 05069 Preamble += "extern \"C\" __declspec(dllexport) " 05070 "void _Block_object_assign(void *, const void *, const int);\n"; 05071 Preamble += "extern \"C\" __declspec(dllexport) void _Block_object_dispose(const void *, const int);\n"; 05072 Preamble += "extern \"C\" __declspec(dllexport) void *_NSConcreteGlobalBlock[32];\n"; 05073 Preamble += "extern \"C\" __declspec(dllexport) void *_NSConcreteStackBlock[32];\n"; 05074 Preamble += "#else\n"; 05075 Preamble += "__OBJC_RW_DLLIMPORT void _Block_object_assign(void *, const void *, const int);\n"; 05076 Preamble += "__OBJC_RW_DLLIMPORT void _Block_object_dispose(const void *, const int);\n"; 05077 Preamble += "__OBJC_RW_DLLIMPORT void *_NSConcreteGlobalBlock[32];\n"; 05078 Preamble += "__OBJC_RW_DLLIMPORT void *_NSConcreteStackBlock[32];\n"; 05079 Preamble += "#endif\n"; 05080 Preamble += "#endif\n"; 05081 if (LangOpts.MicrosoftExt) { 05082 Preamble += "#undef __OBJC_RW_DLLIMPORT\n"; 05083 Preamble += "#undef __OBJC_RW_STATICIMPORT\n"; 05084 Preamble += "#ifndef KEEP_ATTRIBUTES\n"; // We use this for clang tests. 05085 Preamble += "#define __attribute__(X)\n"; 05086 Preamble += "#endif\n"; 05087 Preamble += "#define __weak\n"; 05088 } 05089 else { 05090 Preamble += "#define __block\n"; 05091 Preamble += "#define __weak\n"; 05092 } 05093 // NOTE! Windows uses LLP64 for 64bit mode. So, cast pointer to long long 05094 // as this avoids warning in any 64bit/32bit compilation model. 05095 Preamble += "\n#define __OFFSETOFIVAR__(TYPE, MEMBER) ((long long) &((TYPE *)0)->MEMBER)\n"; 05096 } 05097 05098 /// RewriteIvarOffsetComputation - This rutine synthesizes computation of 05099 /// ivar offset. 05100 void RewriteObjCFragileABI::RewriteIvarOffsetComputation(ObjCIvarDecl *ivar, 05101 std::string &Result) { 05102 if (ivar->isBitField()) { 05103 // FIXME: The hack below doesn't work for bitfields. For now, we simply 05104 // place all bitfields at offset 0. 05105 Result += "0"; 05106 } else { 05107 Result += "__OFFSETOFIVAR__(struct "; 05108 Result += ivar->getContainingInterface()->getNameAsString(); 05109 if (LangOpts.MicrosoftExt) 05110 Result += "_IMPL"; 05111 Result += ", "; 05112 Result += ivar->getNameAsString(); 05113 Result += ")"; 05114 } 05115 } 05116 05117 /// RewriteObjCProtocolMetaData - Rewrite protocols meta-data. 05118 void RewriteObjCFragileABI::RewriteObjCProtocolMetaData( 05119 ObjCProtocolDecl *PDecl, StringRef prefix, 05120 StringRef ClassName, std::string &Result) { 05121 static bool objc_protocol_methods = false; 05122 05123 // Output struct protocol_methods holder of method selector and type. 05124 if (!objc_protocol_methods && PDecl->hasDefinition()) { 05125 /* struct protocol_methods { 05126 SEL _cmd; 05127 char *method_types; 05128 } 05129 */ 05130 Result += "\nstruct _protocol_methods {\n"; 05131 Result += "\tstruct objc_selector *_cmd;\n"; 05132 Result += "\tchar *method_types;\n"; 05133 Result += "};\n"; 05134 05135 objc_protocol_methods = true; 05136 } 05137 // Do not synthesize the protocol more than once. 05138 if (ObjCSynthesizedProtocols.count(PDecl->getCanonicalDecl())) 05139 return; 05140 05141 if (ObjCProtocolDecl *Def = PDecl->getDefinition()) 05142 PDecl = Def; 05143 05144 if (PDecl->instmeth_begin() != PDecl->instmeth_end()) { 05145 unsigned NumMethods = std::distance(PDecl->instmeth_begin(), 05146 PDecl->instmeth_end()); 05147 /* struct _objc_protocol_method_list { 05148 int protocol_method_count; 05149 struct protocol_methods protocols[]; 05150 } 05151 */ 05152 Result += "\nstatic struct {\n"; 05153 Result += "\tint protocol_method_count;\n"; 05154 Result += "\tstruct _protocol_methods protocol_methods["; 05155 Result += utostr(NumMethods); 05156 Result += "];\n} _OBJC_PROTOCOL_INSTANCE_METHODS_"; 05157 Result += PDecl->getNameAsString(); 05158 Result += " __attribute__ ((used, section (\"__OBJC, __cat_inst_meth\")))= " 05159 "{\n\t" + utostr(NumMethods) + "\n"; 05160 05161 // Output instance methods declared in this protocol. 05162 for (ObjCProtocolDecl::instmeth_iterator 05163 I = PDecl->instmeth_begin(), E = PDecl->instmeth_end(); 05164 I != E; ++I) { 05165 if (I == PDecl->instmeth_begin()) 05166 Result += "\t ,{{(struct objc_selector *)\""; 05167 else 05168 Result += "\t ,{(struct objc_selector *)\""; 05169 Result += (*I)->getSelector().getAsString(); 05170 std::string MethodTypeString; 05171 Context->getObjCEncodingForMethodDecl((*I), MethodTypeString); 05172 Result += "\", \""; 05173 Result += MethodTypeString; 05174 Result += "\"}\n"; 05175 } 05176 Result += "\t }\n};\n"; 05177 } 05178 05179 // Output class methods declared in this protocol. 05180 unsigned NumMethods = std::distance(PDecl->classmeth_begin(), 05181 PDecl->classmeth_end()); 05182 if (NumMethods > 0) { 05183 /* struct _objc_protocol_method_list { 05184 int protocol_method_count; 05185 struct protocol_methods protocols[]; 05186 } 05187 */ 05188 Result += "\nstatic struct {\n"; 05189 Result += "\tint protocol_method_count;\n"; 05190 Result += "\tstruct _protocol_methods protocol_methods["; 05191 Result += utostr(NumMethods); 05192 Result += "];\n} _OBJC_PROTOCOL_CLASS_METHODS_"; 05193 Result += PDecl->getNameAsString(); 05194 Result += " __attribute__ ((used, section (\"__OBJC, __cat_cls_meth\")))= " 05195 "{\n\t"; 05196 Result += utostr(NumMethods); 05197 Result += "\n"; 05198 05199 // Output instance methods declared in this protocol. 05200 for (ObjCProtocolDecl::classmeth_iterator 05201 I = PDecl->classmeth_begin(), E = PDecl->classmeth_end(); 05202 I != E; ++I) { 05203 if (I == PDecl->classmeth_begin()) 05204 Result += "\t ,{{(struct objc_selector *)\""; 05205 else 05206 Result += "\t ,{(struct objc_selector *)\""; 05207 Result += (*I)->getSelector().getAsString(); 05208 std::string MethodTypeString; 05209 Context->getObjCEncodingForMethodDecl((*I), MethodTypeString); 05210 Result += "\", \""; 05211 Result += MethodTypeString; 05212 Result += "\"}\n"; 05213 } 05214 Result += "\t }\n};\n"; 05215 } 05216 05217 // Output: 05218 /* struct _objc_protocol { 05219 // Objective-C 1.0 extensions 05220 struct _objc_protocol_extension *isa; 05221 char *protocol_name; 05222 struct _objc_protocol **protocol_list; 05223 struct _objc_protocol_method_list *instance_methods; 05224 struct _objc_protocol_method_list *class_methods; 05225 }; 05226 */ 05227 static bool objc_protocol = false; 05228 if (!objc_protocol) { 05229 Result += "\nstruct _objc_protocol {\n"; 05230 Result += "\tstruct _objc_protocol_extension *isa;\n"; 05231 Result += "\tchar *protocol_name;\n"; 05232 Result += "\tstruct _objc_protocol **protocol_list;\n"; 05233 Result += "\tstruct _objc_protocol_method_list *instance_methods;\n"; 05234 Result += "\tstruct _objc_protocol_method_list *class_methods;\n"; 05235 Result += "};\n"; 05236 05237 objc_protocol = true; 05238 } 05239 05240 Result += "\nstatic struct _objc_protocol _OBJC_PROTOCOL_"; 05241 Result += PDecl->getNameAsString(); 05242 Result += " __attribute__ ((used, section (\"__OBJC, __protocol\")))= " 05243 "{\n\t0, \""; 05244 Result += PDecl->getNameAsString(); 05245 Result += "\", 0, "; 05246 if (PDecl->instmeth_begin() != PDecl->instmeth_end()) { 05247 Result += "(struct _objc_protocol_method_list *)&_OBJC_PROTOCOL_INSTANCE_METHODS_"; 05248 Result += PDecl->getNameAsString(); 05249 Result += ", "; 05250 } 05251 else 05252 Result += "0, "; 05253 if (PDecl->classmeth_begin() != PDecl->classmeth_end()) { 05254 Result += "(struct _objc_protocol_method_list *)&_OBJC_PROTOCOL_CLASS_METHODS_"; 05255 Result += PDecl->getNameAsString(); 05256 Result += "\n"; 05257 } 05258 else 05259 Result += "0\n"; 05260 Result += "};\n"; 05261 05262 // Mark this protocol as having been generated. 05263 if (!ObjCSynthesizedProtocols.insert(PDecl->getCanonicalDecl())) 05264 llvm_unreachable("protocol already synthesized"); 05265 05266 } 05267 05268 void RewriteObjCFragileABI::RewriteObjCProtocolListMetaData( 05269 const ObjCList<ObjCProtocolDecl> &Protocols, 05270 StringRef prefix, StringRef ClassName, 05271 std::string &Result) { 05272 if (Protocols.empty()) return; 05273 05274 for (unsigned i = 0; i != Protocols.size(); i++) 05275 RewriteObjCProtocolMetaData(Protocols[i], prefix, ClassName, Result); 05276 05277 // Output the top lovel protocol meta-data for the class. 05278 /* struct _objc_protocol_list { 05279 struct _objc_protocol_list *next; 05280 int protocol_count; 05281 struct _objc_protocol *class_protocols[]; 05282 } 05283 */ 05284 Result += "\nstatic struct {\n"; 05285 Result += "\tstruct _objc_protocol_list *next;\n"; 05286 Result += "\tint protocol_count;\n"; 05287 Result += "\tstruct _objc_protocol *class_protocols["; 05288 Result += utostr(Protocols.size()); 05289 Result += "];\n} _OBJC_"; 05290 Result += prefix; 05291 Result += "_PROTOCOLS_"; 05292 Result += ClassName; 05293 Result += " __attribute__ ((used, section (\"__OBJC, __cat_cls_meth\")))= " 05294 "{\n\t0, "; 05295 Result += utostr(Protocols.size()); 05296 Result += "\n"; 05297 05298 Result += "\t,{&_OBJC_PROTOCOL_"; 05299 Result += Protocols[0]->getNameAsString(); 05300 Result += " \n"; 05301 05302 for (unsigned i = 1; i != Protocols.size(); i++) { 05303 Result += "\t ,&_OBJC_PROTOCOL_"; 05304 Result += Protocols[i]->getNameAsString(); 05305 Result += "\n"; 05306 } 05307 Result += "\t }\n};\n"; 05308 } 05309 05310 void RewriteObjCFragileABI::RewriteObjCClassMetaData(ObjCImplementationDecl *IDecl, 05311 std::string &Result) { 05312 ObjCInterfaceDecl *CDecl = IDecl->getClassInterface(); 05313 05314 // Explicitly declared @interface's are already synthesized. 05315 if (CDecl->isImplicitInterfaceDecl()) { 05316 // FIXME: Implementation of a class with no @interface (legacy) does not 05317 // produce correct synthesis as yet. 05318 RewriteObjCInternalStruct(CDecl, Result); 05319 } 05320 05321 // Build _objc_ivar_list metadata for classes ivars if needed 05322 unsigned NumIvars = !IDecl->ivar_empty() 05323 ? IDecl->ivar_size() 05324 : (CDecl ? CDecl->ivar_size() : 0); 05325 if (NumIvars > 0) { 05326 static bool objc_ivar = false; 05327 if (!objc_ivar) { 05328 /* struct _objc_ivar { 05329 char *ivar_name; 05330 char *ivar_type; 05331 int ivar_offset; 05332 }; 05333 */ 05334 Result += "\nstruct _objc_ivar {\n"; 05335 Result += "\tchar *ivar_name;\n"; 05336 Result += "\tchar *ivar_type;\n"; 05337 Result += "\tint ivar_offset;\n"; 05338 Result += "};\n"; 05339 05340 objc_ivar = true; 05341 } 05342 05343 /* struct { 05344 int ivar_count; 05345 struct _objc_ivar ivar_list[nIvars]; 05346 }; 05347 */ 05348 Result += "\nstatic struct {\n"; 05349 Result += "\tint ivar_count;\n"; 05350 Result += "\tstruct _objc_ivar ivar_list["; 05351 Result += utostr(NumIvars); 05352 Result += "];\n} _OBJC_INSTANCE_VARIABLES_"; 05353 Result += IDecl->getNameAsString(); 05354 Result += " __attribute__ ((used, section (\"__OBJC, __instance_vars\")))= " 05355 "{\n\t"; 05356 Result += utostr(NumIvars); 05357 Result += "\n"; 05358 05359 ObjCInterfaceDecl::ivar_iterator IVI, IVE; 05360 SmallVector<ObjCIvarDecl *, 8> IVars; 05361 if (!IDecl->ivar_empty()) { 05362 for (auto *IV : IDecl->ivars()) 05363 IVars.push_back(IV); 05364 IVI = IDecl->ivar_begin(); 05365 IVE = IDecl->ivar_end(); 05366 } else { 05367 IVI = CDecl->ivar_begin(); 05368 IVE = CDecl->ivar_end(); 05369 } 05370 Result += "\t,{{\""; 05371 Result += IVI->getNameAsString(); 05372 Result += "\", \""; 05373 std::string TmpString, StrEncoding; 05374 Context->getObjCEncodingForType(IVI->getType(), TmpString, *IVI); 05375 QuoteDoublequotes(TmpString, StrEncoding); 05376 Result += StrEncoding; 05377 Result += "\", "; 05378 RewriteIvarOffsetComputation(*IVI, Result); 05379 Result += "}\n"; 05380 for (++IVI; IVI != IVE; ++IVI) { 05381 Result += "\t ,{\""; 05382 Result += IVI->getNameAsString(); 05383 Result += "\", \""; 05384 std::string TmpString, StrEncoding; 05385 Context->getObjCEncodingForType(IVI->getType(), TmpString, *IVI); 05386 QuoteDoublequotes(TmpString, StrEncoding); 05387 Result += StrEncoding; 05388 Result += "\", "; 05389 RewriteIvarOffsetComputation(*IVI, Result); 05390 Result += "}\n"; 05391 } 05392 05393 Result += "\t }\n};\n"; 05394 } 05395 05396 // Build _objc_method_list for class's instance methods if needed 05397 SmallVector<ObjCMethodDecl *, 32> InstanceMethods(IDecl->instance_methods()); 05398 05399 // If any of our property implementations have associated getters or 05400 // setters, produce metadata for them as well. 05401 for (const auto *Prop : IDecl->property_impls()) { 05402 if (Prop->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic) 05403 continue; 05404 if (!Prop->getPropertyIvarDecl()) 05405 continue; 05406 ObjCPropertyDecl *PD = Prop->getPropertyDecl(); 05407 if (!PD) 05408 continue; 05409 if (ObjCMethodDecl *Getter = PD->getGetterMethodDecl()) 05410 if (!Getter->isDefined()) 05411 InstanceMethods.push_back(Getter); 05412 if (PD->isReadOnly()) 05413 continue; 05414 if (ObjCMethodDecl *Setter = PD->getSetterMethodDecl()) 05415 if (!Setter->isDefined()) 05416 InstanceMethods.push_back(Setter); 05417 } 05418 RewriteObjCMethodsMetaData(InstanceMethods.begin(), InstanceMethods.end(), 05419 true, "", IDecl->getName(), Result); 05420 05421 // Build _objc_method_list for class's class methods if needed 05422 RewriteObjCMethodsMetaData(IDecl->classmeth_begin(), IDecl->classmeth_end(), 05423 false, "", IDecl->getName(), Result); 05424 05425 // Protocols referenced in class declaration? 05426 RewriteObjCProtocolListMetaData(CDecl->getReferencedProtocols(), 05427 "CLASS", CDecl->getName(), Result); 05428 05429 // Declaration of class/meta-class metadata 05430 /* struct _objc_class { 05431 struct _objc_class *isa; // or const char *root_class_name when metadata 05432 const char *super_class_name; 05433 char *name; 05434 long version; 05435 long info; 05436 long instance_size; 05437 struct _objc_ivar_list *ivars; 05438 struct _objc_method_list *methods; 05439 struct objc_cache *cache; 05440 struct objc_protocol_list *protocols; 05441 const char *ivar_layout; 05442 struct _objc_class_ext *ext; 05443 }; 05444 */ 05445 static bool objc_class = false; 05446 if (!objc_class) { 05447 Result += "\nstruct _objc_class {\n"; 05448 Result += "\tstruct _objc_class *isa;\n"; 05449 Result += "\tconst char *super_class_name;\n"; 05450 Result += "\tchar *name;\n"; 05451 Result += "\tlong version;\n"; 05452 Result += "\tlong info;\n"; 05453 Result += "\tlong instance_size;\n"; 05454 Result += "\tstruct _objc_ivar_list *ivars;\n"; 05455 Result += "\tstruct _objc_method_list *methods;\n"; 05456 Result += "\tstruct objc_cache *cache;\n"; 05457 Result += "\tstruct _objc_protocol_list *protocols;\n"; 05458 Result += "\tconst char *ivar_layout;\n"; 05459 Result += "\tstruct _objc_class_ext *ext;\n"; 05460 Result += "};\n"; 05461 objc_class = true; 05462 } 05463 05464 // Meta-class metadata generation. 05465 ObjCInterfaceDecl *RootClass = nullptr; 05466 ObjCInterfaceDecl *SuperClass = CDecl->getSuperClass(); 05467 while (SuperClass) { 05468 RootClass = SuperClass; 05469 SuperClass = SuperClass->getSuperClass(); 05470 } 05471 SuperClass = CDecl->getSuperClass(); 05472 05473 Result += "\nstatic struct _objc_class _OBJC_METACLASS_"; 05474 Result += CDecl->getNameAsString(); 05475 Result += " __attribute__ ((used, section (\"__OBJC, __meta_class\")))= " 05476 "{\n\t(struct _objc_class *)\""; 05477 Result += (RootClass ? RootClass->getNameAsString() : CDecl->getNameAsString()); 05478 Result += "\""; 05479 05480 if (SuperClass) { 05481 Result += ", \""; 05482 Result += SuperClass->getNameAsString(); 05483 Result += "\", \""; 05484 Result += CDecl->getNameAsString(); 05485 Result += "\""; 05486 } 05487 else { 05488 Result += ", 0, \""; 05489 Result += CDecl->getNameAsString(); 05490 Result += "\""; 05491 } 05492 // Set 'ivars' field for root class to 0. ObjC1 runtime does not use it. 05493 // 'info' field is initialized to CLS_META(2) for metaclass 05494 Result += ", 0,2, sizeof(struct _objc_class), 0"; 05495 if (IDecl->classmeth_begin() != IDecl->classmeth_end()) { 05496 Result += "\n\t, (struct _objc_method_list *)&_OBJC_CLASS_METHODS_"; 05497 Result += IDecl->getNameAsString(); 05498 Result += "\n"; 05499 } 05500 else 05501 Result += ", 0\n"; 05502 if (CDecl->protocol_begin() != CDecl->protocol_end()) { 05503 Result += "\t,0, (struct _objc_protocol_list *)&_OBJC_CLASS_PROTOCOLS_"; 05504 Result += CDecl->getNameAsString(); 05505 Result += ",0,0\n"; 05506 } 05507 else 05508 Result += "\t,0,0,0,0\n"; 05509 Result += "};\n"; 05510 05511 // class metadata generation. 05512 Result += "\nstatic struct _objc_class _OBJC_CLASS_"; 05513 Result += CDecl->getNameAsString(); 05514 Result += " __attribute__ ((used, section (\"__OBJC, __class\")))= " 05515 "{\n\t&_OBJC_METACLASS_"; 05516 Result += CDecl->getNameAsString(); 05517 if (SuperClass) { 05518 Result += ", \""; 05519 Result += SuperClass->getNameAsString(); 05520 Result += "\", \""; 05521 Result += CDecl->getNameAsString(); 05522 Result += "\""; 05523 } 05524 else { 05525 Result += ", 0, \""; 05526 Result += CDecl->getNameAsString(); 05527 Result += "\""; 05528 } 05529 // 'info' field is initialized to CLS_CLASS(1) for class 05530 Result += ", 0,1"; 05531 if (!ObjCSynthesizedStructs.count(CDecl)) 05532 Result += ",0"; 05533 else { 05534 // class has size. Must synthesize its size. 05535 Result += ",sizeof(struct "; 05536 Result += CDecl->getNameAsString(); 05537 if (LangOpts.MicrosoftExt) 05538 Result += "_IMPL"; 05539 Result += ")"; 05540 } 05541 if (NumIvars > 0) { 05542 Result += ", (struct _objc_ivar_list *)&_OBJC_INSTANCE_VARIABLES_"; 05543 Result += CDecl->getNameAsString(); 05544 Result += "\n\t"; 05545 } 05546 else 05547 Result += ",0"; 05548 if (IDecl->instmeth_begin() != IDecl->instmeth_end()) { 05549 Result += ", (struct _objc_method_list *)&_OBJC_INSTANCE_METHODS_"; 05550 Result += CDecl->getNameAsString(); 05551 Result += ", 0\n\t"; 05552 } 05553 else 05554 Result += ",0,0"; 05555 if (CDecl->protocol_begin() != CDecl->protocol_end()) { 05556 Result += ", (struct _objc_protocol_list*)&_OBJC_CLASS_PROTOCOLS_"; 05557 Result += CDecl->getNameAsString(); 05558 Result += ", 0,0\n"; 05559 } 05560 else 05561 Result += ",0,0,0\n"; 05562 Result += "};\n"; 05563 } 05564 05565 void RewriteObjCFragileABI::RewriteMetaDataIntoBuffer(std::string &Result) { 05566 int ClsDefCount = ClassImplementation.size(); 05567 int CatDefCount = CategoryImplementation.size(); 05568 05569 // For each implemented class, write out all its meta data. 05570 for (int i = 0; i < ClsDefCount; i++) 05571 RewriteObjCClassMetaData(ClassImplementation[i], Result); 05572 05573 // For each implemented category, write out all its meta data. 05574 for (int i = 0; i < CatDefCount; i++) 05575 RewriteObjCCategoryImplDecl(CategoryImplementation[i], Result); 05576 05577 // Write objc_symtab metadata 05578 /* 05579 struct _objc_symtab 05580 { 05581 long sel_ref_cnt; 05582 SEL *refs; 05583 short cls_def_cnt; 05584 short cat_def_cnt; 05585 void *defs[cls_def_cnt + cat_def_cnt]; 05586 }; 05587 */ 05588 05589 Result += "\nstruct _objc_symtab {\n"; 05590 Result += "\tlong sel_ref_cnt;\n"; 05591 Result += "\tSEL *refs;\n"; 05592 Result += "\tshort cls_def_cnt;\n"; 05593 Result += "\tshort cat_def_cnt;\n"; 05594 Result += "\tvoid *defs[" + utostr(ClsDefCount + CatDefCount)+ "];\n"; 05595 Result += "};\n\n"; 05596 05597 Result += "static struct _objc_symtab " 05598 "_OBJC_SYMBOLS __attribute__((used, section (\"__OBJC, __symbols\")))= {\n"; 05599 Result += "\t0, 0, " + utostr(ClsDefCount) 05600 + ", " + utostr(CatDefCount) + "\n"; 05601 for (int i = 0; i < ClsDefCount; i++) { 05602 Result += "\t,&_OBJC_CLASS_"; 05603 Result += ClassImplementation[i]->getNameAsString(); 05604 Result += "\n"; 05605 } 05606 05607 for (int i = 0; i < CatDefCount; i++) { 05608 Result += "\t,&_OBJC_CATEGORY_"; 05609 Result += CategoryImplementation[i]->getClassInterface()->getNameAsString(); 05610 Result += "_"; 05611 Result += CategoryImplementation[i]->getNameAsString(); 05612 Result += "\n"; 05613 } 05614 05615 Result += "};\n\n"; 05616 05617 // Write objc_module metadata 05618 05619 /* 05620 struct _objc_module { 05621 long version; 05622 long size; 05623 const char *name; 05624 struct _objc_symtab *symtab; 05625 } 05626 */ 05627 05628 Result += "\nstruct _objc_module {\n"; 05629 Result += "\tlong version;\n"; 05630 Result += "\tlong size;\n"; 05631 Result += "\tconst char *name;\n"; 05632 Result += "\tstruct _objc_symtab *symtab;\n"; 05633 Result += "};\n\n"; 05634 Result += "static struct _objc_module " 05635 "_OBJC_MODULES __attribute__ ((used, section (\"__OBJC, __module_info\")))= {\n"; 05636 Result += "\t" + utostr(OBJC_ABI_VERSION) + 05637 ", sizeof(struct _objc_module), \"\", &_OBJC_SYMBOLS\n"; 05638 Result += "};\n\n"; 05639 05640 if (LangOpts.MicrosoftExt) { 05641 if (ProtocolExprDecls.size()) { 05642 Result += "#pragma section(\".objc_protocol$B\",long,read,write)\n"; 05643 Result += "#pragma data_seg(push, \".objc_protocol$B\")\n"; 05644 for (ObjCProtocolDecl *ProtDecl : ProtocolExprDecls) { 05645 Result += "static struct _objc_protocol *_POINTER_OBJC_PROTOCOL_"; 05646 Result += ProtDecl->getNameAsString(); 05647 Result += " = &_OBJC_PROTOCOL_"; 05648 Result += ProtDecl->getNameAsString(); 05649 Result += ";\n"; 05650 } 05651 Result += "#pragma data_seg(pop)\n\n"; 05652 } 05653 Result += "#pragma section(\".objc_module_info$B\",long,read,write)\n"; 05654 Result += "#pragma data_seg(push, \".objc_module_info$B\")\n"; 05655 Result += "static struct _objc_module *_POINTER_OBJC_MODULES = "; 05656 Result += "&_OBJC_MODULES;\n"; 05657 Result += "#pragma data_seg(pop)\n\n"; 05658 } 05659 } 05660 05661 /// RewriteObjCCategoryImplDecl - Rewrite metadata for each category 05662 /// implementation. 05663 void RewriteObjCFragileABI::RewriteObjCCategoryImplDecl(ObjCCategoryImplDecl *IDecl, 05664 std::string &Result) { 05665 ObjCInterfaceDecl *ClassDecl = IDecl->getClassInterface(); 05666 // Find category declaration for this implementation. 05667 ObjCCategoryDecl *CDecl 05668 = ClassDecl->FindCategoryDeclaration(IDecl->getIdentifier()); 05669 05670 std::string FullCategoryName = ClassDecl->getNameAsString(); 05671 FullCategoryName += '_'; 05672 FullCategoryName += IDecl->getNameAsString(); 05673 05674 // Build _objc_method_list for class's instance methods if needed 05675 SmallVector<ObjCMethodDecl *, 32> InstanceMethods(IDecl->instance_methods()); 05676 05677 // If any of our property implementations have associated getters or 05678 // setters, produce metadata for them as well. 05679 for (const auto *Prop : IDecl->property_impls()) { 05680 if (Prop->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic) 05681 continue; 05682 if (!Prop->getPropertyIvarDecl()) 05683 continue; 05684 ObjCPropertyDecl *PD = Prop->getPropertyDecl(); 05685 if (!PD) 05686 continue; 05687 if (ObjCMethodDecl *Getter = PD->getGetterMethodDecl()) 05688 InstanceMethods.push_back(Getter); 05689 if (PD->isReadOnly()) 05690 continue; 05691 if (ObjCMethodDecl *Setter = PD->getSetterMethodDecl()) 05692 InstanceMethods.push_back(Setter); 05693 } 05694 RewriteObjCMethodsMetaData(InstanceMethods.begin(), InstanceMethods.end(), 05695 true, "CATEGORY_", FullCategoryName.c_str(), 05696 Result); 05697 05698 // Build _objc_method_list for class's class methods if needed 05699 RewriteObjCMethodsMetaData(IDecl->classmeth_begin(), IDecl->classmeth_end(), 05700 false, "CATEGORY_", FullCategoryName.c_str(), 05701 Result); 05702 05703 // Protocols referenced in class declaration? 05704 // Null CDecl is case of a category implementation with no category interface 05705 if (CDecl) 05706 RewriteObjCProtocolListMetaData(CDecl->getReferencedProtocols(), "CATEGORY", 05707 FullCategoryName, Result); 05708 /* struct _objc_category { 05709 char *category_name; 05710 char *class_name; 05711 struct _objc_method_list *instance_methods; 05712 struct _objc_method_list *class_methods; 05713 struct _objc_protocol_list *protocols; 05714 // Objective-C 1.0 extensions 05715 uint32_t size; // sizeof (struct _objc_category) 05716 struct _objc_property_list *instance_properties; // category's own 05717 // @property decl. 05718 }; 05719 */ 05720 05721 static bool objc_category = false; 05722 if (!objc_category) { 05723 Result += "\nstruct _objc_category {\n"; 05724 Result += "\tchar *category_name;\n"; 05725 Result += "\tchar *class_name;\n"; 05726 Result += "\tstruct _objc_method_list *instance_methods;\n"; 05727 Result += "\tstruct _objc_method_list *class_methods;\n"; 05728 Result += "\tstruct _objc_protocol_list *protocols;\n"; 05729 Result += "\tunsigned int size;\n"; 05730 Result += "\tstruct _objc_property_list *instance_properties;\n"; 05731 Result += "};\n"; 05732 objc_category = true; 05733 } 05734 Result += "\nstatic struct _objc_category _OBJC_CATEGORY_"; 05735 Result += FullCategoryName; 05736 Result += " __attribute__ ((used, section (\"__OBJC, __category\")))= {\n\t\""; 05737 Result += IDecl->getNameAsString(); 05738 Result += "\"\n\t, \""; 05739 Result += ClassDecl->getNameAsString(); 05740 Result += "\"\n"; 05741 05742 if (IDecl->instmeth_begin() != IDecl->instmeth_end()) { 05743 Result += "\t, (struct _objc_method_list *)" 05744 "&_OBJC_CATEGORY_INSTANCE_METHODS_"; 05745 Result += FullCategoryName; 05746 Result += "\n"; 05747 } 05748 else 05749 Result += "\t, 0\n"; 05750 if (IDecl->classmeth_begin() != IDecl->classmeth_end()) { 05751 Result += "\t, (struct _objc_method_list *)" 05752 "&_OBJC_CATEGORY_CLASS_METHODS_"; 05753 Result += FullCategoryName; 05754 Result += "\n"; 05755 } 05756 else 05757 Result += "\t, 0\n"; 05758 05759 if (CDecl && CDecl->protocol_begin() != CDecl->protocol_end()) { 05760 Result += "\t, (struct _objc_protocol_list *)&_OBJC_CATEGORY_PROTOCOLS_"; 05761 Result += FullCategoryName; 05762 Result += "\n"; 05763 } 05764 else 05765 Result += "\t, 0\n"; 05766 Result += "\t, sizeof(struct _objc_category), 0\n};\n"; 05767 } 05768 05769 // RewriteObjCMethodsMetaData - Rewrite methods metadata for instance or 05770 /// class methods. 05771 template<typename MethodIterator> 05772 void RewriteObjCFragileABI::RewriteObjCMethodsMetaData(MethodIterator MethodBegin, 05773 MethodIterator MethodEnd, 05774 bool IsInstanceMethod, 05775 StringRef prefix, 05776 StringRef ClassName, 05777 std::string &Result) { 05778 if (MethodBegin == MethodEnd) return; 05779 05780 if (!objc_impl_method) { 05781 /* struct _objc_method { 05782 SEL _cmd; 05783 char *method_types; 05784 void *_imp; 05785 } 05786 */ 05787 Result += "\nstruct _objc_method {\n"; 05788 Result += "\tSEL _cmd;\n"; 05789 Result += "\tchar *method_types;\n"; 05790 Result += "\tvoid *_imp;\n"; 05791 Result += "};\n"; 05792 05793 objc_impl_method = true; 05794 } 05795 05796 // Build _objc_method_list for class's methods if needed 05797 05798 /* struct { 05799 struct _objc_method_list *next_method; 05800 int method_count; 05801 struct _objc_method method_list[]; 05802 } 05803 */ 05804 unsigned NumMethods = std::distance(MethodBegin, MethodEnd); 05805 Result += "\nstatic struct {\n"; 05806 Result += "\tstruct _objc_method_list *next_method;\n"; 05807 Result += "\tint method_count;\n"; 05808 Result += "\tstruct _objc_method method_list["; 05809 Result += utostr(NumMethods); 05810 Result += "];\n} _OBJC_"; 05811 Result += prefix; 05812 Result += IsInstanceMethod ? "INSTANCE" : "CLASS"; 05813 Result += "_METHODS_"; 05814 Result += ClassName; 05815 Result += " __attribute__ ((used, section (\"__OBJC, __"; 05816 Result += IsInstanceMethod ? "inst" : "cls"; 05817 Result += "_meth\")))= "; 05818 Result += "{\n\t0, " + utostr(NumMethods) + "\n"; 05819 05820 Result += "\t,{{(SEL)\""; 05821 Result += (*MethodBegin)->getSelector().getAsString().c_str(); 05822 std::string MethodTypeString; 05823 Context->getObjCEncodingForMethodDecl(*MethodBegin, MethodTypeString); 05824 Result += "\", \""; 05825 Result += MethodTypeString; 05826 Result += "\", (void *)"; 05827 Result += MethodInternalNames[*MethodBegin]; 05828 Result += "}\n"; 05829 for (++MethodBegin; MethodBegin != MethodEnd; ++MethodBegin) { 05830 Result += "\t ,{(SEL)\""; 05831 Result += (*MethodBegin)->getSelector().getAsString().c_str(); 05832 std::string MethodTypeString; 05833 Context->getObjCEncodingForMethodDecl(*MethodBegin, MethodTypeString); 05834 Result += "\", \""; 05835 Result += MethodTypeString; 05836 Result += "\", (void *)"; 05837 Result += MethodInternalNames[*MethodBegin]; 05838 Result += "}\n"; 05839 } 05840 Result += "\t }\n};\n"; 05841 } 05842 05843 Stmt *RewriteObjCFragileABI::RewriteObjCIvarRefExpr(ObjCIvarRefExpr *IV) { 05844 SourceRange OldRange = IV->getSourceRange(); 05845 Expr *BaseExpr = IV->getBase(); 05846 05847 // Rewrite the base, but without actually doing replaces. 05848 { 05849 DisableReplaceStmtScope S(*this); 05850 BaseExpr = cast<Expr>(RewriteFunctionBodyOrGlobalInitializer(BaseExpr)); 05851 IV->setBase(BaseExpr); 05852 } 05853 05854 ObjCIvarDecl *D = IV->getDecl(); 05855 05856 Expr *Replacement = IV; 05857 if (CurMethodDef) { 05858 if (BaseExpr->getType()->isObjCObjectPointerType()) { 05859 const ObjCInterfaceType *iFaceDecl = 05860 dyn_cast<ObjCInterfaceType>(BaseExpr->getType()->getPointeeType()); 05861 assert(iFaceDecl && "RewriteObjCIvarRefExpr - iFaceDecl is null"); 05862 // lookup which class implements the instance variable. 05863 ObjCInterfaceDecl *clsDeclared = nullptr; 05864 iFaceDecl->getDecl()->lookupInstanceVariable(D->getIdentifier(), 05865 clsDeclared); 05866 assert(clsDeclared && "RewriteObjCIvarRefExpr(): Can't find class"); 05867 05868 // Synthesize an explicit cast to gain access to the ivar. 05869 std::string RecName = clsDeclared->getIdentifier()->getName(); 05870 RecName += "_IMPL"; 05871 IdentifierInfo *II = &Context->Idents.get(RecName); 05872 RecordDecl *RD = RecordDecl::Create(*Context, TTK_Struct, TUDecl, 05873 SourceLocation(), SourceLocation(), 05874 II); 05875 assert(RD && "RewriteObjCIvarRefExpr(): Can't find RecordDecl"); 05876 QualType castT = Context->getPointerType(Context->getTagDeclType(RD)); 05877 CastExpr *castExpr = NoTypeInfoCStyleCastExpr(Context, castT, 05878 CK_BitCast, 05879 IV->getBase()); 05880 // Don't forget the parens to enforce the proper binding. 05881 ParenExpr *PE = new (Context) ParenExpr(OldRange.getBegin(), 05882 OldRange.getEnd(), 05883 castExpr); 05884 if (IV->isFreeIvar() && 05885 declaresSameEntity(CurMethodDef->getClassInterface(), iFaceDecl->getDecl())) { 05886 MemberExpr *ME = new (Context) MemberExpr(PE, true, D, 05887 IV->getLocation(), 05888 D->getType(), 05889 VK_LValue, OK_Ordinary); 05890 Replacement = ME; 05891 } else { 05892 IV->setBase(PE); 05893 } 05894 } 05895 } else { // we are outside a method. 05896 assert(!IV->isFreeIvar() && "Cannot have a free standing ivar outside a method"); 05897 05898 // Explicit ivar refs need to have a cast inserted. 05899 // FIXME: consider sharing some of this code with the code above. 05900 if (BaseExpr->getType()->isObjCObjectPointerType()) { 05901 const ObjCInterfaceType *iFaceDecl = 05902 dyn_cast<ObjCInterfaceType>(BaseExpr->getType()->getPointeeType()); 05903 // lookup which class implements the instance variable. 05904 ObjCInterfaceDecl *clsDeclared = nullptr; 05905 iFaceDecl->getDecl()->lookupInstanceVariable(D->getIdentifier(), 05906 clsDeclared); 05907 assert(clsDeclared && "RewriteObjCIvarRefExpr(): Can't find class"); 05908 05909 // Synthesize an explicit cast to gain access to the ivar. 05910 std::string RecName = clsDeclared->getIdentifier()->getName(); 05911 RecName += "_IMPL"; 05912 IdentifierInfo *II = &Context->Idents.get(RecName); 05913 RecordDecl *RD = RecordDecl::Create(*Context, TTK_Struct, TUDecl, 05914 SourceLocation(), SourceLocation(), 05915 II); 05916 assert(RD && "RewriteObjCIvarRefExpr(): Can't find RecordDecl"); 05917 QualType castT = Context->getPointerType(Context->getTagDeclType(RD)); 05918 CastExpr *castExpr = NoTypeInfoCStyleCastExpr(Context, castT, 05919 CK_BitCast, 05920 IV->getBase()); 05921 // Don't forget the parens to enforce the proper binding. 05922 ParenExpr *PE = new (Context) ParenExpr(IV->getBase()->getLocStart(), 05923 IV->getBase()->getLocEnd(), castExpr); 05924 // Cannot delete IV->getBase(), since PE points to it. 05925 // Replace the old base with the cast. This is important when doing 05926 // embedded rewrites. For example, [newInv->_container addObject:0]. 05927 IV->setBase(PE); 05928 } 05929 } 05930 05931 ReplaceStmtWithRange(IV, Replacement, OldRange); 05932 return Replacement; 05933 } 05934 05935 #endif