1 //===--- RewriteObjC.cpp - Playground for the code rewriter ---------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // Hacks and fun related to the code rewriter.
12 //===----------------------------------------------------------------------===//
14 #include "clang/Rewrite/ASTConsumers.h"
15 #include "clang/Rewrite/Rewriter.h"
16 #include "clang/AST/AST.h"
17 #include "clang/AST/ASTConsumer.h"
18 #include "clang/AST/ParentMap.h"
19 #include "clang/Basic/SourceManager.h"
20 #include "clang/Basic/IdentifierTable.h"
21 #include "clang/Basic/Diagnostic.h"
22 #include "clang/Lex/Lexer.h"
23 #include "llvm/Support/MemoryBuffer.h"
24 #include "llvm/Support/raw_ostream.h"
25 #include "llvm/ADT/StringExtras.h"
26 #include "llvm/ADT/SmallPtrSet.h"
27 #include "llvm/ADT/OwningPtr.h"
28 #include "llvm/ADT/DenseSet.h"
30 using namespace clang
;
34 class RewriteObjC
: public ASTConsumer
{
36 BLOCK_FIELD_IS_OBJECT
= 3, /* id, NSObject, __attribute__((NSObject)),
38 BLOCK_FIELD_IS_BLOCK
= 7, /* a block variable */
39 BLOCK_FIELD_IS_BYREF
= 8, /* the on stack structure holding the
41 BLOCK_FIELD_IS_WEAK
= 16, /* declared __weak, only used in byref copy
43 BLOCK_BYREF_CALLER
= 128, /* called from __block (byref) copy/dispose
45 BLOCK_BYREF_CURRENT_MAX
= 256
49 BLOCK_NEEDS_FREE
= (1 << 24),
50 BLOCK_HAS_COPY_DISPOSE
= (1 << 25),
51 BLOCK_HAS_CXX_OBJ
= (1 << 26),
52 BLOCK_IS_GC
= (1 << 27),
53 BLOCK_IS_GLOBAL
= (1 << 28),
54 BLOCK_HAS_DESCRIPTOR
= (1 << 29)
59 const LangOptions
&LangOpts
;
60 unsigned RewriteFailedDiag
;
61 unsigned TryFinallyContainsReturnDiag
;
65 TranslationUnitDecl
*TUDecl
;
67 const char *MainFileStart
, *MainFileEnd
;
68 SourceLocation LastIncLoc
;
70 llvm::SmallVector
<ObjCImplementationDecl
*, 8> ClassImplementation
;
71 llvm::SmallVector
<ObjCCategoryImplDecl
*, 8> CategoryImplementation
;
72 llvm::SmallPtrSet
<ObjCInterfaceDecl
*, 8> ObjCSynthesizedStructs
;
73 llvm::SmallPtrSet
<ObjCProtocolDecl
*, 8> ObjCSynthesizedProtocols
;
74 llvm::SmallPtrSet
<ObjCInterfaceDecl
*, 8> ObjCForwardDecls
;
75 llvm::DenseMap
<ObjCMethodDecl
*, std::string
> MethodInternalNames
;
76 llvm::SmallVector
<Stmt
*, 32> Stmts
;
77 llvm::SmallVector
<int, 8> ObjCBcLabelNo
;
78 // Remember all the @protocol(<expr>) expressions.
79 llvm::SmallPtrSet
<ObjCProtocolDecl
*, 32> ProtocolExprDecls
;
81 llvm::DenseSet
<uint64_t> CopyDestroyCache
;
83 unsigned NumObjCStringLiterals
;
85 FunctionDecl
*MsgSendFunctionDecl
;
86 FunctionDecl
*MsgSendSuperFunctionDecl
;
87 FunctionDecl
*MsgSendStretFunctionDecl
;
88 FunctionDecl
*MsgSendSuperStretFunctionDecl
;
89 FunctionDecl
*MsgSendFpretFunctionDecl
;
90 FunctionDecl
*GetClassFunctionDecl
;
91 FunctionDecl
*GetMetaClassFunctionDecl
;
92 FunctionDecl
*GetSuperClassFunctionDecl
;
93 FunctionDecl
*SelGetUidFunctionDecl
;
94 FunctionDecl
*CFStringFunctionDecl
;
95 FunctionDecl
*SuperContructorFunctionDecl
;
97 // ObjC string constant support.
98 VarDecl
*ConstantStringClassReference
;
99 RecordDecl
*NSStringRecord
;
101 // ObjC foreach break/continue generation support.
105 ObjCMethodDecl
*CurMethodDef
;
106 RecordDecl
*SuperStructDecl
;
107 RecordDecl
*ConstantStringDecl
;
109 TypeDecl
*ProtocolTypeDecl
;
110 QualType
getProtocolType();
112 // Needed for header files being rewritten
115 std::string InFileName
;
116 llvm::raw_ostream
* OutFile
;
118 bool SilenceRewriteMacroWarning
;
119 bool objc_impl_method
;
121 std::string Preamble
;
123 // Block expressions.
124 llvm::SmallVector
<BlockExpr
*, 32> Blocks
;
125 llvm::SmallVector
<int, 32> InnerDeclRefsCount
;
126 llvm::SmallVector
<BlockDeclRefExpr
*, 32> InnerDeclRefs
;
128 llvm::SmallVector
<BlockDeclRefExpr
*, 32> BlockDeclRefs
;
130 // Block related declarations.
131 llvm::SmallVector
<ValueDecl
*, 8> BlockByCopyDecls
;
132 llvm::SmallPtrSet
<ValueDecl
*, 8> BlockByCopyDeclsPtrSet
;
133 llvm::SmallVector
<ValueDecl
*, 8> BlockByRefDecls
;
134 llvm::SmallPtrSet
<ValueDecl
*, 8> BlockByRefDeclsPtrSet
;
135 llvm::DenseMap
<ValueDecl
*, unsigned> BlockByRefDeclNo
;
136 llvm::SmallPtrSet
<ValueDecl
*, 8> ImportedBlockDecls
;
137 llvm::SmallPtrSet
<VarDecl
*, 8> ImportedLocalExternalDecls
;
139 llvm::DenseMap
<BlockExpr
*, std::string
> RewrittenBlockExprs
;
141 // This maps a property to it's assignment statement.
142 llvm::DenseMap
<Expr
*, BinaryOperator
*> PropSetters
;
143 // This maps a property to it's synthesied message expression.
144 // This allows us to rewrite chained getters (e.g. o.a.b.c).
145 llvm::DenseMap
<Expr
*, Stmt
*> PropGetters
;
147 // This maps an original source AST to it's rewritten form. This allows
148 // us to avoid rewriting the same node twice (which is very uncommon).
149 // This is needed to support some of the exotic property rewriting.
150 llvm::DenseMap
<Stmt
*, Stmt
*> ReplacedNodes
;
152 FunctionDecl
*CurFunctionDef
;
153 FunctionDecl
*CurFunctionDeclToDeclareForBlock
;
154 VarDecl
*GlobalVarDecl
;
156 bool DisableReplaceStmt
;
158 static const int OBJC_ABI_VERSION
= 7;
160 virtual void Initialize(ASTContext
&context
);
162 // Top Level Driver code.
163 virtual void HandleTopLevelDecl(DeclGroupRef D
) {
164 for (DeclGroupRef::iterator I
= D
.begin(), E
= D
.end(); I
!= E
; ++I
)
165 HandleTopLevelSingleDecl(*I
);
167 void HandleTopLevelSingleDecl(Decl
*D
);
168 void HandleDeclInMainFile(Decl
*D
);
169 RewriteObjC(std::string inFile
, llvm::raw_ostream
*OS
,
170 Diagnostic
&D
, const LangOptions
&LOpts
,
171 bool silenceMacroWarn
);
175 virtual void HandleTranslationUnit(ASTContext
&C
);
177 void ReplaceStmt(Stmt
*Old
, Stmt
*New
) {
178 Stmt
*ReplacingStmt
= ReplacedNodes
[Old
];
181 return; // We can't rewrite the same node twice.
183 if (DisableReplaceStmt
)
184 return; // Used when rewriting the assignment of a property setter.
186 // If replacement succeeded or warning disabled return with no warning.
187 if (!Rewrite
.ReplaceStmt(Old
, New
)) {
188 ReplacedNodes
[Old
] = New
;
191 if (SilenceRewriteMacroWarning
)
193 Diags
.Report(Context
->getFullLoc(Old
->getLocStart()), RewriteFailedDiag
)
194 << Old
->getSourceRange();
197 void ReplaceStmtWithRange(Stmt
*Old
, Stmt
*New
, SourceRange SrcRange
) {
198 // Measure the old text.
199 int Size
= Rewrite
.getRangeSize(SrcRange
);
201 Diags
.Report(Context
->getFullLoc(Old
->getLocStart()), RewriteFailedDiag
)
202 << Old
->getSourceRange();
207 llvm::raw_string_ostream
S(SStr
);
208 New
->printPretty(S
, *Context
, 0, PrintingPolicy(LangOpts
));
209 const std::string
&Str
= S
.str();
211 // If replacement succeeded or warning disabled return with no warning.
212 if (!Rewrite
.ReplaceText(SrcRange
.getBegin(), Size
, Str
)) {
213 ReplacedNodes
[Old
] = New
;
216 if (SilenceRewriteMacroWarning
)
218 Diags
.Report(Context
->getFullLoc(Old
->getLocStart()), RewriteFailedDiag
)
219 << Old
->getSourceRange();
222 void InsertText(SourceLocation Loc
, llvm::StringRef Str
,
223 bool InsertAfter
= true) {
224 // If insertion succeeded or warning disabled return with no warning.
225 if (!Rewrite
.InsertText(Loc
, Str
, InsertAfter
) ||
226 SilenceRewriteMacroWarning
)
229 Diags
.Report(Context
->getFullLoc(Loc
), RewriteFailedDiag
);
232 void ReplaceText(SourceLocation Start
, unsigned OrigLength
,
233 llvm::StringRef Str
) {
234 // If removal succeeded or warning disabled return with no warning.
235 if (!Rewrite
.ReplaceText(Start
, OrigLength
, Str
) ||
236 SilenceRewriteMacroWarning
)
239 Diags
.Report(Context
->getFullLoc(Start
), RewriteFailedDiag
);
242 // Syntactic Rewriting.
243 void RewriteInclude();
244 void RewriteForwardClassDecl(ObjCClassDecl
*Dcl
);
245 void RewritePropertyImplDecl(ObjCPropertyImplDecl
*PID
,
246 ObjCImplementationDecl
*IMD
,
247 ObjCCategoryImplDecl
*CID
);
248 void RewriteInterfaceDecl(ObjCInterfaceDecl
*Dcl
);
249 void RewriteImplementationDecl(Decl
*Dcl
);
250 void RewriteObjCMethodDecl(const ObjCInterfaceDecl
*IDecl
,
251 ObjCMethodDecl
*MDecl
, std::string
&ResultStr
);
252 void RewriteTypeIntoString(QualType T
, std::string
&ResultStr
,
253 const FunctionType
*&FPRetType
);
254 void RewriteByRefString(std::string
&ResultStr
, const std::string
&Name
,
255 ValueDecl
*VD
, bool def
=false);
256 void RewriteCategoryDecl(ObjCCategoryDecl
*Dcl
);
257 void RewriteProtocolDecl(ObjCProtocolDecl
*Dcl
);
258 void RewriteForwardProtocolDecl(ObjCForwardProtocolDecl
*Dcl
);
259 void RewriteMethodDeclaration(ObjCMethodDecl
*Method
);
260 void RewriteProperty(ObjCPropertyDecl
*prop
);
261 void RewriteFunctionDecl(FunctionDecl
*FD
);
262 void RewriteBlockPointerType(std::string
& Str
, QualType Type
);
263 void RewriteBlockPointerTypeVariable(std::string
& Str
, ValueDecl
*VD
);
264 void RewriteBlockLiteralFunctionDecl(FunctionDecl
*FD
);
265 void RewriteObjCQualifiedInterfaceTypes(Decl
*Dcl
);
266 void RewriteTypeOfDecl(VarDecl
*VD
);
267 void RewriteObjCQualifiedInterfaceTypes(Expr
*E
);
268 bool needToScanForQualifiers(QualType T
);
269 QualType
getSuperStructType();
270 QualType
getConstantStringStructType();
271 QualType
convertFunctionTypeOfBlocks(const FunctionType
*FT
);
272 bool BufferContainsPPDirectives(const char *startBuf
, const char *endBuf
);
274 // Expression Rewriting.
275 Stmt
*RewriteFunctionBodyOrGlobalInitializer(Stmt
*S
);
276 void CollectPropertySetters(Stmt
*S
);
279 ParentMap
*PropParentMap
; // created lazily.
281 Stmt
*RewriteAtEncode(ObjCEncodeExpr
*Exp
);
282 Stmt
*RewriteObjCIvarRefExpr(ObjCIvarRefExpr
*IV
, SourceLocation OrigStart
,
284 Stmt
*RewriteObjCNestedIvarRefExpr(Stmt
*S
, bool &replaced
);
285 Stmt
*RewritePropertyOrImplicitGetter(Expr
*PropOrGetterRefExpr
);
286 Stmt
*RewritePropertyOrImplicitSetter(BinaryOperator
*BinOp
, Expr
*newStmt
,
287 SourceRange SrcRange
);
288 Stmt
*RewriteAtSelector(ObjCSelectorExpr
*Exp
);
289 Stmt
*RewriteMessageExpr(ObjCMessageExpr
*Exp
);
290 Stmt
*RewriteObjCStringLiteral(ObjCStringLiteral
*Exp
);
291 Stmt
*RewriteObjCProtocolExpr(ObjCProtocolExpr
*Exp
);
292 void WarnAboutReturnGotoStmts(Stmt
*S
);
293 void HasReturnStmts(Stmt
*S
, bool &hasReturns
);
294 void RewriteTryReturnStmts(Stmt
*S
);
295 void RewriteSyncReturnStmts(Stmt
*S
, std::string buf
);
296 Stmt
*RewriteObjCTryStmt(ObjCAtTryStmt
*S
);
297 Stmt
*RewriteObjCSynchronizedStmt(ObjCAtSynchronizedStmt
*S
);
298 Stmt
*RewriteObjCThrowStmt(ObjCAtThrowStmt
*S
);
299 Stmt
*RewriteObjCForCollectionStmt(ObjCForCollectionStmt
*S
,
300 SourceLocation OrigEnd
);
301 CallExpr
*SynthesizeCallToFunctionDecl(FunctionDecl
*FD
,
302 Expr
**args
, unsigned nargs
,
303 SourceLocation StartLoc
=SourceLocation(),
304 SourceLocation EndLoc
=SourceLocation());
305 Stmt
*SynthMessageExpr(ObjCMessageExpr
*Exp
,
306 SourceLocation StartLoc
=SourceLocation(),
307 SourceLocation EndLoc
=SourceLocation());
308 Stmt
*RewriteBreakStmt(BreakStmt
*S
);
309 Stmt
*RewriteContinueStmt(ContinueStmt
*S
);
310 void SynthCountByEnumWithState(std::string
&buf
);
312 void SynthMsgSendFunctionDecl();
313 void SynthMsgSendSuperFunctionDecl();
314 void SynthMsgSendStretFunctionDecl();
315 void SynthMsgSendFpretFunctionDecl();
316 void SynthMsgSendSuperStretFunctionDecl();
317 void SynthGetClassFunctionDecl();
318 void SynthGetMetaClassFunctionDecl();
319 void SynthGetSuperClassFunctionDecl();
320 void SynthSelGetUidFunctionDecl();
321 void SynthSuperContructorFunctionDecl();
323 // Metadata emission.
324 void RewriteObjCClassMetaData(ObjCImplementationDecl
*IDecl
,
325 std::string
&Result
);
327 void RewriteObjCCategoryImplDecl(ObjCCategoryImplDecl
*CDecl
,
328 std::string
&Result
);
330 template<typename MethodIterator
>
331 void RewriteObjCMethodsMetaData(MethodIterator MethodBegin
,
332 MethodIterator MethodEnd
,
333 bool IsInstanceMethod
,
334 llvm::StringRef prefix
,
335 llvm::StringRef ClassName
,
336 std::string
&Result
);
338 void RewriteObjCProtocolMetaData(ObjCProtocolDecl
*Protocol
,
339 llvm::StringRef prefix
,
340 llvm::StringRef ClassName
,
341 std::string
&Result
);
342 void RewriteObjCProtocolListMetaData(const ObjCList
<ObjCProtocolDecl
> &Prots
,
343 llvm::StringRef prefix
,
344 llvm::StringRef ClassName
,
345 std::string
&Result
);
346 void SynthesizeObjCInternalStruct(ObjCInterfaceDecl
*CDecl
,
347 std::string
&Result
);
348 void SynthesizeIvarOffsetComputation(ObjCIvarDecl
*ivar
,
349 std::string
&Result
);
350 void RewriteImplementations();
351 void SynthesizeMetaDataIntoBuffer(std::string
&Result
);
354 void RewriteBlocksInFunctionProtoType(QualType funcType
, NamedDecl
*D
);
355 void CheckFunctionPointerDecl(QualType dType
, NamedDecl
*ND
);
357 void InsertBlockLiteralsWithinFunction(FunctionDecl
*FD
);
358 void InsertBlockLiteralsWithinMethod(ObjCMethodDecl
*MD
);
360 // Block specific rewrite rules.
361 void RewriteBlockPointerDecl(NamedDecl
*VD
);
362 void RewriteByRefVar(VarDecl
*VD
);
363 std::string
SynthesizeByrefCopyDestroyHelper(VarDecl
*VD
, int flag
);
364 Stmt
*RewriteBlockDeclRefExpr(Expr
*VD
);
365 Stmt
*RewriteLocalVariableExternalStorage(DeclRefExpr
*DRE
);
366 void RewriteBlockPointerFunctionArgs(FunctionDecl
*FD
);
368 std::string
SynthesizeBlockHelperFuncs(BlockExpr
*CE
, int i
,
369 llvm::StringRef funcName
, std::string Tag
);
370 std::string
SynthesizeBlockFunc(BlockExpr
*CE
, int i
,
371 llvm::StringRef funcName
, std::string Tag
);
372 std::string
SynthesizeBlockImpl(BlockExpr
*CE
,
373 std::string Tag
, std::string Desc
);
374 std::string
SynthesizeBlockDescriptor(std::string DescTag
,
376 int i
, llvm::StringRef funcName
,
378 Stmt
*SynthesizeBlockCall(CallExpr
*Exp
, const Expr
* BlockExp
);
379 void SynthesizeBlockLiterals(SourceLocation FunLocStart
,
380 llvm::StringRef FunName
);
381 void RewriteRecordBody(RecordDecl
*RD
);
383 void CollectBlockDeclRefInfo(BlockExpr
*Exp
);
384 void GetBlockDeclRefExprs(Stmt
*S
);
385 void GetInnerBlockDeclRefExprs(Stmt
*S
,
386 llvm::SmallVector
<BlockDeclRefExpr
*, 8> &InnerBlockDeclRefs
,
387 llvm::SmallPtrSet
<const DeclContext
*, 8> &InnerContexts
);
389 // We avoid calling Type::isBlockPointerType(), since it operates on the
390 // canonical type. We only care if the top-level type is a closure pointer.
391 bool isTopLevelBlockPointerType(QualType T
) {
392 return isa
<BlockPointerType
>(T
);
395 /// convertBlockPointerToFunctionPointer - Converts a block-pointer type
396 /// to a function pointer type and upon success, returns true; false
398 bool convertBlockPointerToFunctionPointer(QualType
&T
) {
399 if (isTopLevelBlockPointerType(T
)) {
400 const BlockPointerType
*BPT
= T
->getAs
<BlockPointerType
>();
401 T
= Context
->getPointerType(BPT
->getPointeeType());
407 void convertToUnqualifiedObjCType(QualType
&T
) {
408 if (T
->isObjCQualifiedIdType())
409 T
= Context
->getObjCIdType();
410 else if (T
->isObjCQualifiedClassType())
411 T
= Context
->getObjCClassType();
412 else if (T
->isObjCObjectPointerType() &&
413 T
->getPointeeType()->isObjCQualifiedInterfaceType())
414 T
= Context
->getObjCIdType();
417 // FIXME: This predicate seems like it would be useful to add to ASTContext.
418 bool isObjCType(QualType T
) {
419 if (!LangOpts
.ObjC1
&& !LangOpts
.ObjC2
)
422 QualType OCT
= Context
->getCanonicalType(T
).getUnqualifiedType();
424 if (OCT
== Context
->getCanonicalType(Context
->getObjCIdType()) ||
425 OCT
== Context
->getCanonicalType(Context
->getObjCClassType()))
428 if (const PointerType
*PT
= OCT
->getAs
<PointerType
>()) {
429 if (isa
<ObjCInterfaceType
>(PT
->getPointeeType()) ||
430 PT
->getPointeeType()->isObjCQualifiedIdType())
435 bool PointerTypeTakesAnyBlockArguments(QualType QT
);
436 bool PointerTypeTakesAnyObjCQualifiedType(QualType QT
);
437 void GetExtentOfArgList(const char *Name
, const char *&LParen
,
438 const char *&RParen
);
439 void RewriteCastExpr(CStyleCastExpr
*CE
);
441 FunctionDecl
*SynthBlockInitFunctionDecl(llvm::StringRef name
);
442 Stmt
*SynthBlockInitExpr(BlockExpr
*Exp
,
443 const llvm::SmallVector
<BlockDeclRefExpr
*, 8> &InnerBlockDeclRefs
);
445 void QuoteDoublequotes(std::string
&From
, std::string
&To
) {
446 for (unsigned i
= 0; i
< From
.length(); i
++) {
454 QualType
getSimpleFunctionType(QualType result
,
455 const QualType
*args
,
457 bool variadic
= false) {
458 FunctionProtoType::ExtProtoInfo fpi
;
459 fpi
.Variadic
= variadic
;
460 return Context
->getFunctionType(result
, args
, numArgs
, fpi
);
464 // Helper function: create a CStyleCastExpr with trivial type source info.
465 CStyleCastExpr
* NoTypeInfoCStyleCastExpr(ASTContext
*Ctx
, QualType Ty
,
466 CastKind Kind
, Expr
*E
) {
467 TypeSourceInfo
*TInfo
= Ctx
->getTrivialTypeSourceInfo(Ty
, SourceLocation());
468 return CStyleCastExpr::Create(*Ctx
, Ty
, VK_RValue
, Kind
, E
, 0, TInfo
,
469 SourceLocation(), SourceLocation());
473 void RewriteObjC::RewriteBlocksInFunctionProtoType(QualType funcType
,
475 if (const FunctionProtoType
*fproto
476 = dyn_cast
<FunctionProtoType
>(funcType
.IgnoreParens())) {
477 for (FunctionProtoType::arg_type_iterator I
= fproto
->arg_type_begin(),
478 E
= fproto
->arg_type_end(); I
&& (I
!= E
); ++I
)
479 if (isTopLevelBlockPointerType(*I
)) {
480 // All the args are checked/rewritten. Don't call twice!
481 RewriteBlockPointerDecl(D
);
487 void RewriteObjC::CheckFunctionPointerDecl(QualType funcType
, NamedDecl
*ND
) {
488 const PointerType
*PT
= funcType
->getAs
<PointerType
>();
489 if (PT
&& PointerTypeTakesAnyBlockArguments(funcType
))
490 RewriteBlocksInFunctionProtoType(PT
->getPointeeType(), ND
);
493 static bool IsHeaderFile(const std::string
&Filename
) {
494 std::string::size_type DotPos
= Filename
.rfind('.');
496 if (DotPos
== std::string::npos
) {
501 std::string Ext
= std::string(Filename
.begin()+DotPos
+1, Filename
.end());
503 // C++ header: .hh or .H;
504 return Ext
== "h" || Ext
== "hh" || Ext
== "H";
507 RewriteObjC::RewriteObjC(std::string inFile
, llvm::raw_ostream
* OS
,
508 Diagnostic
&D
, const LangOptions
&LOpts
,
509 bool silenceMacroWarn
)
510 : Diags(D
), LangOpts(LOpts
), InFileName(inFile
), OutFile(OS
),
511 SilenceRewriteMacroWarning(silenceMacroWarn
) {
512 IsHeader
= IsHeaderFile(inFile
);
513 RewriteFailedDiag
= Diags
.getCustomDiagID(Diagnostic::Warning
,
514 "rewriting sub-expression within a macro (may not be correct)");
515 TryFinallyContainsReturnDiag
= Diags
.getCustomDiagID(Diagnostic::Warning
,
516 "rewriter doesn't support user-specified control flow semantics "
517 "for @try/@finally (code may not execute properly)");
520 ASTConsumer
*clang::CreateObjCRewriter(const std::string
& InFile
,
521 llvm::raw_ostream
* OS
,
523 const LangOptions
&LOpts
,
524 bool SilenceRewriteMacroWarning
) {
525 return new RewriteObjC(InFile
, OS
, Diags
, LOpts
, SilenceRewriteMacroWarning
);
528 void RewriteObjC::Initialize(ASTContext
&context
) {
530 SM
= &Context
->getSourceManager();
531 TUDecl
= Context
->getTranslationUnitDecl();
532 MsgSendFunctionDecl
= 0;
533 MsgSendSuperFunctionDecl
= 0;
534 MsgSendStretFunctionDecl
= 0;
535 MsgSendSuperStretFunctionDecl
= 0;
536 MsgSendFpretFunctionDecl
= 0;
537 GetClassFunctionDecl
= 0;
538 GetMetaClassFunctionDecl
= 0;
539 GetSuperClassFunctionDecl
= 0;
540 SelGetUidFunctionDecl
= 0;
541 CFStringFunctionDecl
= 0;
542 ConstantStringClassReference
= 0;
546 CurFunctionDeclToDeclareForBlock
= 0;
549 ProtocolTypeDecl
= 0;
550 ConstantStringDecl
= 0;
552 SuperContructorFunctionDecl
= 0;
553 NumObjCStringLiterals
= 0;
556 DisableReplaceStmt
= false;
557 objc_impl_method
= false;
559 // Get the ID and start/end of the main file.
560 MainFileID
= SM
->getMainFileID();
561 const llvm::MemoryBuffer
*MainBuf
= SM
->getBuffer(MainFileID
);
562 MainFileStart
= MainBuf
->getBufferStart();
563 MainFileEnd
= MainBuf
->getBufferEnd();
565 Rewrite
.setSourceMgr(Context
->getSourceManager(), Context
->getLangOptions());
567 // declaring objc_selector outside the parameter list removes a silly
568 // scope related warning...
570 Preamble
= "#pragma once\n";
571 Preamble
+= "struct objc_selector; struct objc_class;\n";
572 Preamble
+= "struct __rw_objc_super { struct objc_object *object; ";
573 Preamble
+= "struct objc_object *superClass; ";
574 if (LangOpts
.Microsoft
) {
575 // Add a constructor for creating temporary objects.
576 Preamble
+= "__rw_objc_super(struct objc_object *o, struct objc_object *s) "
578 Preamble
+= "object(o), superClass(s) {} ";
581 Preamble
+= "#ifndef _REWRITER_typedef_Protocol\n";
582 Preamble
+= "typedef struct objc_object Protocol;\n";
583 Preamble
+= "#define _REWRITER_typedef_Protocol\n";
584 Preamble
+= "#endif\n";
585 if (LangOpts
.Microsoft
) {
586 Preamble
+= "#define __OBJC_RW_DLLIMPORT extern \"C\" __declspec(dllimport)\n";
587 Preamble
+= "#define __OBJC_RW_STATICIMPORT extern \"C\"\n";
589 Preamble
+= "#define __OBJC_RW_DLLIMPORT extern\n";
590 Preamble
+= "__OBJC_RW_DLLIMPORT struct objc_object *objc_msgSend";
591 Preamble
+= "(struct objc_object *, struct objc_selector *, ...);\n";
592 Preamble
+= "__OBJC_RW_DLLIMPORT struct objc_object *objc_msgSendSuper";
593 Preamble
+= "(struct objc_super *, struct objc_selector *, ...);\n";
594 Preamble
+= "__OBJC_RW_DLLIMPORT struct objc_object *objc_msgSend_stret";
595 Preamble
+= "(struct objc_object *, struct objc_selector *, ...);\n";
596 Preamble
+= "__OBJC_RW_DLLIMPORT struct objc_object *objc_msgSendSuper_stret";
597 Preamble
+= "(struct objc_super *, struct objc_selector *, ...);\n";
598 Preamble
+= "__OBJC_RW_DLLIMPORT double objc_msgSend_fpret";
599 Preamble
+= "(struct objc_object *, struct objc_selector *, ...);\n";
600 Preamble
+= "__OBJC_RW_DLLIMPORT struct objc_object *objc_getClass";
601 Preamble
+= "(const char *);\n";
602 Preamble
+= "__OBJC_RW_DLLIMPORT struct objc_class *class_getSuperclass";
603 Preamble
+= "(struct objc_class *);\n";
604 Preamble
+= "__OBJC_RW_DLLIMPORT struct objc_object *objc_getMetaClass";
605 Preamble
+= "(const char *);\n";
606 Preamble
+= "__OBJC_RW_DLLIMPORT void objc_exception_throw(struct objc_object *);\n";
607 Preamble
+= "__OBJC_RW_DLLIMPORT void objc_exception_try_enter(void *);\n";
608 Preamble
+= "__OBJC_RW_DLLIMPORT void objc_exception_try_exit(void *);\n";
609 Preamble
+= "__OBJC_RW_DLLIMPORT struct objc_object *objc_exception_extract(void *);\n";
610 Preamble
+= "__OBJC_RW_DLLIMPORT int objc_exception_match";
611 Preamble
+= "(struct objc_class *, struct objc_object *);\n";
612 // @synchronized hooks.
613 Preamble
+= "__OBJC_RW_DLLIMPORT void objc_sync_enter(struct objc_object *);\n";
614 Preamble
+= "__OBJC_RW_DLLIMPORT void objc_sync_exit(struct objc_object *);\n";
615 Preamble
+= "__OBJC_RW_DLLIMPORT Protocol *objc_getProtocol(const char *);\n";
616 Preamble
+= "#ifndef __FASTENUMERATIONSTATE\n";
617 Preamble
+= "struct __objcFastEnumerationState {\n\t";
618 Preamble
+= "unsigned long state;\n\t";
619 Preamble
+= "void **itemsPtr;\n\t";
620 Preamble
+= "unsigned long *mutationsPtr;\n\t";
621 Preamble
+= "unsigned long extra[5];\n};\n";
622 Preamble
+= "__OBJC_RW_DLLIMPORT void objc_enumerationMutation(struct objc_object *);\n";
623 Preamble
+= "#define __FASTENUMERATIONSTATE\n";
624 Preamble
+= "#endif\n";
625 Preamble
+= "#ifndef __NSCONSTANTSTRINGIMPL\n";
626 Preamble
+= "struct __NSConstantStringImpl {\n";
627 Preamble
+= " int *isa;\n";
628 Preamble
+= " int flags;\n";
629 Preamble
+= " char *str;\n";
630 Preamble
+= " long length;\n";
632 Preamble
+= "#ifdef CF_EXPORT_CONSTANT_STRING\n";
633 Preamble
+= "extern \"C\" __declspec(dllexport) int __CFConstantStringClassReference[];\n";
634 Preamble
+= "#else\n";
635 Preamble
+= "__OBJC_RW_DLLIMPORT int __CFConstantStringClassReference[];\n";
636 Preamble
+= "#endif\n";
637 Preamble
+= "#define __NSCONSTANTSTRINGIMPL\n";
638 Preamble
+= "#endif\n";
640 Preamble
+= "#ifndef BLOCK_IMPL\n";
641 Preamble
+= "#define BLOCK_IMPL\n";
642 Preamble
+= "struct __block_impl {\n";
643 Preamble
+= " void *isa;\n";
644 Preamble
+= " int Flags;\n";
645 Preamble
+= " int Reserved;\n";
646 Preamble
+= " void *FuncPtr;\n";
648 Preamble
+= "// Runtime copy/destroy helper functions (from Block_private.h)\n";
649 Preamble
+= "#ifdef __OBJC_EXPORT_BLOCKS\n";
650 Preamble
+= "extern \"C\" __declspec(dllexport) "
651 "void _Block_object_assign(void *, const void *, const int);\n";
652 Preamble
+= "extern \"C\" __declspec(dllexport) void _Block_object_dispose(const void *, const int);\n";
653 Preamble
+= "extern \"C\" __declspec(dllexport) void *_NSConcreteGlobalBlock[32];\n";
654 Preamble
+= "extern \"C\" __declspec(dllexport) void *_NSConcreteStackBlock[32];\n";
655 Preamble
+= "#else\n";
656 Preamble
+= "__OBJC_RW_DLLIMPORT void _Block_object_assign(void *, const void *, const int);\n";
657 Preamble
+= "__OBJC_RW_DLLIMPORT void _Block_object_dispose(const void *, const int);\n";
658 Preamble
+= "__OBJC_RW_DLLIMPORT void *_NSConcreteGlobalBlock[32];\n";
659 Preamble
+= "__OBJC_RW_DLLIMPORT void *_NSConcreteStackBlock[32];\n";
660 Preamble
+= "#endif\n";
661 Preamble
+= "#endif\n";
662 if (LangOpts
.Microsoft
) {
663 Preamble
+= "#undef __OBJC_RW_DLLIMPORT\n";
664 Preamble
+= "#undef __OBJC_RW_STATICIMPORT\n";
665 Preamble
+= "#ifndef KEEP_ATTRIBUTES\n"; // We use this for clang tests.
666 Preamble
+= "#define __attribute__(X)\n";
667 Preamble
+= "#endif\n";
668 Preamble
+= "#define __weak\n";
671 Preamble
+= "#define __block\n";
672 Preamble
+= "#define __weak\n";
674 // NOTE! Windows uses LLP64 for 64bit mode. So, cast pointer to long long
675 // as this avoids warning in any 64bit/32bit compilation model.
676 Preamble
+= "\n#define __OFFSETOFIVAR__(TYPE, MEMBER) ((long long) &((TYPE *)0)->MEMBER)\n";
680 //===----------------------------------------------------------------------===//
681 // Top Level Driver Code
682 //===----------------------------------------------------------------------===//
684 void RewriteObjC::HandleTopLevelSingleDecl(Decl
*D
) {
685 if (Diags
.hasErrorOccurred())
688 // Two cases: either the decl could be in the main file, or it could be in a
689 // #included file. If the former, rewrite it now. If the later, check to see
690 // if we rewrote the #include/#import.
691 SourceLocation Loc
= D
->getLocation();
692 Loc
= SM
->getInstantiationLoc(Loc
);
694 // If this is for a builtin, ignore it.
695 if (Loc
.isInvalid()) return;
697 // Look for built-in declarations that we need to refer during the rewrite.
698 if (FunctionDecl
*FD
= dyn_cast
<FunctionDecl
>(D
)) {
699 RewriteFunctionDecl(FD
);
700 } else if (VarDecl
*FVD
= dyn_cast
<VarDecl
>(D
)) {
701 // declared in <Foundation/NSString.h>
702 if (FVD
->getName() == "_NSConstantStringClassReference") {
703 ConstantStringClassReference
= FVD
;
706 } else if (ObjCInterfaceDecl
*MD
= dyn_cast
<ObjCInterfaceDecl
>(D
)) {
707 RewriteInterfaceDecl(MD
);
708 } else if (ObjCCategoryDecl
*CD
= dyn_cast
<ObjCCategoryDecl
>(D
)) {
709 RewriteCategoryDecl(CD
);
710 } else if (ObjCProtocolDecl
*PD
= dyn_cast
<ObjCProtocolDecl
>(D
)) {
711 RewriteProtocolDecl(PD
);
712 } else if (ObjCForwardProtocolDecl
*FP
=
713 dyn_cast
<ObjCForwardProtocolDecl
>(D
)){
714 RewriteForwardProtocolDecl(FP
);
715 } else if (LinkageSpecDecl
*LSD
= dyn_cast
<LinkageSpecDecl
>(D
)) {
716 // Recurse into linkage specifications
717 for (DeclContext::decl_iterator DI
= LSD
->decls_begin(),
718 DIEnd
= LSD
->decls_end();
720 HandleTopLevelSingleDecl(*DI
);
722 // If we have a decl in the main file, see if we should rewrite it.
723 if (SM
->isFromMainFile(Loc
))
724 return HandleDeclInMainFile(D
);
727 //===----------------------------------------------------------------------===//
728 // Syntactic (non-AST) Rewriting Code
729 //===----------------------------------------------------------------------===//
731 void RewriteObjC::RewriteInclude() {
732 SourceLocation LocStart
= SM
->getLocForStartOfFile(MainFileID
);
733 llvm::StringRef MainBuf
= SM
->getBufferData(MainFileID
);
734 const char *MainBufStart
= MainBuf
.begin();
735 const char *MainBufEnd
= MainBuf
.end();
736 size_t ImportLen
= strlen("import");
738 // Loop over the whole file, looking for includes.
739 for (const char *BufPtr
= MainBufStart
; BufPtr
< MainBufEnd
; ++BufPtr
) {
740 if (*BufPtr
== '#') {
741 if (++BufPtr
== MainBufEnd
)
743 while (*BufPtr
== ' ' || *BufPtr
== '\t')
744 if (++BufPtr
== MainBufEnd
)
746 if (!strncmp(BufPtr
, "import", ImportLen
)) {
747 // replace import with include
748 SourceLocation ImportLoc
=
749 LocStart
.getFileLocWithOffset(BufPtr
-MainBufStart
);
750 ReplaceText(ImportLoc
, ImportLen
, "include");
757 static std::string
getIvarAccessString(ObjCIvarDecl
*OID
) {
758 const ObjCInterfaceDecl
*ClassDecl
= OID
->getContainingInterface();
761 S
+= ClassDecl
->getIdentifier()->getName();
762 S
+= "_IMPL *)self)->";
767 void RewriteObjC::RewritePropertyImplDecl(ObjCPropertyImplDecl
*PID
,
768 ObjCImplementationDecl
*IMD
,
769 ObjCCategoryImplDecl
*CID
) {
770 static bool objcGetPropertyDefined
= false;
771 static bool objcSetPropertyDefined
= false;
772 SourceLocation startLoc
= PID
->getLocStart();
773 InsertText(startLoc
, "// ");
774 const char *startBuf
= SM
->getCharacterData(startLoc
);
775 assert((*startBuf
== '@') && "bogus @synthesize location");
776 const char *semiBuf
= strchr(startBuf
, ';');
777 assert((*semiBuf
== ';') && "@synthesize: can't find ';'");
778 SourceLocation onePastSemiLoc
=
779 startLoc
.getFileLocWithOffset(semiBuf
-startBuf
+1);
781 if (PID
->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic
)
782 return; // FIXME: is this correct?
784 // Generate the 'getter' function.
785 ObjCPropertyDecl
*PD
= PID
->getPropertyDecl();
786 ObjCIvarDecl
*OID
= PID
->getPropertyIvarDecl();
790 unsigned Attributes
= PD
->getPropertyAttributes();
791 if (!PD
->getGetterMethodDecl()->isDefined()) {
792 bool GenGetProperty
= !(Attributes
& ObjCPropertyDecl::OBJC_PR_nonatomic
) &&
793 (Attributes
& (ObjCPropertyDecl::OBJC_PR_retain
|
794 ObjCPropertyDecl::OBJC_PR_copy
));
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";
802 RewriteObjCMethodDecl(OID
->getContainingInterface(),
803 PD
->getGetterMethodDecl(), 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)
810 const FunctionType
*FPRetType
= 0;
811 RewriteTypeIntoString(PD
->getGetterMethodDecl()->getResultType(), Getr
,
815 Getr
+= ")"; // close the precedence "scope" for "*".
817 // Now, emit the argument types (if any).
818 if (const FunctionProtoType
*FT
= dyn_cast
<FunctionProtoType
>(FPRetType
)){
820 for (unsigned i
= 0, e
= FT
->getNumArgs(); i
!= e
; ++i
) {
822 std::string ParamStr
= FT
->getArgType(i
).getAsString(
823 Context
->PrintingPolicy
);
826 if (FT
->isVariadic()) {
827 if (FT
->getNumArgs()) Getr
+= ", ";
835 Getr
+= "return (_TYPE)";
836 Getr
+= "objc_getProperty(self, _cmd, ";
837 SynthesizeIvarOffsetComputation(OID
, Getr
);
841 Getr
+= "return " + getIvarAccessString(OID
);
843 InsertText(onePastSemiLoc
, Getr
);
846 if (PD
->isReadOnly() || PD
->getSetterMethodDecl()->isDefined())
849 // Generate the 'setter' function.
851 bool GenSetProperty
= Attributes
& (ObjCPropertyDecl::OBJC_PR_retain
|
852 ObjCPropertyDecl::OBJC_PR_copy
);
853 if (GenSetProperty
&& !objcSetPropertyDefined
) {
854 objcSetPropertyDefined
= true;
855 // FIXME. Is this attribute correct in all cases?
856 Setr
= "\nextern \"C\" __declspec(dllimport) "
857 "void objc_setProperty (id, SEL, long, id, bool, bool);\n";
860 RewriteObjCMethodDecl(OID
->getContainingInterface(),
861 PD
->getSetterMethodDecl(), Setr
);
863 // Synthesize an explicit cast to initialize the ivar.
864 // See objc-act.c:objc_synthesize_new_setter() for details.
865 if (GenSetProperty
) {
866 Setr
+= "objc_setProperty (self, _cmd, ";
867 SynthesizeIvarOffsetComputation(OID
, Setr
);
869 Setr
+= PD
->getName();
871 if (Attributes
& ObjCPropertyDecl::OBJC_PR_nonatomic
)
875 if (Attributes
& ObjCPropertyDecl::OBJC_PR_copy
)
881 Setr
+= getIvarAccessString(OID
) + " = ";
882 Setr
+= PD
->getName();
885 InsertText(onePastSemiLoc
, Setr
);
888 void RewriteObjC::RewriteForwardClassDecl(ObjCClassDecl
*ClassDecl
) {
889 // Get the start location and compute the semi location.
890 SourceLocation startLoc
= ClassDecl
->getLocation();
891 const char *startBuf
= SM
->getCharacterData(startLoc
);
892 const char *semiPtr
= strchr(startBuf
, ';');
894 // Translate to typedef's that forward reference structs with the same name
895 // as the class. As a convenience, we include the original declaration
897 std::string typedefString
;
898 typedefString
+= "// @class ";
899 for (ObjCClassDecl::iterator I
= ClassDecl
->begin(), E
= ClassDecl
->end();
901 ObjCInterfaceDecl
*ForwardDecl
= I
->getInterface();
902 typedefString
+= ForwardDecl
->getNameAsString();
904 typedefString
+= ", ";
906 typedefString
+= ";\n";
909 for (ObjCClassDecl::iterator I
= ClassDecl
->begin(), E
= ClassDecl
->end();
911 ObjCInterfaceDecl
*ForwardDecl
= I
->getInterface();
912 typedefString
+= "#ifndef _REWRITER_typedef_";
913 typedefString
+= ForwardDecl
->getNameAsString();
914 typedefString
+= "\n";
915 typedefString
+= "#define _REWRITER_typedef_";
916 typedefString
+= ForwardDecl
->getNameAsString();
917 typedefString
+= "\n";
918 typedefString
+= "typedef struct objc_object ";
919 typedefString
+= ForwardDecl
->getNameAsString();
920 typedefString
+= ";\n#endif\n";
923 // Replace the @class with typedefs corresponding to the classes.
924 ReplaceText(startLoc
, semiPtr
-startBuf
+1, typedefString
);
927 void RewriteObjC::RewriteMethodDeclaration(ObjCMethodDecl
*Method
) {
928 // When method is a synthesized one, such as a getter/setter there is
929 // nothing to rewrite.
930 if (Method
->isSynthesized())
932 SourceLocation LocStart
= Method
->getLocStart();
933 SourceLocation LocEnd
= Method
->getLocEnd();
935 if (SM
->getInstantiationLineNumber(LocEnd
) >
936 SM
->getInstantiationLineNumber(LocStart
)) {
937 InsertText(LocStart
, "#if 0\n");
938 ReplaceText(LocEnd
, 1, ";\n#endif\n");
940 InsertText(LocStart
, "// ");
944 void RewriteObjC::RewriteProperty(ObjCPropertyDecl
*prop
) {
945 SourceLocation Loc
= prop
->getAtLoc();
947 ReplaceText(Loc
, 0, "// ");
948 // FIXME: handle properties that are declared across multiple lines.
951 void RewriteObjC::RewriteCategoryDecl(ObjCCategoryDecl
*CatDecl
) {
952 SourceLocation LocStart
= CatDecl
->getLocStart();
954 // FIXME: handle category headers that are declared across multiple lines.
955 ReplaceText(LocStart
, 0, "// ");
957 for (ObjCCategoryDecl::prop_iterator I
= CatDecl
->prop_begin(),
958 E
= CatDecl
->prop_end(); I
!= E
; ++I
)
961 for (ObjCCategoryDecl::instmeth_iterator
962 I
= CatDecl
->instmeth_begin(), E
= CatDecl
->instmeth_end();
964 RewriteMethodDeclaration(*I
);
965 for (ObjCCategoryDecl::classmeth_iterator
966 I
= CatDecl
->classmeth_begin(), E
= CatDecl
->classmeth_end();
968 RewriteMethodDeclaration(*I
);
970 // Lastly, comment out the @end.
971 ReplaceText(CatDecl
->getAtEndRange().getBegin(),
972 strlen("@end"), "/* @end */");
975 void RewriteObjC::RewriteProtocolDecl(ObjCProtocolDecl
*PDecl
) {
976 SourceLocation LocStart
= PDecl
->getLocStart();
978 // FIXME: handle protocol headers that are declared across multiple lines.
979 ReplaceText(LocStart
, 0, "// ");
981 for (ObjCProtocolDecl::instmeth_iterator
982 I
= PDecl
->instmeth_begin(), E
= PDecl
->instmeth_end();
984 RewriteMethodDeclaration(*I
);
985 for (ObjCProtocolDecl::classmeth_iterator
986 I
= PDecl
->classmeth_begin(), E
= PDecl
->classmeth_end();
988 RewriteMethodDeclaration(*I
);
990 for (ObjCInterfaceDecl::prop_iterator I
= PDecl
->prop_begin(),
991 E
= PDecl
->prop_end(); I
!= E
; ++I
)
994 // Lastly, comment out the @end.
995 SourceLocation LocEnd
= PDecl
->getAtEndRange().getBegin();
996 ReplaceText(LocEnd
, strlen("@end"), "/* @end */");
998 // Must comment out @optional/@required
999 const char *startBuf
= SM
->getCharacterData(LocStart
);
1000 const char *endBuf
= SM
->getCharacterData(LocEnd
);
1001 for (const char *p
= startBuf
; p
< endBuf
; p
++) {
1002 if (*p
== '@' && !strncmp(p
+1, "optional", strlen("optional"))) {
1003 SourceLocation OptionalLoc
= LocStart
.getFileLocWithOffset(p
-startBuf
);
1004 ReplaceText(OptionalLoc
, strlen("@optional"), "/* @optional */");
1007 else if (*p
== '@' && !strncmp(p
+1, "required", strlen("required"))) {
1008 SourceLocation OptionalLoc
= LocStart
.getFileLocWithOffset(p
-startBuf
);
1009 ReplaceText(OptionalLoc
, strlen("@required"), "/* @required */");
1015 void RewriteObjC::RewriteForwardProtocolDecl(ObjCForwardProtocolDecl
*PDecl
) {
1016 SourceLocation LocStart
= PDecl
->getLocation();
1017 if (LocStart
.isInvalid())
1018 assert(false && "Invalid SourceLocation");
1019 // FIXME: handle forward protocol that are declared across multiple lines.
1020 ReplaceText(LocStart
, 0, "// ");
1023 void RewriteObjC::RewriteTypeIntoString(QualType T
, std::string
&ResultStr
,
1024 const FunctionType
*&FPRetType
) {
1025 if (T
->isObjCQualifiedIdType())
1027 else if (T
->isFunctionPointerType() ||
1028 T
->isBlockPointerType()) {
1029 // needs special handling, since pointer-to-functions have special
1030 // syntax (where a decaration models use).
1031 QualType retType
= T
;
1033 if (const PointerType
* PT
= retType
->getAs
<PointerType
>())
1034 PointeeTy
= PT
->getPointeeType();
1035 else if (const BlockPointerType
*BPT
= retType
->getAs
<BlockPointerType
>())
1036 PointeeTy
= BPT
->getPointeeType();
1037 if ((FPRetType
= PointeeTy
->getAs
<FunctionType
>())) {
1038 ResultStr
+= FPRetType
->getResultType().getAsString(
1039 Context
->PrintingPolicy
);
1043 ResultStr
+= T
.getAsString(Context
->PrintingPolicy
);
1046 void RewriteObjC::RewriteObjCMethodDecl(const ObjCInterfaceDecl
*IDecl
,
1047 ObjCMethodDecl
*OMD
,
1048 std::string
&ResultStr
) {
1049 //fprintf(stderr,"In RewriteObjCMethodDecl\n");
1050 const FunctionType
*FPRetType
= 0;
1051 ResultStr
+= "\nstatic ";
1052 RewriteTypeIntoString(OMD
->getResultType(), ResultStr
, FPRetType
);
1055 // Unique method name
1056 std::string NameStr
;
1058 if (OMD
->isInstanceMethod())
1063 NameStr
+= IDecl
->getNameAsString();
1066 if (ObjCCategoryImplDecl
*CID
=
1067 dyn_cast
<ObjCCategoryImplDecl
>(OMD
->getDeclContext())) {
1068 NameStr
+= CID
->getNameAsString();
1071 // Append selector names, replacing ':' with '_'
1073 std::string selString
= OMD
->getSelector().getAsString();
1074 int len
= selString
.size();
1075 for (int i
= 0; i
< len
; i
++)
1076 if (selString
[i
] == ':')
1078 NameStr
+= selString
;
1080 // Remember this name for metadata emission
1081 MethodInternalNames
[OMD
] = NameStr
;
1082 ResultStr
+= NameStr
;
1084 // Rewrite arguments
1087 // invisible arguments
1088 if (OMD
->isInstanceMethod()) {
1089 QualType selfTy
= Context
->getObjCInterfaceType(IDecl
);
1090 selfTy
= Context
->getPointerType(selfTy
);
1091 if (!LangOpts
.Microsoft
) {
1092 if (ObjCSynthesizedStructs
.count(const_cast<ObjCInterfaceDecl
*>(IDecl
)))
1093 ResultStr
+= "struct ";
1095 // When rewriting for Microsoft, explicitly omit the structure name.
1096 ResultStr
+= IDecl
->getNameAsString();
1100 ResultStr
+= Context
->getObjCClassType().getAsString(
1101 Context
->PrintingPolicy
);
1103 ResultStr
+= " self, ";
1104 ResultStr
+= Context
->getObjCSelType().getAsString(Context
->PrintingPolicy
);
1105 ResultStr
+= " _cmd";
1107 // Method arguments.
1108 for (ObjCMethodDecl::param_iterator PI
= OMD
->param_begin(),
1109 E
= OMD
->param_end(); PI
!= E
; ++PI
) {
1110 ParmVarDecl
*PDecl
= *PI
;
1112 if (PDecl
->getType()->isObjCQualifiedIdType()) {
1114 ResultStr
+= PDecl
->getNameAsString();
1116 std::string Name
= PDecl
->getNameAsString();
1117 QualType QT
= PDecl
->getType();
1118 // Make sure we convert "t (^)(...)" to "t (*)(...)".
1119 if (convertBlockPointerToFunctionPointer(QT
))
1120 QT
.getAsStringInternal(Name
, Context
->PrintingPolicy
);
1122 PDecl
->getType().getAsStringInternal(Name
, Context
->PrintingPolicy
);
1126 if (OMD
->isVariadic())
1127 ResultStr
+= ", ...";
1131 ResultStr
+= ")"; // close the precedence "scope" for "*".
1133 // Now, emit the argument types (if any).
1134 if (const FunctionProtoType
*FT
= dyn_cast
<FunctionProtoType
>(FPRetType
)) {
1136 for (unsigned i
= 0, e
= FT
->getNumArgs(); i
!= e
; ++i
) {
1137 if (i
) ResultStr
+= ", ";
1138 std::string ParamStr
= FT
->getArgType(i
).getAsString(
1139 Context
->PrintingPolicy
);
1140 ResultStr
+= ParamStr
;
1142 if (FT
->isVariadic()) {
1143 if (FT
->getNumArgs()) ResultStr
+= ", ";
1152 void RewriteObjC::RewriteImplementationDecl(Decl
*OID
) {
1153 ObjCImplementationDecl
*IMD
= dyn_cast
<ObjCImplementationDecl
>(OID
);
1154 ObjCCategoryImplDecl
*CID
= dyn_cast
<ObjCCategoryImplDecl
>(OID
);
1156 InsertText(IMD
? IMD
->getLocStart() : CID
->getLocStart(), "// ");
1158 for (ObjCCategoryImplDecl::instmeth_iterator
1159 I
= IMD
? IMD
->instmeth_begin() : CID
->instmeth_begin(),
1160 E
= IMD
? IMD
->instmeth_end() : CID
->instmeth_end();
1162 std::string ResultStr
;
1163 ObjCMethodDecl
*OMD
= *I
;
1164 RewriteObjCMethodDecl(OMD
->getClassInterface(), OMD
, ResultStr
);
1165 SourceLocation LocStart
= OMD
->getLocStart();
1166 SourceLocation LocEnd
= OMD
->getCompoundBody()->getLocStart();
1168 const char *startBuf
= SM
->getCharacterData(LocStart
);
1169 const char *endBuf
= SM
->getCharacterData(LocEnd
);
1170 ReplaceText(LocStart
, endBuf
-startBuf
, ResultStr
);
1173 for (ObjCCategoryImplDecl::classmeth_iterator
1174 I
= IMD
? IMD
->classmeth_begin() : CID
->classmeth_begin(),
1175 E
= IMD
? IMD
->classmeth_end() : CID
->classmeth_end();
1177 std::string ResultStr
;
1178 ObjCMethodDecl
*OMD
= *I
;
1179 RewriteObjCMethodDecl(OMD
->getClassInterface(), OMD
, ResultStr
);
1180 SourceLocation LocStart
= OMD
->getLocStart();
1181 SourceLocation LocEnd
= OMD
->getCompoundBody()->getLocStart();
1183 const char *startBuf
= SM
->getCharacterData(LocStart
);
1184 const char *endBuf
= SM
->getCharacterData(LocEnd
);
1185 ReplaceText(LocStart
, endBuf
-startBuf
, ResultStr
);
1187 for (ObjCCategoryImplDecl::propimpl_iterator
1188 I
= IMD
? IMD
->propimpl_begin() : CID
->propimpl_begin(),
1189 E
= IMD
? IMD
->propimpl_end() : CID
->propimpl_end();
1191 RewritePropertyImplDecl(*I
, IMD
, CID
);
1194 InsertText(IMD
? IMD
->getLocEnd() : CID
->getLocEnd(), "// ");
1197 void RewriteObjC::RewriteInterfaceDecl(ObjCInterfaceDecl
*ClassDecl
) {
1198 std::string ResultStr
;
1199 if (!ObjCForwardDecls
.count(ClassDecl
)) {
1200 // we haven't seen a forward decl - generate a typedef.
1201 ResultStr
= "#ifndef _REWRITER_typedef_";
1202 ResultStr
+= ClassDecl
->getNameAsString();
1204 ResultStr
+= "#define _REWRITER_typedef_";
1205 ResultStr
+= ClassDecl
->getNameAsString();
1207 ResultStr
+= "typedef struct objc_object ";
1208 ResultStr
+= ClassDecl
->getNameAsString();
1209 ResultStr
+= ";\n#endif\n";
1210 // Mark this typedef as having been generated.
1211 ObjCForwardDecls
.insert(ClassDecl
);
1213 SynthesizeObjCInternalStruct(ClassDecl
, ResultStr
);
1215 for (ObjCInterfaceDecl::prop_iterator I
= ClassDecl
->prop_begin(),
1216 E
= ClassDecl
->prop_end(); I
!= E
; ++I
)
1217 RewriteProperty(*I
);
1218 for (ObjCInterfaceDecl::instmeth_iterator
1219 I
= ClassDecl
->instmeth_begin(), E
= ClassDecl
->instmeth_end();
1221 RewriteMethodDeclaration(*I
);
1222 for (ObjCInterfaceDecl::classmeth_iterator
1223 I
= ClassDecl
->classmeth_begin(), E
= ClassDecl
->classmeth_end();
1225 RewriteMethodDeclaration(*I
);
1227 // Lastly, comment out the @end.
1228 ReplaceText(ClassDecl
->getAtEndRange().getBegin(), strlen("@end"),
1232 Stmt
*RewriteObjC::RewritePropertyOrImplicitSetter(BinaryOperator
*BinOp
, Expr
*newStmt
,
1233 SourceRange SrcRange
) {
1234 ObjCMethodDecl
*OMD
= 0;
1240 SourceLocation SuperLocation
;
1241 SourceLocation SelectorLoc
;
1242 // Synthesize a ObjCMessageExpr from a ObjCPropertyRefExpr or ObjCImplicitSetterGetterRefExpr.
1243 // This allows us to reuse all the fun and games in SynthMessageExpr().
1244 if (ObjCPropertyRefExpr
*PropRefExpr
=
1245 dyn_cast
<ObjCPropertyRefExpr
>(BinOp
->getLHS())) {
1246 SelectorLoc
= PropRefExpr
->getLocation();
1247 if (PropRefExpr
->isExplicitProperty()) {
1248 ObjCPropertyDecl
*PDecl
= PropRefExpr
->getExplicitProperty();
1249 OMD
= PDecl
->getSetterMethodDecl();
1250 Ty
= PDecl
->getType();
1251 Sel
= PDecl
->getSetterName();
1253 OMD
= PropRefExpr
->getImplicitPropertySetter();
1254 Sel
= OMD
->getSelector();
1255 Ty
= PropRefExpr
->getType();
1257 Super
= PropRefExpr
->isSuperReceiver();
1259 Receiver
= PropRefExpr
->getBase();
1261 SuperTy
= PropRefExpr
->getSuperReceiverType();
1262 SuperLocation
= PropRefExpr
->getReceiverLocation();
1266 assert(OMD
&& "RewritePropertyOrImplicitSetter - null OMD");
1267 llvm::SmallVector
<Expr
*, 1> ExprVec
;
1268 ExprVec
.push_back(newStmt
);
1270 ObjCMessageExpr
*MsgExpr
;
1272 MsgExpr
= ObjCMessageExpr::Create(*Context
,
1273 Ty
.getNonReferenceType(),
1274 Expr::getValueKindForType(Ty
),
1275 /*FIXME?*/SourceLocation(),
1277 /*IsInstanceSuper=*/true,
1279 Sel
, SelectorLoc
, OMD
,
1281 /*FIXME:*/SourceLocation());
1283 // FIXME. Refactor this into common code with that in
1284 // RewritePropertyOrImplicitGetter
1285 assert(Receiver
&& "RewritePropertyOrImplicitSetter - null Receiver");
1286 if (Expr
*Exp
= dyn_cast
<Expr
>(Receiver
))
1287 if (PropGetters
[Exp
])
1288 // This allows us to handle chain/nested property/implicit getters.
1289 Receiver
= PropGetters
[Exp
];
1291 MsgExpr
= ObjCMessageExpr::Create(*Context
,
1292 Ty
.getNonReferenceType(),
1293 Expr::getValueKindForType(Ty
),
1294 /*FIXME: */SourceLocation(),
1295 cast
<Expr
>(Receiver
),
1296 Sel
, SelectorLoc
, OMD
,
1298 /*FIXME:*/SourceLocation());
1300 Stmt
*ReplacingStmt
= SynthMessageExpr(MsgExpr
);
1302 // Now do the actual rewrite.
1303 ReplaceStmtWithRange(BinOp
, ReplacingStmt
, SrcRange
);
1305 // NOTE: We don't want to call MsgExpr->Destroy(), as it holds references
1306 // to things that stay around.
1307 Context
->Deallocate(MsgExpr
);
1308 return ReplacingStmt
;
1311 Stmt
*RewriteObjC::RewritePropertyOrImplicitGetter(Expr
*PropOrGetterRefExpr
) {
1312 // Synthesize a ObjCMessageExpr from a ObjCPropertyRefExpr or ImplicitGetter.
1313 // This allows us to reuse all the fun and games in SynthMessageExpr().
1315 ObjCMethodDecl
*OMD
= 0;
1320 SourceLocation SuperLocation
;
1321 SourceLocation SelectorLoc
;
1322 if (ObjCPropertyRefExpr
*PropRefExpr
=
1323 dyn_cast
<ObjCPropertyRefExpr
>(PropOrGetterRefExpr
)) {
1324 SelectorLoc
= PropRefExpr
->getLocation();
1325 if (PropRefExpr
->isExplicitProperty()) {
1326 ObjCPropertyDecl
*PDecl
= PropRefExpr
->getExplicitProperty();
1327 OMD
= PDecl
->getGetterMethodDecl();
1328 Ty
= PDecl
->getType();
1329 Sel
= PDecl
->getGetterName();
1331 OMD
= PropRefExpr
->getImplicitPropertyGetter();
1332 Sel
= OMD
->getSelector();
1333 Ty
= PropRefExpr
->getType();
1335 Super
= PropRefExpr
->isSuperReceiver();
1337 Receiver
= PropRefExpr
->getBase();
1339 SuperTy
= PropRefExpr
->getSuperReceiverType();
1340 SuperLocation
= PropRefExpr
->getReceiverLocation();
1344 assert (OMD
&& "RewritePropertyOrImplicitGetter - OMD is null");
1346 ObjCMessageExpr
*MsgExpr
;
1348 MsgExpr
= ObjCMessageExpr::Create(*Context
,
1349 Ty
.getNonReferenceType(),
1350 Expr::getValueKindForType(Ty
),
1351 /*FIXME?*/SourceLocation(),
1353 /*IsInstanceSuper=*/true,
1355 Sel
, SelectorLoc
, OMD
,
1357 /*FIXME:*/SourceLocation());
1359 assert (Receiver
&& "RewritePropertyOrImplicitGetter - Receiver is null");
1360 if (Expr
*Exp
= dyn_cast
<Expr
>(Receiver
))
1361 if (PropGetters
[Exp
])
1362 // This allows us to handle chain/nested property/implicit getters.
1363 Receiver
= PropGetters
[Exp
];
1364 MsgExpr
= ObjCMessageExpr::Create(*Context
,
1365 Ty
.getNonReferenceType(),
1366 Expr::getValueKindForType(Ty
),
1367 /*FIXME:*/SourceLocation(),
1368 cast
<Expr
>(Receiver
),
1369 Sel
, SelectorLoc
, OMD
,
1371 /*FIXME:*/SourceLocation());
1374 Stmt
*ReplacingStmt
= SynthMessageExpr(MsgExpr
);
1377 PropParentMap
= new ParentMap(CurrentBody
);
1378 bool NestedPropertyRef
= false;
1379 Stmt
*Parent
= PropParentMap
->getParent(PropOrGetterRefExpr
);
1380 ImplicitCastExpr
*ICE
=0;
1382 if ((ICE
= dyn_cast
<ImplicitCastExpr
>(Parent
))) {
1383 assert((ICE
->getCastKind() == CK_GetObjCProperty
)
1384 && "RewritePropertyOrImplicitGetter");
1385 Parent
= PropParentMap
->getParent(Parent
);
1386 NestedPropertyRef
= (Parent
&& isa
<ObjCPropertyRefExpr
>(Parent
));
1388 if (NestedPropertyRef
) {
1389 // We stash away the ReplacingStmt since actually doing the
1390 // replacement/rewrite won't work for nested getters (e.g. obj.p.i)
1391 PropGetters
[ICE
] = ReplacingStmt
;
1392 // NOTE: We don't want to call MsgExpr->Destroy(), as it holds references
1393 // to things that stay around.
1394 Context
->Deallocate(MsgExpr
);
1395 return PropOrGetterRefExpr
; // return the original...
1397 ReplaceStmt(PropOrGetterRefExpr
, ReplacingStmt
);
1398 // delete PropRefExpr; elsewhere...
1399 // NOTE: We don't want to call MsgExpr->Destroy(), as it holds references
1400 // to things that stay around.
1401 Context
->Deallocate(MsgExpr
);
1402 return ReplacingStmt
;
1406 Stmt
*RewriteObjC::RewriteObjCIvarRefExpr(ObjCIvarRefExpr
*IV
,
1407 SourceLocation OrigStart
,
1409 ObjCIvarDecl
*D
= IV
->getDecl();
1410 const Expr
*BaseExpr
= IV
->getBase();
1412 if (BaseExpr
->getType()->isObjCObjectPointerType()) {
1413 const ObjCInterfaceType
*iFaceDecl
=
1414 dyn_cast
<ObjCInterfaceType
>(BaseExpr
->getType()->getPointeeType());
1415 assert(iFaceDecl
&& "RewriteObjCIvarRefExpr - iFaceDecl is null");
1416 // lookup which class implements the instance variable.
1417 ObjCInterfaceDecl
*clsDeclared
= 0;
1418 iFaceDecl
->getDecl()->lookupInstanceVariable(D
->getIdentifier(),
1420 assert(clsDeclared
&& "RewriteObjCIvarRefExpr(): Can't find class");
1422 // Synthesize an explicit cast to gain access to the ivar.
1423 std::string RecName
= clsDeclared
->getIdentifier()->getName();
1425 IdentifierInfo
*II
= &Context
->Idents
.get(RecName
);
1426 RecordDecl
*RD
= RecordDecl::Create(*Context
, TTK_Struct
, TUDecl
,
1427 SourceLocation(), II
);
1428 assert(RD
&& "RewriteObjCIvarRefExpr(): Can't find RecordDecl");
1429 QualType castT
= Context
->getPointerType(Context
->getTagDeclType(RD
));
1430 CastExpr
*castExpr
= NoTypeInfoCStyleCastExpr(Context
, castT
,
1433 // Don't forget the parens to enforce the proper binding.
1434 ParenExpr
*PE
= new (Context
) ParenExpr(IV
->getBase()->getLocStart(),
1435 IV
->getBase()->getLocEnd(),
1438 if (IV
->isFreeIvar() &&
1439 CurMethodDef
->getClassInterface() == iFaceDecl
->getDecl()) {
1440 MemberExpr
*ME
= new (Context
) MemberExpr(PE
, true, D
,
1443 VK_LValue
, OK_Ordinary
);
1444 // delete IV; leak for now, see RewritePropertyOrImplicitSetter() usage for more info.
1448 // Cannot delete IV->getBase(), since PE points to it.
1449 // Replace the old base with the cast. This is important when doing
1450 // embedded rewrites. For example, [newInv->_container addObject:0].
1454 } else { // we are outside a method.
1455 assert(!IV
->isFreeIvar() && "Cannot have a free standing ivar outside a method");
1457 // Explicit ivar refs need to have a cast inserted.
1458 // FIXME: consider sharing some of this code with the code above.
1459 if (BaseExpr
->getType()->isObjCObjectPointerType()) {
1460 const ObjCInterfaceType
*iFaceDecl
=
1461 dyn_cast
<ObjCInterfaceType
>(BaseExpr
->getType()->getPointeeType());
1462 // lookup which class implements the instance variable.
1463 ObjCInterfaceDecl
*clsDeclared
= 0;
1464 iFaceDecl
->getDecl()->lookupInstanceVariable(D
->getIdentifier(),
1466 assert(clsDeclared
&& "RewriteObjCIvarRefExpr(): Can't find class");
1468 // Synthesize an explicit cast to gain access to the ivar.
1469 std::string RecName
= clsDeclared
->getIdentifier()->getName();
1471 IdentifierInfo
*II
= &Context
->Idents
.get(RecName
);
1472 RecordDecl
*RD
= RecordDecl::Create(*Context
, TTK_Struct
, TUDecl
,
1473 SourceLocation(), II
);
1474 assert(RD
&& "RewriteObjCIvarRefExpr(): Can't find RecordDecl");
1475 QualType castT
= Context
->getPointerType(Context
->getTagDeclType(RD
));
1476 CastExpr
*castExpr
= NoTypeInfoCStyleCastExpr(Context
, castT
,
1479 // Don't forget the parens to enforce the proper binding.
1480 ParenExpr
*PE
= new (Context
) ParenExpr(IV
->getBase()->getLocStart(),
1481 IV
->getBase()->getLocEnd(), castExpr
);
1483 // Cannot delete IV->getBase(), since PE points to it.
1484 // Replace the old base with the cast. This is important when doing
1485 // embedded rewrites. For example, [newInv->_container addObject:0].
1493 Stmt
*RewriteObjC::RewriteObjCNestedIvarRefExpr(Stmt
*S
, bool &replaced
) {
1494 for (Stmt::child_iterator CI
= S
->child_begin(), E
= S
->child_end();
1497 Stmt
*newStmt
= RewriteObjCNestedIvarRefExpr(*CI
, replaced
);
1502 if (ObjCIvarRefExpr
*IvarRefExpr
= dyn_cast
<ObjCIvarRefExpr
>(S
)) {
1503 SourceRange OrigStmtRange
= S
->getSourceRange();
1504 Stmt
*newStmt
= RewriteObjCIvarRefExpr(IvarRefExpr
, OrigStmtRange
.getBegin(),
1508 if (ObjCMessageExpr
*MsgRefExpr
= dyn_cast
<ObjCMessageExpr
>(S
)) {
1509 Stmt
*newStmt
= SynthMessageExpr(MsgRefExpr
);
1515 /// SynthCountByEnumWithState - To print:
1516 /// ((unsigned int (*)
1517 /// (id, SEL, struct __objcFastEnumerationState *, id *, unsigned int))
1518 /// (void *)objc_msgSend)((id)l_collection,
1519 /// sel_registerName(
1520 /// "countByEnumeratingWithState:objects:count:"),
1522 /// (id *)items, (unsigned int)16)
1524 void RewriteObjC::SynthCountByEnumWithState(std::string
&buf
) {
1525 buf
+= "((unsigned int (*) (id, SEL, struct __objcFastEnumerationState *, "
1526 "id *, unsigned int))(void *)objc_msgSend)";
1528 buf
+= "((id)l_collection,\n\t\t";
1529 buf
+= "sel_registerName(\"countByEnumeratingWithState:objects:count:\"),";
1531 buf
+= "&enumState, "
1532 "(id *)items, (unsigned int)16)";
1535 /// RewriteBreakStmt - Rewrite for a break-stmt inside an ObjC2's foreach
1536 /// statement to exit to its outer synthesized loop.
1538 Stmt
*RewriteObjC::RewriteBreakStmt(BreakStmt
*S
) {
1539 if (Stmts
.empty() || !isa
<ObjCForCollectionStmt
>(Stmts
.back()))
1541 // replace break with goto __break_label
1544 SourceLocation startLoc
= S
->getLocStart();
1545 buf
= "goto __break_label_";
1546 buf
+= utostr(ObjCBcLabelNo
.back());
1547 ReplaceText(startLoc
, strlen("break"), buf
);
1552 /// RewriteContinueStmt - Rewrite for a continue-stmt inside an ObjC2's foreach
1553 /// statement to continue with its inner synthesized loop.
1555 Stmt
*RewriteObjC::RewriteContinueStmt(ContinueStmt
*S
) {
1556 if (Stmts
.empty() || !isa
<ObjCForCollectionStmt
>(Stmts
.back()))
1558 // replace continue with goto __continue_label
1561 SourceLocation startLoc
= S
->getLocStart();
1562 buf
= "goto __continue_label_";
1563 buf
+= utostr(ObjCBcLabelNo
.back());
1564 ReplaceText(startLoc
, strlen("continue"), buf
);
1569 /// RewriteObjCForCollectionStmt - Rewriter for ObjC2's foreach statement.
1571 /// for ( type elem in collection) { stmts; }
1576 /// struct __objcFastEnumerationState enumState = { 0 };
1578 /// id l_collection = (id)collection;
1579 /// unsigned long limit = [l_collection countByEnumeratingWithState:&enumState
1580 /// objects:items count:16];
1582 /// unsigned long startMutations = *enumState.mutationsPtr;
1584 /// unsigned long counter = 0;
1586 /// if (startMutations != *enumState.mutationsPtr)
1587 /// objc_enumerationMutation(l_collection);
1588 /// elem = (type)enumState.itemsPtr[counter++];
1590 /// __continue_label: ;
1591 /// } while (counter < limit);
1592 /// } while (limit = [l_collection countByEnumeratingWithState:&enumState
1593 /// objects:items count:16]);
1595 /// __break_label: ;
1601 Stmt
*RewriteObjC::RewriteObjCForCollectionStmt(ObjCForCollectionStmt
*S
,
1602 SourceLocation OrigEnd
) {
1603 assert(!Stmts
.empty() && "ObjCForCollectionStmt - Statement stack empty");
1604 assert(isa
<ObjCForCollectionStmt
>(Stmts
.back()) &&
1605 "ObjCForCollectionStmt Statement stack mismatch");
1606 assert(!ObjCBcLabelNo
.empty() &&
1607 "ObjCForCollectionStmt - Label No stack empty");
1609 SourceLocation startLoc
= S
->getLocStart();
1610 const char *startBuf
= SM
->getCharacterData(startLoc
);
1611 llvm::StringRef elementName
;
1612 std::string elementTypeAsString
;
1615 if (DeclStmt
*DS
= dyn_cast
<DeclStmt
>(S
->getElement())) {
1617 NamedDecl
* D
= cast
<NamedDecl
>(DS
->getSingleDecl());
1618 QualType ElementType
= cast
<ValueDecl
>(D
)->getType();
1619 if (ElementType
->isObjCQualifiedIdType() ||
1620 ElementType
->isObjCQualifiedInterfaceType())
1621 // Simply use 'id' for all qualified types.
1622 elementTypeAsString
= "id";
1624 elementTypeAsString
= ElementType
.getAsString(Context
->PrintingPolicy
);
1625 buf
+= elementTypeAsString
;
1627 elementName
= D
->getName();
1632 DeclRefExpr
*DR
= cast
<DeclRefExpr
>(S
->getElement());
1633 elementName
= DR
->getDecl()->getName();
1634 ValueDecl
*VD
= cast
<ValueDecl
>(DR
->getDecl());
1635 if (VD
->getType()->isObjCQualifiedIdType() ||
1636 VD
->getType()->isObjCQualifiedInterfaceType())
1637 // Simply use 'id' for all qualified types.
1638 elementTypeAsString
= "id";
1640 elementTypeAsString
= VD
->getType().getAsString(Context
->PrintingPolicy
);
1643 // struct __objcFastEnumerationState enumState = { 0 };
1644 buf
+= "struct __objcFastEnumerationState enumState = { 0 };\n\t";
1646 buf
+= "id items[16];\n\t";
1647 // id l_collection = (id)
1648 buf
+= "id l_collection = (id)";
1649 // Find start location of 'collection' the hard way!
1650 const char *startCollectionBuf
= startBuf
;
1651 startCollectionBuf
+= 3; // skip 'for'
1652 startCollectionBuf
= strchr(startCollectionBuf
, '(');
1653 startCollectionBuf
++; // skip '('
1654 // find 'in' and skip it.
1655 while (*startCollectionBuf
!= ' ' ||
1656 *(startCollectionBuf
+1) != 'i' || *(startCollectionBuf
+2) != 'n' ||
1657 (*(startCollectionBuf
+3) != ' ' &&
1658 *(startCollectionBuf
+3) != '[' && *(startCollectionBuf
+3) != '('))
1659 startCollectionBuf
++;
1660 startCollectionBuf
+= 3;
1662 // Replace: "for (type element in" with string constructed thus far.
1663 ReplaceText(startLoc
, startCollectionBuf
- startBuf
, buf
);
1664 // Replace ')' in for '(' type elem in collection ')' with ';'
1665 SourceLocation rightParenLoc
= S
->getRParenLoc();
1666 const char *rparenBuf
= SM
->getCharacterData(rightParenLoc
);
1667 SourceLocation lparenLoc
= startLoc
.getFileLocWithOffset(rparenBuf
-startBuf
);
1670 // unsigned long limit = [l_collection countByEnumeratingWithState:&enumState
1671 // objects:items count:16];
1672 // which is synthesized into:
1673 // unsigned int limit =
1674 // ((unsigned int (*)
1675 // (id, SEL, struct __objcFastEnumerationState *, id *, unsigned int))
1676 // (void *)objc_msgSend)((id)l_collection,
1677 // sel_registerName(
1678 // "countByEnumeratingWithState:objects:count:"),
1679 // (struct __objcFastEnumerationState *)&state,
1680 // (id *)items, (unsigned int)16);
1681 buf
+= "unsigned long limit =\n\t\t";
1682 SynthCountByEnumWithState(buf
);
1685 /// unsigned long startMutations = *enumState.mutationsPtr;
1687 /// unsigned long counter = 0;
1689 /// if (startMutations != *enumState.mutationsPtr)
1690 /// objc_enumerationMutation(l_collection);
1691 /// elem = (type)enumState.itemsPtr[counter++];
1692 buf
+= "if (limit) {\n\t";
1693 buf
+= "unsigned long startMutations = *enumState.mutationsPtr;\n\t";
1694 buf
+= "do {\n\t\t";
1695 buf
+= "unsigned long counter = 0;\n\t\t";
1696 buf
+= "do {\n\t\t\t";
1697 buf
+= "if (startMutations != *enumState.mutationsPtr)\n\t\t\t\t";
1698 buf
+= "objc_enumerationMutation(l_collection);\n\t\t\t";
1701 buf
+= elementTypeAsString
;
1702 buf
+= ")enumState.itemsPtr[counter++];";
1703 // Replace ')' in for '(' type elem in collection ')' with all of these.
1704 ReplaceText(lparenLoc
, 1, buf
);
1706 /// __continue_label: ;
1707 /// } while (counter < limit);
1708 /// } while (limit = [l_collection countByEnumeratingWithState:&enumState
1709 /// objects:items count:16]);
1711 /// __break_label: ;
1718 buf
+= "__continue_label_";
1719 buf
+= utostr(ObjCBcLabelNo
.back());
1722 buf
+= "} while (counter < limit);\n\t";
1723 buf
+= "} while (limit = ";
1724 SynthCountByEnumWithState(buf
);
1728 buf
+= elementTypeAsString
;
1730 buf
+= "__break_label_";
1731 buf
+= utostr(ObjCBcLabelNo
.back());
1734 buf
+= "else\n\t\t";
1737 buf
+= elementTypeAsString
;
1741 // Insert all these *after* the statement body.
1742 // FIXME: If this should support Obj-C++, support CXXTryStmt
1743 if (isa
<CompoundStmt
>(S
->getBody())) {
1744 SourceLocation endBodyLoc
= OrigEnd
.getFileLocWithOffset(1);
1745 InsertText(endBodyLoc
, buf
);
1747 /* Need to treat single statements specially. For example:
1749 * for (A *a in b) if (stuff()) break;
1750 * for (A *a in b) xxxyy;
1752 * The following code simply scans ahead to the semi to find the actual end.
1754 const char *stmtBuf
= SM
->getCharacterData(OrigEnd
);
1755 const char *semiBuf
= strchr(stmtBuf
, ';');
1756 assert(semiBuf
&& "Can't find ';'");
1757 SourceLocation endBodyLoc
= OrigEnd
.getFileLocWithOffset(semiBuf
-stmtBuf
+1);
1758 InsertText(endBodyLoc
, buf
);
1761 ObjCBcLabelNo
.pop_back();
1765 /// RewriteObjCSynchronizedStmt -
1766 /// This routine rewrites @synchronized(expr) stmt;
1768 /// objc_sync_enter(expr);
1769 /// @try stmt @finally { objc_sync_exit(expr); }
1771 Stmt
*RewriteObjC::RewriteObjCSynchronizedStmt(ObjCAtSynchronizedStmt
*S
) {
1772 // Get the start location and compute the semi location.
1773 SourceLocation startLoc
= S
->getLocStart();
1774 const char *startBuf
= SM
->getCharacterData(startLoc
);
1776 assert((*startBuf
== '@') && "bogus @synchronized location");
1779 buf
= "objc_sync_enter((id)";
1780 const char *lparenBuf
= startBuf
;
1781 while (*lparenBuf
!= '(') lparenBuf
++;
1782 ReplaceText(startLoc
, lparenBuf
-startBuf
+1, buf
);
1783 // We can't use S->getSynchExpr()->getLocEnd() to find the end location, since
1784 // the sync expression is typically a message expression that's already
1785 // been rewritten! (which implies the SourceLocation's are invalid).
1786 SourceLocation endLoc
= S
->getSynchBody()->getLocStart();
1787 const char *endBuf
= SM
->getCharacterData(endLoc
);
1788 while (*endBuf
!= ')') endBuf
--;
1789 SourceLocation rparenLoc
= startLoc
.getFileLocWithOffset(endBuf
-startBuf
);
1791 // declare a new scope with two variables, _stack and _rethrow.
1792 buf
+= "/* @try scope begin */ \n{ struct _objc_exception_data {\n";
1793 buf
+= "int buf[18/*32-bit i386*/];\n";
1794 buf
+= "char *pointers[4];} _stack;\n";
1795 buf
+= "id volatile _rethrow = 0;\n";
1796 buf
+= "objc_exception_try_enter(&_stack);\n";
1797 buf
+= "if (!_setjmp(_stack.buf)) /* @try block continue */\n";
1798 ReplaceText(rparenLoc
, 1, buf
);
1799 startLoc
= S
->getSynchBody()->getLocEnd();
1800 startBuf
= SM
->getCharacterData(startLoc
);
1802 assert((*startBuf
== '}') && "bogus @synchronized block");
1803 SourceLocation lastCurlyLoc
= startLoc
;
1804 buf
= "}\nelse {\n";
1805 buf
+= " _rethrow = objc_exception_extract(&_stack);\n";
1807 buf
+= "{ /* implicit finally clause */\n";
1808 buf
+= " if (!_rethrow) objc_exception_try_exit(&_stack);\n";
1810 std::string syncBuf
;
1811 syncBuf
+= " objc_sync_exit(";
1812 Expr
*syncExpr
= NoTypeInfoCStyleCastExpr(Context
, Context
->getObjCIdType(),
1815 std::string syncExprBufS
;
1816 llvm::raw_string_ostream
syncExprBuf(syncExprBufS
);
1817 syncExpr
->printPretty(syncExprBuf
, *Context
, 0,
1818 PrintingPolicy(LangOpts
));
1819 syncBuf
+= syncExprBuf
.str();
1823 buf
+= "\n if (_rethrow) objc_exception_throw(_rethrow);\n";
1827 ReplaceText(lastCurlyLoc
, 1, buf
);
1829 bool hasReturns
= false;
1830 HasReturnStmts(S
->getSynchBody(), hasReturns
);
1832 RewriteSyncReturnStmts(S
->getSynchBody(), syncBuf
);
1837 void RewriteObjC::WarnAboutReturnGotoStmts(Stmt
*S
)
1839 // Perform a bottom up traversal of all children.
1840 for (Stmt::child_iterator CI
= S
->child_begin(), E
= S
->child_end();
1843 WarnAboutReturnGotoStmts(*CI
);
1845 if (isa
<ReturnStmt
>(S
) || isa
<GotoStmt
>(S
)) {
1846 Diags
.Report(Context
->getFullLoc(S
->getLocStart()),
1847 TryFinallyContainsReturnDiag
);
1852 void RewriteObjC::HasReturnStmts(Stmt
*S
, bool &hasReturns
)
1854 // Perform a bottom up traversal of all children.
1855 for (Stmt::child_iterator CI
= S
->child_begin(), E
= S
->child_end();
1858 HasReturnStmts(*CI
, hasReturns
);
1860 if (isa
<ReturnStmt
>(S
))
1865 void RewriteObjC::RewriteTryReturnStmts(Stmt
*S
) {
1866 // Perform a bottom up traversal of all children.
1867 for (Stmt::child_iterator CI
= S
->child_begin(), E
= S
->child_end();
1870 RewriteTryReturnStmts(*CI
);
1872 if (isa
<ReturnStmt
>(S
)) {
1873 SourceLocation startLoc
= S
->getLocStart();
1874 const char *startBuf
= SM
->getCharacterData(startLoc
);
1876 const char *semiBuf
= strchr(startBuf
, ';');
1877 assert((*semiBuf
== ';') && "RewriteTryReturnStmts: can't find ';'");
1878 SourceLocation onePastSemiLoc
= startLoc
.getFileLocWithOffset(semiBuf
-startBuf
+1);
1881 buf
= "{ objc_exception_try_exit(&_stack); return";
1883 ReplaceText(startLoc
, 6, buf
);
1884 InsertText(onePastSemiLoc
, "}");
1889 void RewriteObjC::RewriteSyncReturnStmts(Stmt
*S
, std::string syncExitBuf
) {
1890 // Perform a bottom up traversal of all children.
1891 for (Stmt::child_iterator CI
= S
->child_begin(), E
= S
->child_end();
1894 RewriteSyncReturnStmts(*CI
, syncExitBuf
);
1896 if (isa
<ReturnStmt
>(S
)) {
1897 SourceLocation startLoc
= S
->getLocStart();
1898 const char *startBuf
= SM
->getCharacterData(startLoc
);
1900 const char *semiBuf
= strchr(startBuf
, ';');
1901 assert((*semiBuf
== ';') && "RewriteSyncReturnStmts: can't find ';'");
1902 SourceLocation onePastSemiLoc
= startLoc
.getFileLocWithOffset(semiBuf
-startBuf
+1);
1905 buf
= "{ objc_exception_try_exit(&_stack);";
1909 ReplaceText(startLoc
, 6, buf
);
1910 InsertText(onePastSemiLoc
, "}");
1915 Stmt
*RewriteObjC::RewriteObjCTryStmt(ObjCAtTryStmt
*S
) {
1916 // Get the start location and compute the semi location.
1917 SourceLocation startLoc
= S
->getLocStart();
1918 const char *startBuf
= SM
->getCharacterData(startLoc
);
1920 assert((*startBuf
== '@') && "bogus @try location");
1923 // declare a new scope with two variables, _stack and _rethrow.
1924 buf
= "/* @try scope begin */ { struct _objc_exception_data {\n";
1925 buf
+= "int buf[18/*32-bit i386*/];\n";
1926 buf
+= "char *pointers[4];} _stack;\n";
1927 buf
+= "id volatile _rethrow = 0;\n";
1928 buf
+= "objc_exception_try_enter(&_stack);\n";
1929 buf
+= "if (!_setjmp(_stack.buf)) /* @try block continue */\n";
1931 ReplaceText(startLoc
, 4, buf
);
1933 startLoc
= S
->getTryBody()->getLocEnd();
1934 startBuf
= SM
->getCharacterData(startLoc
);
1936 assert((*startBuf
== '}') && "bogus @try block");
1938 SourceLocation lastCurlyLoc
= startLoc
;
1939 if (S
->getNumCatchStmts()) {
1940 startLoc
= startLoc
.getFileLocWithOffset(1);
1941 buf
= " /* @catch begin */ else {\n";
1942 buf
+= " id _caught = objc_exception_extract(&_stack);\n";
1943 buf
+= " objc_exception_try_enter (&_stack);\n";
1944 buf
+= " if (_setjmp(_stack.buf))\n";
1945 buf
+= " _rethrow = objc_exception_extract(&_stack);\n";
1946 buf
+= " else { /* @catch continue */";
1948 InsertText(startLoc
, buf
);
1949 } else { /* no catch list */
1950 buf
= "}\nelse {\n";
1951 buf
+= " _rethrow = objc_exception_extract(&_stack);\n";
1953 ReplaceText(lastCurlyLoc
, 1, buf
);
1955 Stmt
*lastCatchBody
= 0;
1956 for (unsigned I
= 0, N
= S
->getNumCatchStmts(); I
!= N
; ++I
) {
1957 ObjCAtCatchStmt
*Catch
= S
->getCatchStmt(I
);
1958 VarDecl
*catchDecl
= Catch
->getCatchParamDecl();
1961 buf
= "if ("; // we are generating code for the first catch clause
1964 startLoc
= Catch
->getLocStart();
1965 startBuf
= SM
->getCharacterData(startLoc
);
1967 assert((*startBuf
== '@') && "bogus @catch location");
1969 const char *lParenLoc
= strchr(startBuf
, '(');
1971 if (Catch
->hasEllipsis()) {
1972 // Now rewrite the body...
1973 lastCatchBody
= Catch
->getCatchBody();
1974 SourceLocation bodyLoc
= lastCatchBody
->getLocStart();
1975 const char *bodyBuf
= SM
->getCharacterData(bodyLoc
);
1976 assert(*SM
->getCharacterData(Catch
->getRParenLoc()) == ')' &&
1977 "bogus @catch paren location");
1978 assert((*bodyBuf
== '{') && "bogus @catch body location");
1980 buf
+= "1) { id _tmp = _caught;";
1981 Rewrite
.ReplaceText(startLoc
, bodyBuf
-startBuf
+1, buf
);
1982 } else if (catchDecl
) {
1983 QualType t
= catchDecl
->getType();
1984 if (t
== Context
->getObjCIdType()) {
1986 ReplaceText(startLoc
, lParenLoc
-startBuf
+1, buf
);
1987 } else if (const ObjCObjectPointerType
*Ptr
=
1988 t
->getAs
<ObjCObjectPointerType
>()) {
1989 // Should be a pointer to a class.
1990 ObjCInterfaceDecl
*IDecl
= Ptr
->getObjectType()->getInterface();
1992 buf
+= "objc_exception_match((struct objc_class *)objc_getClass(\"";
1993 buf
+= IDecl
->getNameAsString();
1994 buf
+= "\"), (struct objc_object *)_caught)) { ";
1995 ReplaceText(startLoc
, lParenLoc
-startBuf
+1, buf
);
1998 // Now rewrite the body...
1999 lastCatchBody
= Catch
->getCatchBody();
2000 SourceLocation rParenLoc
= Catch
->getRParenLoc();
2001 SourceLocation bodyLoc
= lastCatchBody
->getLocStart();
2002 const char *bodyBuf
= SM
->getCharacterData(bodyLoc
);
2003 const char *rParenBuf
= SM
->getCharacterData(rParenLoc
);
2004 assert((*rParenBuf
== ')') && "bogus @catch paren location");
2005 assert((*bodyBuf
== '{') && "bogus @catch body location");
2007 // Here we replace ") {" with "= _caught;" (which initializes and
2008 // declares the @catch parameter).
2009 ReplaceText(rParenLoc
, bodyBuf
-rParenBuf
+1, " = _caught;");
2011 assert(false && "@catch rewrite bug");
2014 // Complete the catch list...
2015 if (lastCatchBody
) {
2016 SourceLocation bodyLoc
= lastCatchBody
->getLocEnd();
2017 assert(*SM
->getCharacterData(bodyLoc
) == '}' &&
2018 "bogus @catch body location");
2020 // Insert the last (implicit) else clause *before* the right curly brace.
2021 bodyLoc
= bodyLoc
.getFileLocWithOffset(-1);
2022 buf
= "} /* last catch end */\n";
2024 buf
+= " _rethrow = _caught;\n";
2025 buf
+= " objc_exception_try_exit(&_stack);\n";
2026 buf
+= "} } /* @catch end */\n";
2027 if (!S
->getFinallyStmt())
2029 InsertText(bodyLoc
, buf
);
2032 lastCurlyLoc
= lastCatchBody
->getLocEnd();
2034 if (ObjCAtFinallyStmt
*finalStmt
= S
->getFinallyStmt()) {
2035 startLoc
= finalStmt
->getLocStart();
2036 startBuf
= SM
->getCharacterData(startLoc
);
2037 assert((*startBuf
== '@') && "bogus @finally start");
2039 ReplaceText(startLoc
, 8, "/* @finally */");
2041 Stmt
*body
= finalStmt
->getFinallyBody();
2042 SourceLocation startLoc
= body
->getLocStart();
2043 SourceLocation endLoc
= body
->getLocEnd();
2044 assert(*SM
->getCharacterData(startLoc
) == '{' &&
2045 "bogus @finally body location");
2046 assert(*SM
->getCharacterData(endLoc
) == '}' &&
2047 "bogus @finally body location");
2049 startLoc
= startLoc
.getFileLocWithOffset(1);
2050 InsertText(startLoc
, " if (!_rethrow) objc_exception_try_exit(&_stack);\n");
2051 endLoc
= endLoc
.getFileLocWithOffset(-1);
2052 InsertText(endLoc
, " if (_rethrow) objc_exception_throw(_rethrow);\n");
2055 lastCurlyLoc
= body
->getLocEnd();
2057 // Now check for any return/continue/go statements within the @try.
2058 WarnAboutReturnGotoStmts(S
->getTryBody());
2059 } else { /* no finally clause - make sure we synthesize an implicit one */
2060 buf
= "{ /* implicit finally clause */\n";
2061 buf
+= " if (!_rethrow) objc_exception_try_exit(&_stack);\n";
2062 buf
+= " if (_rethrow) objc_exception_throw(_rethrow);\n";
2064 ReplaceText(lastCurlyLoc
, 1, buf
);
2066 // Now check for any return/continue/go statements within the @try.
2067 // The implicit finally clause won't called if the @try contains any
2069 bool hasReturns
= false;
2070 HasReturnStmts(S
->getTryBody(), hasReturns
);
2072 RewriteTryReturnStmts(S
->getTryBody());
2074 // Now emit the final closing curly brace...
2075 lastCurlyLoc
= lastCurlyLoc
.getFileLocWithOffset(1);
2076 InsertText(lastCurlyLoc
, " } /* @try scope end */\n");
2080 // This can't be done with ReplaceStmt(S, ThrowExpr), since
2081 // the throw expression is typically a message expression that's already
2082 // been rewritten! (which implies the SourceLocation's are invalid).
2083 Stmt
*RewriteObjC::RewriteObjCThrowStmt(ObjCAtThrowStmt
*S
) {
2084 // Get the start location and compute the semi location.
2085 SourceLocation startLoc
= S
->getLocStart();
2086 const char *startBuf
= SM
->getCharacterData(startLoc
);
2088 assert((*startBuf
== '@') && "bogus @throw location");
2091 /* void objc_exception_throw(id) __attribute__((noreturn)); */
2092 if (S
->getThrowExpr())
2093 buf
= "objc_exception_throw(";
2094 else // add an implicit argument
2095 buf
= "objc_exception_throw(_caught";
2097 // handle "@ throw" correctly.
2098 const char *wBuf
= strchr(startBuf
, 'w');
2099 assert((*wBuf
== 'w') && "@throw: can't find 'w'");
2100 ReplaceText(startLoc
, wBuf
-startBuf
+1, buf
);
2102 const char *semiBuf
= strchr(startBuf
, ';');
2103 assert((*semiBuf
== ';') && "@throw: can't find ';'");
2104 SourceLocation semiLoc
= startLoc
.getFileLocWithOffset(semiBuf
-startBuf
);
2105 ReplaceText(semiLoc
, 1, ");");
2109 Stmt
*RewriteObjC::RewriteAtEncode(ObjCEncodeExpr
*Exp
) {
2110 // Create a new string expression.
2111 QualType StrType
= Context
->getPointerType(Context
->CharTy
);
2112 std::string StrEncoding
;
2113 Context
->getObjCEncodingForType(Exp
->getEncodedType(), StrEncoding
);
2114 Expr
*Replacement
= StringLiteral::Create(*Context
,StrEncoding
.c_str(),
2115 StrEncoding
.length(), false,StrType
,
2117 ReplaceStmt(Exp
, Replacement
);
2119 // Replace this subexpr in the parent.
2120 // delete Exp; leak for now, see RewritePropertyOrImplicitSetter() usage for more info.
2124 Stmt
*RewriteObjC::RewriteAtSelector(ObjCSelectorExpr
*Exp
) {
2125 if (!SelGetUidFunctionDecl
)
2126 SynthSelGetUidFunctionDecl();
2127 assert(SelGetUidFunctionDecl
&& "Can't find sel_registerName() decl");
2128 // Create a call to sel_registerName("selName").
2129 llvm::SmallVector
<Expr
*, 8> SelExprs
;
2130 QualType argType
= Context
->getPointerType(Context
->CharTy
);
2131 SelExprs
.push_back(StringLiteral::Create(*Context
,
2132 Exp
->getSelector().getAsString().c_str(),
2133 Exp
->getSelector().getAsString().size(),
2134 false, argType
, SourceLocation()));
2135 CallExpr
*SelExp
= SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl
,
2136 &SelExprs
[0], SelExprs
.size());
2137 ReplaceStmt(Exp
, SelExp
);
2138 // delete Exp; leak for now, see RewritePropertyOrImplicitSetter() usage for more info.
2142 CallExpr
*RewriteObjC::SynthesizeCallToFunctionDecl(
2143 FunctionDecl
*FD
, Expr
**args
, unsigned nargs
, SourceLocation StartLoc
,
2144 SourceLocation EndLoc
) {
2145 // Get the type, we will need to reference it in a couple spots.
2146 QualType msgSendType
= FD
->getType();
2148 // Create a reference to the objc_msgSend() declaration.
2150 new (Context
) DeclRefExpr(FD
, msgSendType
, VK_LValue
, SourceLocation());
2152 // Now, we cast the reference to a pointer to the objc_msgSend type.
2153 QualType pToFunc
= Context
->getPointerType(msgSendType
);
2154 ImplicitCastExpr
*ICE
=
2155 ImplicitCastExpr::Create(*Context
, pToFunc
, CK_FunctionToPointerDecay
,
2158 const FunctionType
*FT
= msgSendType
->getAs
<FunctionType
>();
2161 new (Context
) CallExpr(*Context
, ICE
, args
, nargs
,
2162 FT
->getCallResultType(*Context
),
2167 static bool scanForProtocolRefs(const char *startBuf
, const char *endBuf
,
2168 const char *&startRef
, const char *&endRef
) {
2169 while (startBuf
< endBuf
) {
2170 if (*startBuf
== '<')
2171 startRef
= startBuf
; // mark the start.
2172 if (*startBuf
== '>') {
2173 if (startRef
&& *startRef
== '<') {
2174 endRef
= startBuf
; // mark the end.
2184 static void scanToNextArgument(const char *&argRef
) {
2186 while (*argRef
!= ')' && (*argRef
!= ',' || angle
> 0)) {
2189 else if (*argRef
== '>')
2193 assert(angle
== 0 && "scanToNextArgument - bad protocol type syntax");
2196 bool RewriteObjC::needToScanForQualifiers(QualType T
) {
2197 if (T
->isObjCQualifiedIdType())
2199 if (const PointerType
*PT
= T
->getAs
<PointerType
>()) {
2200 if (PT
->getPointeeType()->isObjCQualifiedIdType())
2203 if (T
->isObjCObjectPointerType()) {
2204 T
= T
->getPointeeType();
2205 return T
->isObjCQualifiedInterfaceType();
2207 if (T
->isArrayType()) {
2208 QualType ElemTy
= Context
->getBaseElementType(T
);
2209 return needToScanForQualifiers(ElemTy
);
2214 void RewriteObjC::RewriteObjCQualifiedInterfaceTypes(Expr
*E
) {
2215 QualType Type
= E
->getType();
2216 if (needToScanForQualifiers(Type
)) {
2217 SourceLocation Loc
, EndLoc
;
2219 if (const CStyleCastExpr
*ECE
= dyn_cast
<CStyleCastExpr
>(E
)) {
2220 Loc
= ECE
->getLParenLoc();
2221 EndLoc
= ECE
->getRParenLoc();
2223 Loc
= E
->getLocStart();
2224 EndLoc
= E
->getLocEnd();
2226 // This will defend against trying to rewrite synthesized expressions.
2227 if (Loc
.isInvalid() || EndLoc
.isInvalid())
2230 const char *startBuf
= SM
->getCharacterData(Loc
);
2231 const char *endBuf
= SM
->getCharacterData(EndLoc
);
2232 const char *startRef
= 0, *endRef
= 0;
2233 if (scanForProtocolRefs(startBuf
, endBuf
, startRef
, endRef
)) {
2234 // Get the locations of the startRef, endRef.
2235 SourceLocation LessLoc
= Loc
.getFileLocWithOffset(startRef
-startBuf
);
2236 SourceLocation GreaterLoc
= Loc
.getFileLocWithOffset(endRef
-startBuf
+1);
2237 // Comment out the protocol references.
2238 InsertText(LessLoc
, "/*");
2239 InsertText(GreaterLoc
, "*/");
2244 void RewriteObjC::RewriteObjCQualifiedInterfaceTypes(Decl
*Dcl
) {
2247 const FunctionProtoType
*proto
= 0;
2248 if (VarDecl
*VD
= dyn_cast
<VarDecl
>(Dcl
)) {
2249 Loc
= VD
->getLocation();
2250 Type
= VD
->getType();
2252 else if (FunctionDecl
*FD
= dyn_cast
<FunctionDecl
>(Dcl
)) {
2253 Loc
= FD
->getLocation();
2254 // Check for ObjC 'id' and class types that have been adorned with protocol
2255 // information (id<p>, C<p>*). The protocol references need to be rewritten!
2256 const FunctionType
*funcType
= FD
->getType()->getAs
<FunctionType
>();
2257 assert(funcType
&& "missing function type");
2258 proto
= dyn_cast
<FunctionProtoType
>(funcType
);
2261 Type
= proto
->getResultType();
2263 else if (FieldDecl
*FD
= dyn_cast
<FieldDecl
>(Dcl
)) {
2264 Loc
= FD
->getLocation();
2265 Type
= FD
->getType();
2270 if (needToScanForQualifiers(Type
)) {
2271 // Since types are unique, we need to scan the buffer.
2273 const char *endBuf
= SM
->getCharacterData(Loc
);
2274 const char *startBuf
= endBuf
;
2275 while (*startBuf
!= ';' && *startBuf
!= '<' && startBuf
!= MainFileStart
)
2276 startBuf
--; // scan backward (from the decl location) for return type.
2277 const char *startRef
= 0, *endRef
= 0;
2278 if (scanForProtocolRefs(startBuf
, endBuf
, startRef
, endRef
)) {
2279 // Get the locations of the startRef, endRef.
2280 SourceLocation LessLoc
= Loc
.getFileLocWithOffset(startRef
-endBuf
);
2281 SourceLocation GreaterLoc
= Loc
.getFileLocWithOffset(endRef
-endBuf
+1);
2282 // Comment out the protocol references.
2283 InsertText(LessLoc
, "/*");
2284 InsertText(GreaterLoc
, "*/");
2288 return; // most likely, was a variable
2289 // Now check arguments.
2290 const char *startBuf
= SM
->getCharacterData(Loc
);
2291 const char *startFuncBuf
= startBuf
;
2292 for (unsigned i
= 0; i
< proto
->getNumArgs(); i
++) {
2293 if (needToScanForQualifiers(proto
->getArgType(i
))) {
2294 // Since types are unique, we need to scan the buffer.
2296 const char *endBuf
= startBuf
;
2297 // scan forward (from the decl location) for argument types.
2298 scanToNextArgument(endBuf
);
2299 const char *startRef
= 0, *endRef
= 0;
2300 if (scanForProtocolRefs(startBuf
, endBuf
, startRef
, endRef
)) {
2301 // Get the locations of the startRef, endRef.
2302 SourceLocation LessLoc
=
2303 Loc
.getFileLocWithOffset(startRef
-startFuncBuf
);
2304 SourceLocation GreaterLoc
=
2305 Loc
.getFileLocWithOffset(endRef
-startFuncBuf
+1);
2306 // Comment out the protocol references.
2307 InsertText(LessLoc
, "/*");
2308 InsertText(GreaterLoc
, "*/");
2310 startBuf
= ++endBuf
;
2313 // If the function name is derived from a macro expansion, then the
2314 // argument buffer will not follow the name. Need to speak with Chris.
2315 while (*startBuf
&& *startBuf
!= ')' && *startBuf
!= ',')
2316 startBuf
++; // scan forward (from the decl location) for argument types.
2322 void RewriteObjC::RewriteTypeOfDecl(VarDecl
*ND
) {
2323 QualType QT
= ND
->getType();
2324 const Type
* TypePtr
= QT
->getAs
<Type
>();
2325 if (!isa
<TypeOfExprType
>(TypePtr
))
2327 while (isa
<TypeOfExprType
>(TypePtr
)) {
2328 const TypeOfExprType
*TypeOfExprTypePtr
= cast
<TypeOfExprType
>(TypePtr
);
2329 QT
= TypeOfExprTypePtr
->getUnderlyingExpr()->getType();
2330 TypePtr
= QT
->getAs
<Type
>();
2332 // FIXME. This will not work for multiple declarators; as in:
2333 // __typeof__(a) b,c,d;
2334 std::string
TypeAsString(QT
.getAsString(Context
->PrintingPolicy
));
2335 SourceLocation DeclLoc
= ND
->getTypeSpecStartLoc();
2336 const char *startBuf
= SM
->getCharacterData(DeclLoc
);
2337 if (ND
->getInit()) {
2338 std::string
Name(ND
->getNameAsString());
2339 TypeAsString
+= " " + Name
+ " = ";
2340 Expr
*E
= ND
->getInit();
2341 SourceLocation startLoc
;
2342 if (const CStyleCastExpr
*ECE
= dyn_cast
<CStyleCastExpr
>(E
))
2343 startLoc
= ECE
->getLParenLoc();
2345 startLoc
= E
->getLocStart();
2346 startLoc
= SM
->getInstantiationLoc(startLoc
);
2347 const char *endBuf
= SM
->getCharacterData(startLoc
);
2348 ReplaceText(DeclLoc
, endBuf
-startBuf
-1, TypeAsString
);
2351 SourceLocation X
= ND
->getLocEnd();
2352 X
= SM
->getInstantiationLoc(X
);
2353 const char *endBuf
= SM
->getCharacterData(X
);
2354 ReplaceText(DeclLoc
, endBuf
-startBuf
-1, TypeAsString
);
2358 // SynthSelGetUidFunctionDecl - SEL sel_registerName(const char *str);
2359 void RewriteObjC::SynthSelGetUidFunctionDecl() {
2360 IdentifierInfo
*SelGetUidIdent
= &Context
->Idents
.get("sel_registerName");
2361 llvm::SmallVector
<QualType
, 16> ArgTys
;
2362 ArgTys
.push_back(Context
->getPointerType(Context
->CharTy
.withConst()));
2363 QualType getFuncType
=
2364 getSimpleFunctionType(Context
->getObjCSelType(), &ArgTys
[0], ArgTys
.size());
2365 SelGetUidFunctionDecl
= FunctionDecl::Create(*Context
, TUDecl
,
2367 SelGetUidIdent
, getFuncType
, 0,
2372 void RewriteObjC::RewriteFunctionDecl(FunctionDecl
*FD
) {
2373 // declared in <objc/objc.h>
2374 if (FD
->getIdentifier() &&
2375 FD
->getName() == "sel_registerName") {
2376 SelGetUidFunctionDecl
= FD
;
2379 RewriteObjCQualifiedInterfaceTypes(FD
);
2382 void RewriteObjC::RewriteBlockPointerType(std::string
& Str
, QualType Type
) {
2383 std::string
TypeString(Type
.getAsString(Context
->PrintingPolicy
));
2384 const char *argPtr
= TypeString
.c_str();
2385 if (!strchr(argPtr
, '^')) {
2390 Str
+= (*argPtr
== '^' ? '*' : *argPtr
);
2395 // FIXME. Consolidate this routine with RewriteBlockPointerType.
2396 void RewriteObjC::RewriteBlockPointerTypeVariable(std::string
& Str
,
2398 QualType Type
= VD
->getType();
2399 std::string
TypeString(Type
.getAsString(Context
->PrintingPolicy
));
2400 const char *argPtr
= TypeString
.c_str();
2415 Str
+= VD
->getNameAsString();
2426 void RewriteObjC::RewriteBlockLiteralFunctionDecl(FunctionDecl
*FD
) {
2427 SourceLocation FunLocStart
= FD
->getTypeSpecStartLoc();
2428 const FunctionType
*funcType
= FD
->getType()->getAs
<FunctionType
>();
2429 const FunctionProtoType
*proto
= dyn_cast
<FunctionProtoType
>(funcType
);
2432 QualType Type
= proto
->getResultType();
2433 std::string FdStr
= Type
.getAsString(Context
->PrintingPolicy
);
2435 FdStr
+= FD
->getName();
2437 unsigned numArgs
= proto
->getNumArgs();
2438 for (unsigned i
= 0; i
< numArgs
; i
++) {
2439 QualType ArgType
= proto
->getArgType(i
);
2440 RewriteBlockPointerType(FdStr
, ArgType
);
2445 InsertText(FunLocStart
, FdStr
);
2446 CurFunctionDeclToDeclareForBlock
= 0;
2449 // SynthSuperContructorFunctionDecl - id objc_super(id obj, id super);
2450 void RewriteObjC::SynthSuperContructorFunctionDecl() {
2451 if (SuperContructorFunctionDecl
)
2453 IdentifierInfo
*msgSendIdent
= &Context
->Idents
.get("__rw_objc_super");
2454 llvm::SmallVector
<QualType
, 16> ArgTys
;
2455 QualType argT
= Context
->getObjCIdType();
2456 assert(!argT
.isNull() && "Can't find 'id' type");
2457 ArgTys
.push_back(argT
);
2458 ArgTys
.push_back(argT
);
2459 QualType msgSendType
= getSimpleFunctionType(Context
->getObjCIdType(),
2460 &ArgTys
[0], ArgTys
.size());
2461 SuperContructorFunctionDecl
= FunctionDecl::Create(*Context
, TUDecl
,
2463 msgSendIdent
, msgSendType
, 0,
2468 // SynthMsgSendFunctionDecl - id objc_msgSend(id self, SEL op, ...);
2469 void RewriteObjC::SynthMsgSendFunctionDecl() {
2470 IdentifierInfo
*msgSendIdent
= &Context
->Idents
.get("objc_msgSend");
2471 llvm::SmallVector
<QualType
, 16> ArgTys
;
2472 QualType argT
= Context
->getObjCIdType();
2473 assert(!argT
.isNull() && "Can't find 'id' type");
2474 ArgTys
.push_back(argT
);
2475 argT
= Context
->getObjCSelType();
2476 assert(!argT
.isNull() && "Can't find 'SEL' type");
2477 ArgTys
.push_back(argT
);
2478 QualType msgSendType
= getSimpleFunctionType(Context
->getObjCIdType(),
2479 &ArgTys
[0], ArgTys
.size(),
2480 true /*isVariadic*/);
2481 MsgSendFunctionDecl
= FunctionDecl::Create(*Context
, TUDecl
,
2483 msgSendIdent
, msgSendType
, 0,
2488 // SynthMsgSendSuperFunctionDecl - id objc_msgSendSuper(struct objc_super *, SEL op, ...);
2489 void RewriteObjC::SynthMsgSendSuperFunctionDecl() {
2490 IdentifierInfo
*msgSendIdent
= &Context
->Idents
.get("objc_msgSendSuper");
2491 llvm::SmallVector
<QualType
, 16> ArgTys
;
2492 RecordDecl
*RD
= RecordDecl::Create(*Context
, TTK_Struct
, TUDecl
,
2494 &Context
->Idents
.get("objc_super"));
2495 QualType argT
= Context
->getPointerType(Context
->getTagDeclType(RD
));
2496 assert(!argT
.isNull() && "Can't build 'struct objc_super *' type");
2497 ArgTys
.push_back(argT
);
2498 argT
= Context
->getObjCSelType();
2499 assert(!argT
.isNull() && "Can't find 'SEL' type");
2500 ArgTys
.push_back(argT
);
2501 QualType msgSendType
= getSimpleFunctionType(Context
->getObjCIdType(),
2502 &ArgTys
[0], ArgTys
.size(),
2503 true /*isVariadic*/);
2504 MsgSendSuperFunctionDecl
= FunctionDecl::Create(*Context
, TUDecl
,
2506 msgSendIdent
, msgSendType
, 0,
2511 // SynthMsgSendStretFunctionDecl - id objc_msgSend_stret(id self, SEL op, ...);
2512 void RewriteObjC::SynthMsgSendStretFunctionDecl() {
2513 IdentifierInfo
*msgSendIdent
= &Context
->Idents
.get("objc_msgSend_stret");
2514 llvm::SmallVector
<QualType
, 16> ArgTys
;
2515 QualType argT
= Context
->getObjCIdType();
2516 assert(!argT
.isNull() && "Can't find 'id' type");
2517 ArgTys
.push_back(argT
);
2518 argT
= Context
->getObjCSelType();
2519 assert(!argT
.isNull() && "Can't find 'SEL' type");
2520 ArgTys
.push_back(argT
);
2521 QualType msgSendType
= getSimpleFunctionType(Context
->getObjCIdType(),
2522 &ArgTys
[0], ArgTys
.size(),
2523 true /*isVariadic*/);
2524 MsgSendStretFunctionDecl
= FunctionDecl::Create(*Context
, TUDecl
,
2526 msgSendIdent
, msgSendType
, 0,
2531 // SynthMsgSendSuperStretFunctionDecl -
2532 // id objc_msgSendSuper_stret(struct objc_super *, SEL op, ...);
2533 void RewriteObjC::SynthMsgSendSuperStretFunctionDecl() {
2534 IdentifierInfo
*msgSendIdent
=
2535 &Context
->Idents
.get("objc_msgSendSuper_stret");
2536 llvm::SmallVector
<QualType
, 16> ArgTys
;
2537 RecordDecl
*RD
= RecordDecl::Create(*Context
, TTK_Struct
, TUDecl
,
2539 &Context
->Idents
.get("objc_super"));
2540 QualType argT
= Context
->getPointerType(Context
->getTagDeclType(RD
));
2541 assert(!argT
.isNull() && "Can't build 'struct objc_super *' type");
2542 ArgTys
.push_back(argT
);
2543 argT
= Context
->getObjCSelType();
2544 assert(!argT
.isNull() && "Can't find 'SEL' type");
2545 ArgTys
.push_back(argT
);
2546 QualType msgSendType
= getSimpleFunctionType(Context
->getObjCIdType(),
2547 &ArgTys
[0], ArgTys
.size(),
2548 true /*isVariadic*/);
2549 MsgSendSuperStretFunctionDecl
= FunctionDecl::Create(*Context
, TUDecl
,
2551 msgSendIdent
, msgSendType
, 0,
2556 // SynthMsgSendFpretFunctionDecl - double objc_msgSend_fpret(id self, SEL op, ...);
2557 void RewriteObjC::SynthMsgSendFpretFunctionDecl() {
2558 IdentifierInfo
*msgSendIdent
= &Context
->Idents
.get("objc_msgSend_fpret");
2559 llvm::SmallVector
<QualType
, 16> ArgTys
;
2560 QualType argT
= Context
->getObjCIdType();
2561 assert(!argT
.isNull() && "Can't find 'id' type");
2562 ArgTys
.push_back(argT
);
2563 argT
= Context
->getObjCSelType();
2564 assert(!argT
.isNull() && "Can't find 'SEL' type");
2565 ArgTys
.push_back(argT
);
2566 QualType msgSendType
= getSimpleFunctionType(Context
->DoubleTy
,
2567 &ArgTys
[0], ArgTys
.size(),
2568 true /*isVariadic*/);
2569 MsgSendFpretFunctionDecl
= FunctionDecl::Create(*Context
, TUDecl
,
2571 msgSendIdent
, msgSendType
, 0,
2576 // SynthGetClassFunctionDecl - id objc_getClass(const char *name);
2577 void RewriteObjC::SynthGetClassFunctionDecl() {
2578 IdentifierInfo
*getClassIdent
= &Context
->Idents
.get("objc_getClass");
2579 llvm::SmallVector
<QualType
, 16> ArgTys
;
2580 ArgTys
.push_back(Context
->getPointerType(Context
->CharTy
.withConst()));
2581 QualType getClassType
= getSimpleFunctionType(Context
->getObjCIdType(),
2582 &ArgTys
[0], ArgTys
.size());
2583 GetClassFunctionDecl
= FunctionDecl::Create(*Context
, TUDecl
,
2585 getClassIdent
, getClassType
, 0,
2590 // SynthGetSuperClassFunctionDecl - Class class_getSuperclass(Class cls);
2591 void RewriteObjC::SynthGetSuperClassFunctionDecl() {
2592 IdentifierInfo
*getSuperClassIdent
=
2593 &Context
->Idents
.get("class_getSuperclass");
2594 llvm::SmallVector
<QualType
, 16> ArgTys
;
2595 ArgTys
.push_back(Context
->getObjCClassType());
2596 QualType getClassType
= getSimpleFunctionType(Context
->getObjCClassType(),
2597 &ArgTys
[0], ArgTys
.size());
2598 GetSuperClassFunctionDecl
= FunctionDecl::Create(*Context
, TUDecl
,
2607 // SynthGetMetaClassFunctionDecl - id objc_getClass(const char *name);
2608 void RewriteObjC::SynthGetMetaClassFunctionDecl() {
2609 IdentifierInfo
*getClassIdent
= &Context
->Idents
.get("objc_getMetaClass");
2610 llvm::SmallVector
<QualType
, 16> ArgTys
;
2611 ArgTys
.push_back(Context
->getPointerType(Context
->CharTy
.withConst()));
2612 QualType getClassType
= getSimpleFunctionType(Context
->getObjCIdType(),
2613 &ArgTys
[0], ArgTys
.size());
2614 GetMetaClassFunctionDecl
= FunctionDecl::Create(*Context
, TUDecl
,
2616 getClassIdent
, getClassType
, 0,
2621 Stmt
*RewriteObjC::RewriteObjCStringLiteral(ObjCStringLiteral
*Exp
) {
2622 QualType strType
= getConstantStringStructType();
2624 std::string S
= "__NSConstantStringImpl_";
2626 std::string tmpName
= InFileName
;
2628 for (i
=0; i
< tmpName
.length(); i
++) {
2629 char c
= tmpName
.at(i
);
2630 // replace any non alphanumeric characters with '_'.
2631 if (!isalpha(c
) && (c
< '0' || c
> '9'))
2636 S
+= utostr(NumObjCStringLiterals
++);
2638 Preamble
+= "static __NSConstantStringImpl " + S
;
2639 Preamble
+= " __attribute__ ((section (\"__DATA, __cfstring\"))) = {__CFConstantStringClassReference,";
2640 Preamble
+= "0x000007c8,"; // utf8_str
2641 // The pretty printer for StringLiteral handles escape characters properly.
2642 std::string prettyBufS
;
2643 llvm::raw_string_ostream
prettyBuf(prettyBufS
);
2644 Exp
->getString()->printPretty(prettyBuf
, *Context
, 0,
2645 PrintingPolicy(LangOpts
));
2646 Preamble
+= prettyBuf
.str();
2648 Preamble
+= utostr(Exp
->getString()->getByteLength()) + "};\n";
2650 VarDecl
*NewVD
= VarDecl::Create(*Context
, TUDecl
, SourceLocation(),
2651 &Context
->Idents
.get(S
), strType
, 0,
2652 SC_Static
, SC_None
);
2653 DeclRefExpr
*DRE
= new (Context
) DeclRefExpr(NewVD
, strType
, VK_LValue
,
2655 Expr
*Unop
= new (Context
) UnaryOperator(DRE
, UO_AddrOf
,
2656 Context
->getPointerType(DRE
->getType()),
2657 VK_RValue
, OK_Ordinary
,
2659 // cast to NSConstantString *
2660 CastExpr
*cast
= NoTypeInfoCStyleCastExpr(Context
, Exp
->getType(),
2662 ReplaceStmt(Exp
, cast
);
2663 // delete Exp; leak for now, see RewritePropertyOrImplicitSetter() usage for more info.
2667 // struct objc_super { struct objc_object *receiver; struct objc_class *super; };
2668 QualType
RewriteObjC::getSuperStructType() {
2669 if (!SuperStructDecl
) {
2670 SuperStructDecl
= RecordDecl::Create(*Context
, TTK_Struct
, TUDecl
,
2672 &Context
->Idents
.get("objc_super"));
2673 QualType FieldTypes
[2];
2675 // struct objc_object *receiver;
2676 FieldTypes
[0] = Context
->getObjCIdType();
2677 // struct objc_class *super;
2678 FieldTypes
[1] = Context
->getObjCClassType();
2681 for (unsigned i
= 0; i
< 2; ++i
) {
2682 SuperStructDecl
->addDecl(FieldDecl::Create(*Context
, SuperStructDecl
,
2683 SourceLocation(), 0,
2686 /*Mutable=*/false));
2689 SuperStructDecl
->completeDefinition();
2691 return Context
->getTagDeclType(SuperStructDecl
);
2694 QualType
RewriteObjC::getConstantStringStructType() {
2695 if (!ConstantStringDecl
) {
2696 ConstantStringDecl
= RecordDecl::Create(*Context
, TTK_Struct
, TUDecl
,
2698 &Context
->Idents
.get("__NSConstantStringImpl"));
2699 QualType FieldTypes
[4];
2701 // struct objc_object *receiver;
2702 FieldTypes
[0] = Context
->getObjCIdType();
2704 FieldTypes
[1] = Context
->IntTy
;
2706 FieldTypes
[2] = Context
->getPointerType(Context
->CharTy
);
2708 FieldTypes
[3] = Context
->LongTy
;
2711 for (unsigned i
= 0; i
< 4; ++i
) {
2712 ConstantStringDecl
->addDecl(FieldDecl::Create(*Context
,
2714 SourceLocation(), 0,
2720 ConstantStringDecl
->completeDefinition();
2722 return Context
->getTagDeclType(ConstantStringDecl
);
2725 Stmt
*RewriteObjC::SynthMessageExpr(ObjCMessageExpr
*Exp
,
2726 SourceLocation StartLoc
,
2727 SourceLocation EndLoc
) {
2728 if (!SelGetUidFunctionDecl
)
2729 SynthSelGetUidFunctionDecl();
2730 if (!MsgSendFunctionDecl
)
2731 SynthMsgSendFunctionDecl();
2732 if (!MsgSendSuperFunctionDecl
)
2733 SynthMsgSendSuperFunctionDecl();
2734 if (!MsgSendStretFunctionDecl
)
2735 SynthMsgSendStretFunctionDecl();
2736 if (!MsgSendSuperStretFunctionDecl
)
2737 SynthMsgSendSuperStretFunctionDecl();
2738 if (!MsgSendFpretFunctionDecl
)
2739 SynthMsgSendFpretFunctionDecl();
2740 if (!GetClassFunctionDecl
)
2741 SynthGetClassFunctionDecl();
2742 if (!GetSuperClassFunctionDecl
)
2743 SynthGetSuperClassFunctionDecl();
2744 if (!GetMetaClassFunctionDecl
)
2745 SynthGetMetaClassFunctionDecl();
2747 // default to objc_msgSend().
2748 FunctionDecl
*MsgSendFlavor
= MsgSendFunctionDecl
;
2749 // May need to use objc_msgSend_stret() as well.
2750 FunctionDecl
*MsgSendStretFlavor
= 0;
2751 if (ObjCMethodDecl
*mDecl
= Exp
->getMethodDecl()) {
2752 QualType resultType
= mDecl
->getResultType();
2753 if (resultType
->isRecordType())
2754 MsgSendStretFlavor
= MsgSendStretFunctionDecl
;
2755 else if (resultType
->isRealFloatingType())
2756 MsgSendFlavor
= MsgSendFpretFunctionDecl
;
2759 // Synthesize a call to objc_msgSend().
2760 llvm::SmallVector
<Expr
*, 8> MsgExprs
;
2761 switch (Exp
->getReceiverKind()) {
2762 case ObjCMessageExpr::SuperClass
: {
2763 MsgSendFlavor
= MsgSendSuperFunctionDecl
;
2764 if (MsgSendStretFlavor
)
2765 MsgSendStretFlavor
= MsgSendSuperStretFunctionDecl
;
2766 assert(MsgSendFlavor
&& "MsgSendFlavor is NULL!");
2768 ObjCInterfaceDecl
*ClassDecl
= CurMethodDef
->getClassInterface();
2770 llvm::SmallVector
<Expr
*, 4> InitExprs
;
2772 // set the receiver to self, the first argument to all methods.
2773 InitExprs
.push_back(
2774 NoTypeInfoCStyleCastExpr(Context
, Context
->getObjCIdType(),
2776 new (Context
) DeclRefExpr(CurMethodDef
->getSelfDecl(),
2777 Context
->getObjCIdType(),
2780 ); // set the 'receiver'.
2782 // (id)class_getSuperclass((Class)objc_getClass("CurrentClass"))
2783 llvm::SmallVector
<Expr
*, 8> ClsExprs
;
2784 QualType argType
= Context
->getPointerType(Context
->CharTy
);
2785 ClsExprs
.push_back(StringLiteral::Create(*Context
,
2786 ClassDecl
->getIdentifier()->getNameStart(),
2787 ClassDecl
->getIdentifier()->getLength(),
2788 false, argType
, SourceLocation()));
2789 CallExpr
*Cls
= SynthesizeCallToFunctionDecl(GetMetaClassFunctionDecl
,
2794 // (Class)objc_getClass("CurrentClass")
2795 CastExpr
*ArgExpr
= NoTypeInfoCStyleCastExpr(Context
,
2796 Context
->getObjCClassType(),
2799 ClsExprs
.push_back(ArgExpr
);
2800 Cls
= SynthesizeCallToFunctionDecl(GetSuperClassFunctionDecl
,
2801 &ClsExprs
[0], ClsExprs
.size(),
2804 // (id)class_getSuperclass((Class)objc_getClass("CurrentClass"))
2805 // To turn off a warning, type-cast to 'id'
2806 InitExprs
.push_back( // set 'super class', using class_getSuperclass().
2807 NoTypeInfoCStyleCastExpr(Context
,
2808 Context
->getObjCIdType(),
2810 // struct objc_super
2811 QualType superType
= getSuperStructType();
2814 if (LangOpts
.Microsoft
) {
2815 SynthSuperContructorFunctionDecl();
2816 // Simulate a contructor call...
2817 DeclRefExpr
*DRE
= new (Context
) DeclRefExpr(SuperContructorFunctionDecl
,
2818 superType
, VK_LValue
,
2820 SuperRep
= new (Context
) CallExpr(*Context
, DRE
, &InitExprs
[0],
2822 superType
, VK_LValue
,
2824 // The code for super is a little tricky to prevent collision with
2825 // the structure definition in the header. The rewriter has it's own
2826 // internal definition (__rw_objc_super) that is uses. This is why
2827 // we need the cast below. For example:
2828 // (struct objc_super *)&__rw_objc_super((id)self, (id)objc_getClass("SUPER"))
2830 SuperRep
= new (Context
) UnaryOperator(SuperRep
, UO_AddrOf
,
2831 Context
->getPointerType(SuperRep
->getType()),
2832 VK_RValue
, OK_Ordinary
,
2834 SuperRep
= NoTypeInfoCStyleCastExpr(Context
,
2835 Context
->getPointerType(superType
),
2836 CK_BitCast
, SuperRep
);
2838 // (struct objc_super) { <exprs from above> }
2840 new (Context
) InitListExpr(*Context
, SourceLocation(),
2841 &InitExprs
[0], InitExprs
.size(),
2843 TypeSourceInfo
*superTInfo
2844 = Context
->getTrivialTypeSourceInfo(superType
);
2845 SuperRep
= new (Context
) CompoundLiteralExpr(SourceLocation(), superTInfo
,
2846 superType
, VK_LValue
,
2848 // struct objc_super *
2849 SuperRep
= new (Context
) UnaryOperator(SuperRep
, UO_AddrOf
,
2850 Context
->getPointerType(SuperRep
->getType()),
2851 VK_RValue
, OK_Ordinary
,
2854 MsgExprs
.push_back(SuperRep
);
2858 case ObjCMessageExpr::Class
: {
2859 llvm::SmallVector
<Expr
*, 8> ClsExprs
;
2860 QualType argType
= Context
->getPointerType(Context
->CharTy
);
2861 ObjCInterfaceDecl
*Class
2862 = Exp
->getClassReceiver()->getAs
<ObjCObjectType
>()->getInterface();
2863 IdentifierInfo
*clsName
= Class
->getIdentifier();
2864 ClsExprs
.push_back(StringLiteral::Create(*Context
,
2865 clsName
->getNameStart(),
2866 clsName
->getLength(),
2869 CallExpr
*Cls
= SynthesizeCallToFunctionDecl(GetClassFunctionDecl
,
2873 MsgExprs
.push_back(Cls
);
2877 case ObjCMessageExpr::SuperInstance
:{
2878 MsgSendFlavor
= MsgSendSuperFunctionDecl
;
2879 if (MsgSendStretFlavor
)
2880 MsgSendStretFlavor
= MsgSendSuperStretFunctionDecl
;
2881 assert(MsgSendFlavor
&& "MsgSendFlavor is NULL!");
2882 ObjCInterfaceDecl
*ClassDecl
= CurMethodDef
->getClassInterface();
2883 llvm::SmallVector
<Expr
*, 4> InitExprs
;
2885 InitExprs
.push_back(
2886 NoTypeInfoCStyleCastExpr(Context
, Context
->getObjCIdType(),
2888 new (Context
) DeclRefExpr(CurMethodDef
->getSelfDecl(),
2889 Context
->getObjCIdType(),
2890 VK_RValue
, SourceLocation()))
2891 ); // set the 'receiver'.
2893 // (id)class_getSuperclass((Class)objc_getClass("CurrentClass"))
2894 llvm::SmallVector
<Expr
*, 8> ClsExprs
;
2895 QualType argType
= Context
->getPointerType(Context
->CharTy
);
2896 ClsExprs
.push_back(StringLiteral::Create(*Context
,
2897 ClassDecl
->getIdentifier()->getNameStart(),
2898 ClassDecl
->getIdentifier()->getLength(),
2899 false, argType
, SourceLocation()));
2900 CallExpr
*Cls
= SynthesizeCallToFunctionDecl(GetClassFunctionDecl
,
2904 // (Class)objc_getClass("CurrentClass")
2905 CastExpr
*ArgExpr
= NoTypeInfoCStyleCastExpr(Context
,
2906 Context
->getObjCClassType(),
2909 ClsExprs
.push_back(ArgExpr
);
2910 Cls
= SynthesizeCallToFunctionDecl(GetSuperClassFunctionDecl
,
2911 &ClsExprs
[0], ClsExprs
.size(),
2914 // (id)class_getSuperclass((Class)objc_getClass("CurrentClass"))
2915 // To turn off a warning, type-cast to 'id'
2916 InitExprs
.push_back(
2917 // set 'super class', using class_getSuperclass().
2918 NoTypeInfoCStyleCastExpr(Context
, Context
->getObjCIdType(),
2920 // struct objc_super
2921 QualType superType
= getSuperStructType();
2924 if (LangOpts
.Microsoft
) {
2925 SynthSuperContructorFunctionDecl();
2926 // Simulate a contructor call...
2927 DeclRefExpr
*DRE
= new (Context
) DeclRefExpr(SuperContructorFunctionDecl
,
2928 superType
, VK_LValue
,
2930 SuperRep
= new (Context
) CallExpr(*Context
, DRE
, &InitExprs
[0],
2932 superType
, VK_LValue
, SourceLocation());
2933 // The code for super is a little tricky to prevent collision with
2934 // the structure definition in the header. The rewriter has it's own
2935 // internal definition (__rw_objc_super) that is uses. This is why
2936 // we need the cast below. For example:
2937 // (struct objc_super *)&__rw_objc_super((id)self, (id)objc_getClass("SUPER"))
2939 SuperRep
= new (Context
) UnaryOperator(SuperRep
, UO_AddrOf
,
2940 Context
->getPointerType(SuperRep
->getType()),
2941 VK_RValue
, OK_Ordinary
,
2943 SuperRep
= NoTypeInfoCStyleCastExpr(Context
,
2944 Context
->getPointerType(superType
),
2945 CK_BitCast
, SuperRep
);
2947 // (struct objc_super) { <exprs from above> }
2949 new (Context
) InitListExpr(*Context
, SourceLocation(),
2950 &InitExprs
[0], InitExprs
.size(),
2952 TypeSourceInfo
*superTInfo
2953 = Context
->getTrivialTypeSourceInfo(superType
);
2954 SuperRep
= new (Context
) CompoundLiteralExpr(SourceLocation(), superTInfo
,
2955 superType
, VK_RValue
, ILE
,
2958 MsgExprs
.push_back(SuperRep
);
2962 case ObjCMessageExpr::Instance
: {
2963 // Remove all type-casts because it may contain objc-style types; e.g.
2965 Expr
*recExpr
= Exp
->getInstanceReceiver();
2966 while (CStyleCastExpr
*CE
= dyn_cast
<CStyleCastExpr
>(recExpr
))
2967 recExpr
= CE
->getSubExpr();
2968 recExpr
= NoTypeInfoCStyleCastExpr(Context
, Context
->getObjCIdType(),
2969 CK_BitCast
, recExpr
);
2970 MsgExprs
.push_back(recExpr
);
2975 // Create a call to sel_registerName("selName"), it will be the 2nd argument.
2976 llvm::SmallVector
<Expr
*, 8> SelExprs
;
2977 QualType argType
= Context
->getPointerType(Context
->CharTy
);
2978 SelExprs
.push_back(StringLiteral::Create(*Context
,
2979 Exp
->getSelector().getAsString().c_str(),
2980 Exp
->getSelector().getAsString().size(),
2981 false, argType
, SourceLocation()));
2982 CallExpr
*SelExp
= SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl
,
2983 &SelExprs
[0], SelExprs
.size(),
2986 MsgExprs
.push_back(SelExp
);
2988 // Now push any user supplied arguments.
2989 for (unsigned i
= 0; i
< Exp
->getNumArgs(); i
++) {
2990 Expr
*userExpr
= Exp
->getArg(i
);
2991 // Make all implicit casts explicit...ICE comes in handy:-)
2992 if (ImplicitCastExpr
*ICE
= dyn_cast
<ImplicitCastExpr
>(userExpr
)) {
2993 // Reuse the ICE type, it is exactly what the doctor ordered.
2994 QualType type
= ICE
->getType()->isObjCQualifiedIdType()
2995 ? Context
->getObjCIdType()
2997 // Make sure we convert "type (^)(...)" to "type (*)(...)".
2998 (void)convertBlockPointerToFunctionPointer(type
);
2999 userExpr
= NoTypeInfoCStyleCastExpr(Context
, type
, CK_BitCast
,
3002 // Make id<P...> cast into an 'id' cast.
3003 else if (CStyleCastExpr
*CE
= dyn_cast
<CStyleCastExpr
>(userExpr
)) {
3004 if (CE
->getType()->isObjCQualifiedIdType()) {
3005 while ((CE
= dyn_cast
<CStyleCastExpr
>(userExpr
)))
3006 userExpr
= CE
->getSubExpr();
3007 userExpr
= NoTypeInfoCStyleCastExpr(Context
, Context
->getObjCIdType(),
3008 CK_BitCast
, userExpr
);
3011 MsgExprs
.push_back(userExpr
);
3012 // We've transferred the ownership to MsgExprs. For now, we *don't* null
3013 // out the argument in the original expression (since we aren't deleting
3014 // the ObjCMessageExpr). See RewritePropertyOrImplicitSetter() usage for more info.
3015 //Exp->setArg(i, 0);
3017 // Generate the funky cast.
3019 llvm::SmallVector
<QualType
, 8> ArgTypes
;
3020 QualType returnType
;
3022 // Push 'id' and 'SEL', the 2 implicit arguments.
3023 if (MsgSendFlavor
== MsgSendSuperFunctionDecl
)
3024 ArgTypes
.push_back(Context
->getPointerType(getSuperStructType()));
3026 ArgTypes
.push_back(Context
->getObjCIdType());
3027 ArgTypes
.push_back(Context
->getObjCSelType());
3028 if (ObjCMethodDecl
*OMD
= Exp
->getMethodDecl()) {
3029 // Push any user argument types.
3030 for (ObjCMethodDecl::param_iterator PI
= OMD
->param_begin(),
3031 E
= OMD
->param_end(); PI
!= E
; ++PI
) {
3032 QualType t
= (*PI
)->getType()->isObjCQualifiedIdType()
3033 ? Context
->getObjCIdType()
3035 // Make sure we convert "t (^)(...)" to "t (*)(...)".
3036 (void)convertBlockPointerToFunctionPointer(t
);
3037 ArgTypes
.push_back(t
);
3039 returnType
= OMD
->getResultType()->isObjCQualifiedIdType()
3040 ? Context
->getObjCIdType() : OMD
->getResultType();
3041 (void)convertBlockPointerToFunctionPointer(returnType
);
3043 returnType
= Context
->getObjCIdType();
3045 // Get the type, we will need to reference it in a couple spots.
3046 QualType msgSendType
= MsgSendFlavor
->getType();
3048 // Create a reference to the objc_msgSend() declaration.
3049 DeclRefExpr
*DRE
= new (Context
) DeclRefExpr(MsgSendFlavor
, msgSendType
,
3050 VK_LValue
, SourceLocation());
3052 // Need to cast objc_msgSend to "void *" (to workaround a GCC bandaid).
3053 // If we don't do this cast, we get the following bizarre warning/note:
3054 // xx.m:13: warning: function called through a non-compatible type
3055 // xx.m:13: note: if this code is reached, the program will abort
3056 cast
= NoTypeInfoCStyleCastExpr(Context
,
3057 Context
->getPointerType(Context
->VoidTy
),
3060 // Now do the "normal" pointer to function cast.
3062 getSimpleFunctionType(returnType
, &ArgTypes
[0], ArgTypes
.size(),
3063 // If we don't have a method decl, force a variadic cast.
3064 Exp
->getMethodDecl() ? Exp
->getMethodDecl()->isVariadic() : true);
3065 castType
= Context
->getPointerType(castType
);
3066 cast
= NoTypeInfoCStyleCastExpr(Context
, castType
, CK_BitCast
,
3069 // Don't forget the parens to enforce the proper binding.
3070 ParenExpr
*PE
= new (Context
) ParenExpr(StartLoc
, EndLoc
, cast
);
3072 const FunctionType
*FT
= msgSendType
->getAs
<FunctionType
>();
3073 CallExpr
*CE
= new (Context
) CallExpr(*Context
, PE
, &MsgExprs
[0],
3075 FT
->getResultType(), VK_RValue
,
3077 Stmt
*ReplacingStmt
= CE
;
3078 if (MsgSendStretFlavor
) {
3079 // We have the method which returns a struct/union. Must also generate
3080 // call to objc_msgSend_stret and hang both varieties on a conditional
3081 // expression which dictate which one to envoke depending on size of
3082 // method's return type.
3084 // Create a reference to the objc_msgSend_stret() declaration.
3085 DeclRefExpr
*STDRE
= new (Context
) DeclRefExpr(MsgSendStretFlavor
, msgSendType
,
3086 VK_LValue
, SourceLocation());
3087 // Need to cast objc_msgSend_stret to "void *" (see above comment).
3088 cast
= NoTypeInfoCStyleCastExpr(Context
,
3089 Context
->getPointerType(Context
->VoidTy
),
3091 // Now do the "normal" pointer to function cast.
3092 castType
= getSimpleFunctionType(returnType
, &ArgTypes
[0], ArgTypes
.size(),
3093 Exp
->getMethodDecl() ? Exp
->getMethodDecl()->isVariadic() : false);
3094 castType
= Context
->getPointerType(castType
);
3095 cast
= NoTypeInfoCStyleCastExpr(Context
, castType
, CK_BitCast
,
3098 // Don't forget the parens to enforce the proper binding.
3099 PE
= new (Context
) ParenExpr(SourceLocation(), SourceLocation(), cast
);
3101 FT
= msgSendType
->getAs
<FunctionType
>();
3102 CallExpr
*STCE
= new (Context
) CallExpr(*Context
, PE
, &MsgExprs
[0],
3104 FT
->getResultType(), VK_RValue
,
3107 // Build sizeof(returnType)
3108 SizeOfAlignOfExpr
*sizeofExpr
= new (Context
) SizeOfAlignOfExpr(true,
3109 Context
->getTrivialTypeSourceInfo(returnType
),
3110 Context
->getSizeType(),
3111 SourceLocation(), SourceLocation());
3112 // (sizeof(returnType) <= 8 ? objc_msgSend(...) : objc_msgSend_stret(...))
3113 // FIXME: Value of 8 is base on ppc32/x86 ABI for the most common cases.
3114 // For X86 it is more complicated and some kind of target specific routine
3115 // is needed to decide what to do.
3117 static_cast<unsigned>(Context
->getTypeSize(Context
->IntTy
));
3118 IntegerLiteral
*limit
= IntegerLiteral::Create(*Context
,
3119 llvm::APInt(IntSize
, 8),
3122 BinaryOperator
*lessThanExpr
=
3123 new (Context
) BinaryOperator(sizeofExpr
, limit
, BO_LE
, Context
->IntTy
,
3124 VK_RValue
, OK_Ordinary
, SourceLocation());
3125 // (sizeof(returnType) <= 8 ? objc_msgSend(...) : objc_msgSend_stret(...))
3126 ConditionalOperator
*CondExpr
=
3127 new (Context
) ConditionalOperator(lessThanExpr
,
3128 SourceLocation(), CE
,
3129 SourceLocation(), STCE
, (Expr
*)0,
3130 returnType
, VK_RValue
, OK_Ordinary
);
3131 ReplacingStmt
= new (Context
) ParenExpr(SourceLocation(), SourceLocation(),
3134 // delete Exp; leak for now, see RewritePropertyOrImplicitSetter() usage for more info.
3135 return ReplacingStmt
;
3138 Stmt
*RewriteObjC::RewriteMessageExpr(ObjCMessageExpr
*Exp
) {
3139 Stmt
*ReplacingStmt
= SynthMessageExpr(Exp
, Exp
->getLocStart(),
3142 // Now do the actual rewrite.
3143 ReplaceStmt(Exp
, ReplacingStmt
);
3145 // delete Exp; leak for now, see RewritePropertyOrImplicitSetter() usage for more info.
3146 return ReplacingStmt
;
3149 // typedef struct objc_object Protocol;
3150 QualType
RewriteObjC::getProtocolType() {
3151 if (!ProtocolTypeDecl
) {
3152 TypeSourceInfo
*TInfo
3153 = Context
->getTrivialTypeSourceInfo(Context
->getObjCIdType());
3154 ProtocolTypeDecl
= TypedefDecl::Create(*Context
, TUDecl
,
3156 &Context
->Idents
.get("Protocol"),
3159 return Context
->getTypeDeclType(ProtocolTypeDecl
);
3162 /// RewriteObjCProtocolExpr - Rewrite a protocol expression into
3163 /// a synthesized/forward data reference (to the protocol's metadata).
3164 /// The forward references (and metadata) are generated in
3165 /// RewriteObjC::HandleTranslationUnit().
3166 Stmt
*RewriteObjC::RewriteObjCProtocolExpr(ObjCProtocolExpr
*Exp
) {
3167 std::string Name
= "_OBJC_PROTOCOL_" + Exp
->getProtocol()->getNameAsString();
3168 IdentifierInfo
*ID
= &Context
->Idents
.get(Name
);
3169 VarDecl
*VD
= VarDecl::Create(*Context
, TUDecl
, SourceLocation(),
3170 ID
, getProtocolType(), 0,
3171 SC_Extern
, SC_None
);
3172 DeclRefExpr
*DRE
= new (Context
) DeclRefExpr(VD
, getProtocolType(), VK_LValue
,
3174 Expr
*DerefExpr
= new (Context
) UnaryOperator(DRE
, UO_AddrOf
,
3175 Context
->getPointerType(DRE
->getType()),
3176 VK_RValue
, OK_Ordinary
, SourceLocation());
3177 CastExpr
*castExpr
= NoTypeInfoCStyleCastExpr(Context
, DerefExpr
->getType(),
3180 ReplaceStmt(Exp
, castExpr
);
3181 ProtocolExprDecls
.insert(Exp
->getProtocol());
3182 // delete Exp; leak for now, see RewritePropertyOrImplicitSetter() usage for more info.
3187 bool RewriteObjC::BufferContainsPPDirectives(const char *startBuf
,
3188 const char *endBuf
) {
3189 while (startBuf
< endBuf
) {
3190 if (*startBuf
== '#') {
3192 for (++startBuf
; startBuf
[0] == ' ' || startBuf
[0] == '\t'; ++startBuf
)
3194 if (!strncmp(startBuf
, "if", strlen("if")) ||
3195 !strncmp(startBuf
, "ifdef", strlen("ifdef")) ||
3196 !strncmp(startBuf
, "ifndef", strlen("ifndef")) ||
3197 !strncmp(startBuf
, "define", strlen("define")) ||
3198 !strncmp(startBuf
, "undef", strlen("undef")) ||
3199 !strncmp(startBuf
, "else", strlen("else")) ||
3200 !strncmp(startBuf
, "elif", strlen("elif")) ||
3201 !strncmp(startBuf
, "endif", strlen("endif")) ||
3202 !strncmp(startBuf
, "pragma", strlen("pragma")) ||
3203 !strncmp(startBuf
, "include", strlen("include")) ||
3204 !strncmp(startBuf
, "import", strlen("import")) ||
3205 !strncmp(startBuf
, "include_next", strlen("include_next")))
3213 /// SynthesizeObjCInternalStruct - Rewrite one internal struct corresponding to
3214 /// an objective-c class with ivars.
3215 void RewriteObjC::SynthesizeObjCInternalStruct(ObjCInterfaceDecl
*CDecl
,
3216 std::string
&Result
) {
3217 assert(CDecl
&& "Class missing in SynthesizeObjCInternalStruct");
3218 assert(CDecl
->getName() != "" &&
3219 "Name missing in SynthesizeObjCInternalStruct");
3220 // Do not synthesize more than once.
3221 if (ObjCSynthesizedStructs
.count(CDecl
))
3223 ObjCInterfaceDecl
*RCDecl
= CDecl
->getSuperClass();
3224 int NumIvars
= CDecl
->ivar_size();
3225 SourceLocation LocStart
= CDecl
->getLocStart();
3226 SourceLocation LocEnd
= CDecl
->getLocEnd();
3228 const char *startBuf
= SM
->getCharacterData(LocStart
);
3229 const char *endBuf
= SM
->getCharacterData(LocEnd
);
3231 // If no ivars and no root or if its root, directly or indirectly,
3232 // have no ivars (thus not synthesized) then no need to synthesize this class.
3233 if ((CDecl
->isForwardDecl() || NumIvars
== 0) &&
3234 (!RCDecl
|| !ObjCSynthesizedStructs
.count(RCDecl
))) {
3235 endBuf
+= Lexer::MeasureTokenLength(LocEnd
, *SM
, LangOpts
);
3236 ReplaceText(LocStart
, endBuf
-startBuf
, Result
);
3240 // FIXME: This has potential of causing problem. If
3241 // SynthesizeObjCInternalStruct is ever called recursively.
3242 Result
+= "\nstruct ";
3243 Result
+= CDecl
->getNameAsString();
3244 if (LangOpts
.Microsoft
)
3248 const char *cursor
= strchr(startBuf
, '{');
3249 assert((cursor
&& endBuf
)
3250 && "SynthesizeObjCInternalStruct - malformed @interface");
3251 // If the buffer contains preprocessor directives, we do more fine-grained
3252 // rewrites. This is intended to fix code that looks like (which occurs in
3253 // NSURL.h, for example):
3256 // @interface Foo : NSObject
3258 // @interface FooBar : NSObject
3265 // This clause is segregated to avoid breaking the common case.
3266 if (BufferContainsPPDirectives(startBuf
, cursor
)) {
3267 SourceLocation L
= RCDecl
? CDecl
->getSuperClassLoc() :
3268 CDecl
->getClassLoc();
3269 const char *endHeader
= SM
->getCharacterData(L
);
3270 endHeader
+= Lexer::MeasureTokenLength(L
, *SM
, LangOpts
);
3272 if (CDecl
->protocol_begin() != CDecl
->protocol_end()) {
3273 // advance to the end of the referenced protocols.
3274 while (endHeader
< cursor
&& *endHeader
!= '>') endHeader
++;
3277 // rewrite the original header
3278 ReplaceText(LocStart
, endHeader
-startBuf
, Result
);
3280 // rewrite the original header *without* disturbing the '{'
3281 ReplaceText(LocStart
, cursor
-startBuf
, Result
);
3283 if (RCDecl
&& ObjCSynthesizedStructs
.count(RCDecl
)) {
3284 Result
= "\n struct ";
3285 Result
+= RCDecl
->getNameAsString();
3287 Result
+= RCDecl
->getNameAsString();
3288 Result
+= "_IVARS;\n";
3290 // insert the super class structure definition.
3291 SourceLocation OnePastCurly
=
3292 LocStart
.getFileLocWithOffset(cursor
-startBuf
+1);
3293 InsertText(OnePastCurly
, Result
);
3295 cursor
++; // past '{'
3297 // Now comment out any visibility specifiers.
3298 while (cursor
< endBuf
) {
3299 if (*cursor
== '@') {
3300 SourceLocation atLoc
= LocStart
.getFileLocWithOffset(cursor
-startBuf
);
3302 for (++cursor
; cursor
[0] == ' ' || cursor
[0] == '\t'; ++cursor
)
3305 // FIXME: presence of @public, etc. inside comment results in
3306 // this transformation as well, which is still correct c-code.
3307 if (!strncmp(cursor
, "public", strlen("public")) ||
3308 !strncmp(cursor
, "private", strlen("private")) ||
3309 !strncmp(cursor
, "package", strlen("package")) ||
3310 !strncmp(cursor
, "protected", strlen("protected")))
3311 InsertText(atLoc
, "// ");
3313 // FIXME: If there are cases where '<' is used in ivar declaration part
3314 // of user code, then scan the ivar list and use needToScanForQualifiers
3315 // for type checking.
3316 else if (*cursor
== '<') {
3317 SourceLocation atLoc
= LocStart
.getFileLocWithOffset(cursor
-startBuf
);
3318 InsertText(atLoc
, "/* ");
3319 cursor
= strchr(cursor
, '>');
3321 atLoc
= LocStart
.getFileLocWithOffset(cursor
-startBuf
);
3322 InsertText(atLoc
, " */");
3323 } else if (*cursor
== '^') { // rewrite block specifier.
3324 SourceLocation caretLoc
= LocStart
.getFileLocWithOffset(cursor
-startBuf
);
3325 ReplaceText(caretLoc
, 1, "*");
3329 // Don't forget to add a ';'!!
3330 InsertText(LocEnd
.getFileLocWithOffset(1), ";");
3331 } else { // we don't have any instance variables - insert super struct.
3332 endBuf
+= Lexer::MeasureTokenLength(LocEnd
, *SM
, LangOpts
);
3333 Result
+= " {\n struct ";
3334 Result
+= RCDecl
->getNameAsString();
3336 Result
+= RCDecl
->getNameAsString();
3337 Result
+= "_IVARS;\n};\n";
3338 ReplaceText(LocStart
, endBuf
-startBuf
, Result
);
3340 // Mark this struct as having been generated.
3341 if (!ObjCSynthesizedStructs
.insert(CDecl
))
3342 assert(false && "struct already synthesize- SynthesizeObjCInternalStruct");
3345 // RewriteObjCMethodsMetaData - Rewrite methods metadata for instance or
3347 template<typename MethodIterator
>
3348 void RewriteObjC::RewriteObjCMethodsMetaData(MethodIterator MethodBegin
,
3349 MethodIterator MethodEnd
,
3350 bool IsInstanceMethod
,
3351 llvm::StringRef prefix
,
3352 llvm::StringRef ClassName
,
3353 std::string
&Result
) {
3354 if (MethodBegin
== MethodEnd
) return;
3356 if (!objc_impl_method
) {
3357 /* struct _objc_method {
3363 Result
+= "\nstruct _objc_method {\n";
3364 Result
+= "\tSEL _cmd;\n";
3365 Result
+= "\tchar *method_types;\n";
3366 Result
+= "\tvoid *_imp;\n";
3369 objc_impl_method
= true;
3372 // Build _objc_method_list for class's methods if needed
3375 struct _objc_method_list *next_method;
3377 struct _objc_method method_list[];
3380 unsigned NumMethods
= std::distance(MethodBegin
, MethodEnd
);
3381 Result
+= "\nstatic struct {\n";
3382 Result
+= "\tstruct _objc_method_list *next_method;\n";
3383 Result
+= "\tint method_count;\n";
3384 Result
+= "\tstruct _objc_method method_list[";
3385 Result
+= utostr(NumMethods
);
3386 Result
+= "];\n} _OBJC_";
3388 Result
+= IsInstanceMethod
? "INSTANCE" : "CLASS";
3389 Result
+= "_METHODS_";
3390 Result
+= ClassName
;
3391 Result
+= " __attribute__ ((used, section (\"__OBJC, __";
3392 Result
+= IsInstanceMethod
? "inst" : "cls";
3393 Result
+= "_meth\")))= ";
3394 Result
+= "{\n\t0, " + utostr(NumMethods
) + "\n";
3396 Result
+= "\t,{{(SEL)\"";
3397 Result
+= (*MethodBegin
)->getSelector().getAsString().c_str();
3398 std::string MethodTypeString
;
3399 Context
->getObjCEncodingForMethodDecl(*MethodBegin
, MethodTypeString
);
3401 Result
+= MethodTypeString
;
3402 Result
+= "\", (void *)";
3403 Result
+= MethodInternalNames
[*MethodBegin
];
3405 for (++MethodBegin
; MethodBegin
!= MethodEnd
; ++MethodBegin
) {
3406 Result
+= "\t ,{(SEL)\"";
3407 Result
+= (*MethodBegin
)->getSelector().getAsString().c_str();
3408 std::string MethodTypeString
;
3409 Context
->getObjCEncodingForMethodDecl(*MethodBegin
, MethodTypeString
);
3411 Result
+= MethodTypeString
;
3412 Result
+= "\", (void *)";
3413 Result
+= MethodInternalNames
[*MethodBegin
];
3416 Result
+= "\t }\n};\n";
3419 /// RewriteObjCProtocolMetaData - Rewrite protocols meta-data.
3421 RewriteObjCProtocolMetaData(ObjCProtocolDecl
*PDecl
, llvm::StringRef prefix
,
3422 llvm::StringRef ClassName
, std::string
&Result
) {
3423 static bool objc_protocol_methods
= false;
3425 // Output struct protocol_methods holder of method selector and type.
3426 if (!objc_protocol_methods
&& !PDecl
->isForwardDecl()) {
3427 /* struct protocol_methods {
3432 Result
+= "\nstruct _protocol_methods {\n";
3433 Result
+= "\tstruct objc_selector *_cmd;\n";
3434 Result
+= "\tchar *method_types;\n";
3437 objc_protocol_methods
= true;
3439 // Do not synthesize the protocol more than once.
3440 if (ObjCSynthesizedProtocols
.count(PDecl
))
3443 if (PDecl
->instmeth_begin() != PDecl
->instmeth_end()) {
3444 unsigned NumMethods
= std::distance(PDecl
->instmeth_begin(),
3445 PDecl
->instmeth_end());
3446 /* struct _objc_protocol_method_list {
3447 int protocol_method_count;
3448 struct protocol_methods protocols[];
3451 Result
+= "\nstatic struct {\n";
3452 Result
+= "\tint protocol_method_count;\n";
3453 Result
+= "\tstruct _protocol_methods protocol_methods[";
3454 Result
+= utostr(NumMethods
);
3455 Result
+= "];\n} _OBJC_PROTOCOL_INSTANCE_METHODS_";
3456 Result
+= PDecl
->getNameAsString();
3457 Result
+= " __attribute__ ((used, section (\"__OBJC, __cat_inst_meth\")))= "
3458 "{\n\t" + utostr(NumMethods
) + "\n";
3460 // Output instance methods declared in this protocol.
3461 for (ObjCProtocolDecl::instmeth_iterator
3462 I
= PDecl
->instmeth_begin(), E
= PDecl
->instmeth_end();
3464 if (I
== PDecl
->instmeth_begin())
3465 Result
+= "\t ,{{(struct objc_selector *)\"";
3467 Result
+= "\t ,{(struct objc_selector *)\"";
3468 Result
+= (*I
)->getSelector().getAsString();
3469 std::string MethodTypeString
;
3470 Context
->getObjCEncodingForMethodDecl((*I
), MethodTypeString
);
3472 Result
+= MethodTypeString
;
3475 Result
+= "\t }\n};\n";
3478 // Output class methods declared in this protocol.
3479 unsigned NumMethods
= std::distance(PDecl
->classmeth_begin(),
3480 PDecl
->classmeth_end());
3481 if (NumMethods
> 0) {
3482 /* struct _objc_protocol_method_list {
3483 int protocol_method_count;
3484 struct protocol_methods protocols[];
3487 Result
+= "\nstatic struct {\n";
3488 Result
+= "\tint protocol_method_count;\n";
3489 Result
+= "\tstruct _protocol_methods protocol_methods[";
3490 Result
+= utostr(NumMethods
);
3491 Result
+= "];\n} _OBJC_PROTOCOL_CLASS_METHODS_";
3492 Result
+= PDecl
->getNameAsString();
3493 Result
+= " __attribute__ ((used, section (\"__OBJC, __cat_cls_meth\")))= "
3495 Result
+= utostr(NumMethods
);
3498 // Output instance methods declared in this protocol.
3499 for (ObjCProtocolDecl::classmeth_iterator
3500 I
= PDecl
->classmeth_begin(), E
= PDecl
->classmeth_end();
3502 if (I
== PDecl
->classmeth_begin())
3503 Result
+= "\t ,{{(struct objc_selector *)\"";
3505 Result
+= "\t ,{(struct objc_selector *)\"";
3506 Result
+= (*I
)->getSelector().getAsString();
3507 std::string MethodTypeString
;
3508 Context
->getObjCEncodingForMethodDecl((*I
), MethodTypeString
);
3510 Result
+= MethodTypeString
;
3513 Result
+= "\t }\n};\n";
3517 /* struct _objc_protocol {
3518 // Objective-C 1.0 extensions
3519 struct _objc_protocol_extension *isa;
3520 char *protocol_name;
3521 struct _objc_protocol **protocol_list;
3522 struct _objc_protocol_method_list *instance_methods;
3523 struct _objc_protocol_method_list *class_methods;
3526 static bool objc_protocol
= false;
3527 if (!objc_protocol
) {
3528 Result
+= "\nstruct _objc_protocol {\n";
3529 Result
+= "\tstruct _objc_protocol_extension *isa;\n";
3530 Result
+= "\tchar *protocol_name;\n";
3531 Result
+= "\tstruct _objc_protocol **protocol_list;\n";
3532 Result
+= "\tstruct _objc_protocol_method_list *instance_methods;\n";
3533 Result
+= "\tstruct _objc_protocol_method_list *class_methods;\n";
3536 objc_protocol
= true;
3539 Result
+= "\nstatic struct _objc_protocol _OBJC_PROTOCOL_";
3540 Result
+= PDecl
->getNameAsString();
3541 Result
+= " __attribute__ ((used, section (\"__OBJC, __protocol\")))= "
3543 Result
+= PDecl
->getNameAsString();
3544 Result
+= "\", 0, ";
3545 if (PDecl
->instmeth_begin() != PDecl
->instmeth_end()) {
3546 Result
+= "(struct _objc_protocol_method_list *)&_OBJC_PROTOCOL_INSTANCE_METHODS_";
3547 Result
+= PDecl
->getNameAsString();
3552 if (PDecl
->classmeth_begin() != PDecl
->classmeth_end()) {
3553 Result
+= "(struct _objc_protocol_method_list *)&_OBJC_PROTOCOL_CLASS_METHODS_";
3554 Result
+= PDecl
->getNameAsString();
3561 // Mark this protocol as having been generated.
3562 if (!ObjCSynthesizedProtocols
.insert(PDecl
))
3563 assert(false && "protocol already synthesized");
3568 RewriteObjCProtocolListMetaData(const ObjCList
<ObjCProtocolDecl
> &Protocols
,
3569 llvm::StringRef prefix
, llvm::StringRef ClassName
,
3570 std::string
&Result
) {
3571 if (Protocols
.empty()) return;
3573 for (unsigned i
= 0; i
!= Protocols
.size(); i
++)
3574 RewriteObjCProtocolMetaData(Protocols
[i
], prefix
, ClassName
, Result
);
3576 // Output the top lovel protocol meta-data for the class.
3577 /* struct _objc_protocol_list {
3578 struct _objc_protocol_list *next;
3580 struct _objc_protocol *class_protocols[];
3583 Result
+= "\nstatic struct {\n";
3584 Result
+= "\tstruct _objc_protocol_list *next;\n";
3585 Result
+= "\tint protocol_count;\n";
3586 Result
+= "\tstruct _objc_protocol *class_protocols[";
3587 Result
+= utostr(Protocols
.size());
3588 Result
+= "];\n} _OBJC_";
3590 Result
+= "_PROTOCOLS_";
3591 Result
+= ClassName
;
3592 Result
+= " __attribute__ ((used, section (\"__OBJC, __cat_cls_meth\")))= "
3594 Result
+= utostr(Protocols
.size());
3597 Result
+= "\t,{&_OBJC_PROTOCOL_";
3598 Result
+= Protocols
[0]->getNameAsString();
3601 for (unsigned i
= 1; i
!= Protocols
.size(); i
++) {
3602 Result
+= "\t ,&_OBJC_PROTOCOL_";
3603 Result
+= Protocols
[i
]->getNameAsString();
3606 Result
+= "\t }\n};\n";
3610 /// RewriteObjCCategoryImplDecl - Rewrite metadata for each category
3612 void RewriteObjC::RewriteObjCCategoryImplDecl(ObjCCategoryImplDecl
*IDecl
,
3613 std::string
&Result
) {
3614 ObjCInterfaceDecl
*ClassDecl
= IDecl
->getClassInterface();
3615 // Find category declaration for this implementation.
3616 ObjCCategoryDecl
*CDecl
;
3617 for (CDecl
= ClassDecl
->getCategoryList(); CDecl
;
3618 CDecl
= CDecl
->getNextClassCategory())
3619 if (CDecl
->getIdentifier() == IDecl
->getIdentifier())
3622 std::string FullCategoryName
= ClassDecl
->getNameAsString();
3623 FullCategoryName
+= '_';
3624 FullCategoryName
+= IDecl
->getNameAsString();
3626 // Build _objc_method_list for class's instance methods if needed
3627 llvm::SmallVector
<ObjCMethodDecl
*, 32>
3628 InstanceMethods(IDecl
->instmeth_begin(), IDecl
->instmeth_end());
3630 // If any of our property implementations have associated getters or
3631 // setters, produce metadata for them as well.
3632 for (ObjCImplDecl::propimpl_iterator Prop
= IDecl
->propimpl_begin(),
3633 PropEnd
= IDecl
->propimpl_end();
3634 Prop
!= PropEnd
; ++Prop
) {
3635 if ((*Prop
)->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic
)
3637 if (!(*Prop
)->getPropertyIvarDecl())
3639 ObjCPropertyDecl
*PD
= (*Prop
)->getPropertyDecl();
3642 if (ObjCMethodDecl
*Getter
= PD
->getGetterMethodDecl())
3643 InstanceMethods
.push_back(Getter
);
3644 if (PD
->isReadOnly())
3646 if (ObjCMethodDecl
*Setter
= PD
->getSetterMethodDecl())
3647 InstanceMethods
.push_back(Setter
);
3649 RewriteObjCMethodsMetaData(InstanceMethods
.begin(), InstanceMethods
.end(),
3650 true, "CATEGORY_", FullCategoryName
.c_str(),
3653 // Build _objc_method_list for class's class methods if needed
3654 RewriteObjCMethodsMetaData(IDecl
->classmeth_begin(), IDecl
->classmeth_end(),
3655 false, "CATEGORY_", FullCategoryName
.c_str(),
3658 // Protocols referenced in class declaration?
3659 // Null CDecl is case of a category implementation with no category interface
3661 RewriteObjCProtocolListMetaData(CDecl
->getReferencedProtocols(), "CATEGORY",
3662 FullCategoryName
, Result
);
3663 /* struct _objc_category {
3664 char *category_name;
3666 struct _objc_method_list *instance_methods;
3667 struct _objc_method_list *class_methods;
3668 struct _objc_protocol_list *protocols;
3669 // Objective-C 1.0 extensions
3670 uint32_t size; // sizeof (struct _objc_category)
3671 struct _objc_property_list *instance_properties; // category's own
3676 static bool objc_category
= false;
3677 if (!objc_category
) {
3678 Result
+= "\nstruct _objc_category {\n";
3679 Result
+= "\tchar *category_name;\n";
3680 Result
+= "\tchar *class_name;\n";
3681 Result
+= "\tstruct _objc_method_list *instance_methods;\n";
3682 Result
+= "\tstruct _objc_method_list *class_methods;\n";
3683 Result
+= "\tstruct _objc_protocol_list *protocols;\n";
3684 Result
+= "\tunsigned int size;\n";
3685 Result
+= "\tstruct _objc_property_list *instance_properties;\n";
3687 objc_category
= true;
3689 Result
+= "\nstatic struct _objc_category _OBJC_CATEGORY_";
3690 Result
+= FullCategoryName
;
3691 Result
+= " __attribute__ ((used, section (\"__OBJC, __category\")))= {\n\t\"";
3692 Result
+= IDecl
->getNameAsString();
3693 Result
+= "\"\n\t, \"";
3694 Result
+= ClassDecl
->getNameAsString();
3697 if (IDecl
->instmeth_begin() != IDecl
->instmeth_end()) {
3698 Result
+= "\t, (struct _objc_method_list *)"
3699 "&_OBJC_CATEGORY_INSTANCE_METHODS_";
3700 Result
+= FullCategoryName
;
3704 Result
+= "\t, 0\n";
3705 if (IDecl
->classmeth_begin() != IDecl
->classmeth_end()) {
3706 Result
+= "\t, (struct _objc_method_list *)"
3707 "&_OBJC_CATEGORY_CLASS_METHODS_";
3708 Result
+= FullCategoryName
;
3712 Result
+= "\t, 0\n";
3714 if (CDecl
&& CDecl
->protocol_begin() != CDecl
->protocol_end()) {
3715 Result
+= "\t, (struct _objc_protocol_list *)&_OBJC_CATEGORY_PROTOCOLS_";
3716 Result
+= FullCategoryName
;
3720 Result
+= "\t, 0\n";
3721 Result
+= "\t, sizeof(struct _objc_category), 0\n};\n";
3724 /// SynthesizeIvarOffsetComputation - This rutine synthesizes computation of
3726 void RewriteObjC::SynthesizeIvarOffsetComputation(ObjCIvarDecl
*ivar
,
3727 std::string
&Result
) {
3728 if (ivar
->isBitField()) {
3729 // FIXME: The hack below doesn't work for bitfields. For now, we simply
3730 // place all bitfields at offset 0.
3733 Result
+= "__OFFSETOFIVAR__(struct ";
3734 Result
+= ivar
->getContainingInterface()->getNameAsString();
3735 if (LangOpts
.Microsoft
)
3738 Result
+= ivar
->getNameAsString();
3743 //===----------------------------------------------------------------------===//
3744 // Meta Data Emission
3745 //===----------------------------------------------------------------------===//
3747 void RewriteObjC::RewriteObjCClassMetaData(ObjCImplementationDecl
*IDecl
,
3748 std::string
&Result
) {
3749 ObjCInterfaceDecl
*CDecl
= IDecl
->getClassInterface();
3751 // Explictly declared @interface's are already synthesized.
3752 if (CDecl
->isImplicitInterfaceDecl()) {
3753 // FIXME: Implementation of a class with no @interface (legacy) doese not
3754 // produce correct synthesis as yet.
3755 SynthesizeObjCInternalStruct(CDecl
, Result
);
3758 // Build _objc_ivar_list metadata for classes ivars if needed
3759 unsigned NumIvars
= !IDecl
->ivar_empty()
3760 ? IDecl
->ivar_size()
3761 : (CDecl
? CDecl
->ivar_size() : 0);
3763 static bool objc_ivar
= false;
3765 /* struct _objc_ivar {
3771 Result
+= "\nstruct _objc_ivar {\n";
3772 Result
+= "\tchar *ivar_name;\n";
3773 Result
+= "\tchar *ivar_type;\n";
3774 Result
+= "\tint ivar_offset;\n";
3782 struct _objc_ivar ivar_list[nIvars];
3785 Result
+= "\nstatic struct {\n";
3786 Result
+= "\tint ivar_count;\n";
3787 Result
+= "\tstruct _objc_ivar ivar_list[";
3788 Result
+= utostr(NumIvars
);
3789 Result
+= "];\n} _OBJC_INSTANCE_VARIABLES_";
3790 Result
+= IDecl
->getNameAsString();
3791 Result
+= " __attribute__ ((used, section (\"__OBJC, __instance_vars\")))= "
3793 Result
+= utostr(NumIvars
);
3796 ObjCInterfaceDecl::ivar_iterator IVI
, IVE
;
3797 llvm::SmallVector
<ObjCIvarDecl
*, 8> IVars
;
3798 if (!IDecl
->ivar_empty()) {
3799 for (ObjCInterfaceDecl::ivar_iterator
3800 IV
= IDecl
->ivar_begin(), IVEnd
= IDecl
->ivar_end();
3802 IVars
.push_back(*IV
);
3803 IVI
= IDecl
->ivar_begin();
3804 IVE
= IDecl
->ivar_end();
3806 IVI
= CDecl
->ivar_begin();
3807 IVE
= CDecl
->ivar_end();
3809 Result
+= "\t,{{\"";
3810 Result
+= (*IVI
)->getNameAsString();
3812 std::string TmpString
, StrEncoding
;
3813 Context
->getObjCEncodingForType((*IVI
)->getType(), TmpString
, *IVI
);
3814 QuoteDoublequotes(TmpString
, StrEncoding
);
3815 Result
+= StrEncoding
;
3817 SynthesizeIvarOffsetComputation(*IVI
, Result
);
3819 for (++IVI
; IVI
!= IVE
; ++IVI
) {
3820 Result
+= "\t ,{\"";
3821 Result
+= (*IVI
)->getNameAsString();
3823 std::string TmpString
, StrEncoding
;
3824 Context
->getObjCEncodingForType((*IVI
)->getType(), TmpString
, *IVI
);
3825 QuoteDoublequotes(TmpString
, StrEncoding
);
3826 Result
+= StrEncoding
;
3828 SynthesizeIvarOffsetComputation((*IVI
), Result
);
3832 Result
+= "\t }\n};\n";
3835 // Build _objc_method_list for class's instance methods if needed
3836 llvm::SmallVector
<ObjCMethodDecl
*, 32>
3837 InstanceMethods(IDecl
->instmeth_begin(), IDecl
->instmeth_end());
3839 // If any of our property implementations have associated getters or
3840 // setters, produce metadata for them as well.
3841 for (ObjCImplDecl::propimpl_iterator Prop
= IDecl
->propimpl_begin(),
3842 PropEnd
= IDecl
->propimpl_end();
3843 Prop
!= PropEnd
; ++Prop
) {
3844 if ((*Prop
)->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic
)
3846 if (!(*Prop
)->getPropertyIvarDecl())
3848 ObjCPropertyDecl
*PD
= (*Prop
)->getPropertyDecl();
3851 if (ObjCMethodDecl
*Getter
= PD
->getGetterMethodDecl())
3852 if (!Getter
->isDefined())
3853 InstanceMethods
.push_back(Getter
);
3854 if (PD
->isReadOnly())
3856 if (ObjCMethodDecl
*Setter
= PD
->getSetterMethodDecl())
3857 if (!Setter
->isDefined())
3858 InstanceMethods
.push_back(Setter
);
3860 RewriteObjCMethodsMetaData(InstanceMethods
.begin(), InstanceMethods
.end(),
3861 true, "", IDecl
->getName(), Result
);
3863 // Build _objc_method_list for class's class methods if needed
3864 RewriteObjCMethodsMetaData(IDecl
->classmeth_begin(), IDecl
->classmeth_end(),
3865 false, "", IDecl
->getName(), Result
);
3867 // Protocols referenced in class declaration?
3868 RewriteObjCProtocolListMetaData(CDecl
->getReferencedProtocols(),
3869 "CLASS", CDecl
->getName(), Result
);
3871 // Declaration of class/meta-class metadata
3872 /* struct _objc_class {
3873 struct _objc_class *isa; // or const char *root_class_name when metadata
3874 const char *super_class_name;
3879 struct _objc_ivar_list *ivars;
3880 struct _objc_method_list *methods;
3881 struct objc_cache *cache;
3882 struct objc_protocol_list *protocols;
3883 const char *ivar_layout;
3884 struct _objc_class_ext *ext;
3887 static bool objc_class
= false;
3889 Result
+= "\nstruct _objc_class {\n";
3890 Result
+= "\tstruct _objc_class *isa;\n";
3891 Result
+= "\tconst char *super_class_name;\n";
3892 Result
+= "\tchar *name;\n";
3893 Result
+= "\tlong version;\n";
3894 Result
+= "\tlong info;\n";
3895 Result
+= "\tlong instance_size;\n";
3896 Result
+= "\tstruct _objc_ivar_list *ivars;\n";
3897 Result
+= "\tstruct _objc_method_list *methods;\n";
3898 Result
+= "\tstruct objc_cache *cache;\n";
3899 Result
+= "\tstruct _objc_protocol_list *protocols;\n";
3900 Result
+= "\tconst char *ivar_layout;\n";
3901 Result
+= "\tstruct _objc_class_ext *ext;\n";
3906 // Meta-class metadata generation.
3907 ObjCInterfaceDecl
*RootClass
= 0;
3908 ObjCInterfaceDecl
*SuperClass
= CDecl
->getSuperClass();
3909 while (SuperClass
) {
3910 RootClass
= SuperClass
;
3911 SuperClass
= SuperClass
->getSuperClass();
3913 SuperClass
= CDecl
->getSuperClass();
3915 Result
+= "\nstatic struct _objc_class _OBJC_METACLASS_";
3916 Result
+= CDecl
->getNameAsString();
3917 Result
+= " __attribute__ ((used, section (\"__OBJC, __meta_class\")))= "
3918 "{\n\t(struct _objc_class *)\"";
3919 Result
+= (RootClass
? RootClass
->getNameAsString() : CDecl
->getNameAsString());
3924 Result
+= SuperClass
->getNameAsString();
3926 Result
+= CDecl
->getNameAsString();
3930 Result
+= ", 0, \"";
3931 Result
+= CDecl
->getNameAsString();
3934 // Set 'ivars' field for root class to 0. ObjC1 runtime does not use it.
3935 // 'info' field is initialized to CLS_META(2) for metaclass
3936 Result
+= ", 0,2, sizeof(struct _objc_class), 0";
3937 if (IDecl
->classmeth_begin() != IDecl
->classmeth_end()) {
3938 Result
+= "\n\t, (struct _objc_method_list *)&_OBJC_CLASS_METHODS_";
3939 Result
+= IDecl
->getNameAsString();
3944 if (CDecl
->protocol_begin() != CDecl
->protocol_end()) {
3945 Result
+= "\t,0, (struct _objc_protocol_list *)&_OBJC_CLASS_PROTOCOLS_";
3946 Result
+= CDecl
->getNameAsString();
3950 Result
+= "\t,0,0,0,0\n";
3953 // class metadata generation.
3954 Result
+= "\nstatic struct _objc_class _OBJC_CLASS_";
3955 Result
+= CDecl
->getNameAsString();
3956 Result
+= " __attribute__ ((used, section (\"__OBJC, __class\")))= "
3957 "{\n\t&_OBJC_METACLASS_";
3958 Result
+= CDecl
->getNameAsString();
3961 Result
+= SuperClass
->getNameAsString();
3963 Result
+= CDecl
->getNameAsString();
3967 Result
+= ", 0, \"";
3968 Result
+= CDecl
->getNameAsString();
3971 // 'info' field is initialized to CLS_CLASS(1) for class
3973 if (!ObjCSynthesizedStructs
.count(CDecl
))
3976 // class has size. Must synthesize its size.
3977 Result
+= ",sizeof(struct ";
3978 Result
+= CDecl
->getNameAsString();
3979 if (LangOpts
.Microsoft
)
3984 Result
+= ", (struct _objc_ivar_list *)&_OBJC_INSTANCE_VARIABLES_";
3985 Result
+= CDecl
->getNameAsString();
3990 if (IDecl
->instmeth_begin() != IDecl
->instmeth_end()) {
3991 Result
+= ", (struct _objc_method_list *)&_OBJC_INSTANCE_METHODS_";
3992 Result
+= CDecl
->getNameAsString();
3993 Result
+= ", 0\n\t";
3997 if (CDecl
->protocol_begin() != CDecl
->protocol_end()) {
3998 Result
+= ", (struct _objc_protocol_list*)&_OBJC_CLASS_PROTOCOLS_";
3999 Result
+= CDecl
->getNameAsString();
4000 Result
+= ", 0,0\n";
4003 Result
+= ",0,0,0\n";
4007 /// RewriteImplementations - This routine rewrites all method implementations
4008 /// and emits meta-data.
4010 void RewriteObjC::RewriteImplementations() {
4011 int ClsDefCount
= ClassImplementation
.size();
4012 int CatDefCount
= CategoryImplementation
.size();
4014 // Rewrite implemented methods
4015 for (int i
= 0; i
< ClsDefCount
; i
++)
4016 RewriteImplementationDecl(ClassImplementation
[i
]);
4018 for (int i
= 0; i
< CatDefCount
; i
++)
4019 RewriteImplementationDecl(CategoryImplementation
[i
]);
4022 void RewriteObjC::SynthesizeMetaDataIntoBuffer(std::string
&Result
) {
4023 int ClsDefCount
= ClassImplementation
.size();
4024 int CatDefCount
= CategoryImplementation
.size();
4026 // For each implemented class, write out all its meta data.
4027 for (int i
= 0; i
< ClsDefCount
; i
++)
4028 RewriteObjCClassMetaData(ClassImplementation
[i
], Result
);
4030 // For each implemented category, write out all its meta data.
4031 for (int i
= 0; i
< CatDefCount
; i
++)
4032 RewriteObjCCategoryImplDecl(CategoryImplementation
[i
], Result
);
4034 // Write objc_symtab metadata
4042 void *defs[cls_def_cnt + cat_def_cnt];
4046 Result
+= "\nstruct _objc_symtab {\n";
4047 Result
+= "\tlong sel_ref_cnt;\n";
4048 Result
+= "\tSEL *refs;\n";
4049 Result
+= "\tshort cls_def_cnt;\n";
4050 Result
+= "\tshort cat_def_cnt;\n";
4051 Result
+= "\tvoid *defs[" + utostr(ClsDefCount
+ CatDefCount
)+ "];\n";
4054 Result
+= "static struct _objc_symtab "
4055 "_OBJC_SYMBOLS __attribute__((used, section (\"__OBJC, __symbols\")))= {\n";
4056 Result
+= "\t0, 0, " + utostr(ClsDefCount
)
4057 + ", " + utostr(CatDefCount
) + "\n";
4058 for (int i
= 0; i
< ClsDefCount
; i
++) {
4059 Result
+= "\t,&_OBJC_CLASS_";
4060 Result
+= ClassImplementation
[i
]->getNameAsString();
4064 for (int i
= 0; i
< CatDefCount
; i
++) {
4065 Result
+= "\t,&_OBJC_CATEGORY_";
4066 Result
+= CategoryImplementation
[i
]->getClassInterface()->getNameAsString();
4068 Result
+= CategoryImplementation
[i
]->getNameAsString();
4074 // Write objc_module metadata
4077 struct _objc_module {
4081 struct _objc_symtab *symtab;
4085 Result
+= "\nstruct _objc_module {\n";
4086 Result
+= "\tlong version;\n";
4087 Result
+= "\tlong size;\n";
4088 Result
+= "\tconst char *name;\n";
4089 Result
+= "\tstruct _objc_symtab *symtab;\n";
4091 Result
+= "static struct _objc_module "
4092 "_OBJC_MODULES __attribute__ ((used, section (\"__OBJC, __module_info\")))= {\n";
4093 Result
+= "\t" + utostr(OBJC_ABI_VERSION
) +
4094 ", sizeof(struct _objc_module), \"\", &_OBJC_SYMBOLS\n";
4097 if (LangOpts
.Microsoft
) {
4098 if (ProtocolExprDecls
.size()) {
4099 Result
+= "#pragma section(\".objc_protocol$B\",long,read,write)\n";
4100 Result
+= "#pragma data_seg(push, \".objc_protocol$B\")\n";
4101 for (llvm::SmallPtrSet
<ObjCProtocolDecl
*,8>::iterator I
= ProtocolExprDecls
.begin(),
4102 E
= ProtocolExprDecls
.end(); I
!= E
; ++I
) {
4103 Result
+= "static struct _objc_protocol *_POINTER_OBJC_PROTOCOL_";
4104 Result
+= (*I
)->getNameAsString();
4105 Result
+= " = &_OBJC_PROTOCOL_";
4106 Result
+= (*I
)->getNameAsString();
4109 Result
+= "#pragma data_seg(pop)\n\n";
4111 Result
+= "#pragma section(\".objc_module_info$B\",long,read,write)\n";
4112 Result
+= "#pragma data_seg(push, \".objc_module_info$B\")\n";
4113 Result
+= "static struct _objc_module *_POINTER_OBJC_MODULES = ";
4114 Result
+= "&_OBJC_MODULES;\n";
4115 Result
+= "#pragma data_seg(pop)\n\n";
4119 void RewriteObjC::RewriteByRefString(std::string
&ResultStr
,
4120 const std::string
&Name
,
4121 ValueDecl
*VD
, bool def
) {
4122 assert(BlockByRefDeclNo
.count(VD
) &&
4123 "RewriteByRefString: ByRef decl missing");
4125 ResultStr
+= "struct ";
4126 ResultStr
+= "__Block_byref_" + Name
+
4127 "_" + utostr(BlockByRefDeclNo
[VD
]) ;
4130 static bool HasLocalVariableExternalStorage(ValueDecl
*VD
) {
4131 if (VarDecl
*Var
= dyn_cast
<VarDecl
>(VD
))
4132 return (Var
->isFunctionOrMethodVarDecl() && !Var
->hasLocalStorage());
4136 std::string
RewriteObjC::SynthesizeBlockFunc(BlockExpr
*CE
, int i
,
4137 llvm::StringRef funcName
,
4139 const FunctionType
*AFT
= CE
->getFunctionType();
4140 QualType RT
= AFT
->getResultType();
4141 std::string StructRef
= "struct " + Tag
;
4142 std::string S
= "static " + RT
.getAsString(Context
->PrintingPolicy
) + " __" +
4143 funcName
.str() + "_" + "block_func_" + utostr(i
);
4145 BlockDecl
*BD
= CE
->getBlockDecl();
4147 if (isa
<FunctionNoProtoType
>(AFT
)) {
4148 // No user-supplied arguments. Still need to pass in a pointer to the
4149 // block (to reference imported block decl refs).
4150 S
+= "(" + StructRef
+ " *__cself)";
4151 } else if (BD
->param_empty()) {
4152 S
+= "(" + StructRef
+ " *__cself)";
4154 const FunctionProtoType
*FT
= cast
<FunctionProtoType
>(AFT
);
4155 assert(FT
&& "SynthesizeBlockFunc: No function proto");
4157 // first add the implicit argument.
4158 S
+= StructRef
+ " *__cself, ";
4159 std::string ParamStr
;
4160 for (BlockDecl::param_iterator AI
= BD
->param_begin(),
4161 E
= BD
->param_end(); AI
!= E
; ++AI
) {
4162 if (AI
!= BD
->param_begin()) S
+= ", ";
4163 ParamStr
= (*AI
)->getNameAsString();
4164 QualType QT
= (*AI
)->getType();
4165 if (convertBlockPointerToFunctionPointer(QT
))
4166 QT
.getAsStringInternal(ParamStr
, Context
->PrintingPolicy
);
4168 QT
.getAsStringInternal(ParamStr
, Context
->PrintingPolicy
);
4171 if (FT
->isVariadic()) {
4172 if (!BD
->param_empty()) S
+= ", ";
4179 // Create local declarations to avoid rewriting all closure decl ref exprs.
4180 // First, emit a declaration for all "by ref" decls.
4181 for (llvm::SmallVector
<ValueDecl
*,8>::iterator I
= BlockByRefDecls
.begin(),
4182 E
= BlockByRefDecls
.end(); I
!= E
; ++I
) {
4184 std::string Name
= (*I
)->getNameAsString();
4185 std::string TypeString
;
4186 RewriteByRefString(TypeString
, Name
, (*I
));
4188 Name
= TypeString
+ Name
;
4189 S
+= Name
+ " = __cself->" + (*I
)->getNameAsString() + "; // bound by ref\n";
4191 // Next, emit a declaration for all "by copy" declarations.
4192 for (llvm::SmallVector
<ValueDecl
*,8>::iterator I
= BlockByCopyDecls
.begin(),
4193 E
= BlockByCopyDecls
.end(); I
!= E
; ++I
) {
4195 // Handle nested closure invocation. For example:
4197 // void (^myImportedClosure)(void);
4198 // myImportedClosure = ^(void) { setGlobalInt(x + y); };
4200 // void (^anotherClosure)(void);
4201 // anotherClosure = ^(void) {
4202 // myImportedClosure(); // import and invoke the closure
4205 if (isTopLevelBlockPointerType((*I
)->getType())) {
4206 RewriteBlockPointerTypeVariable(S
, (*I
));
4208 RewriteBlockPointerType(S
, (*I
)->getType());
4210 S
+= "__cself->" + (*I
)->getNameAsString() + "; // bound by copy\n";
4213 std::string Name
= (*I
)->getNameAsString();
4214 QualType QT
= (*I
)->getType();
4215 if (HasLocalVariableExternalStorage(*I
))
4216 QT
= Context
->getPointerType(QT
);
4217 QT
.getAsStringInternal(Name
, Context
->PrintingPolicy
);
4218 S
+= Name
+ " = __cself->" +
4219 (*I
)->getNameAsString() + "; // bound by copy\n";
4222 std::string RewrittenStr
= RewrittenBlockExprs
[CE
];
4223 const char *cstr
= RewrittenStr
.c_str();
4224 while (*cstr
++ != '{') ;
4230 std::string
RewriteObjC::SynthesizeBlockHelperFuncs(BlockExpr
*CE
, int i
,
4231 llvm::StringRef funcName
,
4233 std::string StructRef
= "struct " + Tag
;
4234 std::string S
= "static void __";
4237 S
+= "_block_copy_" + utostr(i
);
4238 S
+= "(" + StructRef
;
4239 S
+= "*dst, " + StructRef
;
4241 for (llvm::SmallPtrSet
<ValueDecl
*,8>::iterator I
= ImportedBlockDecls
.begin(),
4242 E
= ImportedBlockDecls
.end(); I
!= E
; ++I
) {
4243 S
+= "_Block_object_assign((void*)&dst->";
4244 S
+= (*I
)->getNameAsString();
4245 S
+= ", (void*)src->";
4246 S
+= (*I
)->getNameAsString();
4247 if (BlockByRefDeclsPtrSet
.count((*I
)))
4248 S
+= ", " + utostr(BLOCK_FIELD_IS_BYREF
) + "/*BLOCK_FIELD_IS_BYREF*/);";
4250 S
+= ", " + utostr(BLOCK_FIELD_IS_OBJECT
) + "/*BLOCK_FIELD_IS_OBJECT*/);";
4254 S
+= "\nstatic void __";
4256 S
+= "_block_dispose_" + utostr(i
);
4257 S
+= "(" + StructRef
;
4259 for (llvm::SmallPtrSet
<ValueDecl
*,8>::iterator I
= ImportedBlockDecls
.begin(),
4260 E
= ImportedBlockDecls
.end(); I
!= E
; ++I
) {
4261 S
+= "_Block_object_dispose((void*)src->";
4262 S
+= (*I
)->getNameAsString();
4263 if (BlockByRefDeclsPtrSet
.count((*I
)))
4264 S
+= ", " + utostr(BLOCK_FIELD_IS_BYREF
) + "/*BLOCK_FIELD_IS_BYREF*/);";
4266 S
+= ", " + utostr(BLOCK_FIELD_IS_OBJECT
) + "/*BLOCK_FIELD_IS_OBJECT*/);";
4272 std::string
RewriteObjC::SynthesizeBlockImpl(BlockExpr
*CE
, std::string Tag
,
4274 std::string S
= "\nstruct " + Tag
;
4275 std::string Constructor
= " " + Tag
;
4277 S
+= " {\n struct __block_impl impl;\n";
4278 S
+= " struct " + Desc
;
4281 Constructor
+= "(void *fp, "; // Invoke function pointer.
4282 Constructor
+= "struct " + Desc
; // Descriptor pointer.
4283 Constructor
+= " *desc";
4285 if (BlockDeclRefs
.size()) {
4286 // Output all "by copy" declarations.
4287 for (llvm::SmallVector
<ValueDecl
*,8>::iterator I
= BlockByCopyDecls
.begin(),
4288 E
= BlockByCopyDecls
.end(); I
!= E
; ++I
) {
4290 std::string FieldName
= (*I
)->getNameAsString();
4291 std::string ArgName
= "_" + FieldName
;
4292 // Handle nested closure invocation. For example:
4294 // void (^myImportedBlock)(void);
4295 // myImportedBlock = ^(void) { setGlobalInt(x + y); };
4297 // void (^anotherBlock)(void);
4298 // anotherBlock = ^(void) {
4299 // myImportedBlock(); // import and invoke the closure
4302 if (isTopLevelBlockPointerType((*I
)->getType())) {
4303 S
+= "struct __block_impl *";
4304 Constructor
+= ", void *" + ArgName
;
4306 QualType QT
= (*I
)->getType();
4307 if (HasLocalVariableExternalStorage(*I
))
4308 QT
= Context
->getPointerType(QT
);
4309 QT
.getAsStringInternal(FieldName
, Context
->PrintingPolicy
);
4310 QT
.getAsStringInternal(ArgName
, Context
->PrintingPolicy
);
4311 Constructor
+= ", " + ArgName
;
4313 S
+= FieldName
+ ";\n";
4315 // Output all "by ref" declarations.
4316 for (llvm::SmallVector
<ValueDecl
*,8>::iterator I
= BlockByRefDecls
.begin(),
4317 E
= BlockByRefDecls
.end(); I
!= E
; ++I
) {
4319 std::string FieldName
= (*I
)->getNameAsString();
4320 std::string ArgName
= "_" + FieldName
;
4321 // Handle nested closure invocation. For example:
4323 // void (^myImportedBlock)(void);
4324 // myImportedBlock = ^(void) { setGlobalInt(x + y); };
4326 // void (^anotherBlock)(void);
4327 // anotherBlock = ^(void) {
4328 // myImportedBlock(); // import and invoke the closure
4331 if (isTopLevelBlockPointerType((*I
)->getType())) {
4332 S
+= "struct __block_impl *";
4333 Constructor
+= ", void *" + ArgName
;
4335 std::string TypeString
;
4336 RewriteByRefString(TypeString
, FieldName
, (*I
));
4338 FieldName
= TypeString
+ FieldName
;
4339 ArgName
= TypeString
+ ArgName
;
4340 Constructor
+= ", " + ArgName
;
4342 S
+= FieldName
+ "; // by ref\n";
4344 // Finish writing the constructor.
4345 Constructor
+= ", int flags=0)";
4346 // Initialize all "by copy" arguments.
4347 bool firsTime
= true;
4348 for (llvm::SmallVector
<ValueDecl
*,8>::iterator I
= BlockByCopyDecls
.begin(),
4349 E
= BlockByCopyDecls
.end(); I
!= E
; ++I
) {
4350 std::string Name
= (*I
)->getNameAsString();
4352 Constructor
+= " : ";
4356 Constructor
+= ", ";
4357 if (isTopLevelBlockPointerType((*I
)->getType()))
4358 Constructor
+= Name
+ "((struct __block_impl *)_" + Name
+ ")";
4360 Constructor
+= Name
+ "(_" + Name
+ ")";
4362 // Initialize all "by ref" arguments.
4363 for (llvm::SmallVector
<ValueDecl
*,8>::iterator I
= BlockByRefDecls
.begin(),
4364 E
= BlockByRefDecls
.end(); I
!= E
; ++I
) {
4365 std::string Name
= (*I
)->getNameAsString();
4367 Constructor
+= " : ";
4371 Constructor
+= ", ";
4372 if (isTopLevelBlockPointerType((*I
)->getType()))
4373 Constructor
+= Name
+ "((struct __block_impl *)_"
4374 + Name
+ "->__forwarding)";
4376 Constructor
+= Name
+ "(_" + Name
+ "->__forwarding)";
4379 Constructor
+= " {\n";
4381 Constructor
+= " impl.isa = &_NSConcreteGlobalBlock;\n";
4383 Constructor
+= " impl.isa = &_NSConcreteStackBlock;\n";
4384 Constructor
+= " impl.Flags = flags;\n impl.FuncPtr = fp;\n";
4386 Constructor
+= " Desc = desc;\n";
4388 // Finish writing the constructor.
4389 Constructor
+= ", int flags=0) {\n";
4391 Constructor
+= " impl.isa = &_NSConcreteGlobalBlock;\n";
4393 Constructor
+= " impl.isa = &_NSConcreteStackBlock;\n";
4394 Constructor
+= " impl.Flags = flags;\n impl.FuncPtr = fp;\n";
4395 Constructor
+= " Desc = desc;\n";
4398 Constructor
+= "}\n";
4404 std::string
RewriteObjC::SynthesizeBlockDescriptor(std::string DescTag
,
4405 std::string ImplTag
, int i
,
4406 llvm::StringRef FunName
,
4408 std::string S
= "\nstatic struct " + DescTag
;
4410 S
+= " {\n unsigned long reserved;\n";
4411 S
+= " unsigned long Block_size;\n";
4413 S
+= " void (*copy)(struct ";
4414 S
+= ImplTag
; S
+= "*, struct ";
4415 S
+= ImplTag
; S
+= "*);\n";
4417 S
+= " void (*dispose)(struct ";
4418 S
+= ImplTag
; S
+= "*);\n";
4422 S
+= DescTag
+ "_DATA = { 0, sizeof(struct ";
4425 S
+= ", __" + FunName
.str() + "_block_copy_" + utostr(i
);
4426 S
+= ", __" + FunName
.str() + "_block_dispose_" + utostr(i
);
4432 void RewriteObjC::SynthesizeBlockLiterals(SourceLocation FunLocStart
,
4433 llvm::StringRef FunName
) {
4434 // Insert declaration for the function in which block literal is used.
4435 if (CurFunctionDeclToDeclareForBlock
&& !Blocks
.empty())
4436 RewriteBlockLiteralFunctionDecl(CurFunctionDeclToDeclareForBlock
);
4437 bool RewriteSC
= (GlobalVarDecl
&&
4439 GlobalVarDecl
->getStorageClass() == SC_Static
&&
4440 GlobalVarDecl
->getType().getCVRQualifiers());
4442 std::string
SC(" void __");
4443 SC
+= GlobalVarDecl
->getNameAsString();
4445 InsertText(FunLocStart
, SC
);
4448 // Insert closures that were part of the function.
4449 for (unsigned i
= 0, count
=0; i
< Blocks
.size(); i
++) {
4450 CollectBlockDeclRefInfo(Blocks
[i
]);
4451 // Need to copy-in the inner copied-in variables not actually used in this
4453 for (int j
= 0; j
< InnerDeclRefsCount
[i
]; j
++) {
4454 BlockDeclRefExpr
*Exp
= InnerDeclRefs
[count
++];
4455 ValueDecl
*VD
= Exp
->getDecl();
4456 BlockDeclRefs
.push_back(Exp
);
4457 if (!Exp
->isByRef() && !BlockByCopyDeclsPtrSet
.count(VD
)) {
4458 BlockByCopyDeclsPtrSet
.insert(VD
);
4459 BlockByCopyDecls
.push_back(VD
);
4461 if (Exp
->isByRef() && !BlockByRefDeclsPtrSet
.count(VD
)) {
4462 BlockByRefDeclsPtrSet
.insert(VD
);
4463 BlockByRefDecls
.push_back(VD
);
4465 // imported objects in the inner blocks not used in the outer
4466 // blocks must be copied/disposed in the outer block as well.
4467 if (Exp
->isByRef() ||
4468 VD
->getType()->isObjCObjectPointerType() ||
4469 VD
->getType()->isBlockPointerType())
4470 ImportedBlockDecls
.insert(VD
);
4473 std::string ImplTag
= "__" + FunName
.str() + "_block_impl_" + utostr(i
);
4474 std::string DescTag
= "__" + FunName
.str() + "_block_desc_" + utostr(i
);
4476 std::string CI
= SynthesizeBlockImpl(Blocks
[i
], ImplTag
, DescTag
);
4478 InsertText(FunLocStart
, CI
);
4480 std::string CF
= SynthesizeBlockFunc(Blocks
[i
], i
, FunName
, ImplTag
);
4482 InsertText(FunLocStart
, CF
);
4484 if (ImportedBlockDecls
.size()) {
4485 std::string HF
= SynthesizeBlockHelperFuncs(Blocks
[i
], i
, FunName
, ImplTag
);
4486 InsertText(FunLocStart
, HF
);
4488 std::string BD
= SynthesizeBlockDescriptor(DescTag
, ImplTag
, i
, FunName
,
4489 ImportedBlockDecls
.size() > 0);
4490 InsertText(FunLocStart
, BD
);
4492 BlockDeclRefs
.clear();
4493 BlockByRefDecls
.clear();
4494 BlockByRefDeclsPtrSet
.clear();
4495 BlockByCopyDecls
.clear();
4496 BlockByCopyDeclsPtrSet
.clear();
4497 ImportedBlockDecls
.clear();
4500 // Must insert any 'const/volatile/static here. Since it has been
4501 // removed as result of rewriting of block literals.
4503 if (GlobalVarDecl
->getStorageClass() == SC_Static
)
4505 if (GlobalVarDecl
->getType().isConstQualified())
4507 if (GlobalVarDecl
->getType().isVolatileQualified())
4509 if (GlobalVarDecl
->getType().isRestrictQualified())
4511 InsertText(FunLocStart
, SC
);
4515 InnerDeclRefsCount
.clear();
4516 InnerDeclRefs
.clear();
4517 RewrittenBlockExprs
.clear();
4520 void RewriteObjC::InsertBlockLiteralsWithinFunction(FunctionDecl
*FD
) {
4521 SourceLocation FunLocStart
= FD
->getTypeSpecStartLoc();
4522 llvm::StringRef FuncName
= FD
->getName();
4524 SynthesizeBlockLiterals(FunLocStart
, FuncName
);
4527 static void BuildUniqueMethodName(std::string
&Name
,
4528 ObjCMethodDecl
*MD
) {
4529 ObjCInterfaceDecl
*IFace
= MD
->getClassInterface();
4530 Name
= IFace
->getName();
4531 Name
+= "__" + MD
->getSelector().getAsString();
4532 // Convert colons to underscores.
4533 std::string::size_type loc
= 0;
4534 while ((loc
= Name
.find(":", loc
)) != std::string::npos
)
4535 Name
.replace(loc
, 1, "_");
4538 void RewriteObjC::InsertBlockLiteralsWithinMethod(ObjCMethodDecl
*MD
) {
4539 //fprintf(stderr,"In InsertBlockLiteralsWitinMethod\n");
4540 //SourceLocation FunLocStart = MD->getLocStart();
4541 SourceLocation FunLocStart
= MD
->getLocStart();
4542 std::string FuncName
;
4543 BuildUniqueMethodName(FuncName
, MD
);
4544 SynthesizeBlockLiterals(FunLocStart
, FuncName
);
4547 void RewriteObjC::GetBlockDeclRefExprs(Stmt
*S
) {
4548 for (Stmt::child_iterator CI
= S
->child_begin(), E
= S
->child_end();
4551 if (BlockExpr
*CBE
= dyn_cast
<BlockExpr
>(*CI
))
4552 GetBlockDeclRefExprs(CBE
->getBody());
4554 GetBlockDeclRefExprs(*CI
);
4556 // Handle specific things.
4557 if (BlockDeclRefExpr
*CDRE
= dyn_cast
<BlockDeclRefExpr
>(S
)) {
4558 // FIXME: Handle enums.
4559 if (!isa
<FunctionDecl
>(CDRE
->getDecl()))
4560 BlockDeclRefs
.push_back(CDRE
);
4562 else if (DeclRefExpr
*DRE
= dyn_cast
<DeclRefExpr
>(S
))
4563 if (HasLocalVariableExternalStorage(DRE
->getDecl())) {
4564 BlockDeclRefExpr
*BDRE
=
4565 new (Context
)BlockDeclRefExpr(DRE
->getDecl(), DRE
->getType(),
4566 VK_LValue
, DRE
->getLocation(), false);
4567 BlockDeclRefs
.push_back(BDRE
);
4573 void RewriteObjC::GetInnerBlockDeclRefExprs(Stmt
*S
,
4574 llvm::SmallVector
<BlockDeclRefExpr
*, 8> &InnerBlockDeclRefs
,
4575 llvm::SmallPtrSet
<const DeclContext
*, 8> &InnerContexts
) {
4576 for (Stmt::child_iterator CI
= S
->child_begin(), E
= S
->child_end();
4579 if (BlockExpr
*CBE
= dyn_cast
<BlockExpr
>(*CI
)) {
4580 InnerContexts
.insert(cast
<DeclContext
>(CBE
->getBlockDecl()));
4581 GetInnerBlockDeclRefExprs(CBE
->getBody(),
4586 GetInnerBlockDeclRefExprs(*CI
,
4591 // Handle specific things.
4592 if (BlockDeclRefExpr
*CDRE
= dyn_cast
<BlockDeclRefExpr
>(S
)) {
4593 if (!isa
<FunctionDecl
>(CDRE
->getDecl()) &&
4594 !InnerContexts
.count(CDRE
->getDecl()->getDeclContext()))
4595 InnerBlockDeclRefs
.push_back(CDRE
);
4597 else if (DeclRefExpr
*DRE
= dyn_cast
<DeclRefExpr
>(S
)) {
4598 if (VarDecl
*Var
= dyn_cast
<VarDecl
>(DRE
->getDecl()))
4599 if (Var
->isFunctionOrMethodVarDecl())
4600 ImportedLocalExternalDecls
.insert(Var
);
4606 /// convertFunctionTypeOfBlocks - This routine converts a function type
4607 /// whose result type may be a block pointer or whose argument type(s)
4608 /// might be block pointers to an equivalent funtion type replacing
4609 /// all block pointers to function pointers.
4610 QualType
RewriteObjC::convertFunctionTypeOfBlocks(const FunctionType
*FT
) {
4611 const FunctionProtoType
*FTP
= dyn_cast
<FunctionProtoType
>(FT
);
4612 // FTP will be null for closures that don't take arguments.
4613 // Generate a funky cast.
4614 llvm::SmallVector
<QualType
, 8> ArgTypes
;
4615 QualType Res
= FT
->getResultType();
4616 bool HasBlockType
= convertBlockPointerToFunctionPointer(Res
);
4619 for (FunctionProtoType::arg_type_iterator I
= FTP
->arg_type_begin(),
4620 E
= FTP
->arg_type_end(); I
&& (I
!= E
); ++I
) {
4622 // Make sure we convert "t (^)(...)" to "t (*)(...)".
4623 if (convertBlockPointerToFunctionPointer(t
))
4624 HasBlockType
= true;
4625 ArgTypes
.push_back(t
);
4629 // FIXME. Does this work if block takes no argument but has a return type
4630 // which is of block type?
4632 FuncType
= getSimpleFunctionType(Res
, &ArgTypes
[0], ArgTypes
.size());
4633 else FuncType
= QualType(FT
, 0);
4637 Stmt
*RewriteObjC::SynthesizeBlockCall(CallExpr
*Exp
, const Expr
*BlockExp
) {
4638 // Navigate to relevant type information.
4639 const BlockPointerType
*CPT
= 0;
4641 if (const DeclRefExpr
*DRE
= dyn_cast
<DeclRefExpr
>(BlockExp
)) {
4642 CPT
= DRE
->getType()->getAs
<BlockPointerType
>();
4643 } else if (const BlockDeclRefExpr
*CDRE
=
4644 dyn_cast
<BlockDeclRefExpr
>(BlockExp
)) {
4645 CPT
= CDRE
->getType()->getAs
<BlockPointerType
>();
4646 } else if (const MemberExpr
*MExpr
= dyn_cast
<MemberExpr
>(BlockExp
)) {
4647 CPT
= MExpr
->getType()->getAs
<BlockPointerType
>();
4649 else if (const ParenExpr
*PRE
= dyn_cast
<ParenExpr
>(BlockExp
)) {
4650 return SynthesizeBlockCall(Exp
, PRE
->getSubExpr());
4652 else if (const ImplicitCastExpr
*IEXPR
= dyn_cast
<ImplicitCastExpr
>(BlockExp
))
4653 CPT
= IEXPR
->getType()->getAs
<BlockPointerType
>();
4654 else if (const ConditionalOperator
*CEXPR
=
4655 dyn_cast
<ConditionalOperator
>(BlockExp
)) {
4656 Expr
*LHSExp
= CEXPR
->getLHS();
4657 Stmt
*LHSStmt
= SynthesizeBlockCall(Exp
, LHSExp
);
4658 Expr
*RHSExp
= CEXPR
->getRHS();
4659 Stmt
*RHSStmt
= SynthesizeBlockCall(Exp
, RHSExp
);
4660 Expr
*CONDExp
= CEXPR
->getCond();
4661 ConditionalOperator
*CondExpr
=
4662 new (Context
) ConditionalOperator(CONDExp
,
4663 SourceLocation(), cast
<Expr
>(LHSStmt
),
4664 SourceLocation(), cast
<Expr
>(RHSStmt
),
4666 Exp
->getType(), VK_RValue
, OK_Ordinary
);
4668 } else if (const ObjCIvarRefExpr
*IRE
= dyn_cast
<ObjCIvarRefExpr
>(BlockExp
)) {
4669 CPT
= IRE
->getType()->getAs
<BlockPointerType
>();
4671 assert(1 && "RewriteBlockClass: Bad type");
4673 assert(CPT
&& "RewriteBlockClass: Bad type");
4674 const FunctionType
*FT
= CPT
->getPointeeType()->getAs
<FunctionType
>();
4675 assert(FT
&& "RewriteBlockClass: Bad type");
4676 const FunctionProtoType
*FTP
= dyn_cast
<FunctionProtoType
>(FT
);
4677 // FTP will be null for closures that don't take arguments.
4679 RecordDecl
*RD
= RecordDecl::Create(*Context
, TTK_Struct
, TUDecl
,
4681 &Context
->Idents
.get("__block_impl"));
4682 QualType PtrBlock
= Context
->getPointerType(Context
->getTagDeclType(RD
));
4684 // Generate a funky cast.
4685 llvm::SmallVector
<QualType
, 8> ArgTypes
;
4687 // Push the block argument type.
4688 ArgTypes
.push_back(PtrBlock
);
4690 for (FunctionProtoType::arg_type_iterator I
= FTP
->arg_type_begin(),
4691 E
= FTP
->arg_type_end(); I
&& (I
!= E
); ++I
) {
4693 // Make sure we convert "t (^)(...)" to "t (*)(...)".
4694 if (!convertBlockPointerToFunctionPointer(t
))
4695 convertToUnqualifiedObjCType(t
);
4696 ArgTypes
.push_back(t
);
4699 // Now do the pointer to function cast.
4700 QualType PtrToFuncCastType
4701 = getSimpleFunctionType(Exp
->getType(), &ArgTypes
[0], ArgTypes
.size());
4703 PtrToFuncCastType
= Context
->getPointerType(PtrToFuncCastType
);
4705 CastExpr
*BlkCast
= NoTypeInfoCStyleCastExpr(Context
, PtrBlock
,
4707 const_cast<Expr
*>(BlockExp
));
4708 // Don't forget the parens to enforce the proper binding.
4709 ParenExpr
*PE
= new (Context
) ParenExpr(SourceLocation(), SourceLocation(),
4713 FieldDecl
*FD
= FieldDecl::Create(*Context
, 0, SourceLocation(),
4714 &Context
->Idents
.get("FuncPtr"), Context
->VoidPtrTy
, 0,
4715 /*BitWidth=*/0, /*Mutable=*/true);
4716 MemberExpr
*ME
= new (Context
) MemberExpr(PE
, true, FD
, SourceLocation(),
4717 FD
->getType(), VK_LValue
,
4721 CastExpr
*FunkCast
= NoTypeInfoCStyleCastExpr(Context
, PtrToFuncCastType
,
4723 PE
= new (Context
) ParenExpr(SourceLocation(), SourceLocation(), FunkCast
);
4725 llvm::SmallVector
<Expr
*, 8> BlkExprs
;
4726 // Add the implicit argument.
4727 BlkExprs
.push_back(BlkCast
);
4728 // Add the user arguments.
4729 for (CallExpr::arg_iterator I
= Exp
->arg_begin(),
4730 E
= Exp
->arg_end(); I
!= E
; ++I
) {
4731 BlkExprs
.push_back(*I
);
4733 CallExpr
*CE
= new (Context
) CallExpr(*Context
, PE
, &BlkExprs
[0],
4735 Exp
->getType(), VK_RValue
,
4740 // We need to return the rewritten expression to handle cases where the
4741 // BlockDeclRefExpr is embedded in another expression being rewritten.
4748 // void (^myblock)() = ^() {
4749 // [f test]; // f is a BlockDeclRefExpr embedded in a message (which is being rewritten).
4753 Stmt
*RewriteObjC::RewriteBlockDeclRefExpr(Expr
*DeclRefExp
) {
4754 // Rewrite the byref variable into BYREFVAR->__forwarding->BYREFVAR
4755 // for each DeclRefExp where BYREFVAR is name of the variable.
4757 bool isArrow
= true;
4758 if (BlockDeclRefExpr
*BDRE
= dyn_cast
<BlockDeclRefExpr
>(DeclRefExp
))
4759 VD
= BDRE
->getDecl();
4761 VD
= cast
<DeclRefExpr
>(DeclRefExp
)->getDecl();
4765 FieldDecl
*FD
= FieldDecl::Create(*Context
, 0, SourceLocation(),
4766 &Context
->Idents
.get("__forwarding"),
4767 Context
->VoidPtrTy
, 0,
4768 /*BitWidth=*/0, /*Mutable=*/true);
4769 MemberExpr
*ME
= new (Context
) MemberExpr(DeclRefExp
, isArrow
,
4770 FD
, SourceLocation(),
4771 FD
->getType(), VK_LValue
,
4774 llvm::StringRef Name
= VD
->getName();
4775 FD
= FieldDecl::Create(*Context
, 0, SourceLocation(),
4776 &Context
->Idents
.get(Name
),
4777 Context
->VoidPtrTy
, 0,
4778 /*BitWidth=*/0, /*Mutable=*/true);
4779 ME
= new (Context
) MemberExpr(ME
, true, FD
, SourceLocation(),
4780 DeclRefExp
->getType(), VK_LValue
, OK_Ordinary
);
4784 // Need parens to enforce precedence.
4785 ParenExpr
*PE
= new (Context
) ParenExpr(SourceLocation(), SourceLocation(),
4787 ReplaceStmt(DeclRefExp
, PE
);
4791 // Rewrites the imported local variable V with external storage
4792 // (static, extern, etc.) as *V
4794 Stmt
*RewriteObjC::RewriteLocalVariableExternalStorage(DeclRefExpr
*DRE
) {
4795 ValueDecl
*VD
= DRE
->getDecl();
4796 if (VarDecl
*Var
= dyn_cast
<VarDecl
>(VD
))
4797 if (!ImportedLocalExternalDecls
.count(Var
))
4799 Expr
*Exp
= new (Context
) UnaryOperator(DRE
, UO_Deref
, DRE
->getType(),
4800 VK_LValue
, OK_Ordinary
,
4801 DRE
->getLocation());
4802 // Need parens to enforce precedence.
4803 ParenExpr
*PE
= new (Context
) ParenExpr(SourceLocation(), SourceLocation(),
4805 ReplaceStmt(DRE
, PE
);
4809 void RewriteObjC::RewriteCastExpr(CStyleCastExpr
*CE
) {
4810 SourceLocation LocStart
= CE
->getLParenLoc();
4811 SourceLocation LocEnd
= CE
->getRParenLoc();
4813 // Need to avoid trying to rewrite synthesized casts.
4814 if (LocStart
.isInvalid())
4816 // Need to avoid trying to rewrite casts contained in macros.
4817 if (!Rewriter::isRewritable(LocStart
) || !Rewriter::isRewritable(LocEnd
))
4820 const char *startBuf
= SM
->getCharacterData(LocStart
);
4821 const char *endBuf
= SM
->getCharacterData(LocEnd
);
4822 QualType QT
= CE
->getType();
4823 const Type
* TypePtr
= QT
->getAs
<Type
>();
4824 if (isa
<TypeOfExprType
>(TypePtr
)) {
4825 const TypeOfExprType
*TypeOfExprTypePtr
= cast
<TypeOfExprType
>(TypePtr
);
4826 QT
= TypeOfExprTypePtr
->getUnderlyingExpr()->getType();
4827 std::string TypeAsString
= "(";
4828 RewriteBlockPointerType(TypeAsString
, QT
);
4829 TypeAsString
+= ")";
4830 ReplaceText(LocStart
, endBuf
-startBuf
+1, TypeAsString
);
4833 // advance the location to startArgList.
4834 const char *argPtr
= startBuf
;
4836 while (*argPtr
++ && (argPtr
< endBuf
)) {
4839 // Replace the '^' with '*'.
4840 LocStart
= LocStart
.getFileLocWithOffset(argPtr
-startBuf
);
4841 ReplaceText(LocStart
, 1, "*");
4848 void RewriteObjC::RewriteBlockPointerFunctionArgs(FunctionDecl
*FD
) {
4849 SourceLocation DeclLoc
= FD
->getLocation();
4850 unsigned parenCount
= 0;
4852 // We have 1 or more arguments that have closure pointers.
4853 const char *startBuf
= SM
->getCharacterData(DeclLoc
);
4854 const char *startArgList
= strchr(startBuf
, '(');
4856 assert((*startArgList
== '(') && "Rewriter fuzzy parser confused");
4859 // advance the location to startArgList.
4860 DeclLoc
= DeclLoc
.getFileLocWithOffset(startArgList
-startBuf
);
4861 assert((DeclLoc
.isValid()) && "Invalid DeclLoc");
4863 const char *argPtr
= startArgList
;
4865 while (*argPtr
++ && parenCount
) {
4868 // Replace the '^' with '*'.
4869 DeclLoc
= DeclLoc
.getFileLocWithOffset(argPtr
-startArgList
);
4870 ReplaceText(DeclLoc
, 1, "*");
4883 bool RewriteObjC::PointerTypeTakesAnyBlockArguments(QualType QT
) {
4884 const FunctionProtoType
*FTP
;
4885 const PointerType
*PT
= QT
->getAs
<PointerType
>();
4887 FTP
= PT
->getPointeeType()->getAs
<FunctionProtoType
>();
4889 const BlockPointerType
*BPT
= QT
->getAs
<BlockPointerType
>();
4890 assert(BPT
&& "BlockPointerTypeTakeAnyBlockArguments(): not a block pointer type");
4891 FTP
= BPT
->getPointeeType()->getAs
<FunctionProtoType
>();
4894 for (FunctionProtoType::arg_type_iterator I
= FTP
->arg_type_begin(),
4895 E
= FTP
->arg_type_end(); I
!= E
; ++I
)
4896 if (isTopLevelBlockPointerType(*I
))
4902 bool RewriteObjC::PointerTypeTakesAnyObjCQualifiedType(QualType QT
) {
4903 const FunctionProtoType
*FTP
;
4904 const PointerType
*PT
= QT
->getAs
<PointerType
>();
4906 FTP
= PT
->getPointeeType()->getAs
<FunctionProtoType
>();
4908 const BlockPointerType
*BPT
= QT
->getAs
<BlockPointerType
>();
4909 assert(BPT
&& "BlockPointerTypeTakeAnyBlockArguments(): not a block pointer type");
4910 FTP
= BPT
->getPointeeType()->getAs
<FunctionProtoType
>();
4913 for (FunctionProtoType::arg_type_iterator I
= FTP
->arg_type_begin(),
4914 E
= FTP
->arg_type_end(); I
!= E
; ++I
) {
4915 if ((*I
)->isObjCQualifiedIdType())
4917 if ((*I
)->isObjCObjectPointerType() &&
4918 (*I
)->getPointeeType()->isObjCQualifiedInterfaceType())
4926 void RewriteObjC::GetExtentOfArgList(const char *Name
, const char *&LParen
,
4927 const char *&RParen
) {
4928 const char *argPtr
= strchr(Name
, '(');
4929 assert((*argPtr
== '(') && "Rewriter fuzzy parser confused");
4931 LParen
= argPtr
; // output the start.
4932 argPtr
++; // skip past the left paren.
4933 unsigned parenCount
= 1;
4935 while (*argPtr
&& parenCount
) {
4937 case '(': parenCount
++; break;
4938 case ')': parenCount
--; break;
4941 if (parenCount
) argPtr
++;
4943 assert((*argPtr
== ')') && "Rewriter fuzzy parser confused");
4944 RParen
= argPtr
; // output the end
4947 void RewriteObjC::RewriteBlockPointerDecl(NamedDecl
*ND
) {
4948 if (FunctionDecl
*FD
= dyn_cast
<FunctionDecl
>(ND
)) {
4949 RewriteBlockPointerFunctionArgs(FD
);
4952 // Handle Variables and Typedefs.
4953 SourceLocation DeclLoc
= ND
->getLocation();
4955 if (VarDecl
*VD
= dyn_cast
<VarDecl
>(ND
))
4956 DeclT
= VD
->getType();
4957 else if (TypedefDecl
*TDD
= dyn_cast
<TypedefDecl
>(ND
))
4958 DeclT
= TDD
->getUnderlyingType();
4959 else if (FieldDecl
*FD
= dyn_cast
<FieldDecl
>(ND
))
4960 DeclT
= FD
->getType();
4962 assert(0 && "RewriteBlockPointerDecl(): Decl type not yet handled");
4964 const char *startBuf
= SM
->getCharacterData(DeclLoc
);
4965 const char *endBuf
= startBuf
;
4966 // scan backward (from the decl location) for the end of the previous decl.
4967 while (*startBuf
!= '^' && *startBuf
!= ';' && startBuf
!= MainFileStart
)
4969 SourceLocation Start
= DeclLoc
.getFileLocWithOffset(startBuf
-endBuf
);
4971 unsigned OrigLength
=0;
4972 // *startBuf != '^' if we are dealing with a pointer to function that
4973 // may take block argument types (which will be handled below).
4974 if (*startBuf
== '^') {
4975 // Replace the '^' with '*', computing a negative offset.
4980 while (*startBuf
!= ')') {
4988 if (PointerTypeTakesAnyBlockArguments(DeclT
) ||
4989 PointerTypeTakesAnyObjCQualifiedType(DeclT
)) {
4990 // Replace the '^' with '*' for arguments.
4991 // Replace id<P> with id/*<>*/
4992 DeclLoc
= ND
->getLocation();
4993 startBuf
= SM
->getCharacterData(DeclLoc
);
4994 const char *argListBegin
, *argListEnd
;
4995 GetExtentOfArgList(startBuf
, argListBegin
, argListEnd
);
4996 while (argListBegin
< argListEnd
) {
4997 if (*argListBegin
== '^')
4999 else if (*argListBegin
== '<') {
5001 buf
+= *argListBegin
++;
5003 while (*argListBegin
!= '>') {
5004 buf
+= *argListBegin
++;
5007 buf
+= *argListBegin
;
5011 buf
+= *argListBegin
;
5018 ReplaceText(Start
, OrigLength
, buf
);
5024 /// SynthesizeByrefCopyDestroyHelper - This routine synthesizes:
5025 /// void __Block_byref_id_object_copy(struct Block_byref_id_object *dst,
5026 /// struct Block_byref_id_object *src) {
5027 /// _Block_object_assign (&_dest->object, _src->object,
5028 /// BLOCK_BYREF_CALLER | BLOCK_FIELD_IS_OBJECT
5029 /// [|BLOCK_FIELD_IS_WEAK]) // object
5030 /// _Block_object_assign(&_dest->object, _src->object,
5031 /// BLOCK_BYREF_CALLER | BLOCK_FIELD_IS_BLOCK
5032 /// [|BLOCK_FIELD_IS_WEAK]) // block
5035 /// void __Block_byref_id_object_dispose(struct Block_byref_id_object *_src) {
5036 /// _Block_object_dispose(_src->object,
5037 /// BLOCK_BYREF_CALLER | BLOCK_FIELD_IS_OBJECT
5038 /// [|BLOCK_FIELD_IS_WEAK]) // object
5039 /// _Block_object_dispose(_src->object,
5040 /// BLOCK_BYREF_CALLER | BLOCK_FIELD_IS_BLOCK
5041 /// [|BLOCK_FIELD_IS_WEAK]) // block
5044 std::string
RewriteObjC::SynthesizeByrefCopyDestroyHelper(VarDecl
*VD
,
5047 if (CopyDestroyCache
.count(flag
))
5049 CopyDestroyCache
.insert(flag
);
5050 S
= "static void __Block_byref_id_object_copy_";
5052 S
+= "(void *dst, void *src) {\n";
5054 // offset into the object pointer is computed as:
5055 // void * + void* + int + int + void* + void *
5057 static_cast<unsigned>(Context
->getTypeSize(Context
->IntTy
));
5058 unsigned VoidPtrSize
=
5059 static_cast<unsigned>(Context
->getTypeSize(Context
->VoidPtrTy
));
5061 unsigned offset
= (VoidPtrSize
*4 + IntSize
+ IntSize
)/8;
5062 S
+= " _Block_object_assign((char*)dst + ";
5063 S
+= utostr(offset
);
5064 S
+= ", *(void * *) ((char*)src + ";
5065 S
+= utostr(offset
);
5070 S
+= "static void __Block_byref_id_object_dispose_";
5072 S
+= "(void *src) {\n";
5073 S
+= " _Block_object_dispose(*(void * *) ((char*)src + ";
5074 S
+= utostr(offset
);
5081 /// RewriteByRefVar - For each __block typex ND variable this routine transforms
5082 /// the declaration into:
5083 /// struct __Block_byref_ND {
5084 /// void *__isa; // NULL for everything except __weak pointers
5085 /// struct __Block_byref_ND *__forwarding;
5086 /// int32_t __flags;
5088 /// void *__Block_byref_id_object_copy; // If variable is __block ObjC object
5089 /// void *__Block_byref_id_object_dispose; // If variable is __block ObjC object
5093 /// It then replaces declaration of ND variable with:
5094 /// struct __Block_byref_ND ND = {__isa=0B, __forwarding=&ND, __flags=some_flag,
5095 /// __size=sizeof(struct __Block_byref_ND),
5096 /// ND=initializer-if-any};
5099 void RewriteObjC::RewriteByRefVar(VarDecl
*ND
) {
5100 // Insert declaration for the function in which block literal is
5102 if (CurFunctionDeclToDeclareForBlock
)
5103 RewriteBlockLiteralFunctionDecl(CurFunctionDeclToDeclareForBlock
);
5106 SourceLocation DeclLoc
= ND
->getTypeSpecStartLoc();
5107 if (DeclLoc
.isInvalid())
5108 // If type location is missing, it is because of missing type (a warning).
5109 // Use variable's location which is good for this case.
5110 DeclLoc
= ND
->getLocation();
5111 const char *startBuf
= SM
->getCharacterData(DeclLoc
);
5112 SourceLocation X
= ND
->getLocEnd();
5113 X
= SM
->getInstantiationLoc(X
);
5114 const char *endBuf
= SM
->getCharacterData(X
);
5115 std::string
Name(ND
->getNameAsString());
5116 std::string ByrefType
;
5117 RewriteByRefString(ByrefType
, Name
, ND
, true);
5118 ByrefType
+= " {\n";
5119 ByrefType
+= " void *__isa;\n";
5120 RewriteByRefString(ByrefType
, Name
, ND
);
5121 ByrefType
+= " *__forwarding;\n";
5122 ByrefType
+= " int __flags;\n";
5123 ByrefType
+= " int __size;\n";
5124 // Add void *__Block_byref_id_object_copy;
5125 // void *__Block_byref_id_object_dispose; if needed.
5126 QualType Ty
= ND
->getType();
5127 bool HasCopyAndDispose
= Context
->BlockRequiresCopying(Ty
);
5128 if (HasCopyAndDispose
) {
5129 ByrefType
+= " void (*__Block_byref_id_object_copy)(void*, void*);\n";
5130 ByrefType
+= " void (*__Block_byref_id_object_dispose)(void*);\n";
5133 Ty
.getAsStringInternal(Name
, Context
->PrintingPolicy
);
5134 ByrefType
+= " " + Name
+ ";\n";
5135 ByrefType
+= "};\n";
5136 // Insert this type in global scope. It is needed by helper function.
5137 SourceLocation FunLocStart
;
5139 FunLocStart
= CurFunctionDef
->getTypeSpecStartLoc();
5141 assert(CurMethodDef
&& "RewriteByRefVar - CurMethodDef is null");
5142 FunLocStart
= CurMethodDef
->getLocStart();
5144 InsertText(FunLocStart
, ByrefType
);
5145 if (Ty
.isObjCGCWeak()) {
5146 flag
|= BLOCK_FIELD_IS_WEAK
;
5150 if (HasCopyAndDispose
) {
5151 flag
= BLOCK_BYREF_CALLER
;
5152 QualType Ty
= ND
->getType();
5153 // FIXME. Handle __weak variable (BLOCK_FIELD_IS_WEAK) as well.
5154 if (Ty
->isBlockPointerType())
5155 flag
|= BLOCK_FIELD_IS_BLOCK
;
5157 flag
|= BLOCK_FIELD_IS_OBJECT
;
5158 std::string HF
= SynthesizeByrefCopyDestroyHelper(ND
, flag
);
5160 InsertText(FunLocStart
, HF
);
5163 // struct __Block_byref_ND ND =
5164 // {0, &ND, some_flag, __size=sizeof(struct __Block_byref_ND),
5165 // initializer-if-any};
5166 bool hasInit
= (ND
->getInit() != 0);
5168 if (HasCopyAndDispose
)
5169 flags
|= BLOCK_HAS_COPY_DISPOSE
;
5170 Name
= ND
->getNameAsString();
5172 RewriteByRefString(ByrefType
, Name
, ND
);
5173 std::string
ForwardingCastType("(");
5174 ForwardingCastType
+= ByrefType
+ " *)";
5176 ByrefType
+= " " + Name
+ " = {(void*)";
5177 ByrefType
+= utostr(isa
);
5178 ByrefType
+= "," + ForwardingCastType
+ "&" + Name
+ ", ";
5179 ByrefType
+= utostr(flags
);
5181 ByrefType
+= "sizeof(";
5182 RewriteByRefString(ByrefType
, Name
, ND
);
5184 if (HasCopyAndDispose
) {
5185 ByrefType
+= ", __Block_byref_id_object_copy_";
5186 ByrefType
+= utostr(flag
);
5187 ByrefType
+= ", __Block_byref_id_object_dispose_";
5188 ByrefType
+= utostr(flag
);
5190 ByrefType
+= "};\n";
5191 ReplaceText(DeclLoc
, endBuf
-startBuf
+Name
.size(), ByrefType
);
5194 SourceLocation startLoc
;
5195 Expr
*E
= ND
->getInit();
5196 if (const CStyleCastExpr
*ECE
= dyn_cast
<CStyleCastExpr
>(E
))
5197 startLoc
= ECE
->getLParenLoc();
5199 startLoc
= E
->getLocStart();
5200 startLoc
= SM
->getInstantiationLoc(startLoc
);
5201 endBuf
= SM
->getCharacterData(startLoc
);
5202 ByrefType
+= " " + Name
;
5203 ByrefType
+= " = {(void*)";
5204 ByrefType
+= utostr(isa
);
5205 ByrefType
+= "," + ForwardingCastType
+ "&" + Name
+ ", ";
5206 ByrefType
+= utostr(flags
);
5208 ByrefType
+= "sizeof(";
5209 RewriteByRefString(ByrefType
, Name
, ND
);
5211 if (HasCopyAndDispose
) {
5212 ByrefType
+= "__Block_byref_id_object_copy_";
5213 ByrefType
+= utostr(flag
);
5214 ByrefType
+= ", __Block_byref_id_object_dispose_";
5215 ByrefType
+= utostr(flag
);
5218 ReplaceText(DeclLoc
, endBuf
-startBuf
, ByrefType
);
5220 // Complete the newly synthesized compound expression by inserting a right
5221 // curly brace before the end of the declaration.
5222 // FIXME: This approach avoids rewriting the initializer expression. It
5223 // also assumes there is only one declarator. For example, the following
5224 // isn't currently supported by this routine (in general):
5226 // double __block BYREFVAR = 1.34, BYREFVAR2 = 1.37;
5228 const char *startInitializerBuf
= SM
->getCharacterData(startLoc
);
5229 const char *semiBuf
= strchr(startInitializerBuf
, ';');
5230 assert((*semiBuf
== ';') && "RewriteByRefVar: can't find ';'");
5231 SourceLocation semiLoc
=
5232 startLoc
.getFileLocWithOffset(semiBuf
-startInitializerBuf
);
5234 InsertText(semiLoc
, "}");
5239 void RewriteObjC::CollectBlockDeclRefInfo(BlockExpr
*Exp
) {
5240 // Add initializers for any closure decl refs.
5241 GetBlockDeclRefExprs(Exp
->getBody());
5242 if (BlockDeclRefs
.size()) {
5243 // Unique all "by copy" declarations.
5244 for (unsigned i
= 0; i
< BlockDeclRefs
.size(); i
++)
5245 if (!BlockDeclRefs
[i
]->isByRef()) {
5246 if (!BlockByCopyDeclsPtrSet
.count(BlockDeclRefs
[i
]->getDecl())) {
5247 BlockByCopyDeclsPtrSet
.insert(BlockDeclRefs
[i
]->getDecl());
5248 BlockByCopyDecls
.push_back(BlockDeclRefs
[i
]->getDecl());
5251 // Unique all "by ref" declarations.
5252 for (unsigned i
= 0; i
< BlockDeclRefs
.size(); i
++)
5253 if (BlockDeclRefs
[i
]->isByRef()) {
5254 if (!BlockByRefDeclsPtrSet
.count(BlockDeclRefs
[i
]->getDecl())) {
5255 BlockByRefDeclsPtrSet
.insert(BlockDeclRefs
[i
]->getDecl());
5256 BlockByRefDecls
.push_back(BlockDeclRefs
[i
]->getDecl());
5259 // Find any imported blocks...they will need special attention.
5260 for (unsigned i
= 0; i
< BlockDeclRefs
.size(); i
++)
5261 if (BlockDeclRefs
[i
]->isByRef() ||
5262 BlockDeclRefs
[i
]->getType()->isObjCObjectPointerType() ||
5263 BlockDeclRefs
[i
]->getType()->isBlockPointerType())
5264 ImportedBlockDecls
.insert(BlockDeclRefs
[i
]->getDecl());
5268 FunctionDecl
*RewriteObjC::SynthBlockInitFunctionDecl(llvm::StringRef name
) {
5269 IdentifierInfo
*ID
= &Context
->Idents
.get(name
);
5270 QualType FType
= Context
->getFunctionNoProtoType(Context
->VoidPtrTy
);
5271 return FunctionDecl::Create(*Context
, TUDecl
,SourceLocation(),
5272 ID
, FType
, 0, SC_Extern
,
5273 SC_None
, false, false);
5276 Stmt
*RewriteObjC::SynthBlockInitExpr(BlockExpr
*Exp
,
5277 const llvm::SmallVector
<BlockDeclRefExpr
*, 8> &InnerBlockDeclRefs
) {
5278 Blocks
.push_back(Exp
);
5280 CollectBlockDeclRefInfo(Exp
);
5282 // Add inner imported variables now used in current block.
5283 int countOfInnerDecls
= 0;
5284 if (!InnerBlockDeclRefs
.empty()) {
5285 for (unsigned i
= 0; i
< InnerBlockDeclRefs
.size(); i
++) {
5286 BlockDeclRefExpr
*Exp
= InnerBlockDeclRefs
[i
];
5287 ValueDecl
*VD
= Exp
->getDecl();
5288 if (!Exp
->isByRef() && !BlockByCopyDeclsPtrSet
.count(VD
)) {
5289 // We need to save the copied-in variables in nested
5290 // blocks because it is needed at the end for some of the API generations.
5291 // See SynthesizeBlockLiterals routine.
5292 InnerDeclRefs
.push_back(Exp
); countOfInnerDecls
++;
5293 BlockDeclRefs
.push_back(Exp
);
5294 BlockByCopyDeclsPtrSet
.insert(VD
);
5295 BlockByCopyDecls
.push_back(VD
);
5297 if (Exp
->isByRef() && !BlockByRefDeclsPtrSet
.count(VD
)) {
5298 InnerDeclRefs
.push_back(Exp
); countOfInnerDecls
++;
5299 BlockDeclRefs
.push_back(Exp
);
5300 BlockByRefDeclsPtrSet
.insert(VD
);
5301 BlockByRefDecls
.push_back(VD
);
5304 // Find any imported blocks...they will need special attention.
5305 for (unsigned i
= 0; i
< InnerBlockDeclRefs
.size(); i
++)
5306 if (InnerBlockDeclRefs
[i
]->isByRef() ||
5307 InnerBlockDeclRefs
[i
]->getType()->isObjCObjectPointerType() ||
5308 InnerBlockDeclRefs
[i
]->getType()->isBlockPointerType())
5309 ImportedBlockDecls
.insert(InnerBlockDeclRefs
[i
]->getDecl());
5311 InnerDeclRefsCount
.push_back(countOfInnerDecls
);
5313 std::string FuncName
;
5316 FuncName
= CurFunctionDef
->getNameAsString();
5317 else if (CurMethodDef
)
5318 BuildUniqueMethodName(FuncName
, CurMethodDef
);
5319 else if (GlobalVarDecl
)
5320 FuncName
= std::string(GlobalVarDecl
->getNameAsString());
5322 std::string BlockNumber
= utostr(Blocks
.size()-1);
5324 std::string Tag
= "__" + FuncName
+ "_block_impl_" + BlockNumber
;
5325 std::string Func
= "__" + FuncName
+ "_block_func_" + BlockNumber
;
5327 // Get a pointer to the function type so we can cast appropriately.
5328 QualType BFT
= convertFunctionTypeOfBlocks(Exp
->getFunctionType());
5329 QualType FType
= Context
->getPointerType(BFT
);
5334 // Simulate a contructor call...
5335 FD
= SynthBlockInitFunctionDecl(Tag
);
5336 DeclRefExpr
*DRE
= new (Context
) DeclRefExpr(FD
, FType
, VK_RValue
,
5339 llvm::SmallVector
<Expr
*, 4> InitExprs
;
5341 // Initialize the block function.
5342 FD
= SynthBlockInitFunctionDecl(Func
);
5343 DeclRefExpr
*Arg
= new (Context
) DeclRefExpr(FD
, FD
->getType(), VK_LValue
,
5345 CastExpr
*castExpr
= NoTypeInfoCStyleCastExpr(Context
, Context
->VoidPtrTy
,
5347 InitExprs
.push_back(castExpr
);
5349 // Initialize the block descriptor.
5350 std::string DescData
= "__" + FuncName
+ "_block_desc_" + BlockNumber
+ "_DATA";
5352 VarDecl
*NewVD
= VarDecl::Create(*Context
, TUDecl
, SourceLocation(),
5353 &Context
->Idents
.get(DescData
.c_str()),
5354 Context
->VoidPtrTy
, 0,
5355 SC_Static
, SC_None
);
5356 UnaryOperator
*DescRefExpr
=
5357 new (Context
) UnaryOperator(new (Context
) DeclRefExpr(NewVD
,
5362 Context
->getPointerType(Context
->VoidPtrTy
),
5363 VK_RValue
, OK_Ordinary
,
5365 InitExprs
.push_back(DescRefExpr
);
5367 // Add initializers for any closure decl refs.
5368 if (BlockDeclRefs
.size()) {
5370 // Output all "by copy" declarations.
5371 for (llvm::SmallVector
<ValueDecl
*,8>::iterator I
= BlockByCopyDecls
.begin(),
5372 E
= BlockByCopyDecls
.end(); I
!= E
; ++I
) {
5373 if (isObjCType((*I
)->getType())) {
5374 // FIXME: Conform to ABI ([[obj retain] autorelease]).
5375 FD
= SynthBlockInitFunctionDecl((*I
)->getName());
5376 Exp
= new (Context
) DeclRefExpr(FD
, FD
->getType(), VK_LValue
,
5378 if (HasLocalVariableExternalStorage(*I
)) {
5379 QualType QT
= (*I
)->getType();
5380 QT
= Context
->getPointerType(QT
);
5381 Exp
= new (Context
) UnaryOperator(Exp
, UO_AddrOf
, QT
, VK_RValue
,
5382 OK_Ordinary
, SourceLocation());
5384 } else if (isTopLevelBlockPointerType((*I
)->getType())) {
5385 FD
= SynthBlockInitFunctionDecl((*I
)->getName());
5386 Arg
= new (Context
) DeclRefExpr(FD
, FD
->getType(), VK_LValue
,
5388 Exp
= NoTypeInfoCStyleCastExpr(Context
, Context
->VoidPtrTy
,
5391 FD
= SynthBlockInitFunctionDecl((*I
)->getName());
5392 Exp
= new (Context
) DeclRefExpr(FD
, FD
->getType(), VK_LValue
,
5394 if (HasLocalVariableExternalStorage(*I
)) {
5395 QualType QT
= (*I
)->getType();
5396 QT
= Context
->getPointerType(QT
);
5397 Exp
= new (Context
) UnaryOperator(Exp
, UO_AddrOf
, QT
, VK_RValue
,
5398 OK_Ordinary
, SourceLocation());
5402 InitExprs
.push_back(Exp
);
5404 // Output all "by ref" declarations.
5405 for (llvm::SmallVector
<ValueDecl
*,8>::iterator I
= BlockByRefDecls
.begin(),
5406 E
= BlockByRefDecls
.end(); I
!= E
; ++I
) {
5407 ValueDecl
*ND
= (*I
);
5408 std::string
Name(ND
->getNameAsString());
5409 std::string RecName
;
5410 RewriteByRefString(RecName
, Name
, ND
, true);
5411 IdentifierInfo
*II
= &Context
->Idents
.get(RecName
.c_str()
5412 + sizeof("struct"));
5413 RecordDecl
*RD
= RecordDecl::Create(*Context
, TTK_Struct
, TUDecl
,
5414 SourceLocation(), II
);
5415 assert(RD
&& "SynthBlockInitExpr(): Can't find RecordDecl");
5416 QualType castT
= Context
->getPointerType(Context
->getTagDeclType(RD
));
5418 FD
= SynthBlockInitFunctionDecl((*I
)->getName());
5419 Exp
= new (Context
) DeclRefExpr(FD
, FD
->getType(), VK_LValue
,
5421 Exp
= new (Context
) UnaryOperator(Exp
, UO_AddrOf
,
5422 Context
->getPointerType(Exp
->getType()),
5423 VK_RValue
, OK_Ordinary
, SourceLocation());
5424 Exp
= NoTypeInfoCStyleCastExpr(Context
, castT
, CK_BitCast
, Exp
);
5425 InitExprs
.push_back(Exp
);
5428 if (ImportedBlockDecls
.size()) {
5429 // generate BLOCK_HAS_COPY_DISPOSE(have helper funcs) | BLOCK_HAS_DESCRIPTOR
5430 int flag
= (BLOCK_HAS_COPY_DISPOSE
| BLOCK_HAS_DESCRIPTOR
);
5432 static_cast<unsigned>(Context
->getTypeSize(Context
->IntTy
));
5433 Expr
*FlagExp
= IntegerLiteral::Create(*Context
, llvm::APInt(IntSize
, flag
),
5434 Context
->IntTy
, SourceLocation());
5435 InitExprs
.push_back(FlagExp
);
5437 NewRep
= new (Context
) CallExpr(*Context
, DRE
, &InitExprs
[0], InitExprs
.size(),
5438 FType
, VK_LValue
, SourceLocation());
5439 NewRep
= new (Context
) UnaryOperator(NewRep
, UO_AddrOf
,
5440 Context
->getPointerType(NewRep
->getType()),
5441 VK_RValue
, OK_Ordinary
, SourceLocation());
5442 NewRep
= NoTypeInfoCStyleCastExpr(Context
, FType
, CK_BitCast
,
5444 BlockDeclRefs
.clear();
5445 BlockByRefDecls
.clear();
5446 BlockByRefDeclsPtrSet
.clear();
5447 BlockByCopyDecls
.clear();
5448 BlockByCopyDeclsPtrSet
.clear();
5449 ImportedBlockDecls
.clear();
5453 //===----------------------------------------------------------------------===//
5454 // Function Body / Expression rewriting
5455 //===----------------------------------------------------------------------===//
5457 // This is run as a first "pass" prior to RewriteFunctionBodyOrGlobalInitializer().
5458 // The allows the main rewrite loop to associate all ObjCPropertyRefExprs with
5459 // their respective BinaryOperator. Without this knowledge, we'd need to rewrite
5460 // the ObjCPropertyRefExpr twice (once as a getter, and later as a setter).
5461 // Since the rewriter isn't capable of rewriting rewritten code, it's important
5462 // we get this right.
5463 void RewriteObjC::CollectPropertySetters(Stmt
*S
) {
5464 // Perform a bottom up traversal of all children.
5465 for (Stmt::child_iterator CI
= S
->child_begin(), E
= S
->child_end();
5468 CollectPropertySetters(*CI
);
5470 if (BinaryOperator
*BinOp
= dyn_cast
<BinaryOperator
>(S
)) {
5471 if (BinOp
->isAssignmentOp()) {
5472 if (isa
<ObjCPropertyRefExpr
>(BinOp
->getLHS()))
5473 PropSetters
[BinOp
->getLHS()] = BinOp
;
5478 Stmt
*RewriteObjC::RewriteFunctionBodyOrGlobalInitializer(Stmt
*S
) {
5479 if (isa
<SwitchStmt
>(S
) || isa
<WhileStmt
>(S
) ||
5480 isa
<DoStmt
>(S
) || isa
<ForStmt
>(S
))
5482 else if (isa
<ObjCForCollectionStmt
>(S
)) {
5484 ObjCBcLabelNo
.push_back(++BcLabelCount
);
5487 SourceRange OrigStmtRange
= S
->getSourceRange();
5489 // Perform a bottom up rewrite of all children.
5490 for (Stmt::child_iterator CI
= S
->child_begin(), E
= S
->child_end();
5495 if (ObjCIvarRefExpr
*IvarRefExpr
= dyn_cast
<ObjCIvarRefExpr
>(S
)) {
5496 Expr
*OldBase
= IvarRefExpr
->getBase();
5497 bool replaced
= false;
5498 newStmt
= RewriteObjCNestedIvarRefExpr(S
, replaced
);
5500 if (ObjCIvarRefExpr
*IRE
= dyn_cast
<ObjCIvarRefExpr
>(newStmt
))
5501 ReplaceStmt(OldBase
, IRE
->getBase());
5503 ReplaceStmt(S
, newStmt
);
5507 newStmt
= RewriteFunctionBodyOrGlobalInitializer(S
);
5510 // If dealing with an assignment with LHS being a property reference
5511 // expression, the entire assignment tree is rewritten into a property
5512 // setter messaging. This involvs the RHS too. Do not attempt to rewrite
5514 if (Expr
*Exp
= dyn_cast
<Expr
>(S
))
5515 if (isa
<ObjCPropertyRefExpr
>(Exp
)) {
5516 if (PropSetters
[Exp
]) {
5523 if (BlockExpr
*BE
= dyn_cast
<BlockExpr
>(S
)) {
5524 llvm::SmallVector
<BlockDeclRefExpr
*, 8> InnerBlockDeclRefs
;
5525 llvm::SmallPtrSet
<const DeclContext
*, 8> InnerContexts
;
5526 InnerContexts
.insert(BE
->getBlockDecl());
5527 ImportedLocalExternalDecls
.clear();
5528 GetInnerBlockDeclRefExprs(BE
->getBody(),
5529 InnerBlockDeclRefs
, InnerContexts
);
5530 // Rewrite the block body in place.
5531 Stmt
*SaveCurrentBody
= CurrentBody
;
5532 CurrentBody
= BE
->getBody();
5534 RewriteFunctionBodyOrGlobalInitializer(BE
->getBody());
5535 CurrentBody
= SaveCurrentBody
;
5537 ImportedLocalExternalDecls
.clear();
5538 // Now we snarf the rewritten text and stash it away for later use.
5539 std::string Str
= Rewrite
.getRewrittenText(BE
->getSourceRange());
5540 RewrittenBlockExprs
[BE
] = Str
;
5542 Stmt
*blockTranscribed
= SynthBlockInitExpr(BE
, InnerBlockDeclRefs
);
5544 //blockTranscribed->dump();
5545 ReplaceStmt(S
, blockTranscribed
);
5546 return blockTranscribed
;
5548 // Handle specific things.
5549 if (ObjCEncodeExpr
*AtEncode
= dyn_cast
<ObjCEncodeExpr
>(S
))
5550 return RewriteAtEncode(AtEncode
);
5552 if (isa
<ObjCPropertyRefExpr
>(S
)) {
5553 Expr
*PropOrImplicitRefExpr
= dyn_cast
<Expr
>(S
);
5554 assert(PropOrImplicitRefExpr
&& "Property or implicit setter/getter is null");
5556 BinaryOperator
*BinOp
= PropSetters
[PropOrImplicitRefExpr
];
5558 // Because the rewriter doesn't allow us to rewrite rewritten code,
5559 // we need to rewrite the right hand side prior to rewriting the setter.
5560 DisableReplaceStmt
= true;
5561 // Save the source range. Even if we disable the replacement, the
5562 // rewritten node will have been inserted into the tree. If the synthesized
5563 // node is at the 'end', the rewriter will fail. Consider this:
5564 // self.errorHandler = handler ? handler :
5565 // ^(NSURL *errorURL, NSError *error) { return (BOOL)1; };
5566 SourceRange SrcRange
= BinOp
->getSourceRange();
5567 Stmt
*newStmt
= RewriteFunctionBodyOrGlobalInitializer(BinOp
->getRHS());
5568 // Need to rewrite the ivar access expression if need be.
5569 if (isa
<ObjCIvarRefExpr
>(newStmt
)) {
5570 bool replaced
= false;
5571 newStmt
= RewriteObjCNestedIvarRefExpr(newStmt
, replaced
);
5574 DisableReplaceStmt
= false;
5576 // Unlike the main iterator, we explicily avoid changing 'BinOp'. If
5577 // we changed the RHS of BinOp, the rewriter would fail (since it needs
5578 // to see the original expression). Consider this example:
5580 // Foo *obj1, *obj2;
5582 // obj1.i = [obj2 rrrr];
5584 // 'BinOp' for the previous expression looks like:
5586 // (BinaryOperator 0x231ccf0 'int' '='
5587 // (ObjCPropertyRefExpr 0x231cc70 'int' Kind=PropertyRef Property="i"
5588 // (DeclRefExpr 0x231cc50 'Foo *' Var='obj1' 0x231cbb0))
5589 // (ObjCMessageExpr 0x231ccb0 'int' selector=rrrr
5590 // (DeclRefExpr 0x231cc90 'Foo *' Var='obj2' 0x231cbe0)))
5592 // 'newStmt' represents the rewritten message expression. For example:
5594 // (CallExpr 0x231d300 'id':'struct objc_object *'
5595 // (ParenExpr 0x231d2e0 'int (*)(id, SEL)'
5596 // (CStyleCastExpr 0x231d2c0 'int (*)(id, SEL)'
5597 // (CStyleCastExpr 0x231d220 'void *'
5598 // (DeclRefExpr 0x231d200 'id (id, SEL, ...)' FunctionDecl='objc_msgSend' 0x231cdc0))))
5600 // Note that 'newStmt' is passed to RewritePropertyOrImplicitSetter so that it
5601 // can be used as the setter argument. ReplaceStmt() will still 'see'
5602 // the original RHS (since we haven't altered BinOp).
5604 // This implies the Rewrite* routines can no longer delete the original
5605 // node. As a result, we now leak the original AST nodes.
5607 return RewritePropertyOrImplicitSetter(BinOp
, dyn_cast
<Expr
>(newStmt
), SrcRange
);
5609 return RewritePropertyOrImplicitGetter(PropOrImplicitRefExpr
);
5613 if (ObjCSelectorExpr
*AtSelector
= dyn_cast
<ObjCSelectorExpr
>(S
))
5614 return RewriteAtSelector(AtSelector
);
5616 if (ObjCStringLiteral
*AtString
= dyn_cast
<ObjCStringLiteral
>(S
))
5617 return RewriteObjCStringLiteral(AtString
);
5619 if (ObjCMessageExpr
*MessExpr
= dyn_cast
<ObjCMessageExpr
>(S
)) {
5621 // Before we rewrite it, put the original message expression in a comment.
5622 SourceLocation startLoc
= MessExpr
->getLocStart();
5623 SourceLocation endLoc
= MessExpr
->getLocEnd();
5625 const char *startBuf
= SM
->getCharacterData(startLoc
);
5626 const char *endBuf
= SM
->getCharacterData(endLoc
);
5628 std::string messString
;
5629 messString
+= "// ";
5630 messString
.append(startBuf
, endBuf
-startBuf
+1);
5633 // FIXME: Missing definition of
5634 // InsertText(clang::SourceLocation, char const*, unsigned int).
5635 // InsertText(startLoc, messString.c_str(), messString.size());
5636 // Tried this, but it didn't work either...
5637 // ReplaceText(startLoc, 0, messString.c_str(), messString.size());
5639 return RewriteMessageExpr(MessExpr
);
5642 if (ObjCAtTryStmt
*StmtTry
= dyn_cast
<ObjCAtTryStmt
>(S
))
5643 return RewriteObjCTryStmt(StmtTry
);
5645 if (ObjCAtSynchronizedStmt
*StmtTry
= dyn_cast
<ObjCAtSynchronizedStmt
>(S
))
5646 return RewriteObjCSynchronizedStmt(StmtTry
);
5648 if (ObjCAtThrowStmt
*StmtThrow
= dyn_cast
<ObjCAtThrowStmt
>(S
))
5649 return RewriteObjCThrowStmt(StmtThrow
);
5651 if (ObjCProtocolExpr
*ProtocolExp
= dyn_cast
<ObjCProtocolExpr
>(S
))
5652 return RewriteObjCProtocolExpr(ProtocolExp
);
5654 if (ObjCForCollectionStmt
*StmtForCollection
=
5655 dyn_cast
<ObjCForCollectionStmt
>(S
))
5656 return RewriteObjCForCollectionStmt(StmtForCollection
,
5657 OrigStmtRange
.getEnd());
5658 if (BreakStmt
*StmtBreakStmt
=
5659 dyn_cast
<BreakStmt
>(S
))
5660 return RewriteBreakStmt(StmtBreakStmt
);
5661 if (ContinueStmt
*StmtContinueStmt
=
5662 dyn_cast
<ContinueStmt
>(S
))
5663 return RewriteContinueStmt(StmtContinueStmt
);
5665 // Need to check for protocol refs (id <P>, Foo <P> *) in variable decls
5667 if (DeclStmt
*DS
= dyn_cast
<DeclStmt
>(S
)) {
5668 // FIXME: What we're doing here is modifying the type-specifier that
5669 // precedes the first Decl. In the future the DeclGroup should have
5670 // a separate type-specifier that we can rewrite.
5671 // NOTE: We need to avoid rewriting the DeclStmt if it is within
5672 // the context of an ObjCForCollectionStmt. For example:
5673 // NSArray *someArray;
5674 // for (id <FooProtocol> index in someArray) ;
5675 // This is because RewriteObjCForCollectionStmt() does textual rewriting
5676 // and it depends on the original text locations/positions.
5677 if (Stmts
.empty() || !isa
<ObjCForCollectionStmt
>(Stmts
.back()))
5678 RewriteObjCQualifiedInterfaceTypes(*DS
->decl_begin());
5680 // Blocks rewrite rules.
5681 for (DeclStmt::decl_iterator DI
= DS
->decl_begin(), DE
= DS
->decl_end();
5684 if (ValueDecl
*ND
= dyn_cast
<ValueDecl
>(SD
)) {
5685 if (isTopLevelBlockPointerType(ND
->getType()))
5686 RewriteBlockPointerDecl(ND
);
5687 else if (ND
->getType()->isFunctionPointerType())
5688 CheckFunctionPointerDecl(ND
->getType(), ND
);
5689 if (VarDecl
*VD
= dyn_cast
<VarDecl
>(SD
)) {
5690 if (VD
->hasAttr
<BlocksAttr
>()) {
5691 static unsigned uniqueByrefDeclCount
= 0;
5692 assert(!BlockByRefDeclNo
.count(ND
) &&
5693 "RewriteFunctionBodyOrGlobalInitializer: Duplicate byref decl");
5694 BlockByRefDeclNo
[ND
] = uniqueByrefDeclCount
++;
5695 RewriteByRefVar(VD
);
5698 RewriteTypeOfDecl(VD
);
5701 if (TypedefDecl
*TD
= dyn_cast
<TypedefDecl
>(SD
)) {
5702 if (isTopLevelBlockPointerType(TD
->getUnderlyingType()))
5703 RewriteBlockPointerDecl(TD
);
5704 else if (TD
->getUnderlyingType()->isFunctionPointerType())
5705 CheckFunctionPointerDecl(TD
->getUnderlyingType(), TD
);
5710 if (CStyleCastExpr
*CE
= dyn_cast
<CStyleCastExpr
>(S
))
5711 RewriteObjCQualifiedInterfaceTypes(CE
);
5713 if (isa
<SwitchStmt
>(S
) || isa
<WhileStmt
>(S
) ||
5714 isa
<DoStmt
>(S
) || isa
<ForStmt
>(S
)) {
5715 assert(!Stmts
.empty() && "Statement stack is empty");
5716 assert ((isa
<SwitchStmt
>(Stmts
.back()) || isa
<WhileStmt
>(Stmts
.back()) ||
5717 isa
<DoStmt
>(Stmts
.back()) || isa
<ForStmt
>(Stmts
.back()))
5718 && "Statement stack mismatch");
5721 // Handle blocks rewriting.
5722 if (BlockDeclRefExpr
*BDRE
= dyn_cast
<BlockDeclRefExpr
>(S
)) {
5723 if (BDRE
->isByRef())
5724 return RewriteBlockDeclRefExpr(BDRE
);
5726 if (DeclRefExpr
*DRE
= dyn_cast
<DeclRefExpr
>(S
)) {
5727 ValueDecl
*VD
= DRE
->getDecl();
5728 if (VD
->hasAttr
<BlocksAttr
>())
5729 return RewriteBlockDeclRefExpr(DRE
);
5730 if (HasLocalVariableExternalStorage(VD
))
5731 return RewriteLocalVariableExternalStorage(DRE
);
5734 if (CallExpr
*CE
= dyn_cast
<CallExpr
>(S
)) {
5735 if (CE
->getCallee()->getType()->isBlockPointerType()) {
5736 Stmt
*BlockCall
= SynthesizeBlockCall(CE
, CE
->getCallee());
5737 ReplaceStmt(S
, BlockCall
);
5741 if (CStyleCastExpr
*CE
= dyn_cast
<CStyleCastExpr
>(S
)) {
5742 RewriteCastExpr(CE
);
5745 if (ImplicitCastExpr
*ICE
= dyn_cast
<ImplicitCastExpr
>(S
)) {
5746 CastExpr
*Replacement
= new (Context
) CastExpr(ICE
->getType(),
5749 // Get the new text.
5751 llvm::raw_string_ostream
Buf(SStr
);
5752 Replacement
->printPretty(Buf
, *Context
);
5753 const std::string
&Str
= Buf
.str();
5755 printf("CAST = %s\n", &Str
[0]);
5756 InsertText(ICE
->getSubExpr()->getLocStart(), &Str
[0], Str
.size());
5761 // Return this stmt unmodified.
5765 void RewriteObjC::RewriteRecordBody(RecordDecl
*RD
) {
5766 for (RecordDecl::field_iterator i
= RD
->field_begin(),
5767 e
= RD
->field_end(); i
!= e
; ++i
) {
5769 if (isTopLevelBlockPointerType(FD
->getType()))
5770 RewriteBlockPointerDecl(FD
);
5771 if (FD
->getType()->isObjCQualifiedIdType() ||
5772 FD
->getType()->isObjCQualifiedInterfaceType())
5773 RewriteObjCQualifiedInterfaceTypes(FD
);
5777 /// HandleDeclInMainFile - This is called for each top-level decl defined in the
5778 /// main file of the input.
5779 void RewriteObjC::HandleDeclInMainFile(Decl
*D
) {
5780 if (FunctionDecl
*FD
= dyn_cast
<FunctionDecl
>(D
)) {
5781 if (FD
->isOverloadedOperator())
5784 // Since function prototypes don't have ParmDecl's, we check the function
5785 // prototype. This enables us to rewrite function declarations and
5786 // definitions using the same code.
5787 RewriteBlocksInFunctionProtoType(FD
->getType(), FD
);
5789 // FIXME: If this should support Obj-C++, support CXXTryStmt
5790 if (CompoundStmt
*Body
= dyn_cast_or_null
<CompoundStmt
>(FD
->getBody())) {
5791 CurFunctionDef
= FD
;
5792 CurFunctionDeclToDeclareForBlock
= FD
;
5793 CollectPropertySetters(Body
);
5796 cast_or_null
<CompoundStmt
>(RewriteFunctionBodyOrGlobalInitializer(Body
));
5799 if (PropParentMap
) {
5800 delete PropParentMap
;
5803 // This synthesizes and inserts the block "impl" struct, invoke function,
5804 // and any copy/dispose helper functions.
5805 InsertBlockLiteralsWithinFunction(FD
);
5807 CurFunctionDeclToDeclareForBlock
= 0;
5811 if (ObjCMethodDecl
*MD
= dyn_cast
<ObjCMethodDecl
>(D
)) {
5812 if (CompoundStmt
*Body
= MD
->getCompoundBody()) {
5814 CollectPropertySetters(Body
);
5817 cast_or_null
<CompoundStmt
>(RewriteFunctionBodyOrGlobalInitializer(Body
));
5820 if (PropParentMap
) {
5821 delete PropParentMap
;
5824 InsertBlockLiteralsWithinMethod(MD
);
5828 if (ObjCImplementationDecl
*CI
= dyn_cast
<ObjCImplementationDecl
>(D
))
5829 ClassImplementation
.push_back(CI
);
5830 else if (ObjCCategoryImplDecl
*CI
= dyn_cast
<ObjCCategoryImplDecl
>(D
))
5831 CategoryImplementation
.push_back(CI
);
5832 else if (ObjCClassDecl
*CD
= dyn_cast
<ObjCClassDecl
>(D
))
5833 RewriteForwardClassDecl(CD
);
5834 else if (VarDecl
*VD
= dyn_cast
<VarDecl
>(D
)) {
5835 RewriteObjCQualifiedInterfaceTypes(VD
);
5836 if (isTopLevelBlockPointerType(VD
->getType()))
5837 RewriteBlockPointerDecl(VD
);
5838 else if (VD
->getType()->isFunctionPointerType()) {
5839 CheckFunctionPointerDecl(VD
->getType(), VD
);
5840 if (VD
->getInit()) {
5841 if (CStyleCastExpr
*CE
= dyn_cast
<CStyleCastExpr
>(VD
->getInit())) {
5842 RewriteCastExpr(CE
);
5845 } else if (VD
->getType()->isRecordType()) {
5846 RecordDecl
*RD
= VD
->getType()->getAs
<RecordType
>()->getDecl();
5847 if (RD
->isDefinition())
5848 RewriteRecordBody(RD
);
5850 if (VD
->getInit()) {
5852 CollectPropertySetters(VD
->getInit());
5853 CurrentBody
= VD
->getInit();
5854 RewriteFunctionBodyOrGlobalInitializer(VD
->getInit());
5856 if (PropParentMap
) {
5857 delete PropParentMap
;
5860 SynthesizeBlockLiterals(VD
->getTypeSpecStartLoc(),
5864 // This is needed for blocks.
5865 if (CStyleCastExpr
*CE
= dyn_cast
<CStyleCastExpr
>(VD
->getInit())) {
5866 RewriteCastExpr(CE
);
5871 if (TypedefDecl
*TD
= dyn_cast
<TypedefDecl
>(D
)) {
5872 if (isTopLevelBlockPointerType(TD
->getUnderlyingType()))
5873 RewriteBlockPointerDecl(TD
);
5874 else if (TD
->getUnderlyingType()->isFunctionPointerType())
5875 CheckFunctionPointerDecl(TD
->getUnderlyingType(), TD
);
5878 if (RecordDecl
*RD
= dyn_cast
<RecordDecl
>(D
)) {
5879 if (RD
->isDefinition())
5880 RewriteRecordBody(RD
);
5886 void RewriteObjC::HandleTranslationUnit(ASTContext
&C
) {
5887 if (Diags
.hasErrorOccurred())
5892 // Here's a great place to add any extra declarations that may be needed.
5893 // Write out meta data for each @protocol(<expr>).
5894 for (llvm::SmallPtrSet
<ObjCProtocolDecl
*,8>::iterator I
= ProtocolExprDecls
.begin(),
5895 E
= ProtocolExprDecls
.end(); I
!= E
; ++I
)
5896 RewriteObjCProtocolMetaData(*I
, "", "", Preamble
);
5898 InsertText(SM
->getLocForStartOfFile(MainFileID
), Preamble
, false);
5899 if (ClassImplementation
.size() || CategoryImplementation
.size())
5900 RewriteImplementations();
5902 // Get the buffer corresponding to MainFileID. If we haven't changed it, then
5904 if (const RewriteBuffer
*RewriteBuf
=
5905 Rewrite
.getRewriteBufferFor(MainFileID
)) {
5906 //printf("Changed:\n");
5907 *OutFile
<< std::string(RewriteBuf
->begin(), RewriteBuf
->end());
5909 llvm::errs() << "No changes\n";
5912 if (ClassImplementation
.size() || CategoryImplementation
.size() ||
5913 ProtocolExprDecls
.size()) {
5914 // Rewrite Objective-c meta data*
5915 std::string ResultStr
;
5916 SynthesizeMetaDataIntoBuffer(ResultStr
);
5918 *OutFile
<< ResultStr
;