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