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