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