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/Frontend/ASTConsumers.h"
15 #include "clang/Rewrite/Core/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
{
38 BLOCK_FIELD_IS_OBJECT
= 3, /* id, NSObject, __attribute__((NSObject)),
40 BLOCK_FIELD_IS_BLOCK
= 7, /* a block variable */
41 BLOCK_FIELD_IS_BYREF
= 8, /* the on stack structure holding the
43 BLOCK_FIELD_IS_WEAK
= 16, /* declared __weak, only used in byref copy
45 BLOCK_BYREF_CALLER
= 128, /* called from __block (byref) copy/dispose
47 BLOCK_BYREF_CURRENT_MAX
= 256
51 BLOCK_NEEDS_FREE
= (1 << 24),
52 BLOCK_HAS_COPY_DISPOSE
= (1 << 25),
53 BLOCK_HAS_CXX_OBJ
= (1 << 26),
54 BLOCK_IS_GC
= (1 << 27),
55 BLOCK_IS_GLOBAL
= (1 << 28),
56 BLOCK_HAS_DESCRIPTOR
= (1 << 29)
58 static const int OBJC_ABI_VERSION
= 7;
61 DiagnosticsEngine
&Diags
;
62 const LangOptions
&LangOpts
;
65 TranslationUnitDecl
*TUDecl
;
67 const char *MainFileStart
, *MainFileEnd
;
69 ParentMap
*PropParentMap
; // created lazily.
70 std::string InFileName
;
74 TypeDecl
*ProtocolTypeDecl
;
75 VarDecl
*GlobalVarDecl
;
76 unsigned RewriteFailedDiag
;
77 // ObjC string constant support.
78 unsigned NumObjCStringLiterals
;
79 VarDecl
*ConstantStringClassReference
;
80 RecordDecl
*NSStringRecord
;
82 // ObjC foreach break/continue generation support.
85 unsigned TryFinallyContainsReturnDiag
;
87 ObjCMethodDecl
*CurMethodDef
;
88 RecordDecl
*SuperStructDecl
;
89 RecordDecl
*ConstantStringDecl
;
91 FunctionDecl
*MsgSendFunctionDecl
;
92 FunctionDecl
*MsgSendSuperFunctionDecl
;
93 FunctionDecl
*MsgSendStretFunctionDecl
;
94 FunctionDecl
*MsgSendSuperStretFunctionDecl
;
95 FunctionDecl
*MsgSendFpretFunctionDecl
;
96 FunctionDecl
*GetClassFunctionDecl
;
97 FunctionDecl
*GetMetaClassFunctionDecl
;
98 FunctionDecl
*GetSuperClassFunctionDecl
;
99 FunctionDecl
*SelGetUidFunctionDecl
;
100 FunctionDecl
*CFStringFunctionDecl
;
101 FunctionDecl
*SuperContructorFunctionDecl
;
102 FunctionDecl
*CurFunctionDef
;
103 FunctionDecl
*CurFunctionDeclToDeclareForBlock
;
105 /* Misc. containers needed for meta-data rewrite. */
106 SmallVector
<ObjCImplementationDecl
*, 8> ClassImplementation
;
107 SmallVector
<ObjCCategoryImplDecl
*, 8> CategoryImplementation
;
108 llvm::SmallPtrSet
<ObjCInterfaceDecl
*, 8> ObjCSynthesizedStructs
;
109 llvm::SmallPtrSet
<ObjCProtocolDecl
*, 8> ObjCSynthesizedProtocols
;
110 llvm::SmallPtrSet
<ObjCInterfaceDecl
*, 8> ObjCForwardDecls
;
111 llvm::DenseMap
<ObjCMethodDecl
*, std::string
> MethodInternalNames
;
112 SmallVector
<Stmt
*, 32> Stmts
;
113 SmallVector
<int, 8> ObjCBcLabelNo
;
114 // Remember all the @protocol(<expr>) expressions.
115 llvm::SmallPtrSet
<ObjCProtocolDecl
*, 32> ProtocolExprDecls
;
117 llvm::DenseSet
<uint64_t> CopyDestroyCache
;
119 // Block expressions.
120 SmallVector
<BlockExpr
*, 32> Blocks
;
121 SmallVector
<int, 32> InnerDeclRefsCount
;
122 SmallVector
<DeclRefExpr
*, 32> InnerDeclRefs
;
124 SmallVector
<DeclRefExpr
*, 32> BlockDeclRefs
;
126 // Block related declarations.
127 SmallVector
<ValueDecl
*, 8> BlockByCopyDecls
;
128 llvm::SmallPtrSet
<ValueDecl
*, 8> BlockByCopyDeclsPtrSet
;
129 SmallVector
<ValueDecl
*, 8> BlockByRefDecls
;
130 llvm::SmallPtrSet
<ValueDecl
*, 8> BlockByRefDeclsPtrSet
;
131 llvm::DenseMap
<ValueDecl
*, unsigned> BlockByRefDeclNo
;
132 llvm::SmallPtrSet
<ValueDecl
*, 8> ImportedBlockDecls
;
133 llvm::SmallPtrSet
<VarDecl
*, 8> ImportedLocalExternalDecls
;
135 llvm::DenseMap
<BlockExpr
*, std::string
> RewrittenBlockExprs
;
137 // This maps an original source AST to it's rewritten form. This allows
138 // us to avoid rewriting the same node twice (which is very uncommon).
139 // This is needed to support some of the exotic property rewriting.
140 llvm::DenseMap
<Stmt
*, Stmt
*> ReplacedNodes
;
142 // Needed for header files being rewritten
144 bool SilenceRewriteMacroWarning
;
145 bool objc_impl_method
;
147 bool DisableReplaceStmt
;
148 class DisableReplaceStmtScope
{
153 DisableReplaceStmtScope(RewriteObjC
&R
)
154 : R(R
), SavedValue(R
.DisableReplaceStmt
) {
155 R
.DisableReplaceStmt
= true;
157 ~DisableReplaceStmtScope() {
158 R
.DisableReplaceStmt
= SavedValue
;
161 void InitializeCommon(ASTContext
&context
);
165 // Top Level Driver code.
166 virtual bool HandleTopLevelDecl(DeclGroupRef D
) {
167 for (DeclGroupRef::iterator I
= D
.begin(), E
= D
.end(); I
!= E
; ++I
) {
168 if (ObjCInterfaceDecl
*Class
= dyn_cast
<ObjCInterfaceDecl
>(*I
)) {
169 if (!Class
->isThisDeclarationADefinition()) {
170 RewriteForwardClassDecl(D
);
175 if (ObjCProtocolDecl
*Proto
= dyn_cast
<ObjCProtocolDecl
>(*I
)) {
176 if (!Proto
->isThisDeclarationADefinition()) {
177 RewriteForwardProtocolDecl(D
);
182 HandleTopLevelSingleDecl(*I
);
186 void HandleTopLevelSingleDecl(Decl
*D
);
187 void HandleDeclInMainFile(Decl
*D
);
188 RewriteObjC(std::string inFile
, raw_ostream
*OS
,
189 DiagnosticsEngine
&D
, const LangOptions
&LOpts
,
190 bool silenceMacroWarn
);
194 virtual void HandleTranslationUnit(ASTContext
&C
);
196 void ReplaceStmt(Stmt
*Old
, Stmt
*New
) {
197 Stmt
*ReplacingStmt
= ReplacedNodes
[Old
];
200 return; // We can't rewrite the same node twice.
202 if (DisableReplaceStmt
)
205 // If replacement succeeded or warning disabled return with no warning.
206 if (!Rewrite
.ReplaceStmt(Old
, New
)) {
207 ReplacedNodes
[Old
] = New
;
210 if (SilenceRewriteMacroWarning
)
212 Diags
.Report(Context
->getFullLoc(Old
->getLocStart()), RewriteFailedDiag
)
213 << Old
->getSourceRange();
216 void ReplaceStmtWithRange(Stmt
*Old
, Stmt
*New
, SourceRange SrcRange
) {
217 if (DisableReplaceStmt
)
220 // Measure the old text.
221 int Size
= Rewrite
.getRangeSize(SrcRange
);
223 Diags
.Report(Context
->getFullLoc(Old
->getLocStart()), RewriteFailedDiag
)
224 << Old
->getSourceRange();
229 llvm::raw_string_ostream
S(SStr
);
230 New
->printPretty(S
, 0, PrintingPolicy(LangOpts
));
231 const std::string
&Str
= S
.str();
233 // If replacement succeeded or warning disabled return with no warning.
234 if (!Rewrite
.ReplaceText(SrcRange
.getBegin(), Size
, Str
)) {
235 ReplacedNodes
[Old
] = New
;
238 if (SilenceRewriteMacroWarning
)
240 Diags
.Report(Context
->getFullLoc(Old
->getLocStart()), RewriteFailedDiag
)
241 << Old
->getSourceRange();
244 void InsertText(SourceLocation Loc
, StringRef Str
,
245 bool InsertAfter
= true) {
246 // If insertion succeeded or warning disabled return with no warning.
247 if (!Rewrite
.InsertText(Loc
, Str
, InsertAfter
) ||
248 SilenceRewriteMacroWarning
)
251 Diags
.Report(Context
->getFullLoc(Loc
), RewriteFailedDiag
);
254 void ReplaceText(SourceLocation Start
, unsigned OrigLength
,
256 // If removal succeeded or warning disabled return with no warning.
257 if (!Rewrite
.ReplaceText(Start
, OrigLength
, Str
) ||
258 SilenceRewriteMacroWarning
)
261 Diags
.Report(Context
->getFullLoc(Start
), RewriteFailedDiag
);
264 // Syntactic Rewriting.
265 void RewriteRecordBody(RecordDecl
*RD
);
266 void RewriteInclude();
267 void RewriteForwardClassDecl(DeclGroupRef D
);
268 void RewriteForwardClassDecl(const llvm::SmallVector
<Decl
*, 8> &DG
);
269 void RewriteForwardClassEpilogue(ObjCInterfaceDecl
*ClassDecl
,
270 const std::string
&typedefString
);
271 void RewriteImplementations();
272 void RewritePropertyImplDecl(ObjCPropertyImplDecl
*PID
,
273 ObjCImplementationDecl
*IMD
,
274 ObjCCategoryImplDecl
*CID
);
275 void RewriteInterfaceDecl(ObjCInterfaceDecl
*Dcl
);
276 void RewriteImplementationDecl(Decl
*Dcl
);
277 void RewriteObjCMethodDecl(const ObjCInterfaceDecl
*IDecl
,
278 ObjCMethodDecl
*MDecl
, std::string
&ResultStr
);
279 void RewriteTypeIntoString(QualType T
, std::string
&ResultStr
,
280 const FunctionType
*&FPRetType
);
281 void RewriteByRefString(std::string
&ResultStr
, const std::string
&Name
,
282 ValueDecl
*VD
, bool def
=false);
283 void RewriteCategoryDecl(ObjCCategoryDecl
*Dcl
);
284 void RewriteProtocolDecl(ObjCProtocolDecl
*Dcl
);
285 void RewriteForwardProtocolDecl(DeclGroupRef D
);
286 void RewriteForwardProtocolDecl(const llvm::SmallVector
<Decl
*, 8> &DG
);
287 void RewriteMethodDeclaration(ObjCMethodDecl
*Method
);
288 void RewriteProperty(ObjCPropertyDecl
*prop
);
289 void RewriteFunctionDecl(FunctionDecl
*FD
);
290 void RewriteBlockPointerType(std::string
& Str
, QualType Type
);
291 void RewriteBlockPointerTypeVariable(std::string
& Str
, ValueDecl
*VD
);
292 void RewriteBlockLiteralFunctionDecl(FunctionDecl
*FD
);
293 void RewriteObjCQualifiedInterfaceTypes(Decl
*Dcl
);
294 void RewriteTypeOfDecl(VarDecl
*VD
);
295 void RewriteObjCQualifiedInterfaceTypes(Expr
*E
);
297 // Expression Rewriting.
298 Stmt
*RewriteFunctionBodyOrGlobalInitializer(Stmt
*S
);
299 Stmt
*RewriteAtEncode(ObjCEncodeExpr
*Exp
);
300 Stmt
*RewritePropertyOrImplicitGetter(PseudoObjectExpr
*Pseudo
);
301 Stmt
*RewritePropertyOrImplicitSetter(PseudoObjectExpr
*Pseudo
);
302 Stmt
*RewriteAtSelector(ObjCSelectorExpr
*Exp
);
303 Stmt
*RewriteMessageExpr(ObjCMessageExpr
*Exp
);
304 Stmt
*RewriteObjCStringLiteral(ObjCStringLiteral
*Exp
);
305 Stmt
*RewriteObjCProtocolExpr(ObjCProtocolExpr
*Exp
);
306 void RewriteTryReturnStmts(Stmt
*S
);
307 void RewriteSyncReturnStmts(Stmt
*S
, std::string buf
);
308 Stmt
*RewriteObjCTryStmt(ObjCAtTryStmt
*S
);
309 Stmt
*RewriteObjCSynchronizedStmt(ObjCAtSynchronizedStmt
*S
);
310 Stmt
*RewriteObjCThrowStmt(ObjCAtThrowStmt
*S
);
311 Stmt
*RewriteObjCForCollectionStmt(ObjCForCollectionStmt
*S
,
312 SourceLocation OrigEnd
);
313 Stmt
*RewriteBreakStmt(BreakStmt
*S
);
314 Stmt
*RewriteContinueStmt(ContinueStmt
*S
);
315 void RewriteCastExpr(CStyleCastExpr
*CE
);
318 void RewriteBlocksInFunctionProtoType(QualType funcType
, NamedDecl
*D
);
320 // Block specific rewrite rules.
321 void RewriteBlockPointerDecl(NamedDecl
*VD
);
322 void RewriteByRefVar(VarDecl
*VD
);
323 Stmt
*RewriteBlockDeclRefExpr(DeclRefExpr
*VD
);
324 Stmt
*RewriteLocalVariableExternalStorage(DeclRefExpr
*DRE
);
325 void RewriteBlockPointerFunctionArgs(FunctionDecl
*FD
);
327 void RewriteObjCInternalStruct(ObjCInterfaceDecl
*CDecl
,
328 std::string
&Result
);
330 virtual void Initialize(ASTContext
&context
) = 0;
332 // Metadata Rewriting.
333 virtual void RewriteMetaDataIntoBuffer(std::string
&Result
) = 0;
334 virtual void RewriteObjCProtocolListMetaData(const ObjCList
<ObjCProtocolDecl
> &Prots
,
337 std::string
&Result
) = 0;
338 virtual void RewriteObjCCategoryImplDecl(ObjCCategoryImplDecl
*CDecl
,
339 std::string
&Result
) = 0;
340 virtual void RewriteObjCProtocolMetaData(ObjCProtocolDecl
*Protocol
,
343 std::string
&Result
) = 0;
344 virtual void RewriteObjCClassMetaData(ObjCImplementationDecl
*IDecl
,
345 std::string
&Result
) = 0;
347 // Rewriting ivar access
348 virtual Stmt
*RewriteObjCIvarRefExpr(ObjCIvarRefExpr
*IV
) = 0;
349 virtual void RewriteIvarOffsetComputation(ObjCIvarDecl
*ivar
,
350 std::string
&Result
) = 0;
352 // Misc. AST transformation routines. Sometimes they end up calling
353 // rewriting routines on the new ASTs.
354 CallExpr
*SynthesizeCallToFunctionDecl(FunctionDecl
*FD
,
355 Expr
**args
, unsigned nargs
,
356 SourceLocation StartLoc
=SourceLocation(),
357 SourceLocation EndLoc
=SourceLocation());
358 CallExpr
*SynthMsgSendStretCallExpr(FunctionDecl
*MsgSendStretFlavor
,
359 QualType msgSendType
,
361 SmallVectorImpl
<QualType
> &ArgTypes
,
362 SmallVectorImpl
<Expr
*> &MsgExprs
,
363 ObjCMethodDecl
*Method
);
364 Stmt
*SynthMessageExpr(ObjCMessageExpr
*Exp
,
365 SourceLocation StartLoc
=SourceLocation(),
366 SourceLocation EndLoc
=SourceLocation());
368 void SynthCountByEnumWithState(std::string
&buf
);
369 void SynthMsgSendFunctionDecl();
370 void SynthMsgSendSuperFunctionDecl();
371 void SynthMsgSendStretFunctionDecl();
372 void SynthMsgSendFpretFunctionDecl();
373 void SynthMsgSendSuperStretFunctionDecl();
374 void SynthGetClassFunctionDecl();
375 void SynthGetMetaClassFunctionDecl();
376 void SynthGetSuperClassFunctionDecl();
377 void SynthSelGetUidFunctionDecl();
378 void SynthSuperContructorFunctionDecl();
380 std::string
SynthesizeByrefCopyDestroyHelper(VarDecl
*VD
, int flag
);
381 std::string
SynthesizeBlockHelperFuncs(BlockExpr
*CE
, int i
,
382 StringRef funcName
, std::string Tag
);
383 std::string
SynthesizeBlockFunc(BlockExpr
*CE
, int i
,
384 StringRef funcName
, std::string Tag
);
385 std::string
SynthesizeBlockImpl(BlockExpr
*CE
,
386 std::string Tag
, std::string Desc
);
387 std::string
SynthesizeBlockDescriptor(std::string DescTag
,
389 int i
, StringRef funcName
,
391 Stmt
*SynthesizeBlockCall(CallExpr
*Exp
, const Expr
* BlockExp
);
392 void SynthesizeBlockLiterals(SourceLocation FunLocStart
,
394 FunctionDecl
*SynthBlockInitFunctionDecl(StringRef name
);
395 Stmt
*SynthBlockInitExpr(BlockExpr
*Exp
,
396 const SmallVector
<DeclRefExpr
*, 8> &InnerBlockDeclRefs
);
398 // Misc. helper routines.
399 QualType
getProtocolType();
400 void WarnAboutReturnGotoStmts(Stmt
*S
);
401 void HasReturnStmts(Stmt
*S
, bool &hasReturns
);
402 void CheckFunctionPointerDecl(QualType dType
, NamedDecl
*ND
);
403 void InsertBlockLiteralsWithinFunction(FunctionDecl
*FD
);
404 void InsertBlockLiteralsWithinMethod(ObjCMethodDecl
*MD
);
406 bool IsDeclStmtInForeachHeader(DeclStmt
*DS
);
407 void CollectBlockDeclRefInfo(BlockExpr
*Exp
);
408 void GetBlockDeclRefExprs(Stmt
*S
);
409 void GetInnerBlockDeclRefExprs(Stmt
*S
,
410 SmallVector
<DeclRefExpr
*, 8> &InnerBlockDeclRefs
,
411 llvm::SmallPtrSet
<const DeclContext
*, 8> &InnerContexts
);
413 // We avoid calling Type::isBlockPointerType(), since it operates on the
414 // canonical type. We only care if the top-level type is a closure pointer.
415 bool isTopLevelBlockPointerType(QualType T
) {
416 return isa
<BlockPointerType
>(T
);
419 /// convertBlockPointerToFunctionPointer - Converts a block-pointer type
420 /// to a function pointer type and upon success, returns true; false
422 bool convertBlockPointerToFunctionPointer(QualType
&T
) {
423 if (isTopLevelBlockPointerType(T
)) {
424 const BlockPointerType
*BPT
= T
->getAs
<BlockPointerType
>();
425 T
= Context
->getPointerType(BPT
->getPointeeType());
431 bool needToScanForQualifiers(QualType T
);
432 QualType
getSuperStructType();
433 QualType
getConstantStringStructType();
434 QualType
convertFunctionTypeOfBlocks(const FunctionType
*FT
);
435 bool BufferContainsPPDirectives(const char *startBuf
, const char *endBuf
);
437 void convertToUnqualifiedObjCType(QualType
&T
) {
438 if (T
->isObjCQualifiedIdType())
439 T
= Context
->getObjCIdType();
440 else if (T
->isObjCQualifiedClassType())
441 T
= Context
->getObjCClassType();
442 else if (T
->isObjCObjectPointerType() &&
443 T
->getPointeeType()->isObjCQualifiedInterfaceType()) {
444 if (const ObjCObjectPointerType
* OBJPT
=
445 T
->getAsObjCInterfacePointerType()) {
446 const ObjCInterfaceType
*IFaceT
= OBJPT
->getInterfaceType();
447 T
= QualType(IFaceT
, 0);
448 T
= Context
->getPointerType(T
);
453 // FIXME: This predicate seems like it would be useful to add to ASTContext.
454 bool isObjCType(QualType T
) {
455 if (!LangOpts
.ObjC1
&& !LangOpts
.ObjC2
)
458 QualType OCT
= Context
->getCanonicalType(T
).getUnqualifiedType();
460 if (OCT
== Context
->getCanonicalType(Context
->getObjCIdType()) ||
461 OCT
== Context
->getCanonicalType(Context
->getObjCClassType()))
464 if (const PointerType
*PT
= OCT
->getAs
<PointerType
>()) {
465 if (isa
<ObjCInterfaceType
>(PT
->getPointeeType()) ||
466 PT
->getPointeeType()->isObjCQualifiedIdType())
471 bool PointerTypeTakesAnyBlockArguments(QualType QT
);
472 bool PointerTypeTakesAnyObjCQualifiedType(QualType QT
);
473 void GetExtentOfArgList(const char *Name
, const char *&LParen
,
474 const char *&RParen
);
476 void QuoteDoublequotes(std::string
&From
, std::string
&To
) {
477 for (unsigned i
= 0; i
< From
.length(); i
++) {
485 QualType
getSimpleFunctionType(QualType result
,
486 const QualType
*args
,
488 bool variadic
= false) {
489 if (result
== Context
->getObjCInstanceType())
490 result
= Context
->getObjCIdType();
491 FunctionProtoType::ExtProtoInfo fpi
;
492 fpi
.Variadic
= variadic
;
493 return Context
->getFunctionType(result
, args
, numArgs
, fpi
);
496 // Helper function: create a CStyleCastExpr with trivial type source info.
497 CStyleCastExpr
* NoTypeInfoCStyleCastExpr(ASTContext
*Ctx
, QualType Ty
,
498 CastKind Kind
, Expr
*E
) {
499 TypeSourceInfo
*TInfo
= Ctx
->getTrivialTypeSourceInfo(Ty
, SourceLocation());
500 return CStyleCastExpr::Create(*Ctx
, Ty
, VK_RValue
, Kind
, E
, 0, TInfo
,
501 SourceLocation(), SourceLocation());
505 class RewriteObjCFragileABI
: public RewriteObjC
{
508 RewriteObjCFragileABI(std::string inFile
, raw_ostream
*OS
,
509 DiagnosticsEngine
&D
, const LangOptions
&LOpts
,
510 bool silenceMacroWarn
) : RewriteObjC(inFile
, OS
,
514 ~RewriteObjCFragileABI() {}
515 virtual void Initialize(ASTContext
&context
);
517 // Rewriting metadata
518 template<typename MethodIterator
>
519 void RewriteObjCMethodsMetaData(MethodIterator MethodBegin
,
520 MethodIterator MethodEnd
,
521 bool IsInstanceMethod
,
524 std::string
&Result
);
525 virtual void RewriteObjCProtocolMetaData(ObjCProtocolDecl
*Protocol
,
528 std::string
&Result
);
529 virtual void RewriteObjCProtocolListMetaData(
530 const ObjCList
<ObjCProtocolDecl
> &Prots
,
531 StringRef prefix
, StringRef ClassName
, std::string
&Result
);
532 virtual void RewriteObjCClassMetaData(ObjCImplementationDecl
*IDecl
,
533 std::string
&Result
);
534 virtual void RewriteMetaDataIntoBuffer(std::string
&Result
);
535 virtual void RewriteObjCCategoryImplDecl(ObjCCategoryImplDecl
*CDecl
,
536 std::string
&Result
);
539 virtual void RewriteIvarOffsetComputation(ObjCIvarDecl
*ivar
,
540 std::string
&Result
);
541 virtual Stmt
*RewriteObjCIvarRefExpr(ObjCIvarRefExpr
*IV
);
545 void RewriteObjC::RewriteBlocksInFunctionProtoType(QualType funcType
,
547 if (const FunctionProtoType
*fproto
548 = dyn_cast
<FunctionProtoType
>(funcType
.IgnoreParens())) {
549 for (FunctionProtoType::arg_type_iterator I
= fproto
->arg_type_begin(),
550 E
= fproto
->arg_type_end(); I
&& (I
!= E
); ++I
)
551 if (isTopLevelBlockPointerType(*I
)) {
552 // All the args are checked/rewritten. Don't call twice!
553 RewriteBlockPointerDecl(D
);
559 void RewriteObjC::CheckFunctionPointerDecl(QualType funcType
, NamedDecl
*ND
) {
560 const PointerType
*PT
= funcType
->getAs
<PointerType
>();
561 if (PT
&& PointerTypeTakesAnyBlockArguments(funcType
))
562 RewriteBlocksInFunctionProtoType(PT
->getPointeeType(), ND
);
565 static bool IsHeaderFile(const std::string
&Filename
) {
566 std::string::size_type DotPos
= Filename
.rfind('.');
568 if (DotPos
== std::string::npos
) {
573 std::string Ext
= std::string(Filename
.begin()+DotPos
+1, Filename
.end());
575 // C++ header: .hh or .H;
576 return Ext
== "h" || Ext
== "hh" || Ext
== "H";
579 RewriteObjC::RewriteObjC(std::string inFile
, raw_ostream
* OS
,
580 DiagnosticsEngine
&D
, const LangOptions
&LOpts
,
581 bool silenceMacroWarn
)
582 : Diags(D
), LangOpts(LOpts
), InFileName(inFile
), OutFile(OS
),
583 SilenceRewriteMacroWarning(silenceMacroWarn
) {
584 IsHeader
= IsHeaderFile(inFile
);
585 RewriteFailedDiag
= Diags
.getCustomDiagID(DiagnosticsEngine::Warning
,
586 "rewriting sub-expression within a macro (may not be correct)");
587 TryFinallyContainsReturnDiag
= Diags
.getCustomDiagID(
588 DiagnosticsEngine::Warning
,
589 "rewriter doesn't support user-specified control flow semantics "
590 "for @try/@finally (code may not execute properly)");
593 ASTConsumer
*clang::CreateObjCRewriter(const std::string
& InFile
,
595 DiagnosticsEngine
&Diags
,
596 const LangOptions
&LOpts
,
597 bool SilenceRewriteMacroWarning
) {
598 return new RewriteObjCFragileABI(InFile
, OS
, Diags
, LOpts
, SilenceRewriteMacroWarning
);
601 void RewriteObjC::InitializeCommon(ASTContext
&context
) {
603 SM
= &Context
->getSourceManager();
604 TUDecl
= Context
->getTranslationUnitDecl();
605 MsgSendFunctionDecl
= 0;
606 MsgSendSuperFunctionDecl
= 0;
607 MsgSendStretFunctionDecl
= 0;
608 MsgSendSuperStretFunctionDecl
= 0;
609 MsgSendFpretFunctionDecl
= 0;
610 GetClassFunctionDecl
= 0;
611 GetMetaClassFunctionDecl
= 0;
612 GetSuperClassFunctionDecl
= 0;
613 SelGetUidFunctionDecl
= 0;
614 CFStringFunctionDecl
= 0;
615 ConstantStringClassReference
= 0;
619 CurFunctionDeclToDeclareForBlock
= 0;
622 ProtocolTypeDecl
= 0;
623 ConstantStringDecl
= 0;
625 SuperContructorFunctionDecl
= 0;
626 NumObjCStringLiterals
= 0;
629 DisableReplaceStmt
= false;
630 objc_impl_method
= false;
632 // Get the ID and start/end of the main file.
633 MainFileID
= SM
->getMainFileID();
634 const llvm::MemoryBuffer
*MainBuf
= SM
->getBuffer(MainFileID
);
635 MainFileStart
= MainBuf
->getBufferStart();
636 MainFileEnd
= MainBuf
->getBufferEnd();
638 Rewrite
.setSourceMgr(Context
->getSourceManager(), Context
->getLangOpts());
641 //===----------------------------------------------------------------------===//
642 // Top Level Driver Code
643 //===----------------------------------------------------------------------===//
645 void RewriteObjC::HandleTopLevelSingleDecl(Decl
*D
) {
646 if (Diags
.hasErrorOccurred())
649 // Two cases: either the decl could be in the main file, or it could be in a
650 // #included file. If the former, rewrite it now. If the later, check to see
651 // if we rewrote the #include/#import.
652 SourceLocation Loc
= D
->getLocation();
653 Loc
= SM
->getExpansionLoc(Loc
);
655 // If this is for a builtin, ignore it.
656 if (Loc
.isInvalid()) return;
658 // Look for built-in declarations that we need to refer during the rewrite.
659 if (FunctionDecl
*FD
= dyn_cast
<FunctionDecl
>(D
)) {
660 RewriteFunctionDecl(FD
);
661 } else if (VarDecl
*FVD
= dyn_cast
<VarDecl
>(D
)) {
662 // declared in <Foundation/NSString.h>
663 if (FVD
->getName() == "_NSConstantStringClassReference") {
664 ConstantStringClassReference
= FVD
;
667 } else if (ObjCInterfaceDecl
*ID
= dyn_cast
<ObjCInterfaceDecl
>(D
)) {
668 if (ID
->isThisDeclarationADefinition())
669 RewriteInterfaceDecl(ID
);
670 } else if (ObjCCategoryDecl
*CD
= dyn_cast
<ObjCCategoryDecl
>(D
)) {
671 RewriteCategoryDecl(CD
);
672 } else if (ObjCProtocolDecl
*PD
= dyn_cast
<ObjCProtocolDecl
>(D
)) {
673 if (PD
->isThisDeclarationADefinition())
674 RewriteProtocolDecl(PD
);
675 } else if (LinkageSpecDecl
*LSD
= dyn_cast
<LinkageSpecDecl
>(D
)) {
676 // Recurse into linkage specifications
677 for (DeclContext::decl_iterator DI
= LSD
->decls_begin(),
678 DIEnd
= LSD
->decls_end();
680 if (ObjCInterfaceDecl
*IFace
= dyn_cast
<ObjCInterfaceDecl
>((*DI
))) {
681 if (!IFace
->isThisDeclarationADefinition()) {
682 SmallVector
<Decl
*, 8> DG
;
683 SourceLocation StartLoc
= IFace
->getLocStart();
685 if (isa
<ObjCInterfaceDecl
>(*DI
) &&
686 !cast
<ObjCInterfaceDecl
>(*DI
)->isThisDeclarationADefinition() &&
687 StartLoc
== (*DI
)->getLocStart())
693 } while (DI
!= DIEnd
);
694 RewriteForwardClassDecl(DG
);
699 if (ObjCProtocolDecl
*Proto
= dyn_cast
<ObjCProtocolDecl
>((*DI
))) {
700 if (!Proto
->isThisDeclarationADefinition()) {
701 SmallVector
<Decl
*, 8> DG
;
702 SourceLocation StartLoc
= Proto
->getLocStart();
704 if (isa
<ObjCProtocolDecl
>(*DI
) &&
705 !cast
<ObjCProtocolDecl
>(*DI
)->isThisDeclarationADefinition() &&
706 StartLoc
== (*DI
)->getLocStart())
712 } while (DI
!= DIEnd
);
713 RewriteForwardProtocolDecl(DG
);
718 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 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
.getLocWithOffset(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
.getLocWithOffset(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
->getPrintingPolicy());
826 if (FT
->isVariadic()) {
827 if (FT
->getNumArgs()) Getr
+= ", ";
835 Getr
+= "return (_TYPE)";
836 Getr
+= "objc_getProperty(self, _cmd, ";
837 RewriteIvarOffsetComputation(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 RewriteIvarOffsetComputation(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 static void RewriteOneForwardClassDecl(ObjCInterfaceDecl
*ForwardDecl
,
889 std::string
&typedefString
) {
890 typedefString
+= "#ifndef _REWRITER_typedef_";
891 typedefString
+= ForwardDecl
->getNameAsString();
892 typedefString
+= "\n";
893 typedefString
+= "#define _REWRITER_typedef_";
894 typedefString
+= ForwardDecl
->getNameAsString();
895 typedefString
+= "\n";
896 typedefString
+= "typedef struct objc_object ";
897 typedefString
+= ForwardDecl
->getNameAsString();
898 typedefString
+= ";\n#endif\n";
901 void RewriteObjC::RewriteForwardClassEpilogue(ObjCInterfaceDecl
*ClassDecl
,
902 const std::string
&typedefString
) {
903 SourceLocation startLoc
= ClassDecl
->getLocStart();
904 const char *startBuf
= SM
->getCharacterData(startLoc
);
905 const char *semiPtr
= strchr(startBuf
, ';');
906 // Replace the @class with typedefs corresponding to the classes.
907 ReplaceText(startLoc
, semiPtr
-startBuf
+1, typedefString
);
910 void RewriteObjC::RewriteForwardClassDecl(DeclGroupRef D
) {
911 std::string typedefString
;
912 for (DeclGroupRef::iterator I
= D
.begin(), E
= D
.end(); I
!= E
; ++I
) {
913 ObjCInterfaceDecl
*ForwardDecl
= cast
<ObjCInterfaceDecl
>(*I
);
914 if (I
== D
.begin()) {
915 // Translate to typedef's that forward reference structs with the same name
916 // as the class. As a convenience, we include the original declaration
918 typedefString
+= "// @class ";
919 typedefString
+= ForwardDecl
->getNameAsString();
920 typedefString
+= ";\n";
922 RewriteOneForwardClassDecl(ForwardDecl
, typedefString
);
924 DeclGroupRef::iterator I
= D
.begin();
925 RewriteForwardClassEpilogue(cast
<ObjCInterfaceDecl
>(*I
), typedefString
);
928 void RewriteObjC::RewriteForwardClassDecl(
929 const llvm::SmallVector
<Decl
*, 8> &D
) {
930 std::string typedefString
;
931 for (unsigned i
= 0; i
< D
.size(); i
++) {
932 ObjCInterfaceDecl
*ForwardDecl
= cast
<ObjCInterfaceDecl
>(D
[i
]);
934 typedefString
+= "// @class ";
935 typedefString
+= ForwardDecl
->getNameAsString();
936 typedefString
+= ";\n";
938 RewriteOneForwardClassDecl(ForwardDecl
, typedefString
);
940 RewriteForwardClassEpilogue(cast
<ObjCInterfaceDecl
>(D
[0]), typedefString
);
943 void RewriteObjC::RewriteMethodDeclaration(ObjCMethodDecl
*Method
) {
944 // When method is a synthesized one, such as a getter/setter there is
945 // nothing to rewrite.
946 if (Method
->isImplicit())
948 SourceLocation LocStart
= Method
->getLocStart();
949 SourceLocation LocEnd
= Method
->getLocEnd();
951 if (SM
->getExpansionLineNumber(LocEnd
) >
952 SM
->getExpansionLineNumber(LocStart
)) {
953 InsertText(LocStart
, "#if 0\n");
954 ReplaceText(LocEnd
, 1, ";\n#endif\n");
956 InsertText(LocStart
, "// ");
960 void RewriteObjC::RewriteProperty(ObjCPropertyDecl
*prop
) {
961 SourceLocation Loc
= prop
->getAtLoc();
963 ReplaceText(Loc
, 0, "// ");
964 // FIXME: handle properties that are declared across multiple lines.
967 void RewriteObjC::RewriteCategoryDecl(ObjCCategoryDecl
*CatDecl
) {
968 SourceLocation LocStart
= CatDecl
->getLocStart();
970 // FIXME: handle category headers that are declared across multiple lines.
971 ReplaceText(LocStart
, 0, "// ");
973 for (ObjCCategoryDecl::prop_iterator I
= CatDecl
->prop_begin(),
974 E
= CatDecl
->prop_end(); I
!= E
; ++I
)
977 for (ObjCCategoryDecl::instmeth_iterator
978 I
= CatDecl
->instmeth_begin(), E
= CatDecl
->instmeth_end();
980 RewriteMethodDeclaration(*I
);
981 for (ObjCCategoryDecl::classmeth_iterator
982 I
= CatDecl
->classmeth_begin(), E
= CatDecl
->classmeth_end();
984 RewriteMethodDeclaration(*I
);
986 // Lastly, comment out the @end.
987 ReplaceText(CatDecl
->getAtEndRange().getBegin(),
988 strlen("@end"), "/* @end */");
991 void RewriteObjC::RewriteProtocolDecl(ObjCProtocolDecl
*PDecl
) {
992 SourceLocation LocStart
= PDecl
->getLocStart();
993 assert(PDecl
->isThisDeclarationADefinition());
995 // FIXME: handle protocol headers that are declared across multiple lines.
996 ReplaceText(LocStart
, 0, "// ");
998 for (ObjCProtocolDecl::instmeth_iterator
999 I
= PDecl
->instmeth_begin(), E
= PDecl
->instmeth_end();
1001 RewriteMethodDeclaration(*I
);
1002 for (ObjCProtocolDecl::classmeth_iterator
1003 I
= PDecl
->classmeth_begin(), E
= PDecl
->classmeth_end();
1005 RewriteMethodDeclaration(*I
);
1007 for (ObjCInterfaceDecl::prop_iterator I
= PDecl
->prop_begin(),
1008 E
= PDecl
->prop_end(); I
!= E
; ++I
)
1009 RewriteProperty(*I
);
1011 // Lastly, comment out the @end.
1012 SourceLocation LocEnd
= PDecl
->getAtEndRange().getBegin();
1013 ReplaceText(LocEnd
, strlen("@end"), "/* @end */");
1015 // Must comment out @optional/@required
1016 const char *startBuf
= SM
->getCharacterData(LocStart
);
1017 const char *endBuf
= SM
->getCharacterData(LocEnd
);
1018 for (const char *p
= startBuf
; p
< endBuf
; p
++) {
1019 if (*p
== '@' && !strncmp(p
+1, "optional", strlen("optional"))) {
1020 SourceLocation OptionalLoc
= LocStart
.getLocWithOffset(p
-startBuf
);
1021 ReplaceText(OptionalLoc
, strlen("@optional"), "/* @optional */");
1024 else if (*p
== '@' && !strncmp(p
+1, "required", strlen("required"))) {
1025 SourceLocation OptionalLoc
= LocStart
.getLocWithOffset(p
-startBuf
);
1026 ReplaceText(OptionalLoc
, strlen("@required"), "/* @required */");
1032 void RewriteObjC::RewriteForwardProtocolDecl(DeclGroupRef D
) {
1033 SourceLocation LocStart
= (*D
.begin())->getLocStart();
1034 if (LocStart
.isInvalid())
1035 llvm_unreachable("Invalid SourceLocation");
1036 // FIXME: handle forward protocol that are declared across multiple lines.
1037 ReplaceText(LocStart
, 0, "// ");
1041 RewriteObjC::RewriteForwardProtocolDecl(const llvm::SmallVector
<Decl
*, 8> &DG
) {
1042 SourceLocation LocStart
= DG
[0]->getLocStart();
1043 if (LocStart
.isInvalid())
1044 llvm_unreachable("Invalid SourceLocation");
1045 // FIXME: handle forward protocol that are declared across multiple lines.
1046 ReplaceText(LocStart
, 0, "// ");
1049 void RewriteObjC::RewriteTypeIntoString(QualType T
, std::string
&ResultStr
,
1050 const FunctionType
*&FPRetType
) {
1051 if (T
->isObjCQualifiedIdType())
1053 else if (T
->isFunctionPointerType() ||
1054 T
->isBlockPointerType()) {
1055 // needs special handling, since pointer-to-functions have special
1056 // syntax (where a decaration models use).
1057 QualType retType
= T
;
1059 if (const PointerType
* PT
= retType
->getAs
<PointerType
>())
1060 PointeeTy
= PT
->getPointeeType();
1061 else if (const BlockPointerType
*BPT
= retType
->getAs
<BlockPointerType
>())
1062 PointeeTy
= BPT
->getPointeeType();
1063 if ((FPRetType
= PointeeTy
->getAs
<FunctionType
>())) {
1064 ResultStr
+= FPRetType
->getResultType().getAsString(
1065 Context
->getPrintingPolicy());
1069 ResultStr
+= T
.getAsString(Context
->getPrintingPolicy());
1072 void RewriteObjC::RewriteObjCMethodDecl(const ObjCInterfaceDecl
*IDecl
,
1073 ObjCMethodDecl
*OMD
,
1074 std::string
&ResultStr
) {
1075 //fprintf(stderr,"In RewriteObjCMethodDecl\n");
1076 const FunctionType
*FPRetType
= 0;
1077 ResultStr
+= "\nstatic ";
1078 RewriteTypeIntoString(OMD
->getResultType(), ResultStr
, FPRetType
);
1081 // Unique method name
1082 std::string NameStr
;
1084 if (OMD
->isInstanceMethod())
1089 NameStr
+= IDecl
->getNameAsString();
1092 if (ObjCCategoryImplDecl
*CID
=
1093 dyn_cast
<ObjCCategoryImplDecl
>(OMD
->getDeclContext())) {
1094 NameStr
+= CID
->getNameAsString();
1097 // Append selector names, replacing ':' with '_'
1099 std::string selString
= OMD
->getSelector().getAsString();
1100 int len
= selString
.size();
1101 for (int i
= 0; i
< len
; i
++)
1102 if (selString
[i
] == ':')
1104 NameStr
+= selString
;
1106 // Remember this name for metadata emission
1107 MethodInternalNames
[OMD
] = NameStr
;
1108 ResultStr
+= NameStr
;
1110 // Rewrite arguments
1113 // invisible arguments
1114 if (OMD
->isInstanceMethod()) {
1115 QualType selfTy
= Context
->getObjCInterfaceType(IDecl
);
1116 selfTy
= Context
->getPointerType(selfTy
);
1117 if (!LangOpts
.MicrosoftExt
) {
1118 if (ObjCSynthesizedStructs
.count(const_cast<ObjCInterfaceDecl
*>(IDecl
)))
1119 ResultStr
+= "struct ";
1121 // When rewriting for Microsoft, explicitly omit the structure name.
1122 ResultStr
+= IDecl
->getNameAsString();
1126 ResultStr
+= Context
->getObjCClassType().getAsString(
1127 Context
->getPrintingPolicy());
1129 ResultStr
+= " self, ";
1130 ResultStr
+= Context
->getObjCSelType().getAsString(Context
->getPrintingPolicy());
1131 ResultStr
+= " _cmd";
1133 // Method arguments.
1134 for (ObjCMethodDecl::param_iterator PI
= OMD
->param_begin(),
1135 E
= OMD
->param_end(); PI
!= E
; ++PI
) {
1136 ParmVarDecl
*PDecl
= *PI
;
1138 if (PDecl
->getType()->isObjCQualifiedIdType()) {
1140 ResultStr
+= PDecl
->getNameAsString();
1142 std::string Name
= PDecl
->getNameAsString();
1143 QualType QT
= PDecl
->getType();
1144 // Make sure we convert "t (^)(...)" to "t (*)(...)".
1145 (void)convertBlockPointerToFunctionPointer(QT
);
1146 QT
.getAsStringInternal(Name
, Context
->getPrintingPolicy());
1150 if (OMD
->isVariadic())
1151 ResultStr
+= ", ...";
1155 ResultStr
+= ")"; // close the precedence "scope" for "*".
1157 // Now, emit the argument types (if any).
1158 if (const FunctionProtoType
*FT
= dyn_cast
<FunctionProtoType
>(FPRetType
)) {
1160 for (unsigned i
= 0, e
= FT
->getNumArgs(); i
!= e
; ++i
) {
1161 if (i
) ResultStr
+= ", ";
1162 std::string ParamStr
= FT
->getArgType(i
).getAsString(
1163 Context
->getPrintingPolicy());
1164 ResultStr
+= ParamStr
;
1166 if (FT
->isVariadic()) {
1167 if (FT
->getNumArgs()) ResultStr
+= ", ";
1176 void RewriteObjC::RewriteImplementationDecl(Decl
*OID
) {
1177 ObjCImplementationDecl
*IMD
= dyn_cast
<ObjCImplementationDecl
>(OID
);
1178 ObjCCategoryImplDecl
*CID
= dyn_cast
<ObjCCategoryImplDecl
>(OID
);
1180 InsertText(IMD
? IMD
->getLocStart() : CID
->getLocStart(), "// ");
1182 for (ObjCCategoryImplDecl::instmeth_iterator
1183 I
= IMD
? IMD
->instmeth_begin() : CID
->instmeth_begin(),
1184 E
= IMD
? IMD
->instmeth_end() : CID
->instmeth_end();
1186 std::string ResultStr
;
1187 ObjCMethodDecl
*OMD
= *I
;
1188 RewriteObjCMethodDecl(OMD
->getClassInterface(), OMD
, ResultStr
);
1189 SourceLocation LocStart
= OMD
->getLocStart();
1190 SourceLocation LocEnd
= OMD
->getCompoundBody()->getLocStart();
1192 const char *startBuf
= SM
->getCharacterData(LocStart
);
1193 const char *endBuf
= SM
->getCharacterData(LocEnd
);
1194 ReplaceText(LocStart
, endBuf
-startBuf
, ResultStr
);
1197 for (ObjCCategoryImplDecl::classmeth_iterator
1198 I
= IMD
? IMD
->classmeth_begin() : CID
->classmeth_begin(),
1199 E
= IMD
? IMD
->classmeth_end() : CID
->classmeth_end();
1201 std::string ResultStr
;
1202 ObjCMethodDecl
*OMD
= *I
;
1203 RewriteObjCMethodDecl(OMD
->getClassInterface(), OMD
, ResultStr
);
1204 SourceLocation LocStart
= OMD
->getLocStart();
1205 SourceLocation LocEnd
= OMD
->getCompoundBody()->getLocStart();
1207 const char *startBuf
= SM
->getCharacterData(LocStart
);
1208 const char *endBuf
= SM
->getCharacterData(LocEnd
);
1209 ReplaceText(LocStart
, endBuf
-startBuf
, ResultStr
);
1211 for (ObjCCategoryImplDecl::propimpl_iterator
1212 I
= IMD
? IMD
->propimpl_begin() : CID
->propimpl_begin(),
1213 E
= IMD
? IMD
->propimpl_end() : CID
->propimpl_end();
1215 RewritePropertyImplDecl(*I
, IMD
, CID
);
1218 InsertText(IMD
? IMD
->getLocEnd() : CID
->getLocEnd(), "// ");
1221 void RewriteObjC::RewriteInterfaceDecl(ObjCInterfaceDecl
*ClassDecl
) {
1222 std::string ResultStr
;
1223 if (!ObjCForwardDecls
.count(ClassDecl
->getCanonicalDecl())) {
1224 // we haven't seen a forward decl - generate a typedef.
1225 ResultStr
= "#ifndef _REWRITER_typedef_";
1226 ResultStr
+= ClassDecl
->getNameAsString();
1228 ResultStr
+= "#define _REWRITER_typedef_";
1229 ResultStr
+= ClassDecl
->getNameAsString();
1231 ResultStr
+= "typedef struct objc_object ";
1232 ResultStr
+= ClassDecl
->getNameAsString();
1233 ResultStr
+= ";\n#endif\n";
1234 // Mark this typedef as having been generated.
1235 ObjCForwardDecls
.insert(ClassDecl
->getCanonicalDecl());
1237 RewriteObjCInternalStruct(ClassDecl
, ResultStr
);
1239 for (ObjCInterfaceDecl::prop_iterator I
= ClassDecl
->prop_begin(),
1240 E
= ClassDecl
->prop_end(); I
!= E
; ++I
)
1241 RewriteProperty(*I
);
1242 for (ObjCInterfaceDecl::instmeth_iterator
1243 I
= ClassDecl
->instmeth_begin(), E
= ClassDecl
->instmeth_end();
1245 RewriteMethodDeclaration(*I
);
1246 for (ObjCInterfaceDecl::classmeth_iterator
1247 I
= ClassDecl
->classmeth_begin(), E
= ClassDecl
->classmeth_end();
1249 RewriteMethodDeclaration(*I
);
1251 // Lastly, comment out the @end.
1252 ReplaceText(ClassDecl
->getAtEndRange().getBegin(), strlen("@end"),
1256 Stmt
*RewriteObjC::RewritePropertyOrImplicitSetter(PseudoObjectExpr
*PseudoOp
) {
1257 SourceRange OldRange
= PseudoOp
->getSourceRange();
1259 // We just magically know some things about the structure of this
1261 ObjCMessageExpr
*OldMsg
=
1262 cast
<ObjCMessageExpr
>(PseudoOp
->getSemanticExpr(
1263 PseudoOp
->getNumSemanticExprs() - 1));
1265 // Because the rewriter doesn't allow us to rewrite rewritten code,
1266 // we need to suppress rewriting the sub-statements.
1269 DisableReplaceStmtScope
S(*this);
1271 // Rebuild the base expression if we have one.
1273 if (OldMsg
->getReceiverKind() == ObjCMessageExpr::Instance
) {
1274 Base
= OldMsg
->getInstanceReceiver();
1275 Base
= cast
<OpaqueValueExpr
>(Base
)->getSourceExpr();
1276 Base
= cast
<Expr
>(RewriteFunctionBodyOrGlobalInitializer(Base
));
1280 RHS
= cast
<BinaryOperator
>(PseudoOp
->getSyntacticForm())->getRHS();
1281 RHS
= cast
<OpaqueValueExpr
>(RHS
)->getSourceExpr();
1282 RHS
= cast
<Expr
>(RewriteFunctionBodyOrGlobalInitializer(RHS
));
1285 // TODO: avoid this copy.
1286 SmallVector
<SourceLocation
, 1> SelLocs
;
1287 OldMsg
->getSelectorLocs(SelLocs
);
1289 ObjCMessageExpr
*NewMsg
= 0;
1290 switch (OldMsg
->getReceiverKind()) {
1291 case ObjCMessageExpr::Class
:
1292 NewMsg
= ObjCMessageExpr::Create(*Context
, OldMsg
->getType(),
1293 OldMsg
->getValueKind(),
1294 OldMsg
->getLeftLoc(),
1295 OldMsg
->getClassReceiverTypeInfo(),
1296 OldMsg
->getSelector(),
1298 OldMsg
->getMethodDecl(),
1300 OldMsg
->getRightLoc(),
1301 OldMsg
->isImplicit());
1304 case ObjCMessageExpr::Instance
:
1305 NewMsg
= ObjCMessageExpr::Create(*Context
, OldMsg
->getType(),
1306 OldMsg
->getValueKind(),
1307 OldMsg
->getLeftLoc(),
1309 OldMsg
->getSelector(),
1311 OldMsg
->getMethodDecl(),
1313 OldMsg
->getRightLoc(),
1314 OldMsg
->isImplicit());
1317 case ObjCMessageExpr::SuperClass
:
1318 case ObjCMessageExpr::SuperInstance
:
1319 NewMsg
= ObjCMessageExpr::Create(*Context
, OldMsg
->getType(),
1320 OldMsg
->getValueKind(),
1321 OldMsg
->getLeftLoc(),
1322 OldMsg
->getSuperLoc(),
1323 OldMsg
->getReceiverKind() == ObjCMessageExpr::SuperInstance
,
1324 OldMsg
->getSuperType(),
1325 OldMsg
->getSelector(),
1327 OldMsg
->getMethodDecl(),
1329 OldMsg
->getRightLoc(),
1330 OldMsg
->isImplicit());
1334 Stmt
*Replacement
= SynthMessageExpr(NewMsg
);
1335 ReplaceStmtWithRange(PseudoOp
, Replacement
, OldRange
);
1339 Stmt
*RewriteObjC::RewritePropertyOrImplicitGetter(PseudoObjectExpr
*PseudoOp
) {
1340 SourceRange OldRange
= PseudoOp
->getSourceRange();
1342 // We just magically know some things about the structure of this
1344 ObjCMessageExpr
*OldMsg
=
1345 cast
<ObjCMessageExpr
>(PseudoOp
->getResultExpr()->IgnoreImplicit());
1347 // Because the rewriter doesn't allow us to rewrite rewritten code,
1348 // we need to suppress rewriting the sub-statements.
1351 DisableReplaceStmtScope
S(*this);
1353 // Rebuild the base expression if we have one.
1354 if (OldMsg
->getReceiverKind() == ObjCMessageExpr::Instance
) {
1355 Base
= OldMsg
->getInstanceReceiver();
1356 Base
= cast
<OpaqueValueExpr
>(Base
)->getSourceExpr();
1357 Base
= cast
<Expr
>(RewriteFunctionBodyOrGlobalInitializer(Base
));
1361 // Intentionally empty.
1362 SmallVector
<SourceLocation
, 1> SelLocs
;
1363 SmallVector
<Expr
*, 1> Args
;
1365 ObjCMessageExpr
*NewMsg
= 0;
1366 switch (OldMsg
->getReceiverKind()) {
1367 case ObjCMessageExpr::Class
:
1368 NewMsg
= ObjCMessageExpr::Create(*Context
, OldMsg
->getType(),
1369 OldMsg
->getValueKind(),
1370 OldMsg
->getLeftLoc(),
1371 OldMsg
->getClassReceiverTypeInfo(),
1372 OldMsg
->getSelector(),
1374 OldMsg
->getMethodDecl(),
1376 OldMsg
->getRightLoc(),
1377 OldMsg
->isImplicit());
1380 case ObjCMessageExpr::Instance
:
1381 NewMsg
= ObjCMessageExpr::Create(*Context
, OldMsg
->getType(),
1382 OldMsg
->getValueKind(),
1383 OldMsg
->getLeftLoc(),
1385 OldMsg
->getSelector(),
1387 OldMsg
->getMethodDecl(),
1389 OldMsg
->getRightLoc(),
1390 OldMsg
->isImplicit());
1393 case ObjCMessageExpr::SuperClass
:
1394 case ObjCMessageExpr::SuperInstance
:
1395 NewMsg
= ObjCMessageExpr::Create(*Context
, OldMsg
->getType(),
1396 OldMsg
->getValueKind(),
1397 OldMsg
->getLeftLoc(),
1398 OldMsg
->getSuperLoc(),
1399 OldMsg
->getReceiverKind() == ObjCMessageExpr::SuperInstance
,
1400 OldMsg
->getSuperType(),
1401 OldMsg
->getSelector(),
1403 OldMsg
->getMethodDecl(),
1405 OldMsg
->getRightLoc(),
1406 OldMsg
->isImplicit());
1410 Stmt
*Replacement
= SynthMessageExpr(NewMsg
);
1411 ReplaceStmtWithRange(PseudoOp
, Replacement
, OldRange
);
1415 /// SynthCountByEnumWithState - To print:
1416 /// ((unsigned int (*)
1417 /// (id, SEL, struct __objcFastEnumerationState *, id *, unsigned int))
1418 /// (void *)objc_msgSend)((id)l_collection,
1419 /// sel_registerName(
1420 /// "countByEnumeratingWithState:objects:count:"),
1422 /// (id *)__rw_items, (unsigned int)16)
1424 void RewriteObjC::SynthCountByEnumWithState(std::string
&buf
) {
1425 buf
+= "((unsigned int (*) (id, SEL, struct __objcFastEnumerationState *, "
1426 "id *, unsigned int))(void *)objc_msgSend)";
1428 buf
+= "((id)l_collection,\n\t\t";
1429 buf
+= "sel_registerName(\"countByEnumeratingWithState:objects:count:\"),";
1431 buf
+= "&enumState, "
1432 "(id *)__rw_items, (unsigned int)16)";
1435 /// RewriteBreakStmt - Rewrite for a break-stmt inside an ObjC2's foreach
1436 /// statement to exit to its outer synthesized loop.
1438 Stmt
*RewriteObjC::RewriteBreakStmt(BreakStmt
*S
) {
1439 if (Stmts
.empty() || !isa
<ObjCForCollectionStmt
>(Stmts
.back()))
1441 // replace break with goto __break_label
1444 SourceLocation startLoc
= S
->getLocStart();
1445 buf
= "goto __break_label_";
1446 buf
+= utostr(ObjCBcLabelNo
.back());
1447 ReplaceText(startLoc
, strlen("break"), buf
);
1452 /// RewriteContinueStmt - Rewrite for a continue-stmt inside an ObjC2's foreach
1453 /// statement to continue with its inner synthesized loop.
1455 Stmt
*RewriteObjC::RewriteContinueStmt(ContinueStmt
*S
) {
1456 if (Stmts
.empty() || !isa
<ObjCForCollectionStmt
>(Stmts
.back()))
1458 // replace continue with goto __continue_label
1461 SourceLocation startLoc
= S
->getLocStart();
1462 buf
= "goto __continue_label_";
1463 buf
+= utostr(ObjCBcLabelNo
.back());
1464 ReplaceText(startLoc
, strlen("continue"), buf
);
1469 /// RewriteObjCForCollectionStmt - Rewriter for ObjC2's foreach statement.
1471 /// for ( type elem in collection) { stmts; }
1476 /// struct __objcFastEnumerationState enumState = { 0 };
1477 /// id __rw_items[16];
1478 /// id l_collection = (id)collection;
1479 /// unsigned long limit = [l_collection countByEnumeratingWithState:&enumState
1480 /// objects:__rw_items count:16];
1482 /// unsigned long startMutations = *enumState.mutationsPtr;
1484 /// unsigned long counter = 0;
1486 /// if (startMutations != *enumState.mutationsPtr)
1487 /// objc_enumerationMutation(l_collection);
1488 /// elem = (type)enumState.itemsPtr[counter++];
1490 /// __continue_label: ;
1491 /// } while (counter < limit);
1492 /// } while (limit = [l_collection countByEnumeratingWithState:&enumState
1493 /// objects:__rw_items count:16]);
1495 /// __break_label: ;
1501 Stmt
*RewriteObjC::RewriteObjCForCollectionStmt(ObjCForCollectionStmt
*S
,
1502 SourceLocation OrigEnd
) {
1503 assert(!Stmts
.empty() && "ObjCForCollectionStmt - Statement stack empty");
1504 assert(isa
<ObjCForCollectionStmt
>(Stmts
.back()) &&
1505 "ObjCForCollectionStmt Statement stack mismatch");
1506 assert(!ObjCBcLabelNo
.empty() &&
1507 "ObjCForCollectionStmt - Label No stack empty");
1509 SourceLocation startLoc
= S
->getLocStart();
1510 const char *startBuf
= SM
->getCharacterData(startLoc
);
1511 StringRef elementName
;
1512 std::string elementTypeAsString
;
1515 if (DeclStmt
*DS
= dyn_cast
<DeclStmt
>(S
->getElement())) {
1517 NamedDecl
* D
= cast
<NamedDecl
>(DS
->getSingleDecl());
1518 QualType ElementType
= cast
<ValueDecl
>(D
)->getType();
1519 if (ElementType
->isObjCQualifiedIdType() ||
1520 ElementType
->isObjCQualifiedInterfaceType())
1521 // Simply use 'id' for all qualified types.
1522 elementTypeAsString
= "id";
1524 elementTypeAsString
= ElementType
.getAsString(Context
->getPrintingPolicy());
1525 buf
+= elementTypeAsString
;
1527 elementName
= D
->getName();
1532 DeclRefExpr
*DR
= cast
<DeclRefExpr
>(S
->getElement());
1533 elementName
= DR
->getDecl()->getName();
1534 ValueDecl
*VD
= cast
<ValueDecl
>(DR
->getDecl());
1535 if (VD
->getType()->isObjCQualifiedIdType() ||
1536 VD
->getType()->isObjCQualifiedInterfaceType())
1537 // Simply use 'id' for all qualified types.
1538 elementTypeAsString
= "id";
1540 elementTypeAsString
= VD
->getType().getAsString(Context
->getPrintingPolicy());
1543 // struct __objcFastEnumerationState enumState = { 0 };
1544 buf
+= "struct __objcFastEnumerationState enumState = { 0 };\n\t";
1545 // id __rw_items[16];
1546 buf
+= "id __rw_items[16];\n\t";
1547 // id l_collection = (id)
1548 buf
+= "id l_collection = (id)";
1549 // Find start location of 'collection' the hard way!
1550 const char *startCollectionBuf
= startBuf
;
1551 startCollectionBuf
+= 3; // skip 'for'
1552 startCollectionBuf
= strchr(startCollectionBuf
, '(');
1553 startCollectionBuf
++; // skip '('
1554 // find 'in' and skip it.
1555 while (*startCollectionBuf
!= ' ' ||
1556 *(startCollectionBuf
+1) != 'i' || *(startCollectionBuf
+2) != 'n' ||
1557 (*(startCollectionBuf
+3) != ' ' &&
1558 *(startCollectionBuf
+3) != '[' && *(startCollectionBuf
+3) != '('))
1559 startCollectionBuf
++;
1560 startCollectionBuf
+= 3;
1562 // Replace: "for (type element in" with string constructed thus far.
1563 ReplaceText(startLoc
, startCollectionBuf
- startBuf
, buf
);
1564 // Replace ')' in for '(' type elem in collection ')' with ';'
1565 SourceLocation rightParenLoc
= S
->getRParenLoc();
1566 const char *rparenBuf
= SM
->getCharacterData(rightParenLoc
);
1567 SourceLocation lparenLoc
= startLoc
.getLocWithOffset(rparenBuf
-startBuf
);
1570 // unsigned long limit = [l_collection countByEnumeratingWithState:&enumState
1571 // objects:__rw_items count:16];
1572 // which is synthesized into:
1573 // unsigned int limit =
1574 // ((unsigned int (*)
1575 // (id, SEL, struct __objcFastEnumerationState *, id *, unsigned int))
1576 // (void *)objc_msgSend)((id)l_collection,
1577 // sel_registerName(
1578 // "countByEnumeratingWithState:objects:count:"),
1579 // (struct __objcFastEnumerationState *)&state,
1580 // (id *)__rw_items, (unsigned int)16);
1581 buf
+= "unsigned long limit =\n\t\t";
1582 SynthCountByEnumWithState(buf
);
1585 /// unsigned long startMutations = *enumState.mutationsPtr;
1587 /// unsigned long counter = 0;
1589 /// if (startMutations != *enumState.mutationsPtr)
1590 /// objc_enumerationMutation(l_collection);
1591 /// elem = (type)enumState.itemsPtr[counter++];
1592 buf
+= "if (limit) {\n\t";
1593 buf
+= "unsigned long startMutations = *enumState.mutationsPtr;\n\t";
1594 buf
+= "do {\n\t\t";
1595 buf
+= "unsigned long counter = 0;\n\t\t";
1596 buf
+= "do {\n\t\t\t";
1597 buf
+= "if (startMutations != *enumState.mutationsPtr)\n\t\t\t\t";
1598 buf
+= "objc_enumerationMutation(l_collection);\n\t\t\t";
1601 buf
+= elementTypeAsString
;
1602 buf
+= ")enumState.itemsPtr[counter++];";
1603 // Replace ')' in for '(' type elem in collection ')' with all of these.
1604 ReplaceText(lparenLoc
, 1, buf
);
1606 /// __continue_label: ;
1607 /// } while (counter < limit);
1608 /// } while (limit = [l_collection countByEnumeratingWithState:&enumState
1609 /// objects:__rw_items count:16]);
1611 /// __break_label: ;
1618 buf
+= "__continue_label_";
1619 buf
+= utostr(ObjCBcLabelNo
.back());
1622 buf
+= "} while (counter < limit);\n\t";
1623 buf
+= "} while (limit = ";
1624 SynthCountByEnumWithState(buf
);
1628 buf
+= elementTypeAsString
;
1630 buf
+= "__break_label_";
1631 buf
+= utostr(ObjCBcLabelNo
.back());
1634 buf
+= "else\n\t\t";
1637 buf
+= elementTypeAsString
;
1641 // Insert all these *after* the statement body.
1642 // FIXME: If this should support Obj-C++, support CXXTryStmt
1643 if (isa
<CompoundStmt
>(S
->getBody())) {
1644 SourceLocation endBodyLoc
= OrigEnd
.getLocWithOffset(1);
1645 InsertText(endBodyLoc
, buf
);
1647 /* Need to treat single statements specially. For example:
1649 * for (A *a in b) if (stuff()) break;
1650 * for (A *a in b) xxxyy;
1652 * The following code simply scans ahead to the semi to find the actual end.
1654 const char *stmtBuf
= SM
->getCharacterData(OrigEnd
);
1655 const char *semiBuf
= strchr(stmtBuf
, ';');
1656 assert(semiBuf
&& "Can't find ';'");
1657 SourceLocation endBodyLoc
= OrigEnd
.getLocWithOffset(semiBuf
-stmtBuf
+1);
1658 InsertText(endBodyLoc
, buf
);
1661 ObjCBcLabelNo
.pop_back();
1665 /// RewriteObjCSynchronizedStmt -
1666 /// This routine rewrites @synchronized(expr) stmt;
1668 /// objc_sync_enter(expr);
1669 /// @try stmt @finally { objc_sync_exit(expr); }
1671 Stmt
*RewriteObjC::RewriteObjCSynchronizedStmt(ObjCAtSynchronizedStmt
*S
) {
1672 // Get the start location and compute the semi location.
1673 SourceLocation startLoc
= S
->getLocStart();
1674 const char *startBuf
= SM
->getCharacterData(startLoc
);
1676 assert((*startBuf
== '@') && "bogus @synchronized location");
1679 buf
= "objc_sync_enter((id)";
1680 const char *lparenBuf
= startBuf
;
1681 while (*lparenBuf
!= '(') lparenBuf
++;
1682 ReplaceText(startLoc
, lparenBuf
-startBuf
+1, buf
);
1683 // We can't use S->getSynchExpr()->getLocEnd() to find the end location, since
1684 // the sync expression is typically a message expression that's already
1685 // been rewritten! (which implies the SourceLocation's are invalid).
1686 SourceLocation endLoc
= S
->getSynchBody()->getLocStart();
1687 const char *endBuf
= SM
->getCharacterData(endLoc
);
1688 while (*endBuf
!= ')') endBuf
--;
1689 SourceLocation rparenLoc
= startLoc
.getLocWithOffset(endBuf
-startBuf
);
1691 // declare a new scope with two variables, _stack and _rethrow.
1692 buf
+= "/* @try scope begin */ \n{ struct _objc_exception_data {\n";
1693 buf
+= "int buf[18/*32-bit i386*/];\n";
1694 buf
+= "char *pointers[4];} _stack;\n";
1695 buf
+= "id volatile _rethrow = 0;\n";
1696 buf
+= "objc_exception_try_enter(&_stack);\n";
1697 buf
+= "if (!_setjmp(_stack.buf)) /* @try block continue */\n";
1698 ReplaceText(rparenLoc
, 1, buf
);
1699 startLoc
= S
->getSynchBody()->getLocEnd();
1700 startBuf
= SM
->getCharacterData(startLoc
);
1702 assert((*startBuf
== '}') && "bogus @synchronized block");
1703 SourceLocation lastCurlyLoc
= startLoc
;
1704 buf
= "}\nelse {\n";
1705 buf
+= " _rethrow = objc_exception_extract(&_stack);\n";
1707 buf
+= "{ /* implicit finally clause */\n";
1708 buf
+= " if (!_rethrow) objc_exception_try_exit(&_stack);\n";
1710 std::string syncBuf
;
1711 syncBuf
+= " objc_sync_exit(";
1713 Expr
*syncExpr
= S
->getSynchExpr();
1714 CastKind CK
= syncExpr
->getType()->isObjCObjectPointerType()
1716 syncExpr
->getType()->isBlockPointerType()
1717 ? CK_BlockPointerToObjCPointerCast
1718 : CK_CPointerToObjCPointerCast
;
1719 syncExpr
= NoTypeInfoCStyleCastExpr(Context
, Context
->getObjCIdType(),
1721 std::string syncExprBufS
;
1722 llvm::raw_string_ostream
syncExprBuf(syncExprBufS
);
1723 syncExpr
->printPretty(syncExprBuf
, 0, PrintingPolicy(LangOpts
));
1724 syncBuf
+= syncExprBuf
.str();
1728 buf
+= "\n if (_rethrow) objc_exception_throw(_rethrow);\n";
1732 ReplaceText(lastCurlyLoc
, 1, buf
);
1734 bool hasReturns
= false;
1735 HasReturnStmts(S
->getSynchBody(), hasReturns
);
1737 RewriteSyncReturnStmts(S
->getSynchBody(), syncBuf
);
1742 void RewriteObjC::WarnAboutReturnGotoStmts(Stmt
*S
)
1744 // Perform a bottom up traversal of all children.
1745 for (Stmt::child_range CI
= S
->children(); CI
; ++CI
)
1747 WarnAboutReturnGotoStmts(*CI
);
1749 if (isa
<ReturnStmt
>(S
) || isa
<GotoStmt
>(S
)) {
1750 Diags
.Report(Context
->getFullLoc(S
->getLocStart()),
1751 TryFinallyContainsReturnDiag
);
1756 void RewriteObjC::HasReturnStmts(Stmt
*S
, bool &hasReturns
)
1758 // Perform a bottom up traversal of all children.
1759 for (Stmt::child_range CI
= S
->children(); CI
; ++CI
)
1761 HasReturnStmts(*CI
, hasReturns
);
1763 if (isa
<ReturnStmt
>(S
))
1768 void RewriteObjC::RewriteTryReturnStmts(Stmt
*S
) {
1769 // Perform a bottom up traversal of all children.
1770 for (Stmt::child_range CI
= S
->children(); CI
; ++CI
)
1772 RewriteTryReturnStmts(*CI
);
1774 if (isa
<ReturnStmt
>(S
)) {
1775 SourceLocation startLoc
= S
->getLocStart();
1776 const char *startBuf
= SM
->getCharacterData(startLoc
);
1778 const char *semiBuf
= strchr(startBuf
, ';');
1779 assert((*semiBuf
== ';') && "RewriteTryReturnStmts: can't find ';'");
1780 SourceLocation onePastSemiLoc
= startLoc
.getLocWithOffset(semiBuf
-startBuf
+1);
1783 buf
= "{ objc_exception_try_exit(&_stack); return";
1785 ReplaceText(startLoc
, 6, buf
);
1786 InsertText(onePastSemiLoc
, "}");
1791 void RewriteObjC::RewriteSyncReturnStmts(Stmt
*S
, std::string syncExitBuf
) {
1792 // Perform a bottom up traversal of all children.
1793 for (Stmt::child_range CI
= S
->children(); CI
; ++CI
)
1795 RewriteSyncReturnStmts(*CI
, syncExitBuf
);
1797 if (isa
<ReturnStmt
>(S
)) {
1798 SourceLocation startLoc
= S
->getLocStart();
1799 const char *startBuf
= SM
->getCharacterData(startLoc
);
1801 const char *semiBuf
= strchr(startBuf
, ';');
1802 assert((*semiBuf
== ';') && "RewriteSyncReturnStmts: can't find ';'");
1803 SourceLocation onePastSemiLoc
= startLoc
.getLocWithOffset(semiBuf
-startBuf
+1);
1806 buf
= "{ objc_exception_try_exit(&_stack);";
1810 ReplaceText(startLoc
, 6, buf
);
1811 InsertText(onePastSemiLoc
, "}");
1816 Stmt
*RewriteObjC::RewriteObjCTryStmt(ObjCAtTryStmt
*S
) {
1817 // Get the start location and compute the semi location.
1818 SourceLocation startLoc
= S
->getLocStart();
1819 const char *startBuf
= SM
->getCharacterData(startLoc
);
1821 assert((*startBuf
== '@') && "bogus @try location");
1824 // declare a new scope with two variables, _stack and _rethrow.
1825 buf
= "/* @try scope begin */ { struct _objc_exception_data {\n";
1826 buf
+= "int buf[18/*32-bit i386*/];\n";
1827 buf
+= "char *pointers[4];} _stack;\n";
1828 buf
+= "id volatile _rethrow = 0;\n";
1829 buf
+= "objc_exception_try_enter(&_stack);\n";
1830 buf
+= "if (!_setjmp(_stack.buf)) /* @try block continue */\n";
1832 ReplaceText(startLoc
, 4, buf
);
1834 startLoc
= S
->getTryBody()->getLocEnd();
1835 startBuf
= SM
->getCharacterData(startLoc
);
1837 assert((*startBuf
== '}') && "bogus @try block");
1839 SourceLocation lastCurlyLoc
= startLoc
;
1840 if (S
->getNumCatchStmts()) {
1841 startLoc
= startLoc
.getLocWithOffset(1);
1842 buf
= " /* @catch begin */ else {\n";
1843 buf
+= " id _caught = objc_exception_extract(&_stack);\n";
1844 buf
+= " objc_exception_try_enter (&_stack);\n";
1845 buf
+= " if (_setjmp(_stack.buf))\n";
1846 buf
+= " _rethrow = objc_exception_extract(&_stack);\n";
1847 buf
+= " else { /* @catch continue */";
1849 InsertText(startLoc
, buf
);
1850 } else { /* no catch list */
1851 buf
= "}\nelse {\n";
1852 buf
+= " _rethrow = objc_exception_extract(&_stack);\n";
1854 ReplaceText(lastCurlyLoc
, 1, buf
);
1856 Stmt
*lastCatchBody
= 0;
1857 for (unsigned I
= 0, N
= S
->getNumCatchStmts(); I
!= N
; ++I
) {
1858 ObjCAtCatchStmt
*Catch
= S
->getCatchStmt(I
);
1859 VarDecl
*catchDecl
= Catch
->getCatchParamDecl();
1862 buf
= "if ("; // we are generating code for the first catch clause
1865 startLoc
= Catch
->getLocStart();
1866 startBuf
= SM
->getCharacterData(startLoc
);
1868 assert((*startBuf
== '@') && "bogus @catch location");
1870 const char *lParenLoc
= strchr(startBuf
, '(');
1872 if (Catch
->hasEllipsis()) {
1873 // Now rewrite the body...
1874 lastCatchBody
= Catch
->getCatchBody();
1875 SourceLocation bodyLoc
= lastCatchBody
->getLocStart();
1876 const char *bodyBuf
= SM
->getCharacterData(bodyLoc
);
1877 assert(*SM
->getCharacterData(Catch
->getRParenLoc()) == ')' &&
1878 "bogus @catch paren location");
1879 assert((*bodyBuf
== '{') && "bogus @catch body location");
1881 buf
+= "1) { id _tmp = _caught;";
1882 Rewrite
.ReplaceText(startLoc
, bodyBuf
-startBuf
+1, buf
);
1883 } else if (catchDecl
) {
1884 QualType t
= catchDecl
->getType();
1885 if (t
== Context
->getObjCIdType()) {
1887 ReplaceText(startLoc
, lParenLoc
-startBuf
+1, buf
);
1888 } else if (const ObjCObjectPointerType
*Ptr
=
1889 t
->getAs
<ObjCObjectPointerType
>()) {
1890 // Should be a pointer to a class.
1891 ObjCInterfaceDecl
*IDecl
= Ptr
->getObjectType()->getInterface();
1893 buf
+= "objc_exception_match((struct objc_class *)objc_getClass(\"";
1894 buf
+= IDecl
->getNameAsString();
1895 buf
+= "\"), (struct objc_object *)_caught)) { ";
1896 ReplaceText(startLoc
, lParenLoc
-startBuf
+1, buf
);
1899 // Now rewrite the body...
1900 lastCatchBody
= Catch
->getCatchBody();
1901 SourceLocation rParenLoc
= Catch
->getRParenLoc();
1902 SourceLocation bodyLoc
= lastCatchBody
->getLocStart();
1903 const char *bodyBuf
= SM
->getCharacterData(bodyLoc
);
1904 const char *rParenBuf
= SM
->getCharacterData(rParenLoc
);
1905 assert((*rParenBuf
== ')') && "bogus @catch paren location");
1906 assert((*bodyBuf
== '{') && "bogus @catch body location");
1908 // Here we replace ") {" with "= _caught;" (which initializes and
1909 // declares the @catch parameter).
1910 ReplaceText(rParenLoc
, bodyBuf
-rParenBuf
+1, " = _caught;");
1912 llvm_unreachable("@catch rewrite bug");
1915 // Complete the catch list...
1916 if (lastCatchBody
) {
1917 SourceLocation bodyLoc
= lastCatchBody
->getLocEnd();
1918 assert(*SM
->getCharacterData(bodyLoc
) == '}' &&
1919 "bogus @catch body location");
1921 // Insert the last (implicit) else clause *before* the right curly brace.
1922 bodyLoc
= bodyLoc
.getLocWithOffset(-1);
1923 buf
= "} /* last catch end */\n";
1925 buf
+= " _rethrow = _caught;\n";
1926 buf
+= " objc_exception_try_exit(&_stack);\n";
1927 buf
+= "} } /* @catch end */\n";
1928 if (!S
->getFinallyStmt())
1930 InsertText(bodyLoc
, buf
);
1933 lastCurlyLoc
= lastCatchBody
->getLocEnd();
1935 if (ObjCAtFinallyStmt
*finalStmt
= S
->getFinallyStmt()) {
1936 startLoc
= finalStmt
->getLocStart();
1937 startBuf
= SM
->getCharacterData(startLoc
);
1938 assert((*startBuf
== '@') && "bogus @finally start");
1940 ReplaceText(startLoc
, 8, "/* @finally */");
1942 Stmt
*body
= finalStmt
->getFinallyBody();
1943 SourceLocation startLoc
= body
->getLocStart();
1944 SourceLocation endLoc
= body
->getLocEnd();
1945 assert(*SM
->getCharacterData(startLoc
) == '{' &&
1946 "bogus @finally body location");
1947 assert(*SM
->getCharacterData(endLoc
) == '}' &&
1948 "bogus @finally body location");
1950 startLoc
= startLoc
.getLocWithOffset(1);
1951 InsertText(startLoc
, " if (!_rethrow) objc_exception_try_exit(&_stack);\n");
1952 endLoc
= endLoc
.getLocWithOffset(-1);
1953 InsertText(endLoc
, " if (_rethrow) objc_exception_throw(_rethrow);\n");
1956 lastCurlyLoc
= body
->getLocEnd();
1958 // Now check for any return/continue/go statements within the @try.
1959 WarnAboutReturnGotoStmts(S
->getTryBody());
1960 } else { /* no finally clause - make sure we synthesize an implicit one */
1961 buf
= "{ /* implicit finally clause */\n";
1962 buf
+= " if (!_rethrow) objc_exception_try_exit(&_stack);\n";
1963 buf
+= " if (_rethrow) objc_exception_throw(_rethrow);\n";
1965 ReplaceText(lastCurlyLoc
, 1, buf
);
1967 // Now check for any return/continue/go statements within the @try.
1968 // The implicit finally clause won't called if the @try contains any
1970 bool hasReturns
= false;
1971 HasReturnStmts(S
->getTryBody(), hasReturns
);
1973 RewriteTryReturnStmts(S
->getTryBody());
1975 // Now emit the final closing curly brace...
1976 lastCurlyLoc
= lastCurlyLoc
.getLocWithOffset(1);
1977 InsertText(lastCurlyLoc
, " } /* @try scope end */\n");
1981 // This can't be done with ReplaceStmt(S, ThrowExpr), since
1982 // the throw expression is typically a message expression that's already
1983 // been rewritten! (which implies the SourceLocation's are invalid).
1984 Stmt
*RewriteObjC::RewriteObjCThrowStmt(ObjCAtThrowStmt
*S
) {
1985 // Get the start location and compute the semi location.
1986 SourceLocation startLoc
= S
->getLocStart();
1987 const char *startBuf
= SM
->getCharacterData(startLoc
);
1989 assert((*startBuf
== '@') && "bogus @throw location");
1992 /* void objc_exception_throw(id) __attribute__((noreturn)); */
1993 if (S
->getThrowExpr())
1994 buf
= "objc_exception_throw(";
1995 else // add an implicit argument
1996 buf
= "objc_exception_throw(_caught";
1998 // handle "@ throw" correctly.
1999 const char *wBuf
= strchr(startBuf
, 'w');
2000 assert((*wBuf
== 'w') && "@throw: can't find 'w'");
2001 ReplaceText(startLoc
, wBuf
-startBuf
+1, buf
);
2003 const char *semiBuf
= strchr(startBuf
, ';');
2004 assert((*semiBuf
== ';') && "@throw: can't find ';'");
2005 SourceLocation semiLoc
= startLoc
.getLocWithOffset(semiBuf
-startBuf
);
2006 ReplaceText(semiLoc
, 1, ");");
2010 Stmt
*RewriteObjC::RewriteAtEncode(ObjCEncodeExpr
*Exp
) {
2011 // Create a new string expression.
2012 QualType StrType
= Context
->getPointerType(Context
->CharTy
);
2013 std::string StrEncoding
;
2014 Context
->getObjCEncodingForType(Exp
->getEncodedType(), StrEncoding
);
2015 Expr
*Replacement
= StringLiteral::Create(*Context
, StrEncoding
,
2016 StringLiteral::Ascii
, false,
2017 StrType
, SourceLocation());
2018 ReplaceStmt(Exp
, Replacement
);
2020 // Replace this subexpr in the parent.
2021 // delete Exp; leak for now, see RewritePropertyOrImplicitSetter() usage for more info.
2025 Stmt
*RewriteObjC::RewriteAtSelector(ObjCSelectorExpr
*Exp
) {
2026 if (!SelGetUidFunctionDecl
)
2027 SynthSelGetUidFunctionDecl();
2028 assert(SelGetUidFunctionDecl
&& "Can't find sel_registerName() decl");
2029 // Create a call to sel_registerName("selName").
2030 SmallVector
<Expr
*, 8> SelExprs
;
2031 QualType argType
= Context
->getPointerType(Context
->CharTy
);
2032 SelExprs
.push_back(StringLiteral::Create(*Context
,
2033 Exp
->getSelector().getAsString(),
2034 StringLiteral::Ascii
, false,
2035 argType
, SourceLocation()));
2036 CallExpr
*SelExp
= SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl
,
2037 &SelExprs
[0], SelExprs
.size());
2038 ReplaceStmt(Exp
, SelExp
);
2039 // delete Exp; leak for now, see RewritePropertyOrImplicitSetter() usage for more info.
2043 CallExpr
*RewriteObjC::SynthesizeCallToFunctionDecl(
2044 FunctionDecl
*FD
, Expr
**args
, unsigned nargs
, SourceLocation StartLoc
,
2045 SourceLocation EndLoc
) {
2046 // Get the type, we will need to reference it in a couple spots.
2047 QualType msgSendType
= FD
->getType();
2049 // Create a reference to the objc_msgSend() declaration.
2050 DeclRefExpr
*DRE
= new (Context
) DeclRefExpr(FD
, false, msgSendType
,
2051 VK_LValue
, SourceLocation());
2053 // Now, we cast the reference to a pointer to the objc_msgSend type.
2054 QualType pToFunc
= Context
->getPointerType(msgSendType
);
2055 ImplicitCastExpr
*ICE
=
2056 ImplicitCastExpr::Create(*Context
, pToFunc
, CK_FunctionToPointerDecay
,
2059 const FunctionType
*FT
= msgSendType
->getAs
<FunctionType
>();
2062 new (Context
) CallExpr(*Context
, ICE
, llvm::makeArrayRef(args
, nargs
),
2063 FT
->getCallResultType(*Context
),
2068 static bool scanForProtocolRefs(const char *startBuf
, const char *endBuf
,
2069 const char *&startRef
, const char *&endRef
) {
2070 while (startBuf
< endBuf
) {
2071 if (*startBuf
== '<')
2072 startRef
= startBuf
; // mark the start.
2073 if (*startBuf
== '>') {
2074 if (startRef
&& *startRef
== '<') {
2075 endRef
= startBuf
; // mark the end.
2085 static void scanToNextArgument(const char *&argRef
) {
2087 while (*argRef
!= ')' && (*argRef
!= ',' || angle
> 0)) {
2090 else if (*argRef
== '>')
2094 assert(angle
== 0 && "scanToNextArgument - bad protocol type syntax");
2097 bool RewriteObjC::needToScanForQualifiers(QualType T
) {
2098 if (T
->isObjCQualifiedIdType())
2100 if (const PointerType
*PT
= T
->getAs
<PointerType
>()) {
2101 if (PT
->getPointeeType()->isObjCQualifiedIdType())
2104 if (T
->isObjCObjectPointerType()) {
2105 T
= T
->getPointeeType();
2106 return T
->isObjCQualifiedInterfaceType();
2108 if (T
->isArrayType()) {
2109 QualType ElemTy
= Context
->getBaseElementType(T
);
2110 return needToScanForQualifiers(ElemTy
);
2115 void RewriteObjC::RewriteObjCQualifiedInterfaceTypes(Expr
*E
) {
2116 QualType Type
= E
->getType();
2117 if (needToScanForQualifiers(Type
)) {
2118 SourceLocation Loc
, EndLoc
;
2120 if (const CStyleCastExpr
*ECE
= dyn_cast
<CStyleCastExpr
>(E
)) {
2121 Loc
= ECE
->getLParenLoc();
2122 EndLoc
= ECE
->getRParenLoc();
2124 Loc
= E
->getLocStart();
2125 EndLoc
= E
->getLocEnd();
2127 // This will defend against trying to rewrite synthesized expressions.
2128 if (Loc
.isInvalid() || EndLoc
.isInvalid())
2131 const char *startBuf
= SM
->getCharacterData(Loc
);
2132 const char *endBuf
= SM
->getCharacterData(EndLoc
);
2133 const char *startRef
= 0, *endRef
= 0;
2134 if (scanForProtocolRefs(startBuf
, endBuf
, startRef
, endRef
)) {
2135 // Get the locations of the startRef, endRef.
2136 SourceLocation LessLoc
= Loc
.getLocWithOffset(startRef
-startBuf
);
2137 SourceLocation GreaterLoc
= Loc
.getLocWithOffset(endRef
-startBuf
+1);
2138 // Comment out the protocol references.
2139 InsertText(LessLoc
, "/*");
2140 InsertText(GreaterLoc
, "*/");
2145 void RewriteObjC::RewriteObjCQualifiedInterfaceTypes(Decl
*Dcl
) {
2148 const FunctionProtoType
*proto
= 0;
2149 if (VarDecl
*VD
= dyn_cast
<VarDecl
>(Dcl
)) {
2150 Loc
= VD
->getLocation();
2151 Type
= VD
->getType();
2153 else if (FunctionDecl
*FD
= dyn_cast
<FunctionDecl
>(Dcl
)) {
2154 Loc
= FD
->getLocation();
2155 // Check for ObjC 'id' and class types that have been adorned with protocol
2156 // information (id<p>, C<p>*). The protocol references need to be rewritten!
2157 const FunctionType
*funcType
= FD
->getType()->getAs
<FunctionType
>();
2158 assert(funcType
&& "missing function type");
2159 proto
= dyn_cast
<FunctionProtoType
>(funcType
);
2162 Type
= proto
->getResultType();
2164 else if (FieldDecl
*FD
= dyn_cast
<FieldDecl
>(Dcl
)) {
2165 Loc
= FD
->getLocation();
2166 Type
= FD
->getType();
2171 if (needToScanForQualifiers(Type
)) {
2172 // Since types are unique, we need to scan the buffer.
2174 const char *endBuf
= SM
->getCharacterData(Loc
);
2175 const char *startBuf
= endBuf
;
2176 while (*startBuf
!= ';' && *startBuf
!= '<' && startBuf
!= MainFileStart
)
2177 startBuf
--; // scan backward (from the decl location) for return type.
2178 const char *startRef
= 0, *endRef
= 0;
2179 if (scanForProtocolRefs(startBuf
, endBuf
, startRef
, endRef
)) {
2180 // Get the locations of the startRef, endRef.
2181 SourceLocation LessLoc
= Loc
.getLocWithOffset(startRef
-endBuf
);
2182 SourceLocation GreaterLoc
= Loc
.getLocWithOffset(endRef
-endBuf
+1);
2183 // Comment out the protocol references.
2184 InsertText(LessLoc
, "/*");
2185 InsertText(GreaterLoc
, "*/");
2189 return; // most likely, was a variable
2190 // Now check arguments.
2191 const char *startBuf
= SM
->getCharacterData(Loc
);
2192 const char *startFuncBuf
= startBuf
;
2193 for (unsigned i
= 0; i
< proto
->getNumArgs(); i
++) {
2194 if (needToScanForQualifiers(proto
->getArgType(i
))) {
2195 // Since types are unique, we need to scan the buffer.
2197 const char *endBuf
= startBuf
;
2198 // scan forward (from the decl location) for argument types.
2199 scanToNextArgument(endBuf
);
2200 const char *startRef
= 0, *endRef
= 0;
2201 if (scanForProtocolRefs(startBuf
, endBuf
, startRef
, endRef
)) {
2202 // Get the locations of the startRef, endRef.
2203 SourceLocation LessLoc
=
2204 Loc
.getLocWithOffset(startRef
-startFuncBuf
);
2205 SourceLocation GreaterLoc
=
2206 Loc
.getLocWithOffset(endRef
-startFuncBuf
+1);
2207 // Comment out the protocol references.
2208 InsertText(LessLoc
, "/*");
2209 InsertText(GreaterLoc
, "*/");
2211 startBuf
= ++endBuf
;
2214 // If the function name is derived from a macro expansion, then the
2215 // argument buffer will not follow the name. Need to speak with Chris.
2216 while (*startBuf
&& *startBuf
!= ')' && *startBuf
!= ',')
2217 startBuf
++; // scan forward (from the decl location) for argument types.
2223 void RewriteObjC::RewriteTypeOfDecl(VarDecl
*ND
) {
2224 QualType QT
= ND
->getType();
2225 const Type
* TypePtr
= QT
->getAs
<Type
>();
2226 if (!isa
<TypeOfExprType
>(TypePtr
))
2228 while (isa
<TypeOfExprType
>(TypePtr
)) {
2229 const TypeOfExprType
*TypeOfExprTypePtr
= cast
<TypeOfExprType
>(TypePtr
);
2230 QT
= TypeOfExprTypePtr
->getUnderlyingExpr()->getType();
2231 TypePtr
= QT
->getAs
<Type
>();
2233 // FIXME. This will not work for multiple declarators; as in:
2234 // __typeof__(a) b,c,d;
2235 std::string
TypeAsString(QT
.getAsString(Context
->getPrintingPolicy()));
2236 SourceLocation DeclLoc
= ND
->getTypeSpecStartLoc();
2237 const char *startBuf
= SM
->getCharacterData(DeclLoc
);
2238 if (ND
->getInit()) {
2239 std::string
Name(ND
->getNameAsString());
2240 TypeAsString
+= " " + Name
+ " = ";
2241 Expr
*E
= ND
->getInit();
2242 SourceLocation startLoc
;
2243 if (const CStyleCastExpr
*ECE
= dyn_cast
<CStyleCastExpr
>(E
))
2244 startLoc
= ECE
->getLParenLoc();
2246 startLoc
= E
->getLocStart();
2247 startLoc
= SM
->getExpansionLoc(startLoc
);
2248 const char *endBuf
= SM
->getCharacterData(startLoc
);
2249 ReplaceText(DeclLoc
, endBuf
-startBuf
-1, TypeAsString
);
2252 SourceLocation X
= ND
->getLocEnd();
2253 X
= SM
->getExpansionLoc(X
);
2254 const char *endBuf
= SM
->getCharacterData(X
);
2255 ReplaceText(DeclLoc
, endBuf
-startBuf
-1, TypeAsString
);
2259 // SynthSelGetUidFunctionDecl - SEL sel_registerName(const char *str);
2260 void RewriteObjC::SynthSelGetUidFunctionDecl() {
2261 IdentifierInfo
*SelGetUidIdent
= &Context
->Idents
.get("sel_registerName");
2262 SmallVector
<QualType
, 16> ArgTys
;
2263 ArgTys
.push_back(Context
->getPointerType(Context
->CharTy
.withConst()));
2264 QualType getFuncType
=
2265 getSimpleFunctionType(Context
->getObjCSelType(), &ArgTys
[0], ArgTys
.size());
2266 SelGetUidFunctionDecl
= FunctionDecl::Create(*Context
, TUDecl
,
2269 SelGetUidIdent
, getFuncType
, 0,
2274 void RewriteObjC::RewriteFunctionDecl(FunctionDecl
*FD
) {
2275 // declared in <objc/objc.h>
2276 if (FD
->getIdentifier() &&
2277 FD
->getName() == "sel_registerName") {
2278 SelGetUidFunctionDecl
= FD
;
2281 RewriteObjCQualifiedInterfaceTypes(FD
);
2284 void RewriteObjC::RewriteBlockPointerType(std::string
& Str
, QualType Type
) {
2285 std::string
TypeString(Type
.getAsString(Context
->getPrintingPolicy()));
2286 const char *argPtr
= TypeString
.c_str();
2287 if (!strchr(argPtr
, '^')) {
2292 Str
+= (*argPtr
== '^' ? '*' : *argPtr
);
2297 // FIXME. Consolidate this routine with RewriteBlockPointerType.
2298 void RewriteObjC::RewriteBlockPointerTypeVariable(std::string
& Str
,
2300 QualType Type
= VD
->getType();
2301 std::string
TypeString(Type
.getAsString(Context
->getPrintingPolicy()));
2302 const char *argPtr
= TypeString
.c_str();
2317 Str
+= VD
->getNameAsString();
2328 void RewriteObjC::RewriteBlockLiteralFunctionDecl(FunctionDecl
*FD
) {
2329 SourceLocation FunLocStart
= FD
->getTypeSpecStartLoc();
2330 const FunctionType
*funcType
= FD
->getType()->getAs
<FunctionType
>();
2331 const FunctionProtoType
*proto
= dyn_cast
<FunctionProtoType
>(funcType
);
2334 QualType Type
= proto
->getResultType();
2335 std::string FdStr
= Type
.getAsString(Context
->getPrintingPolicy());
2337 FdStr
+= FD
->getName();
2339 unsigned numArgs
= proto
->getNumArgs();
2340 for (unsigned i
= 0; i
< numArgs
; i
++) {
2341 QualType ArgType
= proto
->getArgType(i
);
2342 RewriteBlockPointerType(FdStr
, ArgType
);
2347 InsertText(FunLocStart
, FdStr
);
2348 CurFunctionDeclToDeclareForBlock
= 0;
2351 // SynthSuperContructorFunctionDecl - id objc_super(id obj, id super);
2352 void RewriteObjC::SynthSuperContructorFunctionDecl() {
2353 if (SuperContructorFunctionDecl
)
2355 IdentifierInfo
*msgSendIdent
= &Context
->Idents
.get("__rw_objc_super");
2356 SmallVector
<QualType
, 16> ArgTys
;
2357 QualType argT
= Context
->getObjCIdType();
2358 assert(!argT
.isNull() && "Can't find 'id' type");
2359 ArgTys
.push_back(argT
);
2360 ArgTys
.push_back(argT
);
2361 QualType msgSendType
= getSimpleFunctionType(Context
->getObjCIdType(),
2362 &ArgTys
[0], ArgTys
.size());
2363 SuperContructorFunctionDecl
= FunctionDecl::Create(*Context
, TUDecl
,
2366 msgSendIdent
, msgSendType
, 0,
2371 // SynthMsgSendFunctionDecl - id objc_msgSend(id self, SEL op, ...);
2372 void RewriteObjC::SynthMsgSendFunctionDecl() {
2373 IdentifierInfo
*msgSendIdent
= &Context
->Idents
.get("objc_msgSend");
2374 SmallVector
<QualType
, 16> ArgTys
;
2375 QualType argT
= Context
->getObjCIdType();
2376 assert(!argT
.isNull() && "Can't find 'id' type");
2377 ArgTys
.push_back(argT
);
2378 argT
= Context
->getObjCSelType();
2379 assert(!argT
.isNull() && "Can't find 'SEL' type");
2380 ArgTys
.push_back(argT
);
2381 QualType msgSendType
= getSimpleFunctionType(Context
->getObjCIdType(),
2382 &ArgTys
[0], ArgTys
.size(),
2383 true /*isVariadic*/);
2384 MsgSendFunctionDecl
= FunctionDecl::Create(*Context
, TUDecl
,
2387 msgSendIdent
, msgSendType
, 0,
2392 // SynthMsgSendSuperFunctionDecl - id objc_msgSendSuper(struct objc_super *, SEL op, ...);
2393 void RewriteObjC::SynthMsgSendSuperFunctionDecl() {
2394 IdentifierInfo
*msgSendIdent
= &Context
->Idents
.get("objc_msgSendSuper");
2395 SmallVector
<QualType
, 16> ArgTys
;
2396 RecordDecl
*RD
= RecordDecl::Create(*Context
, TTK_Struct
, TUDecl
,
2397 SourceLocation(), SourceLocation(),
2398 &Context
->Idents
.get("objc_super"));
2399 QualType argT
= Context
->getPointerType(Context
->getTagDeclType(RD
));
2400 assert(!argT
.isNull() && "Can't build 'struct objc_super *' type");
2401 ArgTys
.push_back(argT
);
2402 argT
= Context
->getObjCSelType();
2403 assert(!argT
.isNull() && "Can't find 'SEL' type");
2404 ArgTys
.push_back(argT
);
2405 QualType msgSendType
= getSimpleFunctionType(Context
->getObjCIdType(),
2406 &ArgTys
[0], ArgTys
.size(),
2407 true /*isVariadic*/);
2408 MsgSendSuperFunctionDecl
= FunctionDecl::Create(*Context
, TUDecl
,
2411 msgSendIdent
, msgSendType
, 0,
2416 // SynthMsgSendStretFunctionDecl - id objc_msgSend_stret(id self, SEL op, ...);
2417 void RewriteObjC::SynthMsgSendStretFunctionDecl() {
2418 IdentifierInfo
*msgSendIdent
= &Context
->Idents
.get("objc_msgSend_stret");
2419 SmallVector
<QualType
, 16> ArgTys
;
2420 QualType argT
= Context
->getObjCIdType();
2421 assert(!argT
.isNull() && "Can't find 'id' type");
2422 ArgTys
.push_back(argT
);
2423 argT
= Context
->getObjCSelType();
2424 assert(!argT
.isNull() && "Can't find 'SEL' type");
2425 ArgTys
.push_back(argT
);
2426 QualType msgSendType
= getSimpleFunctionType(Context
->getObjCIdType(),
2427 &ArgTys
[0], ArgTys
.size(),
2428 true /*isVariadic*/);
2429 MsgSendStretFunctionDecl
= FunctionDecl::Create(*Context
, TUDecl
,
2432 msgSendIdent
, msgSendType
, 0,
2437 // SynthMsgSendSuperStretFunctionDecl -
2438 // id objc_msgSendSuper_stret(struct objc_super *, SEL op, ...);
2439 void RewriteObjC::SynthMsgSendSuperStretFunctionDecl() {
2440 IdentifierInfo
*msgSendIdent
=
2441 &Context
->Idents
.get("objc_msgSendSuper_stret");
2442 SmallVector
<QualType
, 16> ArgTys
;
2443 RecordDecl
*RD
= RecordDecl::Create(*Context
, TTK_Struct
, TUDecl
,
2444 SourceLocation(), SourceLocation(),
2445 &Context
->Idents
.get("objc_super"));
2446 QualType argT
= Context
->getPointerType(Context
->getTagDeclType(RD
));
2447 assert(!argT
.isNull() && "Can't build 'struct objc_super *' type");
2448 ArgTys
.push_back(argT
);
2449 argT
= Context
->getObjCSelType();
2450 assert(!argT
.isNull() && "Can't find 'SEL' type");
2451 ArgTys
.push_back(argT
);
2452 QualType msgSendType
= getSimpleFunctionType(Context
->getObjCIdType(),
2453 &ArgTys
[0], ArgTys
.size(),
2454 true /*isVariadic*/);
2455 MsgSendSuperStretFunctionDecl
= FunctionDecl::Create(*Context
, TUDecl
,
2458 msgSendIdent
, msgSendType
, 0,
2463 // SynthMsgSendFpretFunctionDecl - double objc_msgSend_fpret(id self, SEL op, ...);
2464 void RewriteObjC::SynthMsgSendFpretFunctionDecl() {
2465 IdentifierInfo
*msgSendIdent
= &Context
->Idents
.get("objc_msgSend_fpret");
2466 SmallVector
<QualType
, 16> ArgTys
;
2467 QualType argT
= Context
->getObjCIdType();
2468 assert(!argT
.isNull() && "Can't find 'id' type");
2469 ArgTys
.push_back(argT
);
2470 argT
= Context
->getObjCSelType();
2471 assert(!argT
.isNull() && "Can't find 'SEL' type");
2472 ArgTys
.push_back(argT
);
2473 QualType msgSendType
= getSimpleFunctionType(Context
->DoubleTy
,
2474 &ArgTys
[0], ArgTys
.size(),
2475 true /*isVariadic*/);
2476 MsgSendFpretFunctionDecl
= FunctionDecl::Create(*Context
, TUDecl
,
2479 msgSendIdent
, msgSendType
, 0,
2484 // SynthGetClassFunctionDecl - id objc_getClass(const char *name);
2485 void RewriteObjC::SynthGetClassFunctionDecl() {
2486 IdentifierInfo
*getClassIdent
= &Context
->Idents
.get("objc_getClass");
2487 SmallVector
<QualType
, 16> ArgTys
;
2488 ArgTys
.push_back(Context
->getPointerType(Context
->CharTy
.withConst()));
2489 QualType getClassType
= getSimpleFunctionType(Context
->getObjCIdType(),
2490 &ArgTys
[0], ArgTys
.size());
2491 GetClassFunctionDecl
= FunctionDecl::Create(*Context
, TUDecl
,
2494 getClassIdent
, getClassType
, 0,
2499 // SynthGetSuperClassFunctionDecl - Class class_getSuperclass(Class cls);
2500 void RewriteObjC::SynthGetSuperClassFunctionDecl() {
2501 IdentifierInfo
*getSuperClassIdent
=
2502 &Context
->Idents
.get("class_getSuperclass");
2503 SmallVector
<QualType
, 16> ArgTys
;
2504 ArgTys
.push_back(Context
->getObjCClassType());
2505 QualType getClassType
= getSimpleFunctionType(Context
->getObjCClassType(),
2506 &ArgTys
[0], ArgTys
.size());
2507 GetSuperClassFunctionDecl
= FunctionDecl::Create(*Context
, TUDecl
,
2517 // SynthGetMetaClassFunctionDecl - id objc_getMetaClass(const char *name);
2518 void RewriteObjC::SynthGetMetaClassFunctionDecl() {
2519 IdentifierInfo
*getClassIdent
= &Context
->Idents
.get("objc_getMetaClass");
2520 SmallVector
<QualType
, 16> ArgTys
;
2521 ArgTys
.push_back(Context
->getPointerType(Context
->CharTy
.withConst()));
2522 QualType getClassType
= getSimpleFunctionType(Context
->getObjCIdType(),
2523 &ArgTys
[0], ArgTys
.size());
2524 GetMetaClassFunctionDecl
= FunctionDecl::Create(*Context
, TUDecl
,
2527 getClassIdent
, getClassType
, 0,
2532 Stmt
*RewriteObjC::RewriteObjCStringLiteral(ObjCStringLiteral
*Exp
) {
2533 QualType strType
= getConstantStringStructType();
2535 std::string S
= "__NSConstantStringImpl_";
2537 std::string tmpName
= InFileName
;
2539 for (i
=0; i
< tmpName
.length(); i
++) {
2540 char c
= tmpName
.at(i
);
2541 // replace any non alphanumeric characters with '_'.
2542 if (!isalpha(c
) && (c
< '0' || c
> '9'))
2547 S
+= utostr(NumObjCStringLiterals
++);
2549 Preamble
+= "static __NSConstantStringImpl " + S
;
2550 Preamble
+= " __attribute__ ((section (\"__DATA, __cfstring\"))) = {__CFConstantStringClassReference,";
2551 Preamble
+= "0x000007c8,"; // utf8_str
2552 // The pretty printer for StringLiteral handles escape characters properly.
2553 std::string prettyBufS
;
2554 llvm::raw_string_ostream
prettyBuf(prettyBufS
);
2555 Exp
->getString()->printPretty(prettyBuf
, 0, PrintingPolicy(LangOpts
));
2556 Preamble
+= prettyBuf
.str();
2558 Preamble
+= utostr(Exp
->getString()->getByteLength()) + "};\n";
2560 VarDecl
*NewVD
= VarDecl::Create(*Context
, TUDecl
, SourceLocation(),
2561 SourceLocation(), &Context
->Idents
.get(S
),
2562 strType
, 0, SC_Static
, SC_None
);
2563 DeclRefExpr
*DRE
= new (Context
) DeclRefExpr(NewVD
, false, strType
, VK_LValue
,
2565 Expr
*Unop
= new (Context
) UnaryOperator(DRE
, UO_AddrOf
,
2566 Context
->getPointerType(DRE
->getType()),
2567 VK_RValue
, OK_Ordinary
,
2569 // cast to NSConstantString *
2570 CastExpr
*cast
= NoTypeInfoCStyleCastExpr(Context
, Exp
->getType(),
2571 CK_CPointerToObjCPointerCast
, Unop
);
2572 ReplaceStmt(Exp
, cast
);
2573 // delete Exp; leak for now, see RewritePropertyOrImplicitSetter() usage for more info.
2577 // struct objc_super { struct objc_object *receiver; struct objc_class *super; };
2578 QualType
RewriteObjC::getSuperStructType() {
2579 if (!SuperStructDecl
) {
2580 SuperStructDecl
= RecordDecl::Create(*Context
, TTK_Struct
, TUDecl
,
2581 SourceLocation(), SourceLocation(),
2582 &Context
->Idents
.get("objc_super"));
2583 QualType FieldTypes
[2];
2585 // struct objc_object *receiver;
2586 FieldTypes
[0] = Context
->getObjCIdType();
2587 // struct objc_class *super;
2588 FieldTypes
[1] = Context
->getObjCClassType();
2591 for (unsigned i
= 0; i
< 2; ++i
) {
2592 SuperStructDecl
->addDecl(FieldDecl::Create(*Context
, SuperStructDecl
,
2594 SourceLocation(), 0,
2601 SuperStructDecl
->completeDefinition();
2603 return Context
->getTagDeclType(SuperStructDecl
);
2606 QualType
RewriteObjC::getConstantStringStructType() {
2607 if (!ConstantStringDecl
) {
2608 ConstantStringDecl
= RecordDecl::Create(*Context
, TTK_Struct
, TUDecl
,
2609 SourceLocation(), SourceLocation(),
2610 &Context
->Idents
.get("__NSConstantStringImpl"));
2611 QualType FieldTypes
[4];
2613 // struct objc_object *receiver;
2614 FieldTypes
[0] = Context
->getObjCIdType();
2616 FieldTypes
[1] = Context
->IntTy
;
2618 FieldTypes
[2] = Context
->getPointerType(Context
->CharTy
);
2620 FieldTypes
[3] = Context
->LongTy
;
2623 for (unsigned i
= 0; i
< 4; ++i
) {
2624 ConstantStringDecl
->addDecl(FieldDecl::Create(*Context
,
2627 SourceLocation(), 0,
2634 ConstantStringDecl
->completeDefinition();
2636 return Context
->getTagDeclType(ConstantStringDecl
);
2639 CallExpr
*RewriteObjC::SynthMsgSendStretCallExpr(FunctionDecl
*MsgSendStretFlavor
,
2640 QualType msgSendType
,
2641 QualType returnType
,
2642 SmallVectorImpl
<QualType
> &ArgTypes
,
2643 SmallVectorImpl
<Expr
*> &MsgExprs
,
2644 ObjCMethodDecl
*Method
) {
2645 // Create a reference to the objc_msgSend_stret() declaration.
2646 DeclRefExpr
*STDRE
= new (Context
) DeclRefExpr(MsgSendStretFlavor
,
2648 VK_LValue
, SourceLocation());
2649 // Need to cast objc_msgSend_stret to "void *" (see above comment).
2650 CastExpr
*cast
= NoTypeInfoCStyleCastExpr(Context
,
2651 Context
->getPointerType(Context
->VoidTy
),
2653 // Now do the "normal" pointer to function cast.
2654 QualType castType
= getSimpleFunctionType(returnType
, &ArgTypes
[0], ArgTypes
.size(),
2655 Method
? Method
->isVariadic() : false);
2656 castType
= Context
->getPointerType(castType
);
2657 cast
= NoTypeInfoCStyleCastExpr(Context
, castType
, CK_BitCast
,
2660 // Don't forget the parens to enforce the proper binding.
2661 ParenExpr
*PE
= new (Context
) ParenExpr(SourceLocation(), SourceLocation(), cast
);
2663 const FunctionType
*FT
= msgSendType
->getAs
<FunctionType
>();
2664 CallExpr
*STCE
= new (Context
) CallExpr(*Context
, PE
, MsgExprs
,
2665 FT
->getResultType(), VK_RValue
,
2672 Stmt
*RewriteObjC::SynthMessageExpr(ObjCMessageExpr
*Exp
,
2673 SourceLocation StartLoc
,
2674 SourceLocation EndLoc
) {
2675 if (!SelGetUidFunctionDecl
)
2676 SynthSelGetUidFunctionDecl();
2677 if (!MsgSendFunctionDecl
)
2678 SynthMsgSendFunctionDecl();
2679 if (!MsgSendSuperFunctionDecl
)
2680 SynthMsgSendSuperFunctionDecl();
2681 if (!MsgSendStretFunctionDecl
)
2682 SynthMsgSendStretFunctionDecl();
2683 if (!MsgSendSuperStretFunctionDecl
)
2684 SynthMsgSendSuperStretFunctionDecl();
2685 if (!MsgSendFpretFunctionDecl
)
2686 SynthMsgSendFpretFunctionDecl();
2687 if (!GetClassFunctionDecl
)
2688 SynthGetClassFunctionDecl();
2689 if (!GetSuperClassFunctionDecl
)
2690 SynthGetSuperClassFunctionDecl();
2691 if (!GetMetaClassFunctionDecl
)
2692 SynthGetMetaClassFunctionDecl();
2694 // default to objc_msgSend().
2695 FunctionDecl
*MsgSendFlavor
= MsgSendFunctionDecl
;
2696 // May need to use objc_msgSend_stret() as well.
2697 FunctionDecl
*MsgSendStretFlavor
= 0;
2698 if (ObjCMethodDecl
*mDecl
= Exp
->getMethodDecl()) {
2699 QualType resultType
= mDecl
->getResultType();
2700 if (resultType
->isRecordType())
2701 MsgSendStretFlavor
= MsgSendStretFunctionDecl
;
2702 else if (resultType
->isRealFloatingType())
2703 MsgSendFlavor
= MsgSendFpretFunctionDecl
;
2706 // Synthesize a call to objc_msgSend().
2707 SmallVector
<Expr
*, 8> MsgExprs
;
2708 switch (Exp
->getReceiverKind()) {
2709 case ObjCMessageExpr::SuperClass
: {
2710 MsgSendFlavor
= MsgSendSuperFunctionDecl
;
2711 if (MsgSendStretFlavor
)
2712 MsgSendStretFlavor
= MsgSendSuperStretFunctionDecl
;
2713 assert(MsgSendFlavor
&& "MsgSendFlavor is NULL!");
2715 ObjCInterfaceDecl
*ClassDecl
= CurMethodDef
->getClassInterface();
2717 SmallVector
<Expr
*, 4> InitExprs
;
2719 // set the receiver to self, the first argument to all methods.
2720 InitExprs
.push_back(
2721 NoTypeInfoCStyleCastExpr(Context
, Context
->getObjCIdType(),
2723 new (Context
) DeclRefExpr(CurMethodDef
->getSelfDecl(),
2725 Context
->getObjCIdType(),
2728 ); // set the 'receiver'.
2730 // (id)class_getSuperclass((Class)objc_getClass("CurrentClass"))
2731 SmallVector
<Expr
*, 8> ClsExprs
;
2732 QualType argType
= Context
->getPointerType(Context
->CharTy
);
2733 ClsExprs
.push_back(StringLiteral::Create(*Context
,
2734 ClassDecl
->getIdentifier()->getName(),
2735 StringLiteral::Ascii
, false,
2736 argType
, SourceLocation()));
2737 CallExpr
*Cls
= SynthesizeCallToFunctionDecl(GetMetaClassFunctionDecl
,
2742 // (Class)objc_getClass("CurrentClass")
2743 CastExpr
*ArgExpr
= NoTypeInfoCStyleCastExpr(Context
,
2744 Context
->getObjCClassType(),
2747 ClsExprs
.push_back(ArgExpr
);
2748 Cls
= SynthesizeCallToFunctionDecl(GetSuperClassFunctionDecl
,
2749 &ClsExprs
[0], ClsExprs
.size(),
2752 // (id)class_getSuperclass((Class)objc_getClass("CurrentClass"))
2753 // To turn off a warning, type-cast to 'id'
2754 InitExprs
.push_back( // set 'super class', using class_getSuperclass().
2755 NoTypeInfoCStyleCastExpr(Context
,
2756 Context
->getObjCIdType(),
2758 // struct objc_super
2759 QualType superType
= getSuperStructType();
2762 if (LangOpts
.MicrosoftExt
) {
2763 SynthSuperContructorFunctionDecl();
2764 // Simulate a contructor call...
2765 DeclRefExpr
*DRE
= new (Context
) DeclRefExpr(SuperContructorFunctionDecl
,
2766 false, superType
, VK_LValue
,
2768 SuperRep
= new (Context
) CallExpr(*Context
, DRE
, InitExprs
,
2769 superType
, VK_LValue
,
2771 // The code for super is a little tricky to prevent collision with
2772 // the structure definition in the header. The rewriter has it's own
2773 // internal definition (__rw_objc_super) that is uses. This is why
2774 // we need the cast below. For example:
2775 // (struct objc_super *)&__rw_objc_super((id)self, (id)objc_getClass("SUPER"))
2777 SuperRep
= new (Context
) UnaryOperator(SuperRep
, UO_AddrOf
,
2778 Context
->getPointerType(SuperRep
->getType()),
2779 VK_RValue
, OK_Ordinary
,
2781 SuperRep
= NoTypeInfoCStyleCastExpr(Context
,
2782 Context
->getPointerType(superType
),
2783 CK_BitCast
, SuperRep
);
2785 // (struct objc_super) { <exprs from above> }
2787 new (Context
) InitListExpr(*Context
, SourceLocation(), InitExprs
,
2789 TypeSourceInfo
*superTInfo
2790 = Context
->getTrivialTypeSourceInfo(superType
);
2791 SuperRep
= new (Context
) CompoundLiteralExpr(SourceLocation(), superTInfo
,
2792 superType
, VK_LValue
,
2794 // struct objc_super *
2795 SuperRep
= new (Context
) UnaryOperator(SuperRep
, UO_AddrOf
,
2796 Context
->getPointerType(SuperRep
->getType()),
2797 VK_RValue
, OK_Ordinary
,
2800 MsgExprs
.push_back(SuperRep
);
2804 case ObjCMessageExpr::Class
: {
2805 SmallVector
<Expr
*, 8> ClsExprs
;
2806 QualType argType
= Context
->getPointerType(Context
->CharTy
);
2807 ObjCInterfaceDecl
*Class
2808 = Exp
->getClassReceiver()->getAs
<ObjCObjectType
>()->getInterface();
2809 IdentifierInfo
*clsName
= Class
->getIdentifier();
2810 ClsExprs
.push_back(StringLiteral::Create(*Context
,
2812 StringLiteral::Ascii
, false,
2813 argType
, SourceLocation()));
2814 CallExpr
*Cls
= SynthesizeCallToFunctionDecl(GetClassFunctionDecl
,
2818 MsgExprs
.push_back(Cls
);
2822 case ObjCMessageExpr::SuperInstance
:{
2823 MsgSendFlavor
= MsgSendSuperFunctionDecl
;
2824 if (MsgSendStretFlavor
)
2825 MsgSendStretFlavor
= MsgSendSuperStretFunctionDecl
;
2826 assert(MsgSendFlavor
&& "MsgSendFlavor is NULL!");
2827 ObjCInterfaceDecl
*ClassDecl
= CurMethodDef
->getClassInterface();
2828 SmallVector
<Expr
*, 4> InitExprs
;
2830 InitExprs
.push_back(
2831 NoTypeInfoCStyleCastExpr(Context
, Context
->getObjCIdType(),
2833 new (Context
) DeclRefExpr(CurMethodDef
->getSelfDecl(),
2835 Context
->getObjCIdType(),
2836 VK_RValue
, SourceLocation()))
2837 ); // set the 'receiver'.
2839 // (id)class_getSuperclass((Class)objc_getClass("CurrentClass"))
2840 SmallVector
<Expr
*, 8> ClsExprs
;
2841 QualType argType
= Context
->getPointerType(Context
->CharTy
);
2842 ClsExprs
.push_back(StringLiteral::Create(*Context
,
2843 ClassDecl
->getIdentifier()->getName(),
2844 StringLiteral::Ascii
, false, argType
,
2846 CallExpr
*Cls
= SynthesizeCallToFunctionDecl(GetClassFunctionDecl
,
2850 // (Class)objc_getClass("CurrentClass")
2851 CastExpr
*ArgExpr
= NoTypeInfoCStyleCastExpr(Context
,
2852 Context
->getObjCClassType(),
2855 ClsExprs
.push_back(ArgExpr
);
2856 Cls
= SynthesizeCallToFunctionDecl(GetSuperClassFunctionDecl
,
2857 &ClsExprs
[0], ClsExprs
.size(),
2860 // (id)class_getSuperclass((Class)objc_getClass("CurrentClass"))
2861 // To turn off a warning, type-cast to 'id'
2862 InitExprs
.push_back(
2863 // set 'super class', using class_getSuperclass().
2864 NoTypeInfoCStyleCastExpr(Context
, Context
->getObjCIdType(),
2866 // struct objc_super
2867 QualType superType
= getSuperStructType();
2870 if (LangOpts
.MicrosoftExt
) {
2871 SynthSuperContructorFunctionDecl();
2872 // Simulate a contructor call...
2873 DeclRefExpr
*DRE
= new (Context
) DeclRefExpr(SuperContructorFunctionDecl
,
2874 false, superType
, VK_LValue
,
2876 SuperRep
= new (Context
) CallExpr(*Context
, DRE
, InitExprs
,
2877 superType
, VK_LValue
, SourceLocation());
2878 // The code for super is a little tricky to prevent collision with
2879 // the structure definition in the header. The rewriter has it's own
2880 // internal definition (__rw_objc_super) that is uses. This is why
2881 // we need the cast below. For example:
2882 // (struct objc_super *)&__rw_objc_super((id)self, (id)objc_getClass("SUPER"))
2884 SuperRep
= new (Context
) UnaryOperator(SuperRep
, UO_AddrOf
,
2885 Context
->getPointerType(SuperRep
->getType()),
2886 VK_RValue
, OK_Ordinary
,
2888 SuperRep
= NoTypeInfoCStyleCastExpr(Context
,
2889 Context
->getPointerType(superType
),
2890 CK_BitCast
, SuperRep
);
2892 // (struct objc_super) { <exprs from above> }
2894 new (Context
) InitListExpr(*Context
, SourceLocation(), InitExprs
,
2896 TypeSourceInfo
*superTInfo
2897 = Context
->getTrivialTypeSourceInfo(superType
);
2898 SuperRep
= new (Context
) CompoundLiteralExpr(SourceLocation(), superTInfo
,
2899 superType
, VK_RValue
, ILE
,
2902 MsgExprs
.push_back(SuperRep
);
2906 case ObjCMessageExpr::Instance
: {
2907 // Remove all type-casts because it may contain objc-style types; e.g.
2909 Expr
*recExpr
= Exp
->getInstanceReceiver();
2910 while (CStyleCastExpr
*CE
= dyn_cast
<CStyleCastExpr
>(recExpr
))
2911 recExpr
= CE
->getSubExpr();
2912 CastKind CK
= recExpr
->getType()->isObjCObjectPointerType()
2913 ? CK_BitCast
: recExpr
->getType()->isBlockPointerType()
2914 ? CK_BlockPointerToObjCPointerCast
2915 : CK_CPointerToObjCPointerCast
;
2917 recExpr
= NoTypeInfoCStyleCastExpr(Context
, Context
->getObjCIdType(),
2919 MsgExprs
.push_back(recExpr
);
2924 // Create a call to sel_registerName("selName"), it will be the 2nd argument.
2925 SmallVector
<Expr
*, 8> SelExprs
;
2926 QualType argType
= Context
->getPointerType(Context
->CharTy
);
2927 SelExprs
.push_back(StringLiteral::Create(*Context
,
2928 Exp
->getSelector().getAsString(),
2929 StringLiteral::Ascii
, false,
2930 argType
, SourceLocation()));
2931 CallExpr
*SelExp
= SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl
,
2932 &SelExprs
[0], SelExprs
.size(),
2935 MsgExprs
.push_back(SelExp
);
2937 // Now push any user supplied arguments.
2938 for (unsigned i
= 0; i
< Exp
->getNumArgs(); i
++) {
2939 Expr
*userExpr
= Exp
->getArg(i
);
2940 // Make all implicit casts explicit...ICE comes in handy:-)
2941 if (ImplicitCastExpr
*ICE
= dyn_cast
<ImplicitCastExpr
>(userExpr
)) {
2942 // Reuse the ICE type, it is exactly what the doctor ordered.
2943 QualType type
= ICE
->getType();
2944 if (needToScanForQualifiers(type
))
2945 type
= Context
->getObjCIdType();
2946 // Make sure we convert "type (^)(...)" to "type (*)(...)".
2947 (void)convertBlockPointerToFunctionPointer(type
);
2948 const Expr
*SubExpr
= ICE
->IgnoreParenImpCasts();
2950 if (SubExpr
->getType()->isIntegralType(*Context
) &&
2951 type
->isBooleanType()) {
2952 CK
= CK_IntegralToBoolean
;
2953 } else if (type
->isObjCObjectPointerType()) {
2954 if (SubExpr
->getType()->isBlockPointerType()) {
2955 CK
= CK_BlockPointerToObjCPointerCast
;
2956 } else if (SubExpr
->getType()->isPointerType()) {
2957 CK
= CK_CPointerToObjCPointerCast
;
2965 userExpr
= NoTypeInfoCStyleCastExpr(Context
, type
, CK
, userExpr
);
2967 // Make id<P...> cast into an 'id' cast.
2968 else if (CStyleCastExpr
*CE
= dyn_cast
<CStyleCastExpr
>(userExpr
)) {
2969 if (CE
->getType()->isObjCQualifiedIdType()) {
2970 while ((CE
= dyn_cast
<CStyleCastExpr
>(userExpr
)))
2971 userExpr
= CE
->getSubExpr();
2973 if (userExpr
->getType()->isIntegralType(*Context
)) {
2974 CK
= CK_IntegralToPointer
;
2975 } else if (userExpr
->getType()->isBlockPointerType()) {
2976 CK
= CK_BlockPointerToObjCPointerCast
;
2977 } else if (userExpr
->getType()->isPointerType()) {
2978 CK
= CK_CPointerToObjCPointerCast
;
2982 userExpr
= NoTypeInfoCStyleCastExpr(Context
, Context
->getObjCIdType(),
2986 MsgExprs
.push_back(userExpr
);
2987 // We've transferred the ownership to MsgExprs. For now, we *don't* null
2988 // out the argument in the original expression (since we aren't deleting
2989 // the ObjCMessageExpr). See RewritePropertyOrImplicitSetter() usage for more info.
2990 //Exp->setArg(i, 0);
2992 // Generate the funky cast.
2994 SmallVector
<QualType
, 8> ArgTypes
;
2995 QualType returnType
;
2997 // Push 'id' and 'SEL', the 2 implicit arguments.
2998 if (MsgSendFlavor
== MsgSendSuperFunctionDecl
)
2999 ArgTypes
.push_back(Context
->getPointerType(getSuperStructType()));
3001 ArgTypes
.push_back(Context
->getObjCIdType());
3002 ArgTypes
.push_back(Context
->getObjCSelType());
3003 if (ObjCMethodDecl
*OMD
= Exp
->getMethodDecl()) {
3004 // Push any user argument types.
3005 for (ObjCMethodDecl::param_iterator PI
= OMD
->param_begin(),
3006 E
= OMD
->param_end(); PI
!= E
; ++PI
) {
3007 QualType t
= (*PI
)->getType()->isObjCQualifiedIdType()
3008 ? Context
->getObjCIdType()
3010 // Make sure we convert "t (^)(...)" to "t (*)(...)".
3011 (void)convertBlockPointerToFunctionPointer(t
);
3012 ArgTypes
.push_back(t
);
3014 returnType
= Exp
->getType();
3015 convertToUnqualifiedObjCType(returnType
);
3016 (void)convertBlockPointerToFunctionPointer(returnType
);
3018 returnType
= Context
->getObjCIdType();
3020 // Get the type, we will need to reference it in a couple spots.
3021 QualType msgSendType
= MsgSendFlavor
->getType();
3023 // Create a reference to the objc_msgSend() declaration.
3024 DeclRefExpr
*DRE
= new (Context
) DeclRefExpr(MsgSendFlavor
, false, msgSendType
,
3025 VK_LValue
, SourceLocation());
3027 // Need to cast objc_msgSend to "void *" (to workaround a GCC bandaid).
3028 // If we don't do this cast, we get the following bizarre warning/note:
3029 // xx.m:13: warning: function called through a non-compatible type
3030 // xx.m:13: note: if this code is reached, the program will abort
3031 cast
= NoTypeInfoCStyleCastExpr(Context
,
3032 Context
->getPointerType(Context
->VoidTy
),
3035 // Now do the "normal" pointer to function cast.
3037 getSimpleFunctionType(returnType
, &ArgTypes
[0], ArgTypes
.size(),
3038 // If we don't have a method decl, force a variadic cast.
3039 Exp
->getMethodDecl() ? Exp
->getMethodDecl()->isVariadic() : true);
3040 castType
= Context
->getPointerType(castType
);
3041 cast
= NoTypeInfoCStyleCastExpr(Context
, castType
, CK_BitCast
,
3044 // Don't forget the parens to enforce the proper binding.
3045 ParenExpr
*PE
= new (Context
) ParenExpr(StartLoc
, EndLoc
, cast
);
3047 const FunctionType
*FT
= msgSendType
->getAs
<FunctionType
>();
3048 CallExpr
*CE
= new (Context
) CallExpr(*Context
, PE
, MsgExprs
,
3049 FT
->getResultType(), VK_RValue
,
3051 Stmt
*ReplacingStmt
= CE
;
3052 if (MsgSendStretFlavor
) {
3053 // We have the method which returns a struct/union. Must also generate
3054 // call to objc_msgSend_stret and hang both varieties on a conditional
3055 // expression which dictate which one to envoke depending on size of
3056 // method's return type.
3058 CallExpr
*STCE
= SynthMsgSendStretCallExpr(MsgSendStretFlavor
,
3059 msgSendType
, returnType
,
3061 Exp
->getMethodDecl());
3063 // Build sizeof(returnType)
3064 UnaryExprOrTypeTraitExpr
*sizeofExpr
=
3065 new (Context
) UnaryExprOrTypeTraitExpr(UETT_SizeOf
,
3066 Context
->getTrivialTypeSourceInfo(returnType
),
3067 Context
->getSizeType(), SourceLocation(),
3069 // (sizeof(returnType) <= 8 ? objc_msgSend(...) : objc_msgSend_stret(...))
3070 // FIXME: Value of 8 is base on ppc32/x86 ABI for the most common cases.
3071 // For X86 it is more complicated and some kind of target specific routine
3072 // is needed to decide what to do.
3074 static_cast<unsigned>(Context
->getTypeSize(Context
->IntTy
));
3075 IntegerLiteral
*limit
= IntegerLiteral::Create(*Context
,
3076 llvm::APInt(IntSize
, 8),
3079 BinaryOperator
*lessThanExpr
=
3080 new (Context
) BinaryOperator(sizeofExpr
, limit
, BO_LE
, Context
->IntTy
,
3081 VK_RValue
, OK_Ordinary
, SourceLocation());
3082 // (sizeof(returnType) <= 8 ? objc_msgSend(...) : objc_msgSend_stret(...))
3083 ConditionalOperator
*CondExpr
=
3084 new (Context
) ConditionalOperator(lessThanExpr
,
3085 SourceLocation(), CE
,
3086 SourceLocation(), STCE
,
3087 returnType
, VK_RValue
, OK_Ordinary
);
3088 ReplacingStmt
= new (Context
) ParenExpr(SourceLocation(), SourceLocation(),
3091 // delete Exp; leak for now, see RewritePropertyOrImplicitSetter() usage for more info.
3092 return ReplacingStmt
;
3095 Stmt
*RewriteObjC::RewriteMessageExpr(ObjCMessageExpr
*Exp
) {
3096 Stmt
*ReplacingStmt
= SynthMessageExpr(Exp
, Exp
->getLocStart(),
3099 // Now do the actual rewrite.
3100 ReplaceStmt(Exp
, ReplacingStmt
);
3102 // delete Exp; leak for now, see RewritePropertyOrImplicitSetter() usage for more info.
3103 return ReplacingStmt
;
3106 // typedef struct objc_object Protocol;
3107 QualType
RewriteObjC::getProtocolType() {
3108 if (!ProtocolTypeDecl
) {
3109 TypeSourceInfo
*TInfo
3110 = Context
->getTrivialTypeSourceInfo(Context
->getObjCIdType());
3111 ProtocolTypeDecl
= TypedefDecl::Create(*Context
, TUDecl
,
3112 SourceLocation(), SourceLocation(),
3113 &Context
->Idents
.get("Protocol"),
3116 return Context
->getTypeDeclType(ProtocolTypeDecl
);
3119 /// RewriteObjCProtocolExpr - Rewrite a protocol expression into
3120 /// a synthesized/forward data reference (to the protocol's metadata).
3121 /// The forward references (and metadata) are generated in
3122 /// RewriteObjC::HandleTranslationUnit().
3123 Stmt
*RewriteObjC::RewriteObjCProtocolExpr(ObjCProtocolExpr
*Exp
) {
3124 std::string Name
= "_OBJC_PROTOCOL_" + Exp
->getProtocol()->getNameAsString();
3125 IdentifierInfo
*ID
= &Context
->Idents
.get(Name
);
3126 VarDecl
*VD
= VarDecl::Create(*Context
, TUDecl
, SourceLocation(),
3127 SourceLocation(), ID
, getProtocolType(), 0,
3128 SC_Extern
, SC_None
);
3129 DeclRefExpr
*DRE
= new (Context
) DeclRefExpr(VD
, false, getProtocolType(),
3130 VK_LValue
, SourceLocation());
3131 Expr
*DerefExpr
= new (Context
) UnaryOperator(DRE
, UO_AddrOf
,
3132 Context
->getPointerType(DRE
->getType()),
3133 VK_RValue
, OK_Ordinary
, SourceLocation());
3134 CastExpr
*castExpr
= NoTypeInfoCStyleCastExpr(Context
, DerefExpr
->getType(),
3137 ReplaceStmt(Exp
, castExpr
);
3138 ProtocolExprDecls
.insert(Exp
->getProtocol()->getCanonicalDecl());
3139 // delete Exp; leak for now, see RewritePropertyOrImplicitSetter() usage for more info.
3144 bool RewriteObjC::BufferContainsPPDirectives(const char *startBuf
,
3145 const char *endBuf
) {
3146 while (startBuf
< endBuf
) {
3147 if (*startBuf
== '#') {
3149 for (++startBuf
; startBuf
[0] == ' ' || startBuf
[0] == '\t'; ++startBuf
)
3151 if (!strncmp(startBuf
, "if", strlen("if")) ||
3152 !strncmp(startBuf
, "ifdef", strlen("ifdef")) ||
3153 !strncmp(startBuf
, "ifndef", strlen("ifndef")) ||
3154 !strncmp(startBuf
, "define", strlen("define")) ||
3155 !strncmp(startBuf
, "undef", strlen("undef")) ||
3156 !strncmp(startBuf
, "else", strlen("else")) ||
3157 !strncmp(startBuf
, "elif", strlen("elif")) ||
3158 !strncmp(startBuf
, "endif", strlen("endif")) ||
3159 !strncmp(startBuf
, "pragma", strlen("pragma")) ||
3160 !strncmp(startBuf
, "include", strlen("include")) ||
3161 !strncmp(startBuf
, "import", strlen("import")) ||
3162 !strncmp(startBuf
, "include_next", strlen("include_next")))
3170 /// RewriteObjCInternalStruct - Rewrite one internal struct corresponding to
3171 /// an objective-c class with ivars.
3172 void RewriteObjC::RewriteObjCInternalStruct(ObjCInterfaceDecl
*CDecl
,
3173 std::string
&Result
) {
3174 assert(CDecl
&& "Class missing in SynthesizeObjCInternalStruct");
3175 assert(CDecl
->getName() != "" &&
3176 "Name missing in SynthesizeObjCInternalStruct");
3177 // Do not synthesize more than once.
3178 if (ObjCSynthesizedStructs
.count(CDecl
))
3180 ObjCInterfaceDecl
*RCDecl
= CDecl
->getSuperClass();
3181 int NumIvars
= CDecl
->ivar_size();
3182 SourceLocation LocStart
= CDecl
->getLocStart();
3183 SourceLocation LocEnd
= CDecl
->getEndOfDefinitionLoc();
3185 const char *startBuf
= SM
->getCharacterData(LocStart
);
3186 const char *endBuf
= SM
->getCharacterData(LocEnd
);
3188 // If no ivars and no root or if its root, directly or indirectly,
3189 // have no ivars (thus not synthesized) then no need to synthesize this class.
3190 if ((!CDecl
->isThisDeclarationADefinition() || NumIvars
== 0) &&
3191 (!RCDecl
|| !ObjCSynthesizedStructs
.count(RCDecl
))) {
3192 endBuf
+= Lexer::MeasureTokenLength(LocEnd
, *SM
, LangOpts
);
3193 ReplaceText(LocStart
, endBuf
-startBuf
, Result
);
3197 // FIXME: This has potential of causing problem. If
3198 // SynthesizeObjCInternalStruct is ever called recursively.
3199 Result
+= "\nstruct ";
3200 Result
+= CDecl
->getNameAsString();
3201 if (LangOpts
.MicrosoftExt
)
3205 const char *cursor
= strchr(startBuf
, '{');
3206 assert((cursor
&& endBuf
)
3207 && "SynthesizeObjCInternalStruct - malformed @interface");
3208 // If the buffer contains preprocessor directives, we do more fine-grained
3209 // rewrites. This is intended to fix code that looks like (which occurs in
3210 // NSURL.h, for example):
3213 // @interface Foo : NSObject
3215 // @interface FooBar : NSObject
3222 // This clause is segregated to avoid breaking the common case.
3223 if (BufferContainsPPDirectives(startBuf
, cursor
)) {
3224 SourceLocation L
= RCDecl
? CDecl
->getSuperClassLoc() :
3225 CDecl
->getAtStartLoc();
3226 const char *endHeader
= SM
->getCharacterData(L
);
3227 endHeader
+= Lexer::MeasureTokenLength(L
, *SM
, LangOpts
);
3229 if (CDecl
->protocol_begin() != CDecl
->protocol_end()) {
3230 // advance to the end of the referenced protocols.
3231 while (endHeader
< cursor
&& *endHeader
!= '>') endHeader
++;
3234 // rewrite the original header
3235 ReplaceText(LocStart
, endHeader
-startBuf
, Result
);
3237 // rewrite the original header *without* disturbing the '{'
3238 ReplaceText(LocStart
, cursor
-startBuf
, Result
);
3240 if (RCDecl
&& ObjCSynthesizedStructs
.count(RCDecl
)) {
3241 Result
= "\n struct ";
3242 Result
+= RCDecl
->getNameAsString();
3244 Result
+= RCDecl
->getNameAsString();
3245 Result
+= "_IVARS;\n";
3247 // insert the super class structure definition.
3248 SourceLocation OnePastCurly
=
3249 LocStart
.getLocWithOffset(cursor
-startBuf
+1);
3250 InsertText(OnePastCurly
, Result
);
3252 cursor
++; // past '{'
3254 // Now comment out any visibility specifiers.
3255 while (cursor
< endBuf
) {
3256 if (*cursor
== '@') {
3257 SourceLocation atLoc
= LocStart
.getLocWithOffset(cursor
-startBuf
);
3259 for (++cursor
; cursor
[0] == ' ' || cursor
[0] == '\t'; ++cursor
)
3262 // FIXME: presence of @public, etc. inside comment results in
3263 // this transformation as well, which is still correct c-code.
3264 if (!strncmp(cursor
, "public", strlen("public")) ||
3265 !strncmp(cursor
, "private", strlen("private")) ||
3266 !strncmp(cursor
, "package", strlen("package")) ||
3267 !strncmp(cursor
, "protected", strlen("protected")))
3268 InsertText(atLoc
, "// ");
3270 // FIXME: If there are cases where '<' is used in ivar declaration part
3271 // of user code, then scan the ivar list and use needToScanForQualifiers
3272 // for type checking.
3273 else if (*cursor
== '<') {
3274 SourceLocation atLoc
= LocStart
.getLocWithOffset(cursor
-startBuf
);
3275 InsertText(atLoc
, "/* ");
3276 cursor
= strchr(cursor
, '>');
3278 atLoc
= LocStart
.getLocWithOffset(cursor
-startBuf
);
3279 InsertText(atLoc
, " */");
3280 } else if (*cursor
== '^') { // rewrite block specifier.
3281 SourceLocation caretLoc
= LocStart
.getLocWithOffset(cursor
-startBuf
);
3282 ReplaceText(caretLoc
, 1, "*");
3286 // Don't forget to add a ';'!!
3287 InsertText(LocEnd
.getLocWithOffset(1), ";");
3288 } else { // we don't have any instance variables - insert super struct.
3289 endBuf
+= Lexer::MeasureTokenLength(LocEnd
, *SM
, LangOpts
);
3290 Result
+= " {\n struct ";
3291 Result
+= RCDecl
->getNameAsString();
3293 Result
+= RCDecl
->getNameAsString();
3294 Result
+= "_IVARS;\n};\n";
3295 ReplaceText(LocStart
, endBuf
-startBuf
, Result
);
3297 // Mark this struct as having been generated.
3298 if (!ObjCSynthesizedStructs
.insert(CDecl
))
3299 llvm_unreachable("struct already synthesize- SynthesizeObjCInternalStruct");
3302 //===----------------------------------------------------------------------===//
3303 // Meta Data Emission
3304 //===----------------------------------------------------------------------===//
3307 /// RewriteImplementations - This routine rewrites all method implementations
3308 /// and emits meta-data.
3310 void RewriteObjC::RewriteImplementations() {
3311 int ClsDefCount
= ClassImplementation
.size();
3312 int CatDefCount
= CategoryImplementation
.size();
3314 // Rewrite implemented methods
3315 for (int i
= 0; i
< ClsDefCount
; i
++)
3316 RewriteImplementationDecl(ClassImplementation
[i
]);
3318 for (int i
= 0; i
< CatDefCount
; i
++)
3319 RewriteImplementationDecl(CategoryImplementation
[i
]);
3322 void RewriteObjC::RewriteByRefString(std::string
&ResultStr
,
3323 const std::string
&Name
,
3324 ValueDecl
*VD
, bool def
) {
3325 assert(BlockByRefDeclNo
.count(VD
) &&
3326 "RewriteByRefString: ByRef decl missing");
3328 ResultStr
+= "struct ";
3329 ResultStr
+= "__Block_byref_" + Name
+
3330 "_" + utostr(BlockByRefDeclNo
[VD
]) ;
3333 static bool HasLocalVariableExternalStorage(ValueDecl
*VD
) {
3334 if (VarDecl
*Var
= dyn_cast
<VarDecl
>(VD
))
3335 return (Var
->isFunctionOrMethodVarDecl() && !Var
->hasLocalStorage());
3339 std::string
RewriteObjC::SynthesizeBlockFunc(BlockExpr
*CE
, int i
,
3342 const FunctionType
*AFT
= CE
->getFunctionType();
3343 QualType RT
= AFT
->getResultType();
3344 std::string StructRef
= "struct " + Tag
;
3345 std::string S
= "static " + RT
.getAsString(Context
->getPrintingPolicy()) + " __" +
3346 funcName
.str() + "_" + "block_func_" + utostr(i
);
3348 BlockDecl
*BD
= CE
->getBlockDecl();
3350 if (isa
<FunctionNoProtoType
>(AFT
)) {
3351 // No user-supplied arguments. Still need to pass in a pointer to the
3352 // block (to reference imported block decl refs).
3353 S
+= "(" + StructRef
+ " *__cself)";
3354 } else if (BD
->param_empty()) {
3355 S
+= "(" + StructRef
+ " *__cself)";
3357 const FunctionProtoType
*FT
= cast
<FunctionProtoType
>(AFT
);
3358 assert(FT
&& "SynthesizeBlockFunc: No function proto");
3360 // first add the implicit argument.
3361 S
+= StructRef
+ " *__cself, ";
3362 std::string ParamStr
;
3363 for (BlockDecl::param_iterator AI
= BD
->param_begin(),
3364 E
= BD
->param_end(); AI
!= E
; ++AI
) {
3365 if (AI
!= BD
->param_begin()) S
+= ", ";
3366 ParamStr
= (*AI
)->getNameAsString();
3367 QualType QT
= (*AI
)->getType();
3368 (void)convertBlockPointerToFunctionPointer(QT
);
3369 QT
.getAsStringInternal(ParamStr
, Context
->getPrintingPolicy());
3372 if (FT
->isVariadic()) {
3373 if (!BD
->param_empty()) S
+= ", ";
3380 // Create local declarations to avoid rewriting all closure decl ref exprs.
3381 // First, emit a declaration for all "by ref" decls.
3382 for (SmallVector
<ValueDecl
*,8>::iterator I
= BlockByRefDecls
.begin(),
3383 E
= BlockByRefDecls
.end(); I
!= E
; ++I
) {
3385 std::string Name
= (*I
)->getNameAsString();
3386 std::string TypeString
;
3387 RewriteByRefString(TypeString
, Name
, (*I
));
3389 Name
= TypeString
+ Name
;
3390 S
+= Name
+ " = __cself->" + (*I
)->getNameAsString() + "; // bound by ref\n";
3392 // Next, emit a declaration for all "by copy" declarations.
3393 for (SmallVector
<ValueDecl
*,8>::iterator I
= BlockByCopyDecls
.begin(),
3394 E
= BlockByCopyDecls
.end(); I
!= E
; ++I
) {
3396 // Handle nested closure invocation. For example:
3398 // void (^myImportedClosure)(void);
3399 // myImportedClosure = ^(void) { setGlobalInt(x + y); };
3401 // void (^anotherClosure)(void);
3402 // anotherClosure = ^(void) {
3403 // myImportedClosure(); // import and invoke the closure
3406 if (isTopLevelBlockPointerType((*I
)->getType())) {
3407 RewriteBlockPointerTypeVariable(S
, (*I
));
3409 RewriteBlockPointerType(S
, (*I
)->getType());
3411 S
+= "__cself->" + (*I
)->getNameAsString() + "; // bound by copy\n";
3414 std::string Name
= (*I
)->getNameAsString();
3415 QualType QT
= (*I
)->getType();
3416 if (HasLocalVariableExternalStorage(*I
))
3417 QT
= Context
->getPointerType(QT
);
3418 QT
.getAsStringInternal(Name
, Context
->getPrintingPolicy());
3419 S
+= Name
+ " = __cself->" +
3420 (*I
)->getNameAsString() + "; // bound by copy\n";
3423 std::string RewrittenStr
= RewrittenBlockExprs
[CE
];
3424 const char *cstr
= RewrittenStr
.c_str();
3425 while (*cstr
++ != '{') ;
3431 std::string
RewriteObjC::SynthesizeBlockHelperFuncs(BlockExpr
*CE
, int i
,
3434 std::string StructRef
= "struct " + Tag
;
3435 std::string S
= "static void __";
3438 S
+= "_block_copy_" + utostr(i
);
3439 S
+= "(" + StructRef
;
3440 S
+= "*dst, " + StructRef
;
3442 for (llvm::SmallPtrSet
<ValueDecl
*,8>::iterator I
= ImportedBlockDecls
.begin(),
3443 E
= ImportedBlockDecls
.end(); I
!= E
; ++I
) {
3444 ValueDecl
*VD
= (*I
);
3445 S
+= "_Block_object_assign((void*)&dst->";
3446 S
+= (*I
)->getNameAsString();
3447 S
+= ", (void*)src->";
3448 S
+= (*I
)->getNameAsString();
3449 if (BlockByRefDeclsPtrSet
.count((*I
)))
3450 S
+= ", " + utostr(BLOCK_FIELD_IS_BYREF
) + "/*BLOCK_FIELD_IS_BYREF*/);";
3451 else if (VD
->getType()->isBlockPointerType())
3452 S
+= ", " + utostr(BLOCK_FIELD_IS_BLOCK
) + "/*BLOCK_FIELD_IS_BLOCK*/);";
3454 S
+= ", " + utostr(BLOCK_FIELD_IS_OBJECT
) + "/*BLOCK_FIELD_IS_OBJECT*/);";
3458 S
+= "\nstatic void __";
3460 S
+= "_block_dispose_" + utostr(i
);
3461 S
+= "(" + StructRef
;
3463 for (llvm::SmallPtrSet
<ValueDecl
*,8>::iterator I
= ImportedBlockDecls
.begin(),
3464 E
= ImportedBlockDecls
.end(); I
!= E
; ++I
) {
3465 ValueDecl
*VD
= (*I
);
3466 S
+= "_Block_object_dispose((void*)src->";
3467 S
+= (*I
)->getNameAsString();
3468 if (BlockByRefDeclsPtrSet
.count((*I
)))
3469 S
+= ", " + utostr(BLOCK_FIELD_IS_BYREF
) + "/*BLOCK_FIELD_IS_BYREF*/);";
3470 else if (VD
->getType()->isBlockPointerType())
3471 S
+= ", " + utostr(BLOCK_FIELD_IS_BLOCK
) + "/*BLOCK_FIELD_IS_BLOCK*/);";
3473 S
+= ", " + utostr(BLOCK_FIELD_IS_OBJECT
) + "/*BLOCK_FIELD_IS_OBJECT*/);";
3479 std::string
RewriteObjC::SynthesizeBlockImpl(BlockExpr
*CE
, std::string Tag
,
3481 std::string S
= "\nstruct " + Tag
;
3482 std::string Constructor
= " " + Tag
;
3484 S
+= " {\n struct __block_impl impl;\n";
3485 S
+= " struct " + Desc
;
3488 Constructor
+= "(void *fp, "; // Invoke function pointer.
3489 Constructor
+= "struct " + Desc
; // Descriptor pointer.
3490 Constructor
+= " *desc";
3492 if (BlockDeclRefs
.size()) {
3493 // Output all "by copy" declarations.
3494 for (SmallVector
<ValueDecl
*,8>::iterator I
= BlockByCopyDecls
.begin(),
3495 E
= BlockByCopyDecls
.end(); I
!= E
; ++I
) {
3497 std::string FieldName
= (*I
)->getNameAsString();
3498 std::string ArgName
= "_" + FieldName
;
3499 // Handle nested closure invocation. For example:
3501 // void (^myImportedBlock)(void);
3502 // myImportedBlock = ^(void) { setGlobalInt(x + y); };
3504 // void (^anotherBlock)(void);
3505 // anotherBlock = ^(void) {
3506 // myImportedBlock(); // import and invoke the closure
3509 if (isTopLevelBlockPointerType((*I
)->getType())) {
3510 S
+= "struct __block_impl *";
3511 Constructor
+= ", void *" + ArgName
;
3513 QualType QT
= (*I
)->getType();
3514 if (HasLocalVariableExternalStorage(*I
))
3515 QT
= Context
->getPointerType(QT
);
3516 QT
.getAsStringInternal(FieldName
, Context
->getPrintingPolicy());
3517 QT
.getAsStringInternal(ArgName
, Context
->getPrintingPolicy());
3518 Constructor
+= ", " + ArgName
;
3520 S
+= FieldName
+ ";\n";
3522 // Output all "by ref" declarations.
3523 for (SmallVector
<ValueDecl
*,8>::iterator I
= BlockByRefDecls
.begin(),
3524 E
= BlockByRefDecls
.end(); I
!= E
; ++I
) {
3526 std::string FieldName
= (*I
)->getNameAsString();
3527 std::string ArgName
= "_" + FieldName
;
3529 std::string TypeString
;
3530 RewriteByRefString(TypeString
, FieldName
, (*I
));
3532 FieldName
= TypeString
+ FieldName
;
3533 ArgName
= TypeString
+ ArgName
;
3534 Constructor
+= ", " + ArgName
;
3536 S
+= FieldName
+ "; // by ref\n";
3538 // Finish writing the constructor.
3539 Constructor
+= ", int flags=0)";
3540 // Initialize all "by copy" arguments.
3541 bool firsTime
= true;
3542 for (SmallVector
<ValueDecl
*,8>::iterator I
= BlockByCopyDecls
.begin(),
3543 E
= BlockByCopyDecls
.end(); I
!= E
; ++I
) {
3544 std::string Name
= (*I
)->getNameAsString();
3546 Constructor
+= " : ";
3550 Constructor
+= ", ";
3551 if (isTopLevelBlockPointerType((*I
)->getType()))
3552 Constructor
+= Name
+ "((struct __block_impl *)_" + Name
+ ")";
3554 Constructor
+= Name
+ "(_" + Name
+ ")";
3556 // Initialize all "by ref" arguments.
3557 for (SmallVector
<ValueDecl
*,8>::iterator I
= BlockByRefDecls
.begin(),
3558 E
= BlockByRefDecls
.end(); I
!= E
; ++I
) {
3559 std::string Name
= (*I
)->getNameAsString();
3561 Constructor
+= " : ";
3565 Constructor
+= ", ";
3566 Constructor
+= Name
+ "(_" + Name
+ "->__forwarding)";
3569 Constructor
+= " {\n";
3571 Constructor
+= " impl.isa = &_NSConcreteGlobalBlock;\n";
3573 Constructor
+= " impl.isa = &_NSConcreteStackBlock;\n";
3574 Constructor
+= " impl.Flags = flags;\n impl.FuncPtr = fp;\n";
3576 Constructor
+= " Desc = desc;\n";
3578 // Finish writing the constructor.
3579 Constructor
+= ", int flags=0) {\n";
3581 Constructor
+= " impl.isa = &_NSConcreteGlobalBlock;\n";
3583 Constructor
+= " impl.isa = &_NSConcreteStackBlock;\n";
3584 Constructor
+= " impl.Flags = flags;\n impl.FuncPtr = fp;\n";
3585 Constructor
+= " Desc = desc;\n";
3588 Constructor
+= "}\n";
3594 std::string
RewriteObjC::SynthesizeBlockDescriptor(std::string DescTag
,
3595 std::string ImplTag
, int i
,
3598 std::string S
= "\nstatic struct " + DescTag
;
3600 S
+= " {\n unsigned long reserved;\n";
3601 S
+= " unsigned long Block_size;\n";
3603 S
+= " void (*copy)(struct ";
3604 S
+= ImplTag
; S
+= "*, struct ";
3605 S
+= ImplTag
; S
+= "*);\n";
3607 S
+= " void (*dispose)(struct ";
3608 S
+= ImplTag
; S
+= "*);\n";
3612 S
+= DescTag
+ "_DATA = { 0, sizeof(struct ";
3615 S
+= ", __" + FunName
.str() + "_block_copy_" + utostr(i
);
3616 S
+= ", __" + FunName
.str() + "_block_dispose_" + utostr(i
);
3622 void RewriteObjC::SynthesizeBlockLiterals(SourceLocation FunLocStart
,
3623 StringRef FunName
) {
3624 // Insert declaration for the function in which block literal is used.
3625 if (CurFunctionDeclToDeclareForBlock
&& !Blocks
.empty())
3626 RewriteBlockLiteralFunctionDecl(CurFunctionDeclToDeclareForBlock
);
3627 bool RewriteSC
= (GlobalVarDecl
&&
3629 GlobalVarDecl
->getStorageClass() == SC_Static
&&
3630 GlobalVarDecl
->getType().getCVRQualifiers());
3632 std::string
SC(" void __");
3633 SC
+= GlobalVarDecl
->getNameAsString();
3635 InsertText(FunLocStart
, SC
);
3638 // Insert closures that were part of the function.
3639 for (unsigned i
= 0, count
=0; i
< Blocks
.size(); i
++) {
3640 CollectBlockDeclRefInfo(Blocks
[i
]);
3641 // Need to copy-in the inner copied-in variables not actually used in this
3643 for (int j
= 0; j
< InnerDeclRefsCount
[i
]; j
++) {
3644 DeclRefExpr
*Exp
= InnerDeclRefs
[count
++];
3645 ValueDecl
*VD
= Exp
->getDecl();
3646 BlockDeclRefs
.push_back(Exp
);
3647 if (!VD
->hasAttr
<BlocksAttr
>() && !BlockByCopyDeclsPtrSet
.count(VD
)) {
3648 BlockByCopyDeclsPtrSet
.insert(VD
);
3649 BlockByCopyDecls
.push_back(VD
);
3651 if (VD
->hasAttr
<BlocksAttr
>() && !BlockByRefDeclsPtrSet
.count(VD
)) {
3652 BlockByRefDeclsPtrSet
.insert(VD
);
3653 BlockByRefDecls
.push_back(VD
);
3655 // imported objects in the inner blocks not used in the outer
3656 // blocks must be copied/disposed in the outer block as well.
3657 if (VD
->hasAttr
<BlocksAttr
>() ||
3658 VD
->getType()->isObjCObjectPointerType() ||
3659 VD
->getType()->isBlockPointerType())
3660 ImportedBlockDecls
.insert(VD
);
3663 std::string ImplTag
= "__" + FunName
.str() + "_block_impl_" + utostr(i
);
3664 std::string DescTag
= "__" + FunName
.str() + "_block_desc_" + utostr(i
);
3666 std::string CI
= SynthesizeBlockImpl(Blocks
[i
], ImplTag
, DescTag
);
3668 InsertText(FunLocStart
, CI
);
3670 std::string CF
= SynthesizeBlockFunc(Blocks
[i
], i
, FunName
, ImplTag
);
3672 InsertText(FunLocStart
, CF
);
3674 if (ImportedBlockDecls
.size()) {
3675 std::string HF
= SynthesizeBlockHelperFuncs(Blocks
[i
], i
, FunName
, ImplTag
);
3676 InsertText(FunLocStart
, HF
);
3678 std::string BD
= SynthesizeBlockDescriptor(DescTag
, ImplTag
, i
, FunName
,
3679 ImportedBlockDecls
.size() > 0);
3680 InsertText(FunLocStart
, BD
);
3682 BlockDeclRefs
.clear();
3683 BlockByRefDecls
.clear();
3684 BlockByRefDeclsPtrSet
.clear();
3685 BlockByCopyDecls
.clear();
3686 BlockByCopyDeclsPtrSet
.clear();
3687 ImportedBlockDecls
.clear();
3690 // Must insert any 'const/volatile/static here. Since it has been
3691 // removed as result of rewriting of block literals.
3693 if (GlobalVarDecl
->getStorageClass() == SC_Static
)
3695 if (GlobalVarDecl
->getType().isConstQualified())
3697 if (GlobalVarDecl
->getType().isVolatileQualified())
3699 if (GlobalVarDecl
->getType().isRestrictQualified())
3701 InsertText(FunLocStart
, SC
);
3705 InnerDeclRefsCount
.clear();
3706 InnerDeclRefs
.clear();
3707 RewrittenBlockExprs
.clear();
3710 void RewriteObjC::InsertBlockLiteralsWithinFunction(FunctionDecl
*FD
) {
3711 SourceLocation FunLocStart
= FD
->getTypeSpecStartLoc();
3712 StringRef FuncName
= FD
->getName();
3714 SynthesizeBlockLiterals(FunLocStart
, FuncName
);
3717 static void BuildUniqueMethodName(std::string
&Name
,
3718 ObjCMethodDecl
*MD
) {
3719 ObjCInterfaceDecl
*IFace
= MD
->getClassInterface();
3720 Name
= IFace
->getName();
3721 Name
+= "__" + MD
->getSelector().getAsString();
3722 // Convert colons to underscores.
3723 std::string::size_type loc
= 0;
3724 while ((loc
= Name
.find(":", loc
)) != std::string::npos
)
3725 Name
.replace(loc
, 1, "_");
3728 void RewriteObjC::InsertBlockLiteralsWithinMethod(ObjCMethodDecl
*MD
) {
3729 //fprintf(stderr,"In InsertBlockLiteralsWitinMethod\n");
3730 //SourceLocation FunLocStart = MD->getLocStart();
3731 SourceLocation FunLocStart
= MD
->getLocStart();
3732 std::string FuncName
;
3733 BuildUniqueMethodName(FuncName
, MD
);
3734 SynthesizeBlockLiterals(FunLocStart
, FuncName
);
3737 void RewriteObjC::GetBlockDeclRefExprs(Stmt
*S
) {
3738 for (Stmt::child_range CI
= S
->children(); CI
; ++CI
)
3740 if (BlockExpr
*CBE
= dyn_cast
<BlockExpr
>(*CI
))
3741 GetBlockDeclRefExprs(CBE
->getBody());
3743 GetBlockDeclRefExprs(*CI
);
3745 // Handle specific things.
3746 if (DeclRefExpr
*DRE
= dyn_cast
<DeclRefExpr
>(S
)) {
3747 if (DRE
->refersToEnclosingLocal()) {
3748 // FIXME: Handle enums.
3749 if (!isa
<FunctionDecl
>(DRE
->getDecl()))
3750 BlockDeclRefs
.push_back(DRE
);
3751 if (HasLocalVariableExternalStorage(DRE
->getDecl()))
3752 BlockDeclRefs
.push_back(DRE
);
3759 void RewriteObjC::GetInnerBlockDeclRefExprs(Stmt
*S
,
3760 SmallVector
<DeclRefExpr
*, 8> &InnerBlockDeclRefs
,
3761 llvm::SmallPtrSet
<const DeclContext
*, 8> &InnerContexts
) {
3762 for (Stmt::child_range CI
= S
->children(); CI
; ++CI
)
3764 if (BlockExpr
*CBE
= dyn_cast
<BlockExpr
>(*CI
)) {
3765 InnerContexts
.insert(cast
<DeclContext
>(CBE
->getBlockDecl()));
3766 GetInnerBlockDeclRefExprs(CBE
->getBody(),
3771 GetInnerBlockDeclRefExprs(*CI
,
3776 // Handle specific things.
3777 if (DeclRefExpr
*DRE
= dyn_cast
<DeclRefExpr
>(S
)) {
3778 if (DRE
->refersToEnclosingLocal()) {
3779 if (!isa
<FunctionDecl
>(DRE
->getDecl()) &&
3780 !InnerContexts
.count(DRE
->getDecl()->getDeclContext()))
3781 InnerBlockDeclRefs
.push_back(DRE
);
3782 if (VarDecl
*Var
= dyn_cast
<VarDecl
>(DRE
->getDecl()))
3783 if (Var
->isFunctionOrMethodVarDecl())
3784 ImportedLocalExternalDecls
.insert(Var
);
3791 /// convertFunctionTypeOfBlocks - This routine converts a function type
3792 /// whose result type may be a block pointer or whose argument type(s)
3793 /// might be block pointers to an equivalent function type replacing
3794 /// all block pointers to function pointers.
3795 QualType
RewriteObjC::convertFunctionTypeOfBlocks(const FunctionType
*FT
) {
3796 const FunctionProtoType
*FTP
= dyn_cast
<FunctionProtoType
>(FT
);
3797 // FTP will be null for closures that don't take arguments.
3798 // Generate a funky cast.
3799 SmallVector
<QualType
, 8> ArgTypes
;
3800 QualType Res
= FT
->getResultType();
3801 bool HasBlockType
= convertBlockPointerToFunctionPointer(Res
);
3804 for (FunctionProtoType::arg_type_iterator I
= FTP
->arg_type_begin(),
3805 E
= FTP
->arg_type_end(); I
&& (I
!= E
); ++I
) {
3807 // Make sure we convert "t (^)(...)" to "t (*)(...)".
3808 if (convertBlockPointerToFunctionPointer(t
))
3809 HasBlockType
= true;
3810 ArgTypes
.push_back(t
);
3814 // FIXME. Does this work if block takes no argument but has a return type
3815 // which is of block type?
3817 FuncType
= getSimpleFunctionType(Res
, &ArgTypes
[0], ArgTypes
.size());
3818 else FuncType
= QualType(FT
, 0);
3822 Stmt
*RewriteObjC::SynthesizeBlockCall(CallExpr
*Exp
, const Expr
*BlockExp
) {
3823 // Navigate to relevant type information.
3824 const BlockPointerType
*CPT
= 0;
3826 if (const DeclRefExpr
*DRE
= dyn_cast
<DeclRefExpr
>(BlockExp
)) {
3827 CPT
= DRE
->getType()->getAs
<BlockPointerType
>();
3828 } else if (const MemberExpr
*MExpr
= dyn_cast
<MemberExpr
>(BlockExp
)) {
3829 CPT
= MExpr
->getType()->getAs
<BlockPointerType
>();
3831 else if (const ParenExpr
*PRE
= dyn_cast
<ParenExpr
>(BlockExp
)) {
3832 return SynthesizeBlockCall(Exp
, PRE
->getSubExpr());
3834 else if (const ImplicitCastExpr
*IEXPR
= dyn_cast
<ImplicitCastExpr
>(BlockExp
))
3835 CPT
= IEXPR
->getType()->getAs
<BlockPointerType
>();
3836 else if (const ConditionalOperator
*CEXPR
=
3837 dyn_cast
<ConditionalOperator
>(BlockExp
)) {
3838 Expr
*LHSExp
= CEXPR
->getLHS();
3839 Stmt
*LHSStmt
= SynthesizeBlockCall(Exp
, LHSExp
);
3840 Expr
*RHSExp
= CEXPR
->getRHS();
3841 Stmt
*RHSStmt
= SynthesizeBlockCall(Exp
, RHSExp
);
3842 Expr
*CONDExp
= CEXPR
->getCond();
3843 ConditionalOperator
*CondExpr
=
3844 new (Context
) ConditionalOperator(CONDExp
,
3845 SourceLocation(), cast
<Expr
>(LHSStmt
),
3846 SourceLocation(), cast
<Expr
>(RHSStmt
),
3847 Exp
->getType(), VK_RValue
, OK_Ordinary
);
3849 } else if (const ObjCIvarRefExpr
*IRE
= dyn_cast
<ObjCIvarRefExpr
>(BlockExp
)) {
3850 CPT
= IRE
->getType()->getAs
<BlockPointerType
>();
3851 } else if (const PseudoObjectExpr
*POE
3852 = dyn_cast
<PseudoObjectExpr
>(BlockExp
)) {
3853 CPT
= POE
->getType()->castAs
<BlockPointerType
>();
3855 assert(1 && "RewriteBlockClass: Bad type");
3857 assert(CPT
&& "RewriteBlockClass: Bad type");
3858 const FunctionType
*FT
= CPT
->getPointeeType()->getAs
<FunctionType
>();
3859 assert(FT
&& "RewriteBlockClass: Bad type");
3860 const FunctionProtoType
*FTP
= dyn_cast
<FunctionProtoType
>(FT
);
3861 // FTP will be null for closures that don't take arguments.
3863 RecordDecl
*RD
= RecordDecl::Create(*Context
, TTK_Struct
, TUDecl
,
3864 SourceLocation(), SourceLocation(),
3865 &Context
->Idents
.get("__block_impl"));
3866 QualType PtrBlock
= Context
->getPointerType(Context
->getTagDeclType(RD
));
3868 // Generate a funky cast.
3869 SmallVector
<QualType
, 8> ArgTypes
;
3871 // Push the block argument type.
3872 ArgTypes
.push_back(PtrBlock
);
3874 for (FunctionProtoType::arg_type_iterator I
= FTP
->arg_type_begin(),
3875 E
= FTP
->arg_type_end(); I
&& (I
!= E
); ++I
) {
3877 // Make sure we convert "t (^)(...)" to "t (*)(...)".
3878 if (!convertBlockPointerToFunctionPointer(t
))
3879 convertToUnqualifiedObjCType(t
);
3880 ArgTypes
.push_back(t
);
3883 // Now do the pointer to function cast.
3884 QualType PtrToFuncCastType
3885 = getSimpleFunctionType(Exp
->getType(), &ArgTypes
[0], ArgTypes
.size());
3887 PtrToFuncCastType
= Context
->getPointerType(PtrToFuncCastType
);
3889 CastExpr
*BlkCast
= NoTypeInfoCStyleCastExpr(Context
, PtrBlock
,
3891 const_cast<Expr
*>(BlockExp
));
3892 // Don't forget the parens to enforce the proper binding.
3893 ParenExpr
*PE
= new (Context
) ParenExpr(SourceLocation(), SourceLocation(),
3897 FieldDecl
*FD
= FieldDecl::Create(*Context
, 0, SourceLocation(),
3899 &Context
->Idents
.get("FuncPtr"),
3900 Context
->VoidPtrTy
, 0,
3901 /*BitWidth=*/0, /*Mutable=*/true,
3903 MemberExpr
*ME
= new (Context
) MemberExpr(PE
, true, FD
, SourceLocation(),
3904 FD
->getType(), VK_LValue
,
3908 CastExpr
*FunkCast
= NoTypeInfoCStyleCastExpr(Context
, PtrToFuncCastType
,
3910 PE
= new (Context
) ParenExpr(SourceLocation(), SourceLocation(), FunkCast
);
3912 SmallVector
<Expr
*, 8> BlkExprs
;
3913 // Add the implicit argument.
3914 BlkExprs
.push_back(BlkCast
);
3915 // Add the user arguments.
3916 for (CallExpr::arg_iterator I
= Exp
->arg_begin(),
3917 E
= Exp
->arg_end(); I
!= E
; ++I
) {
3918 BlkExprs
.push_back(*I
);
3920 CallExpr
*CE
= new (Context
) CallExpr(*Context
, PE
, BlkExprs
,
3921 Exp
->getType(), VK_RValue
,
3926 // We need to return the rewritten expression to handle cases where the
3927 // BlockDeclRefExpr is embedded in another expression being rewritten.
3934 // void (^myblock)() = ^() {
3935 // [f test]; // f is a BlockDeclRefExpr embedded in a message (which is being rewritten).
3939 Stmt
*RewriteObjC::RewriteBlockDeclRefExpr(DeclRefExpr
*DeclRefExp
) {
3940 // Rewrite the byref variable into BYREFVAR->__forwarding->BYREFVAR
3941 // for each DeclRefExp where BYREFVAR is name of the variable.
3942 ValueDecl
*VD
= DeclRefExp
->getDecl();
3943 bool isArrow
= DeclRefExp
->refersToEnclosingLocal();
3945 FieldDecl
*FD
= FieldDecl::Create(*Context
, 0, SourceLocation(),
3947 &Context
->Idents
.get("__forwarding"),
3948 Context
->VoidPtrTy
, 0,
3949 /*BitWidth=*/0, /*Mutable=*/true,
3951 MemberExpr
*ME
= new (Context
) MemberExpr(DeclRefExp
, isArrow
,
3952 FD
, SourceLocation(),
3953 FD
->getType(), VK_LValue
,
3956 StringRef Name
= VD
->getName();
3957 FD
= FieldDecl::Create(*Context
, 0, SourceLocation(), SourceLocation(),
3958 &Context
->Idents
.get(Name
),
3959 Context
->VoidPtrTy
, 0,
3960 /*BitWidth=*/0, /*Mutable=*/true,
3962 ME
= new (Context
) MemberExpr(ME
, true, FD
, SourceLocation(),
3963 DeclRefExp
->getType(), VK_LValue
, OK_Ordinary
);
3967 // Need parens to enforce precedence.
3968 ParenExpr
*PE
= new (Context
) ParenExpr(DeclRefExp
->getExprLoc(),
3969 DeclRefExp
->getExprLoc(),
3971 ReplaceStmt(DeclRefExp
, PE
);
3975 // Rewrites the imported local variable V with external storage
3976 // (static, extern, etc.) as *V
3978 Stmt
*RewriteObjC::RewriteLocalVariableExternalStorage(DeclRefExpr
*DRE
) {
3979 ValueDecl
*VD
= DRE
->getDecl();
3980 if (VarDecl
*Var
= dyn_cast
<VarDecl
>(VD
))
3981 if (!ImportedLocalExternalDecls
.count(Var
))
3983 Expr
*Exp
= new (Context
) UnaryOperator(DRE
, UO_Deref
, DRE
->getType(),
3984 VK_LValue
, OK_Ordinary
,
3985 DRE
->getLocation());
3986 // Need parens to enforce precedence.
3987 ParenExpr
*PE
= new (Context
) ParenExpr(SourceLocation(), SourceLocation(),
3989 ReplaceStmt(DRE
, PE
);
3993 void RewriteObjC::RewriteCastExpr(CStyleCastExpr
*CE
) {
3994 SourceLocation LocStart
= CE
->getLParenLoc();
3995 SourceLocation LocEnd
= CE
->getRParenLoc();
3997 // Need to avoid trying to rewrite synthesized casts.
3998 if (LocStart
.isInvalid())
4000 // Need to avoid trying to rewrite casts contained in macros.
4001 if (!Rewriter::isRewritable(LocStart
) || !Rewriter::isRewritable(LocEnd
))
4004 const char *startBuf
= SM
->getCharacterData(LocStart
);
4005 const char *endBuf
= SM
->getCharacterData(LocEnd
);
4006 QualType QT
= CE
->getType();
4007 const Type
* TypePtr
= QT
->getAs
<Type
>();
4008 if (isa
<TypeOfExprType
>(TypePtr
)) {
4009 const TypeOfExprType
*TypeOfExprTypePtr
= cast
<TypeOfExprType
>(TypePtr
);
4010 QT
= TypeOfExprTypePtr
->getUnderlyingExpr()->getType();
4011 std::string TypeAsString
= "(";
4012 RewriteBlockPointerType(TypeAsString
, QT
);
4013 TypeAsString
+= ")";
4014 ReplaceText(LocStart
, endBuf
-startBuf
+1, TypeAsString
);
4017 // advance the location to startArgList.
4018 const char *argPtr
= startBuf
;
4020 while (*argPtr
++ && (argPtr
< endBuf
)) {
4023 // Replace the '^' with '*'.
4024 LocStart
= LocStart
.getLocWithOffset(argPtr
-startBuf
);
4025 ReplaceText(LocStart
, 1, "*");
4032 void RewriteObjC::RewriteBlockPointerFunctionArgs(FunctionDecl
*FD
) {
4033 SourceLocation DeclLoc
= FD
->getLocation();
4034 unsigned parenCount
= 0;
4036 // We have 1 or more arguments that have closure pointers.
4037 const char *startBuf
= SM
->getCharacterData(DeclLoc
);
4038 const char *startArgList
= strchr(startBuf
, '(');
4040 assert((*startArgList
== '(') && "Rewriter fuzzy parser confused");
4043 // advance the location to startArgList.
4044 DeclLoc
= DeclLoc
.getLocWithOffset(startArgList
-startBuf
);
4045 assert((DeclLoc
.isValid()) && "Invalid DeclLoc");
4047 const char *argPtr
= startArgList
;
4049 while (*argPtr
++ && parenCount
) {
4052 // Replace the '^' with '*'.
4053 DeclLoc
= DeclLoc
.getLocWithOffset(argPtr
-startArgList
);
4054 ReplaceText(DeclLoc
, 1, "*");
4067 bool RewriteObjC::PointerTypeTakesAnyBlockArguments(QualType QT
) {
4068 const FunctionProtoType
*FTP
;
4069 const PointerType
*PT
= QT
->getAs
<PointerType
>();
4071 FTP
= PT
->getPointeeType()->getAs
<FunctionProtoType
>();
4073 const BlockPointerType
*BPT
= QT
->getAs
<BlockPointerType
>();
4074 assert(BPT
&& "BlockPointerTypeTakeAnyBlockArguments(): not a block pointer type");
4075 FTP
= BPT
->getPointeeType()->getAs
<FunctionProtoType
>();
4078 for (FunctionProtoType::arg_type_iterator I
= FTP
->arg_type_begin(),
4079 E
= FTP
->arg_type_end(); I
!= E
; ++I
)
4080 if (isTopLevelBlockPointerType(*I
))
4086 bool RewriteObjC::PointerTypeTakesAnyObjCQualifiedType(QualType QT
) {
4087 const FunctionProtoType
*FTP
;
4088 const PointerType
*PT
= QT
->getAs
<PointerType
>();
4090 FTP
= PT
->getPointeeType()->getAs
<FunctionProtoType
>();
4092 const BlockPointerType
*BPT
= QT
->getAs
<BlockPointerType
>();
4093 assert(BPT
&& "BlockPointerTypeTakeAnyBlockArguments(): not a block pointer type");
4094 FTP
= BPT
->getPointeeType()->getAs
<FunctionProtoType
>();
4097 for (FunctionProtoType::arg_type_iterator I
= FTP
->arg_type_begin(),
4098 E
= FTP
->arg_type_end(); I
!= E
; ++I
) {
4099 if ((*I
)->isObjCQualifiedIdType())
4101 if ((*I
)->isObjCObjectPointerType() &&
4102 (*I
)->getPointeeType()->isObjCQualifiedInterfaceType())
4110 void RewriteObjC::GetExtentOfArgList(const char *Name
, const char *&LParen
,
4111 const char *&RParen
) {
4112 const char *argPtr
= strchr(Name
, '(');
4113 assert((*argPtr
== '(') && "Rewriter fuzzy parser confused");
4115 LParen
= argPtr
; // output the start.
4116 argPtr
++; // skip past the left paren.
4117 unsigned parenCount
= 1;
4119 while (*argPtr
&& parenCount
) {
4121 case '(': parenCount
++; break;
4122 case ')': parenCount
--; break;
4125 if (parenCount
) argPtr
++;
4127 assert((*argPtr
== ')') && "Rewriter fuzzy parser confused");
4128 RParen
= argPtr
; // output the end
4131 void RewriteObjC::RewriteBlockPointerDecl(NamedDecl
*ND
) {
4132 if (FunctionDecl
*FD
= dyn_cast
<FunctionDecl
>(ND
)) {
4133 RewriteBlockPointerFunctionArgs(FD
);
4136 // Handle Variables and Typedefs.
4137 SourceLocation DeclLoc
= ND
->getLocation();
4139 if (VarDecl
*VD
= dyn_cast
<VarDecl
>(ND
))
4140 DeclT
= VD
->getType();
4141 else if (TypedefNameDecl
*TDD
= dyn_cast
<TypedefNameDecl
>(ND
))
4142 DeclT
= TDD
->getUnderlyingType();
4143 else if (FieldDecl
*FD
= dyn_cast
<FieldDecl
>(ND
))
4144 DeclT
= FD
->getType();
4146 llvm_unreachable("RewriteBlockPointerDecl(): Decl type not yet handled");
4148 const char *startBuf
= SM
->getCharacterData(DeclLoc
);
4149 const char *endBuf
= startBuf
;
4150 // scan backward (from the decl location) for the end of the previous decl.
4151 while (*startBuf
!= '^' && *startBuf
!= ';' && startBuf
!= MainFileStart
)
4153 SourceLocation Start
= DeclLoc
.getLocWithOffset(startBuf
-endBuf
);
4155 unsigned OrigLength
=0;
4156 // *startBuf != '^' if we are dealing with a pointer to function that
4157 // may take block argument types (which will be handled below).
4158 if (*startBuf
== '^') {
4159 // Replace the '^' with '*', computing a negative offset.
4164 while (*startBuf
!= ')') {
4172 if (PointerTypeTakesAnyBlockArguments(DeclT
) ||
4173 PointerTypeTakesAnyObjCQualifiedType(DeclT
)) {
4174 // Replace the '^' with '*' for arguments.
4175 // Replace id<P> with id/*<>*/
4176 DeclLoc
= ND
->getLocation();
4177 startBuf
= SM
->getCharacterData(DeclLoc
);
4178 const char *argListBegin
, *argListEnd
;
4179 GetExtentOfArgList(startBuf
, argListBegin
, argListEnd
);
4180 while (argListBegin
< argListEnd
) {
4181 if (*argListBegin
== '^')
4183 else if (*argListBegin
== '<') {
4185 buf
+= *argListBegin
++;
4187 while (*argListBegin
!= '>') {
4188 buf
+= *argListBegin
++;
4191 buf
+= *argListBegin
;
4195 buf
+= *argListBegin
;
4202 ReplaceText(Start
, OrigLength
, buf
);
4208 /// SynthesizeByrefCopyDestroyHelper - This routine synthesizes:
4209 /// void __Block_byref_id_object_copy(struct Block_byref_id_object *dst,
4210 /// struct Block_byref_id_object *src) {
4211 /// _Block_object_assign (&_dest->object, _src->object,
4212 /// BLOCK_BYREF_CALLER | BLOCK_FIELD_IS_OBJECT
4213 /// [|BLOCK_FIELD_IS_WEAK]) // object
4214 /// _Block_object_assign(&_dest->object, _src->object,
4215 /// BLOCK_BYREF_CALLER | BLOCK_FIELD_IS_BLOCK
4216 /// [|BLOCK_FIELD_IS_WEAK]) // block
4219 /// void __Block_byref_id_object_dispose(struct Block_byref_id_object *_src) {
4220 /// _Block_object_dispose(_src->object,
4221 /// BLOCK_BYREF_CALLER | BLOCK_FIELD_IS_OBJECT
4222 /// [|BLOCK_FIELD_IS_WEAK]) // object
4223 /// _Block_object_dispose(_src->object,
4224 /// BLOCK_BYREF_CALLER | BLOCK_FIELD_IS_BLOCK
4225 /// [|BLOCK_FIELD_IS_WEAK]) // block
4228 std::string
RewriteObjC::SynthesizeByrefCopyDestroyHelper(VarDecl
*VD
,
4231 if (CopyDestroyCache
.count(flag
))
4233 CopyDestroyCache
.insert(flag
);
4234 S
= "static void __Block_byref_id_object_copy_";
4236 S
+= "(void *dst, void *src) {\n";
4238 // offset into the object pointer is computed as:
4239 // void * + void* + int + int + void* + void *
4241 static_cast<unsigned>(Context
->getTypeSize(Context
->IntTy
));
4242 unsigned VoidPtrSize
=
4243 static_cast<unsigned>(Context
->getTypeSize(Context
->VoidPtrTy
));
4245 unsigned offset
= (VoidPtrSize
*4 + IntSize
+ IntSize
)/Context
->getCharWidth();
4246 S
+= " _Block_object_assign((char*)dst + ";
4247 S
+= utostr(offset
);
4248 S
+= ", *(void * *) ((char*)src + ";
4249 S
+= utostr(offset
);
4254 S
+= "static void __Block_byref_id_object_dispose_";
4256 S
+= "(void *src) {\n";
4257 S
+= " _Block_object_dispose(*(void * *) ((char*)src + ";
4258 S
+= utostr(offset
);
4265 /// RewriteByRefVar - For each __block typex ND variable this routine transforms
4266 /// the declaration into:
4267 /// struct __Block_byref_ND {
4268 /// void *__isa; // NULL for everything except __weak pointers
4269 /// struct __Block_byref_ND *__forwarding;
4270 /// int32_t __flags;
4272 /// void *__Block_byref_id_object_copy; // If variable is __block ObjC object
4273 /// void *__Block_byref_id_object_dispose; // If variable is __block ObjC object
4277 /// It then replaces declaration of ND variable with:
4278 /// struct __Block_byref_ND ND = {__isa=0B, __forwarding=&ND, __flags=some_flag,
4279 /// __size=sizeof(struct __Block_byref_ND),
4280 /// ND=initializer-if-any};
4283 void RewriteObjC::RewriteByRefVar(VarDecl
*ND
) {
4284 // Insert declaration for the function in which block literal is
4286 if (CurFunctionDeclToDeclareForBlock
)
4287 RewriteBlockLiteralFunctionDecl(CurFunctionDeclToDeclareForBlock
);
4290 SourceLocation DeclLoc
= ND
->getTypeSpecStartLoc();
4291 if (DeclLoc
.isInvalid())
4292 // If type location is missing, it is because of missing type (a warning).
4293 // Use variable's location which is good for this case.
4294 DeclLoc
= ND
->getLocation();
4295 const char *startBuf
= SM
->getCharacterData(DeclLoc
);
4296 SourceLocation X
= ND
->getLocEnd();
4297 X
= SM
->getExpansionLoc(X
);
4298 const char *endBuf
= SM
->getCharacterData(X
);
4299 std::string
Name(ND
->getNameAsString());
4300 std::string ByrefType
;
4301 RewriteByRefString(ByrefType
, Name
, ND
, true);
4302 ByrefType
+= " {\n";
4303 ByrefType
+= " void *__isa;\n";
4304 RewriteByRefString(ByrefType
, Name
, ND
);
4305 ByrefType
+= " *__forwarding;\n";
4306 ByrefType
+= " int __flags;\n";
4307 ByrefType
+= " int __size;\n";
4308 // Add void *__Block_byref_id_object_copy;
4309 // void *__Block_byref_id_object_dispose; if needed.
4310 QualType Ty
= ND
->getType();
4311 bool HasCopyAndDispose
= Context
->BlockRequiresCopying(Ty
);
4312 if (HasCopyAndDispose
) {
4313 ByrefType
+= " void (*__Block_byref_id_object_copy)(void*, void*);\n";
4314 ByrefType
+= " void (*__Block_byref_id_object_dispose)(void*);\n";
4318 (void)convertBlockPointerToFunctionPointer(T
);
4319 T
.getAsStringInternal(Name
, Context
->getPrintingPolicy());
4321 ByrefType
+= " " + Name
+ ";\n";
4322 ByrefType
+= "};\n";
4323 // Insert this type in global scope. It is needed by helper function.
4324 SourceLocation FunLocStart
;
4326 FunLocStart
= CurFunctionDef
->getTypeSpecStartLoc();
4328 assert(CurMethodDef
&& "RewriteByRefVar - CurMethodDef is null");
4329 FunLocStart
= CurMethodDef
->getLocStart();
4331 InsertText(FunLocStart
, ByrefType
);
4332 if (Ty
.isObjCGCWeak()) {
4333 flag
|= BLOCK_FIELD_IS_WEAK
;
4337 if (HasCopyAndDispose
) {
4338 flag
= BLOCK_BYREF_CALLER
;
4339 QualType Ty
= ND
->getType();
4340 // FIXME. Handle __weak variable (BLOCK_FIELD_IS_WEAK) as well.
4341 if (Ty
->isBlockPointerType())
4342 flag
|= BLOCK_FIELD_IS_BLOCK
;
4344 flag
|= BLOCK_FIELD_IS_OBJECT
;
4345 std::string HF
= SynthesizeByrefCopyDestroyHelper(ND
, flag
);
4347 InsertText(FunLocStart
, HF
);
4350 // struct __Block_byref_ND ND =
4351 // {0, &ND, some_flag, __size=sizeof(struct __Block_byref_ND),
4352 // initializer-if-any};
4353 bool hasInit
= (ND
->getInit() != 0);
4355 if (HasCopyAndDispose
)
4356 flags
|= BLOCK_HAS_COPY_DISPOSE
;
4357 Name
= ND
->getNameAsString();
4359 RewriteByRefString(ByrefType
, Name
, ND
);
4360 std::string
ForwardingCastType("(");
4361 ForwardingCastType
+= ByrefType
+ " *)";
4363 ByrefType
+= " " + Name
+ " = {(void*)";
4364 ByrefType
+= utostr(isa
);
4365 ByrefType
+= "," + ForwardingCastType
+ "&" + Name
+ ", ";
4366 ByrefType
+= utostr(flags
);
4368 ByrefType
+= "sizeof(";
4369 RewriteByRefString(ByrefType
, Name
, ND
);
4371 if (HasCopyAndDispose
) {
4372 ByrefType
+= ", __Block_byref_id_object_copy_";
4373 ByrefType
+= utostr(flag
);
4374 ByrefType
+= ", __Block_byref_id_object_dispose_";
4375 ByrefType
+= utostr(flag
);
4377 ByrefType
+= "};\n";
4378 unsigned nameSize
= Name
.size();
4379 // for block or function pointer declaration. Name is aleady
4380 // part of the declaration.
4381 if (Ty
->isBlockPointerType() || Ty
->isFunctionPointerType())
4383 ReplaceText(DeclLoc
, endBuf
-startBuf
+nameSize
, ByrefType
);
4386 SourceLocation startLoc
;
4387 Expr
*E
= ND
->getInit();
4388 if (const CStyleCastExpr
*ECE
= dyn_cast
<CStyleCastExpr
>(E
))
4389 startLoc
= ECE
->getLParenLoc();
4391 startLoc
= E
->getLocStart();
4392 startLoc
= SM
->getExpansionLoc(startLoc
);
4393 endBuf
= SM
->getCharacterData(startLoc
);
4394 ByrefType
+= " " + Name
;
4395 ByrefType
+= " = {(void*)";
4396 ByrefType
+= utostr(isa
);
4397 ByrefType
+= "," + ForwardingCastType
+ "&" + Name
+ ", ";
4398 ByrefType
+= utostr(flags
);
4400 ByrefType
+= "sizeof(";
4401 RewriteByRefString(ByrefType
, Name
, ND
);
4403 if (HasCopyAndDispose
) {
4404 ByrefType
+= "__Block_byref_id_object_copy_";
4405 ByrefType
+= utostr(flag
);
4406 ByrefType
+= ", __Block_byref_id_object_dispose_";
4407 ByrefType
+= utostr(flag
);
4410 ReplaceText(DeclLoc
, endBuf
-startBuf
, ByrefType
);
4412 // Complete the newly synthesized compound expression by inserting a right
4413 // curly brace before the end of the declaration.
4414 // FIXME: This approach avoids rewriting the initializer expression. It
4415 // also assumes there is only one declarator. For example, the following
4416 // isn't currently supported by this routine (in general):
4418 // double __block BYREFVAR = 1.34, BYREFVAR2 = 1.37;
4420 const char *startInitializerBuf
= SM
->getCharacterData(startLoc
);
4421 const char *semiBuf
= strchr(startInitializerBuf
, ';');
4422 assert((*semiBuf
== ';') && "RewriteByRefVar: can't find ';'");
4423 SourceLocation semiLoc
=
4424 startLoc
.getLocWithOffset(semiBuf
-startInitializerBuf
);
4426 InsertText(semiLoc
, "}");
4431 void RewriteObjC::CollectBlockDeclRefInfo(BlockExpr
*Exp
) {
4432 // Add initializers for any closure decl refs.
4433 GetBlockDeclRefExprs(Exp
->getBody());
4434 if (BlockDeclRefs
.size()) {
4435 // Unique all "by copy" declarations.
4436 for (unsigned i
= 0; i
< BlockDeclRefs
.size(); i
++)
4437 if (!BlockDeclRefs
[i
]->getDecl()->hasAttr
<BlocksAttr
>()) {
4438 if (!BlockByCopyDeclsPtrSet
.count(BlockDeclRefs
[i
]->getDecl())) {
4439 BlockByCopyDeclsPtrSet
.insert(BlockDeclRefs
[i
]->getDecl());
4440 BlockByCopyDecls
.push_back(BlockDeclRefs
[i
]->getDecl());
4443 // Unique all "by ref" declarations.
4444 for (unsigned i
= 0; i
< BlockDeclRefs
.size(); i
++)
4445 if (BlockDeclRefs
[i
]->getDecl()->hasAttr
<BlocksAttr
>()) {
4446 if (!BlockByRefDeclsPtrSet
.count(BlockDeclRefs
[i
]->getDecl())) {
4447 BlockByRefDeclsPtrSet
.insert(BlockDeclRefs
[i
]->getDecl());
4448 BlockByRefDecls
.push_back(BlockDeclRefs
[i
]->getDecl());
4451 // Find any imported blocks...they will need special attention.
4452 for (unsigned i
= 0; i
< BlockDeclRefs
.size(); i
++)
4453 if (BlockDeclRefs
[i
]->getDecl()->hasAttr
<BlocksAttr
>() ||
4454 BlockDeclRefs
[i
]->getType()->isObjCObjectPointerType() ||
4455 BlockDeclRefs
[i
]->getType()->isBlockPointerType())
4456 ImportedBlockDecls
.insert(BlockDeclRefs
[i
]->getDecl());
4460 FunctionDecl
*RewriteObjC::SynthBlockInitFunctionDecl(StringRef name
) {
4461 IdentifierInfo
*ID
= &Context
->Idents
.get(name
);
4462 QualType FType
= Context
->getFunctionNoProtoType(Context
->VoidPtrTy
);
4463 return FunctionDecl::Create(*Context
, TUDecl
, SourceLocation(),
4464 SourceLocation(), ID
, FType
, 0, SC_Extern
,
4465 SC_None
, false, false);
4468 Stmt
*RewriteObjC::SynthBlockInitExpr(BlockExpr
*Exp
,
4469 const SmallVector
<DeclRefExpr
*, 8> &InnerBlockDeclRefs
) {
4470 const BlockDecl
*block
= Exp
->getBlockDecl();
4471 Blocks
.push_back(Exp
);
4473 CollectBlockDeclRefInfo(Exp
);
4475 // Add inner imported variables now used in current block.
4476 int countOfInnerDecls
= 0;
4477 if (!InnerBlockDeclRefs
.empty()) {
4478 for (unsigned i
= 0; i
< InnerBlockDeclRefs
.size(); i
++) {
4479 DeclRefExpr
*Exp
= InnerBlockDeclRefs
[i
];
4480 ValueDecl
*VD
= Exp
->getDecl();
4481 if (!VD
->hasAttr
<BlocksAttr
>() && !BlockByCopyDeclsPtrSet
.count(VD
)) {
4482 // We need to save the copied-in variables in nested
4483 // blocks because it is needed at the end for some of the API generations.
4484 // See SynthesizeBlockLiterals routine.
4485 InnerDeclRefs
.push_back(Exp
); countOfInnerDecls
++;
4486 BlockDeclRefs
.push_back(Exp
);
4487 BlockByCopyDeclsPtrSet
.insert(VD
);
4488 BlockByCopyDecls
.push_back(VD
);
4490 if (VD
->hasAttr
<BlocksAttr
>() && !BlockByRefDeclsPtrSet
.count(VD
)) {
4491 InnerDeclRefs
.push_back(Exp
); countOfInnerDecls
++;
4492 BlockDeclRefs
.push_back(Exp
);
4493 BlockByRefDeclsPtrSet
.insert(VD
);
4494 BlockByRefDecls
.push_back(VD
);
4497 // Find any imported blocks...they will need special attention.
4498 for (unsigned i
= 0; i
< InnerBlockDeclRefs
.size(); i
++)
4499 if (InnerBlockDeclRefs
[i
]->getDecl()->hasAttr
<BlocksAttr
>() ||
4500 InnerBlockDeclRefs
[i
]->getType()->isObjCObjectPointerType() ||
4501 InnerBlockDeclRefs
[i
]->getType()->isBlockPointerType())
4502 ImportedBlockDecls
.insert(InnerBlockDeclRefs
[i
]->getDecl());
4504 InnerDeclRefsCount
.push_back(countOfInnerDecls
);
4506 std::string FuncName
;
4509 FuncName
= CurFunctionDef
->getNameAsString();
4510 else if (CurMethodDef
)
4511 BuildUniqueMethodName(FuncName
, CurMethodDef
);
4512 else if (GlobalVarDecl
)
4513 FuncName
= std::string(GlobalVarDecl
->getNameAsString());
4515 std::string BlockNumber
= utostr(Blocks
.size()-1);
4517 std::string Tag
= "__" + FuncName
+ "_block_impl_" + BlockNumber
;
4518 std::string Func
= "__" + FuncName
+ "_block_func_" + BlockNumber
;
4520 // Get a pointer to the function type so we can cast appropriately.
4521 QualType BFT
= convertFunctionTypeOfBlocks(Exp
->getFunctionType());
4522 QualType FType
= Context
->getPointerType(BFT
);
4527 // Simulate a contructor call...
4528 FD
= SynthBlockInitFunctionDecl(Tag
);
4529 DeclRefExpr
*DRE
= new (Context
) DeclRefExpr(FD
, false, FType
, VK_RValue
,
4532 SmallVector
<Expr
*, 4> InitExprs
;
4534 // Initialize the block function.
4535 FD
= SynthBlockInitFunctionDecl(Func
);
4536 DeclRefExpr
*Arg
= new (Context
) DeclRefExpr(FD
, false, FD
->getType(),
4537 VK_LValue
, SourceLocation());
4538 CastExpr
*castExpr
= NoTypeInfoCStyleCastExpr(Context
, Context
->VoidPtrTy
,
4540 InitExprs
.push_back(castExpr
);
4542 // Initialize the block descriptor.
4543 std::string DescData
= "__" + FuncName
+ "_block_desc_" + BlockNumber
+ "_DATA";
4545 VarDecl
*NewVD
= VarDecl::Create(*Context
, TUDecl
,
4546 SourceLocation(), SourceLocation(),
4547 &Context
->Idents
.get(DescData
.c_str()),
4548 Context
->VoidPtrTy
, 0,
4549 SC_Static
, SC_None
);
4550 UnaryOperator
*DescRefExpr
=
4551 new (Context
) UnaryOperator(new (Context
) DeclRefExpr(NewVD
, false,
4556 Context
->getPointerType(Context
->VoidPtrTy
),
4557 VK_RValue
, OK_Ordinary
,
4559 InitExprs
.push_back(DescRefExpr
);
4561 // Add initializers for any closure decl refs.
4562 if (BlockDeclRefs
.size()) {
4564 // Output all "by copy" declarations.
4565 for (SmallVector
<ValueDecl
*,8>::iterator I
= BlockByCopyDecls
.begin(),
4566 E
= BlockByCopyDecls
.end(); I
!= E
; ++I
) {
4567 if (isObjCType((*I
)->getType())) {
4568 // FIXME: Conform to ABI ([[obj retain] autorelease]).
4569 FD
= SynthBlockInitFunctionDecl((*I
)->getName());
4570 Exp
= new (Context
) DeclRefExpr(FD
, false, FD
->getType(), VK_LValue
,
4572 if (HasLocalVariableExternalStorage(*I
)) {
4573 QualType QT
= (*I
)->getType();
4574 QT
= Context
->getPointerType(QT
);
4575 Exp
= new (Context
) UnaryOperator(Exp
, UO_AddrOf
, QT
, VK_RValue
,
4576 OK_Ordinary
, SourceLocation());
4578 } else if (isTopLevelBlockPointerType((*I
)->getType())) {
4579 FD
= SynthBlockInitFunctionDecl((*I
)->getName());
4580 Arg
= new (Context
) DeclRefExpr(FD
, false, FD
->getType(), VK_LValue
,
4582 Exp
= NoTypeInfoCStyleCastExpr(Context
, Context
->VoidPtrTy
,
4585 FD
= SynthBlockInitFunctionDecl((*I
)->getName());
4586 Exp
= new (Context
) DeclRefExpr(FD
, false, FD
->getType(), VK_LValue
,
4588 if (HasLocalVariableExternalStorage(*I
)) {
4589 QualType QT
= (*I
)->getType();
4590 QT
= Context
->getPointerType(QT
);
4591 Exp
= new (Context
) UnaryOperator(Exp
, UO_AddrOf
, QT
, VK_RValue
,
4592 OK_Ordinary
, SourceLocation());
4596 InitExprs
.push_back(Exp
);
4598 // Output all "by ref" declarations.
4599 for (SmallVector
<ValueDecl
*,8>::iterator I
= BlockByRefDecls
.begin(),
4600 E
= BlockByRefDecls
.end(); I
!= E
; ++I
) {
4601 ValueDecl
*ND
= (*I
);
4602 std::string
Name(ND
->getNameAsString());
4603 std::string RecName
;
4604 RewriteByRefString(RecName
, Name
, ND
, true);
4605 IdentifierInfo
*II
= &Context
->Idents
.get(RecName
.c_str()
4606 + sizeof("struct"));
4607 RecordDecl
*RD
= RecordDecl::Create(*Context
, TTK_Struct
, TUDecl
,
4608 SourceLocation(), SourceLocation(),
4610 assert(RD
&& "SynthBlockInitExpr(): Can't find RecordDecl");
4611 QualType castT
= Context
->getPointerType(Context
->getTagDeclType(RD
));
4613 FD
= SynthBlockInitFunctionDecl((*I
)->getName());
4614 Exp
= new (Context
) DeclRefExpr(FD
, false, FD
->getType(), VK_LValue
,
4616 bool isNestedCapturedVar
= false;
4618 for (BlockDecl::capture_const_iterator ci
= block
->capture_begin(),
4619 ce
= block
->capture_end(); ci
!= ce
; ++ci
) {
4620 const VarDecl
*variable
= ci
->getVariable();
4621 if (variable
== ND
&& ci
->isNested()) {
4622 assert (ci
->isByRef() &&
4623 "SynthBlockInitExpr - captured block variable is not byref");
4624 isNestedCapturedVar
= true;
4628 // captured nested byref variable has its address passed. Do not take
4629 // its address again.
4630 if (!isNestedCapturedVar
)
4631 Exp
= new (Context
) UnaryOperator(Exp
, UO_AddrOf
,
4632 Context
->getPointerType(Exp
->getType()),
4633 VK_RValue
, OK_Ordinary
, SourceLocation());
4634 Exp
= NoTypeInfoCStyleCastExpr(Context
, castT
, CK_BitCast
, Exp
);
4635 InitExprs
.push_back(Exp
);
4638 if (ImportedBlockDecls
.size()) {
4639 // generate BLOCK_HAS_COPY_DISPOSE(have helper funcs) | BLOCK_HAS_DESCRIPTOR
4640 int flag
= (BLOCK_HAS_COPY_DISPOSE
| BLOCK_HAS_DESCRIPTOR
);
4642 static_cast<unsigned>(Context
->getTypeSize(Context
->IntTy
));
4643 Expr
*FlagExp
= IntegerLiteral::Create(*Context
, llvm::APInt(IntSize
, flag
),
4644 Context
->IntTy
, SourceLocation());
4645 InitExprs
.push_back(FlagExp
);
4647 NewRep
= new (Context
) CallExpr(*Context
, DRE
, InitExprs
,
4648 FType
, VK_LValue
, SourceLocation());
4649 NewRep
= new (Context
) UnaryOperator(NewRep
, UO_AddrOf
,
4650 Context
->getPointerType(NewRep
->getType()),
4651 VK_RValue
, OK_Ordinary
, SourceLocation());
4652 NewRep
= NoTypeInfoCStyleCastExpr(Context
, FType
, CK_BitCast
,
4654 BlockDeclRefs
.clear();
4655 BlockByRefDecls
.clear();
4656 BlockByRefDeclsPtrSet
.clear();
4657 BlockByCopyDecls
.clear();
4658 BlockByCopyDeclsPtrSet
.clear();
4659 ImportedBlockDecls
.clear();
4663 bool RewriteObjC::IsDeclStmtInForeachHeader(DeclStmt
*DS
) {
4664 if (const ObjCForCollectionStmt
* CS
=
4665 dyn_cast
<ObjCForCollectionStmt
>(Stmts
.back()))
4666 return CS
->getElement() == DS
;
4670 //===----------------------------------------------------------------------===//
4671 // Function Body / Expression rewriting
4672 //===----------------------------------------------------------------------===//
4674 Stmt
*RewriteObjC::RewriteFunctionBodyOrGlobalInitializer(Stmt
*S
) {
4675 if (isa
<SwitchStmt
>(S
) || isa
<WhileStmt
>(S
) ||
4676 isa
<DoStmt
>(S
) || isa
<ForStmt
>(S
))
4678 else if (isa
<ObjCForCollectionStmt
>(S
)) {
4680 ObjCBcLabelNo
.push_back(++BcLabelCount
);
4683 // Pseudo-object operations and ivar references need special
4684 // treatment because we're going to recursively rewrite them.
4685 if (PseudoObjectExpr
*PseudoOp
= dyn_cast
<PseudoObjectExpr
>(S
)) {
4686 if (isa
<BinaryOperator
>(PseudoOp
->getSyntacticForm())) {
4687 return RewritePropertyOrImplicitSetter(PseudoOp
);
4689 return RewritePropertyOrImplicitGetter(PseudoOp
);
4691 } else if (ObjCIvarRefExpr
*IvarRefExpr
= dyn_cast
<ObjCIvarRefExpr
>(S
)) {
4692 return RewriteObjCIvarRefExpr(IvarRefExpr
);
4695 SourceRange OrigStmtRange
= S
->getSourceRange();
4697 // Perform a bottom up rewrite of all children.
4698 for (Stmt::child_range CI
= S
->children(); CI
; ++CI
)
4700 Stmt
*childStmt
= (*CI
);
4701 Stmt
*newStmt
= RewriteFunctionBodyOrGlobalInitializer(childStmt
);
4707 if (BlockExpr
*BE
= dyn_cast
<BlockExpr
>(S
)) {
4708 SmallVector
<DeclRefExpr
*, 8> InnerBlockDeclRefs
;
4709 llvm::SmallPtrSet
<const DeclContext
*, 8> InnerContexts
;
4710 InnerContexts
.insert(BE
->getBlockDecl());
4711 ImportedLocalExternalDecls
.clear();
4712 GetInnerBlockDeclRefExprs(BE
->getBody(),
4713 InnerBlockDeclRefs
, InnerContexts
);
4714 // Rewrite the block body in place.
4715 Stmt
*SaveCurrentBody
= CurrentBody
;
4716 CurrentBody
= BE
->getBody();
4718 // block literal on rhs of a property-dot-sytax assignment
4719 // must be replaced by its synthesize ast so getRewrittenText
4720 // works as expected. In this case, what actually ends up on RHS
4721 // is the blockTranscribed which is the helper function for the
4722 // block literal; as in: self.c = ^() {[ace ARR];};
4723 bool saveDisableReplaceStmt
= DisableReplaceStmt
;
4724 DisableReplaceStmt
= false;
4725 RewriteFunctionBodyOrGlobalInitializer(BE
->getBody());
4726 DisableReplaceStmt
= saveDisableReplaceStmt
;
4727 CurrentBody
= SaveCurrentBody
;
4729 ImportedLocalExternalDecls
.clear();
4730 // Now we snarf the rewritten text and stash it away for later use.
4731 std::string Str
= Rewrite
.getRewrittenText(BE
->getSourceRange());
4732 RewrittenBlockExprs
[BE
] = Str
;
4734 Stmt
*blockTranscribed
= SynthBlockInitExpr(BE
, InnerBlockDeclRefs
);
4736 //blockTranscribed->dump();
4737 ReplaceStmt(S
, blockTranscribed
);
4738 return blockTranscribed
;
4740 // Handle specific things.
4741 if (ObjCEncodeExpr
*AtEncode
= dyn_cast
<ObjCEncodeExpr
>(S
))
4742 return RewriteAtEncode(AtEncode
);
4744 if (ObjCSelectorExpr
*AtSelector
= dyn_cast
<ObjCSelectorExpr
>(S
))
4745 return RewriteAtSelector(AtSelector
);
4747 if (ObjCStringLiteral
*AtString
= dyn_cast
<ObjCStringLiteral
>(S
))
4748 return RewriteObjCStringLiteral(AtString
);
4750 if (ObjCMessageExpr
*MessExpr
= dyn_cast
<ObjCMessageExpr
>(S
)) {
4752 // Before we rewrite it, put the original message expression in a comment.
4753 SourceLocation startLoc
= MessExpr
->getLocStart();
4754 SourceLocation endLoc
= MessExpr
->getLocEnd();
4756 const char *startBuf
= SM
->getCharacterData(startLoc
);
4757 const char *endBuf
= SM
->getCharacterData(endLoc
);
4759 std::string messString
;
4760 messString
+= "// ";
4761 messString
.append(startBuf
, endBuf
-startBuf
+1);
4764 // FIXME: Missing definition of
4765 // InsertText(clang::SourceLocation, char const*, unsigned int).
4766 // InsertText(startLoc, messString.c_str(), messString.size());
4767 // Tried this, but it didn't work either...
4768 // ReplaceText(startLoc, 0, messString.c_str(), messString.size());
4770 return RewriteMessageExpr(MessExpr
);
4773 if (ObjCAtTryStmt
*StmtTry
= dyn_cast
<ObjCAtTryStmt
>(S
))
4774 return RewriteObjCTryStmt(StmtTry
);
4776 if (ObjCAtSynchronizedStmt
*StmtTry
= dyn_cast
<ObjCAtSynchronizedStmt
>(S
))
4777 return RewriteObjCSynchronizedStmt(StmtTry
);
4779 if (ObjCAtThrowStmt
*StmtThrow
= dyn_cast
<ObjCAtThrowStmt
>(S
))
4780 return RewriteObjCThrowStmt(StmtThrow
);
4782 if (ObjCProtocolExpr
*ProtocolExp
= dyn_cast
<ObjCProtocolExpr
>(S
))
4783 return RewriteObjCProtocolExpr(ProtocolExp
);
4785 if (ObjCForCollectionStmt
*StmtForCollection
=
4786 dyn_cast
<ObjCForCollectionStmt
>(S
))
4787 return RewriteObjCForCollectionStmt(StmtForCollection
,
4788 OrigStmtRange
.getEnd());
4789 if (BreakStmt
*StmtBreakStmt
=
4790 dyn_cast
<BreakStmt
>(S
))
4791 return RewriteBreakStmt(StmtBreakStmt
);
4792 if (ContinueStmt
*StmtContinueStmt
=
4793 dyn_cast
<ContinueStmt
>(S
))
4794 return RewriteContinueStmt(StmtContinueStmt
);
4796 // Need to check for protocol refs (id <P>, Foo <P> *) in variable decls
4798 if (DeclStmt
*DS
= dyn_cast
<DeclStmt
>(S
)) {
4799 // FIXME: What we're doing here is modifying the type-specifier that
4800 // precedes the first Decl. In the future the DeclGroup should have
4801 // a separate type-specifier that we can rewrite.
4802 // NOTE: We need to avoid rewriting the DeclStmt if it is within
4803 // the context of an ObjCForCollectionStmt. For example:
4804 // NSArray *someArray;
4805 // for (id <FooProtocol> index in someArray) ;
4806 // This is because RewriteObjCForCollectionStmt() does textual rewriting
4807 // and it depends on the original text locations/positions.
4808 if (Stmts
.empty() || !IsDeclStmtInForeachHeader(DS
))
4809 RewriteObjCQualifiedInterfaceTypes(*DS
->decl_begin());
4811 // Blocks rewrite rules.
4812 for (DeclStmt::decl_iterator DI
= DS
->decl_begin(), DE
= DS
->decl_end();
4815 if (ValueDecl
*ND
= dyn_cast
<ValueDecl
>(SD
)) {
4816 if (isTopLevelBlockPointerType(ND
->getType()))
4817 RewriteBlockPointerDecl(ND
);
4818 else if (ND
->getType()->isFunctionPointerType())
4819 CheckFunctionPointerDecl(ND
->getType(), ND
);
4820 if (VarDecl
*VD
= dyn_cast
<VarDecl
>(SD
)) {
4821 if (VD
->hasAttr
<BlocksAttr
>()) {
4822 static unsigned uniqueByrefDeclCount
= 0;
4823 assert(!BlockByRefDeclNo
.count(ND
) &&
4824 "RewriteFunctionBodyOrGlobalInitializer: Duplicate byref decl");
4825 BlockByRefDeclNo
[ND
] = uniqueByrefDeclCount
++;
4826 RewriteByRefVar(VD
);
4829 RewriteTypeOfDecl(VD
);
4832 if (TypedefNameDecl
*TD
= dyn_cast
<TypedefNameDecl
>(SD
)) {
4833 if (isTopLevelBlockPointerType(TD
->getUnderlyingType()))
4834 RewriteBlockPointerDecl(TD
);
4835 else if (TD
->getUnderlyingType()->isFunctionPointerType())
4836 CheckFunctionPointerDecl(TD
->getUnderlyingType(), TD
);
4841 if (CStyleCastExpr
*CE
= dyn_cast
<CStyleCastExpr
>(S
))
4842 RewriteObjCQualifiedInterfaceTypes(CE
);
4844 if (isa
<SwitchStmt
>(S
) || isa
<WhileStmt
>(S
) ||
4845 isa
<DoStmt
>(S
) || isa
<ForStmt
>(S
)) {
4846 assert(!Stmts
.empty() && "Statement stack is empty");
4847 assert ((isa
<SwitchStmt
>(Stmts
.back()) || isa
<WhileStmt
>(Stmts
.back()) ||
4848 isa
<DoStmt
>(Stmts
.back()) || isa
<ForStmt
>(Stmts
.back()))
4849 && "Statement stack mismatch");
4852 // Handle blocks rewriting.
4853 if (DeclRefExpr
*DRE
= dyn_cast
<DeclRefExpr
>(S
)) {
4854 ValueDecl
*VD
= DRE
->getDecl();
4855 if (VD
->hasAttr
<BlocksAttr
>())
4856 return RewriteBlockDeclRefExpr(DRE
);
4857 if (HasLocalVariableExternalStorage(VD
))
4858 return RewriteLocalVariableExternalStorage(DRE
);
4861 if (CallExpr
*CE
= dyn_cast
<CallExpr
>(S
)) {
4862 if (CE
->getCallee()->getType()->isBlockPointerType()) {
4863 Stmt
*BlockCall
= SynthesizeBlockCall(CE
, CE
->getCallee());
4864 ReplaceStmt(S
, BlockCall
);
4868 if (CStyleCastExpr
*CE
= dyn_cast
<CStyleCastExpr
>(S
)) {
4869 RewriteCastExpr(CE
);
4872 if (ImplicitCastExpr
*ICE
= dyn_cast
<ImplicitCastExpr
>(S
)) {
4873 CastExpr
*Replacement
= new (Context
) CastExpr(ICE
->getType(),
4876 // Get the new text.
4878 llvm::raw_string_ostream
Buf(SStr
);
4879 Replacement
->printPretty(Buf
);
4880 const std::string
&Str
= Buf
.str();
4882 printf("CAST = %s\n", &Str
[0]);
4883 InsertText(ICE
->getSubExpr()->getLocStart(), &Str
[0], Str
.size());
4888 // Return this stmt unmodified.
4892 void RewriteObjC::RewriteRecordBody(RecordDecl
*RD
) {
4893 for (RecordDecl::field_iterator i
= RD
->field_begin(),
4894 e
= RD
->field_end(); i
!= e
; ++i
) {
4896 if (isTopLevelBlockPointerType(FD
->getType()))
4897 RewriteBlockPointerDecl(FD
);
4898 if (FD
->getType()->isObjCQualifiedIdType() ||
4899 FD
->getType()->isObjCQualifiedInterfaceType())
4900 RewriteObjCQualifiedInterfaceTypes(FD
);
4904 /// HandleDeclInMainFile - This is called for each top-level decl defined in the
4905 /// main file of the input.
4906 void RewriteObjC::HandleDeclInMainFile(Decl
*D
) {
4907 switch (D
->getKind()) {
4908 case Decl::Function
: {
4909 FunctionDecl
*FD
= cast
<FunctionDecl
>(D
);
4910 if (FD
->isOverloadedOperator())
4913 // Since function prototypes don't have ParmDecl's, we check the function
4914 // prototype. This enables us to rewrite function declarations and
4915 // definitions using the same code.
4916 RewriteBlocksInFunctionProtoType(FD
->getType(), FD
);
4918 if (!FD
->isThisDeclarationADefinition())
4921 // FIXME: If this should support Obj-C++, support CXXTryStmt
4922 if (CompoundStmt
*Body
= dyn_cast_or_null
<CompoundStmt
>(FD
->getBody())) {
4923 CurFunctionDef
= FD
;
4924 CurFunctionDeclToDeclareForBlock
= FD
;
4927 cast_or_null
<CompoundStmt
>(RewriteFunctionBodyOrGlobalInitializer(Body
));
4930 if (PropParentMap
) {
4931 delete PropParentMap
;
4934 // This synthesizes and inserts the block "impl" struct, invoke function,
4935 // and any copy/dispose helper functions.
4936 InsertBlockLiteralsWithinFunction(FD
);
4938 CurFunctionDeclToDeclareForBlock
= 0;
4942 case Decl::ObjCMethod
: {
4943 ObjCMethodDecl
*MD
= cast
<ObjCMethodDecl
>(D
);
4944 if (CompoundStmt
*Body
= MD
->getCompoundBody()) {
4948 cast_or_null
<CompoundStmt
>(RewriteFunctionBodyOrGlobalInitializer(Body
));
4951 if (PropParentMap
) {
4952 delete PropParentMap
;
4955 InsertBlockLiteralsWithinMethod(MD
);
4960 case Decl::ObjCImplementation
: {
4961 ObjCImplementationDecl
*CI
= cast
<ObjCImplementationDecl
>(D
);
4962 ClassImplementation
.push_back(CI
);
4965 case Decl::ObjCCategoryImpl
: {
4966 ObjCCategoryImplDecl
*CI
= cast
<ObjCCategoryImplDecl
>(D
);
4967 CategoryImplementation
.push_back(CI
);
4971 VarDecl
*VD
= cast
<VarDecl
>(D
);
4972 RewriteObjCQualifiedInterfaceTypes(VD
);
4973 if (isTopLevelBlockPointerType(VD
->getType()))
4974 RewriteBlockPointerDecl(VD
);
4975 else if (VD
->getType()->isFunctionPointerType()) {
4976 CheckFunctionPointerDecl(VD
->getType(), VD
);
4977 if (VD
->getInit()) {
4978 if (CStyleCastExpr
*CE
= dyn_cast
<CStyleCastExpr
>(VD
->getInit())) {
4979 RewriteCastExpr(CE
);
4982 } else if (VD
->getType()->isRecordType()) {
4983 RecordDecl
*RD
= VD
->getType()->getAs
<RecordType
>()->getDecl();
4984 if (RD
->isCompleteDefinition())
4985 RewriteRecordBody(RD
);
4987 if (VD
->getInit()) {
4989 CurrentBody
= VD
->getInit();
4990 RewriteFunctionBodyOrGlobalInitializer(VD
->getInit());
4992 if (PropParentMap
) {
4993 delete PropParentMap
;
4996 SynthesizeBlockLiterals(VD
->getTypeSpecStartLoc(), VD
->getName());
4999 // This is needed for blocks.
5000 if (CStyleCastExpr
*CE
= dyn_cast
<CStyleCastExpr
>(VD
->getInit())) {
5001 RewriteCastExpr(CE
);
5006 case Decl::TypeAlias
:
5007 case Decl::Typedef
: {
5008 if (TypedefNameDecl
*TD
= dyn_cast
<TypedefNameDecl
>(D
)) {
5009 if (isTopLevelBlockPointerType(TD
->getUnderlyingType()))
5010 RewriteBlockPointerDecl(TD
);
5011 else if (TD
->getUnderlyingType()->isFunctionPointerType())
5012 CheckFunctionPointerDecl(TD
->getUnderlyingType(), TD
);
5016 case Decl::CXXRecord
:
5017 case Decl::Record
: {
5018 RecordDecl
*RD
= cast
<RecordDecl
>(D
);
5019 if (RD
->isCompleteDefinition())
5020 RewriteRecordBody(RD
);
5029 void RewriteObjC::HandleTranslationUnit(ASTContext
&C
) {
5030 if (Diags
.hasErrorOccurred())
5035 // Here's a great place to add any extra declarations that may be needed.
5036 // Write out meta data for each @protocol(<expr>).
5037 for (llvm::SmallPtrSet
<ObjCProtocolDecl
*,8>::iterator I
= ProtocolExprDecls
.begin(),
5038 E
= ProtocolExprDecls
.end(); I
!= E
; ++I
)
5039 RewriteObjCProtocolMetaData(*I
, "", "", Preamble
);
5041 InsertText(SM
->getLocForStartOfFile(MainFileID
), Preamble
, false);
5042 if (ClassImplementation
.size() || CategoryImplementation
.size())
5043 RewriteImplementations();
5045 // Get the buffer corresponding to MainFileID. If we haven't changed it, then
5047 if (const RewriteBuffer
*RewriteBuf
=
5048 Rewrite
.getRewriteBufferFor(MainFileID
)) {
5049 //printf("Changed:\n");
5050 *OutFile
<< std::string(RewriteBuf
->begin(), RewriteBuf
->end());
5052 llvm::errs() << "No changes\n";
5055 if (ClassImplementation
.size() || CategoryImplementation
.size() ||
5056 ProtocolExprDecls
.size()) {
5057 // Rewrite Objective-c meta data*
5058 std::string ResultStr
;
5059 RewriteMetaDataIntoBuffer(ResultStr
);
5061 *OutFile
<< ResultStr
;
5066 void RewriteObjCFragileABI::Initialize(ASTContext
&context
) {
5067 InitializeCommon(context
);
5069 // declaring objc_selector outside the parameter list removes a silly
5070 // scope related warning...
5072 Preamble
= "#pragma once\n";
5073 Preamble
+= "struct objc_selector; struct objc_class;\n";
5074 Preamble
+= "struct __rw_objc_super { struct objc_object *object; ";
5075 Preamble
+= "struct objc_object *superClass; ";
5076 if (LangOpts
.MicrosoftExt
) {
5077 // Add a constructor for creating temporary objects.
5078 Preamble
+= "__rw_objc_super(struct objc_object *o, struct objc_object *s) "
5080 Preamble
+= "object(o), superClass(s) {} ";
5083 Preamble
+= "#ifndef _REWRITER_typedef_Protocol\n";
5084 Preamble
+= "typedef struct objc_object Protocol;\n";
5085 Preamble
+= "#define _REWRITER_typedef_Protocol\n";
5086 Preamble
+= "#endif\n";
5087 if (LangOpts
.MicrosoftExt
) {
5088 Preamble
+= "#define __OBJC_RW_DLLIMPORT extern \"C\" __declspec(dllimport)\n";
5089 Preamble
+= "#define __OBJC_RW_STATICIMPORT extern \"C\"\n";
5091 Preamble
+= "#define __OBJC_RW_DLLIMPORT extern\n";
5092 Preamble
+= "__OBJC_RW_DLLIMPORT struct objc_object *objc_msgSend";
5093 Preamble
+= "(struct objc_object *, struct objc_selector *, ...);\n";
5094 Preamble
+= "__OBJC_RW_DLLIMPORT struct objc_object *objc_msgSendSuper";
5095 Preamble
+= "(struct objc_super *, struct objc_selector *, ...);\n";
5096 Preamble
+= "__OBJC_RW_DLLIMPORT struct objc_object* objc_msgSend_stret";
5097 Preamble
+= "(struct objc_object *, struct objc_selector *, ...);\n";
5098 Preamble
+= "__OBJC_RW_DLLIMPORT struct objc_object* objc_msgSendSuper_stret";
5099 Preamble
+= "(struct objc_super *, struct objc_selector *, ...);\n";
5100 Preamble
+= "__OBJC_RW_DLLIMPORT double objc_msgSend_fpret";
5101 Preamble
+= "(struct objc_object *, struct objc_selector *, ...);\n";
5102 Preamble
+= "__OBJC_RW_DLLIMPORT struct objc_object *objc_getClass";
5103 Preamble
+= "(const char *);\n";
5104 Preamble
+= "__OBJC_RW_DLLIMPORT struct objc_class *class_getSuperclass";
5105 Preamble
+= "(struct objc_class *);\n";
5106 Preamble
+= "__OBJC_RW_DLLIMPORT struct objc_object *objc_getMetaClass";
5107 Preamble
+= "(const char *);\n";
5108 Preamble
+= "__OBJC_RW_DLLIMPORT void objc_exception_throw(struct objc_object *);\n";
5109 Preamble
+= "__OBJC_RW_DLLIMPORT void objc_exception_try_enter(void *);\n";
5110 Preamble
+= "__OBJC_RW_DLLIMPORT void objc_exception_try_exit(void *);\n";
5111 Preamble
+= "__OBJC_RW_DLLIMPORT struct objc_object *objc_exception_extract(void *);\n";
5112 Preamble
+= "__OBJC_RW_DLLIMPORT int objc_exception_match";
5113 Preamble
+= "(struct objc_class *, struct objc_object *);\n";
5114 // @synchronized hooks.
5115 Preamble
+= "__OBJC_RW_DLLIMPORT int objc_sync_enter(struct objc_object *);\n";
5116 Preamble
+= "__OBJC_RW_DLLIMPORT int objc_sync_exit(struct objc_object *);\n";
5117 Preamble
+= "__OBJC_RW_DLLIMPORT Protocol *objc_getProtocol(const char *);\n";
5118 Preamble
+= "#ifndef __FASTENUMERATIONSTATE\n";
5119 Preamble
+= "struct __objcFastEnumerationState {\n\t";
5120 Preamble
+= "unsigned long state;\n\t";
5121 Preamble
+= "void **itemsPtr;\n\t";
5122 Preamble
+= "unsigned long *mutationsPtr;\n\t";
5123 Preamble
+= "unsigned long extra[5];\n};\n";
5124 Preamble
+= "__OBJC_RW_DLLIMPORT void objc_enumerationMutation(struct objc_object *);\n";
5125 Preamble
+= "#define __FASTENUMERATIONSTATE\n";
5126 Preamble
+= "#endif\n";
5127 Preamble
+= "#ifndef __NSCONSTANTSTRINGIMPL\n";
5128 Preamble
+= "struct __NSConstantStringImpl {\n";
5129 Preamble
+= " int *isa;\n";
5130 Preamble
+= " int flags;\n";
5131 Preamble
+= " char *str;\n";
5132 Preamble
+= " long length;\n";
5134 Preamble
+= "#ifdef CF_EXPORT_CONSTANT_STRING\n";
5135 Preamble
+= "extern \"C\" __declspec(dllexport) int __CFConstantStringClassReference[];\n";
5136 Preamble
+= "#else\n";
5137 Preamble
+= "__OBJC_RW_DLLIMPORT int __CFConstantStringClassReference[];\n";
5138 Preamble
+= "#endif\n";
5139 Preamble
+= "#define __NSCONSTANTSTRINGIMPL\n";
5140 Preamble
+= "#endif\n";
5142 Preamble
+= "#ifndef BLOCK_IMPL\n";
5143 Preamble
+= "#define BLOCK_IMPL\n";
5144 Preamble
+= "struct __block_impl {\n";
5145 Preamble
+= " void *isa;\n";
5146 Preamble
+= " int Flags;\n";
5147 Preamble
+= " int Reserved;\n";
5148 Preamble
+= " void *FuncPtr;\n";
5150 Preamble
+= "// Runtime copy/destroy helper functions (from Block_private.h)\n";
5151 Preamble
+= "#ifdef __OBJC_EXPORT_BLOCKS\n";
5152 Preamble
+= "extern \"C\" __declspec(dllexport) "
5153 "void _Block_object_assign(void *, const void *, const int);\n";
5154 Preamble
+= "extern \"C\" __declspec(dllexport) void _Block_object_dispose(const void *, const int);\n";
5155 Preamble
+= "extern \"C\" __declspec(dllexport) void *_NSConcreteGlobalBlock[32];\n";
5156 Preamble
+= "extern \"C\" __declspec(dllexport) void *_NSConcreteStackBlock[32];\n";
5157 Preamble
+= "#else\n";
5158 Preamble
+= "__OBJC_RW_DLLIMPORT void _Block_object_assign(void *, const void *, const int);\n";
5159 Preamble
+= "__OBJC_RW_DLLIMPORT void _Block_object_dispose(const void *, const int);\n";
5160 Preamble
+= "__OBJC_RW_DLLIMPORT void *_NSConcreteGlobalBlock[32];\n";
5161 Preamble
+= "__OBJC_RW_DLLIMPORT void *_NSConcreteStackBlock[32];\n";
5162 Preamble
+= "#endif\n";
5163 Preamble
+= "#endif\n";
5164 if (LangOpts
.MicrosoftExt
) {
5165 Preamble
+= "#undef __OBJC_RW_DLLIMPORT\n";
5166 Preamble
+= "#undef __OBJC_RW_STATICIMPORT\n";
5167 Preamble
+= "#ifndef KEEP_ATTRIBUTES\n"; // We use this for clang tests.
5168 Preamble
+= "#define __attribute__(X)\n";
5169 Preamble
+= "#endif\n";
5170 Preamble
+= "#define __weak\n";
5173 Preamble
+= "#define __block\n";
5174 Preamble
+= "#define __weak\n";
5176 // NOTE! Windows uses LLP64 for 64bit mode. So, cast pointer to long long
5177 // as this avoids warning in any 64bit/32bit compilation model.
5178 Preamble
+= "\n#define __OFFSETOFIVAR__(TYPE, MEMBER) ((long long) &((TYPE *)0)->MEMBER)\n";
5181 /// RewriteIvarOffsetComputation - This rutine synthesizes computation of
5183 void RewriteObjCFragileABI::RewriteIvarOffsetComputation(ObjCIvarDecl
*ivar
,
5184 std::string
&Result
) {
5185 if (ivar
->isBitField()) {
5186 // FIXME: The hack below doesn't work for bitfields. For now, we simply
5187 // place all bitfields at offset 0.
5190 Result
+= "__OFFSETOFIVAR__(struct ";
5191 Result
+= ivar
->getContainingInterface()->getNameAsString();
5192 if (LangOpts
.MicrosoftExt
)
5195 Result
+= ivar
->getNameAsString();
5200 /// RewriteObjCProtocolMetaData - Rewrite protocols meta-data.
5201 void RewriteObjCFragileABI::RewriteObjCProtocolMetaData(
5202 ObjCProtocolDecl
*PDecl
, StringRef prefix
,
5203 StringRef ClassName
, std::string
&Result
) {
5204 static bool objc_protocol_methods
= false;
5206 // Output struct protocol_methods holder of method selector and type.
5207 if (!objc_protocol_methods
&& PDecl
->hasDefinition()) {
5208 /* struct protocol_methods {
5213 Result
+= "\nstruct _protocol_methods {\n";
5214 Result
+= "\tstruct objc_selector *_cmd;\n";
5215 Result
+= "\tchar *method_types;\n";
5218 objc_protocol_methods
= true;
5220 // Do not synthesize the protocol more than once.
5221 if (ObjCSynthesizedProtocols
.count(PDecl
->getCanonicalDecl()))
5224 if (ObjCProtocolDecl
*Def
= PDecl
->getDefinition())
5227 if (PDecl
->instmeth_begin() != PDecl
->instmeth_end()) {
5228 unsigned NumMethods
= std::distance(PDecl
->instmeth_begin(),
5229 PDecl
->instmeth_end());
5230 /* struct _objc_protocol_method_list {
5231 int protocol_method_count;
5232 struct protocol_methods protocols[];
5235 Result
+= "\nstatic struct {\n";
5236 Result
+= "\tint protocol_method_count;\n";
5237 Result
+= "\tstruct _protocol_methods protocol_methods[";
5238 Result
+= utostr(NumMethods
);
5239 Result
+= "];\n} _OBJC_PROTOCOL_INSTANCE_METHODS_";
5240 Result
+= PDecl
->getNameAsString();
5241 Result
+= " __attribute__ ((used, section (\"__OBJC, __cat_inst_meth\")))= "
5242 "{\n\t" + utostr(NumMethods
) + "\n";
5244 // Output instance methods declared in this protocol.
5245 for (ObjCProtocolDecl::instmeth_iterator
5246 I
= PDecl
->instmeth_begin(), E
= PDecl
->instmeth_end();
5248 if (I
== PDecl
->instmeth_begin())
5249 Result
+= "\t ,{{(struct objc_selector *)\"";
5251 Result
+= "\t ,{(struct objc_selector *)\"";
5252 Result
+= (*I
)->getSelector().getAsString();
5253 std::string MethodTypeString
;
5254 Context
->getObjCEncodingForMethodDecl((*I
), MethodTypeString
);
5256 Result
+= MethodTypeString
;
5259 Result
+= "\t }\n};\n";
5262 // Output class methods declared in this protocol.
5263 unsigned NumMethods
= std::distance(PDecl
->classmeth_begin(),
5264 PDecl
->classmeth_end());
5265 if (NumMethods
> 0) {
5266 /* struct _objc_protocol_method_list {
5267 int protocol_method_count;
5268 struct protocol_methods protocols[];
5271 Result
+= "\nstatic struct {\n";
5272 Result
+= "\tint protocol_method_count;\n";
5273 Result
+= "\tstruct _protocol_methods protocol_methods[";
5274 Result
+= utostr(NumMethods
);
5275 Result
+= "];\n} _OBJC_PROTOCOL_CLASS_METHODS_";
5276 Result
+= PDecl
->getNameAsString();
5277 Result
+= " __attribute__ ((used, section (\"__OBJC, __cat_cls_meth\")))= "
5279 Result
+= utostr(NumMethods
);
5282 // Output instance methods declared in this protocol.
5283 for (ObjCProtocolDecl::classmeth_iterator
5284 I
= PDecl
->classmeth_begin(), E
= PDecl
->classmeth_end();
5286 if (I
== PDecl
->classmeth_begin())
5287 Result
+= "\t ,{{(struct objc_selector *)\"";
5289 Result
+= "\t ,{(struct objc_selector *)\"";
5290 Result
+= (*I
)->getSelector().getAsString();
5291 std::string MethodTypeString
;
5292 Context
->getObjCEncodingForMethodDecl((*I
), MethodTypeString
);
5294 Result
+= MethodTypeString
;
5297 Result
+= "\t }\n};\n";
5301 /* struct _objc_protocol {
5302 // Objective-C 1.0 extensions
5303 struct _objc_protocol_extension *isa;
5304 char *protocol_name;
5305 struct _objc_protocol **protocol_list;
5306 struct _objc_protocol_method_list *instance_methods;
5307 struct _objc_protocol_method_list *class_methods;
5310 static bool objc_protocol
= false;
5311 if (!objc_protocol
) {
5312 Result
+= "\nstruct _objc_protocol {\n";
5313 Result
+= "\tstruct _objc_protocol_extension *isa;\n";
5314 Result
+= "\tchar *protocol_name;\n";
5315 Result
+= "\tstruct _objc_protocol **protocol_list;\n";
5316 Result
+= "\tstruct _objc_protocol_method_list *instance_methods;\n";
5317 Result
+= "\tstruct _objc_protocol_method_list *class_methods;\n";
5320 objc_protocol
= true;
5323 Result
+= "\nstatic struct _objc_protocol _OBJC_PROTOCOL_";
5324 Result
+= PDecl
->getNameAsString();
5325 Result
+= " __attribute__ ((used, section (\"__OBJC, __protocol\")))= "
5327 Result
+= PDecl
->getNameAsString();
5328 Result
+= "\", 0, ";
5329 if (PDecl
->instmeth_begin() != PDecl
->instmeth_end()) {
5330 Result
+= "(struct _objc_protocol_method_list *)&_OBJC_PROTOCOL_INSTANCE_METHODS_";
5331 Result
+= PDecl
->getNameAsString();
5336 if (PDecl
->classmeth_begin() != PDecl
->classmeth_end()) {
5337 Result
+= "(struct _objc_protocol_method_list *)&_OBJC_PROTOCOL_CLASS_METHODS_";
5338 Result
+= PDecl
->getNameAsString();
5345 // Mark this protocol as having been generated.
5346 if (!ObjCSynthesizedProtocols
.insert(PDecl
->getCanonicalDecl()))
5347 llvm_unreachable("protocol already synthesized");
5351 void RewriteObjCFragileABI::RewriteObjCProtocolListMetaData(
5352 const ObjCList
<ObjCProtocolDecl
> &Protocols
,
5353 StringRef prefix
, StringRef ClassName
,
5354 std::string
&Result
) {
5355 if (Protocols
.empty()) return;
5357 for (unsigned i
= 0; i
!= Protocols
.size(); i
++)
5358 RewriteObjCProtocolMetaData(Protocols
[i
], prefix
, ClassName
, Result
);
5360 // Output the top lovel protocol meta-data for the class.
5361 /* struct _objc_protocol_list {
5362 struct _objc_protocol_list *next;
5364 struct _objc_protocol *class_protocols[];
5367 Result
+= "\nstatic struct {\n";
5368 Result
+= "\tstruct _objc_protocol_list *next;\n";
5369 Result
+= "\tint protocol_count;\n";
5370 Result
+= "\tstruct _objc_protocol *class_protocols[";
5371 Result
+= utostr(Protocols
.size());
5372 Result
+= "];\n} _OBJC_";
5374 Result
+= "_PROTOCOLS_";
5375 Result
+= ClassName
;
5376 Result
+= " __attribute__ ((used, section (\"__OBJC, __cat_cls_meth\")))= "
5378 Result
+= utostr(Protocols
.size());
5381 Result
+= "\t,{&_OBJC_PROTOCOL_";
5382 Result
+= Protocols
[0]->getNameAsString();
5385 for (unsigned i
= 1; i
!= Protocols
.size(); i
++) {
5386 Result
+= "\t ,&_OBJC_PROTOCOL_";
5387 Result
+= Protocols
[i
]->getNameAsString();
5390 Result
+= "\t }\n};\n";
5393 void RewriteObjCFragileABI::RewriteObjCClassMetaData(ObjCImplementationDecl
*IDecl
,
5394 std::string
&Result
) {
5395 ObjCInterfaceDecl
*CDecl
= IDecl
->getClassInterface();
5397 // Explicitly declared @interface's are already synthesized.
5398 if (CDecl
->isImplicitInterfaceDecl()) {
5399 // FIXME: Implementation of a class with no @interface (legacy) does not
5400 // produce correct synthesis as yet.
5401 RewriteObjCInternalStruct(CDecl
, Result
);
5404 // Build _objc_ivar_list metadata for classes ivars if needed
5405 unsigned NumIvars
= !IDecl
->ivar_empty()
5406 ? IDecl
->ivar_size()
5407 : (CDecl
? CDecl
->ivar_size() : 0);
5409 static bool objc_ivar
= false;
5411 /* struct _objc_ivar {
5417 Result
+= "\nstruct _objc_ivar {\n";
5418 Result
+= "\tchar *ivar_name;\n";
5419 Result
+= "\tchar *ivar_type;\n";
5420 Result
+= "\tint ivar_offset;\n";
5428 struct _objc_ivar ivar_list[nIvars];
5431 Result
+= "\nstatic struct {\n";
5432 Result
+= "\tint ivar_count;\n";
5433 Result
+= "\tstruct _objc_ivar ivar_list[";
5434 Result
+= utostr(NumIvars
);
5435 Result
+= "];\n} _OBJC_INSTANCE_VARIABLES_";
5436 Result
+= IDecl
->getNameAsString();
5437 Result
+= " __attribute__ ((used, section (\"__OBJC, __instance_vars\")))= "
5439 Result
+= utostr(NumIvars
);
5442 ObjCInterfaceDecl::ivar_iterator IVI
, IVE
;
5443 SmallVector
<ObjCIvarDecl
*, 8> IVars
;
5444 if (!IDecl
->ivar_empty()) {
5445 for (ObjCInterfaceDecl::ivar_iterator
5446 IV
= IDecl
->ivar_begin(), IVEnd
= IDecl
->ivar_end();
5448 IVars
.push_back(*IV
);
5449 IVI
= IDecl
->ivar_begin();
5450 IVE
= IDecl
->ivar_end();
5452 IVI
= CDecl
->ivar_begin();
5453 IVE
= CDecl
->ivar_end();
5455 Result
+= "\t,{{\"";
5456 Result
+= IVI
->getNameAsString();
5458 std::string TmpString
, StrEncoding
;
5459 Context
->getObjCEncodingForType(IVI
->getType(), TmpString
, *IVI
);
5460 QuoteDoublequotes(TmpString
, StrEncoding
);
5461 Result
+= StrEncoding
;
5463 RewriteIvarOffsetComputation(*IVI
, Result
);
5465 for (++IVI
; IVI
!= IVE
; ++IVI
) {
5466 Result
+= "\t ,{\"";
5467 Result
+= IVI
->getNameAsString();
5469 std::string TmpString
, StrEncoding
;
5470 Context
->getObjCEncodingForType(IVI
->getType(), TmpString
, *IVI
);
5471 QuoteDoublequotes(TmpString
, StrEncoding
);
5472 Result
+= StrEncoding
;
5474 RewriteIvarOffsetComputation(*IVI
, Result
);
5478 Result
+= "\t }\n};\n";
5481 // Build _objc_method_list for class's instance methods if needed
5482 SmallVector
<ObjCMethodDecl
*, 32>
5483 InstanceMethods(IDecl
->instmeth_begin(), IDecl
->instmeth_end());
5485 // If any of our property implementations have associated getters or
5486 // setters, produce metadata for them as well.
5487 for (ObjCImplDecl::propimpl_iterator Prop
= IDecl
->propimpl_begin(),
5488 PropEnd
= IDecl
->propimpl_end();
5489 Prop
!= PropEnd
; ++Prop
) {
5490 if (Prop
->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic
)
5492 if (!Prop
->getPropertyIvarDecl())
5494 ObjCPropertyDecl
*PD
= Prop
->getPropertyDecl();
5497 if (ObjCMethodDecl
*Getter
= PD
->getGetterMethodDecl())
5498 if (!Getter
->isDefined())
5499 InstanceMethods
.push_back(Getter
);
5500 if (PD
->isReadOnly())
5502 if (ObjCMethodDecl
*Setter
= PD
->getSetterMethodDecl())
5503 if (!Setter
->isDefined())
5504 InstanceMethods
.push_back(Setter
);
5506 RewriteObjCMethodsMetaData(InstanceMethods
.begin(), InstanceMethods
.end(),
5507 true, "", IDecl
->getName(), Result
);
5509 // Build _objc_method_list for class's class methods if needed
5510 RewriteObjCMethodsMetaData(IDecl
->classmeth_begin(), IDecl
->classmeth_end(),
5511 false, "", IDecl
->getName(), Result
);
5513 // Protocols referenced in class declaration?
5514 RewriteObjCProtocolListMetaData(CDecl
->getReferencedProtocols(),
5515 "CLASS", CDecl
->getName(), Result
);
5517 // Declaration of class/meta-class metadata
5518 /* struct _objc_class {
5519 struct _objc_class *isa; // or const char *root_class_name when metadata
5520 const char *super_class_name;
5525 struct _objc_ivar_list *ivars;
5526 struct _objc_method_list *methods;
5527 struct objc_cache *cache;
5528 struct objc_protocol_list *protocols;
5529 const char *ivar_layout;
5530 struct _objc_class_ext *ext;
5533 static bool objc_class
= false;
5535 Result
+= "\nstruct _objc_class {\n";
5536 Result
+= "\tstruct _objc_class *isa;\n";
5537 Result
+= "\tconst char *super_class_name;\n";
5538 Result
+= "\tchar *name;\n";
5539 Result
+= "\tlong version;\n";
5540 Result
+= "\tlong info;\n";
5541 Result
+= "\tlong instance_size;\n";
5542 Result
+= "\tstruct _objc_ivar_list *ivars;\n";
5543 Result
+= "\tstruct _objc_method_list *methods;\n";
5544 Result
+= "\tstruct objc_cache *cache;\n";
5545 Result
+= "\tstruct _objc_protocol_list *protocols;\n";
5546 Result
+= "\tconst char *ivar_layout;\n";
5547 Result
+= "\tstruct _objc_class_ext *ext;\n";
5552 // Meta-class metadata generation.
5553 ObjCInterfaceDecl
*RootClass
= 0;
5554 ObjCInterfaceDecl
*SuperClass
= CDecl
->getSuperClass();
5555 while (SuperClass
) {
5556 RootClass
= SuperClass
;
5557 SuperClass
= SuperClass
->getSuperClass();
5559 SuperClass
= CDecl
->getSuperClass();
5561 Result
+= "\nstatic struct _objc_class _OBJC_METACLASS_";
5562 Result
+= CDecl
->getNameAsString();
5563 Result
+= " __attribute__ ((used, section (\"__OBJC, __meta_class\")))= "
5564 "{\n\t(struct _objc_class *)\"";
5565 Result
+= (RootClass
? RootClass
->getNameAsString() : CDecl
->getNameAsString());
5570 Result
+= SuperClass
->getNameAsString();
5572 Result
+= CDecl
->getNameAsString();
5576 Result
+= ", 0, \"";
5577 Result
+= CDecl
->getNameAsString();
5580 // Set 'ivars' field for root class to 0. ObjC1 runtime does not use it.
5581 // 'info' field is initialized to CLS_META(2) for metaclass
5582 Result
+= ", 0,2, sizeof(struct _objc_class), 0";
5583 if (IDecl
->classmeth_begin() != IDecl
->classmeth_end()) {
5584 Result
+= "\n\t, (struct _objc_method_list *)&_OBJC_CLASS_METHODS_";
5585 Result
+= IDecl
->getNameAsString();
5590 if (CDecl
->protocol_begin() != CDecl
->protocol_end()) {
5591 Result
+= "\t,0, (struct _objc_protocol_list *)&_OBJC_CLASS_PROTOCOLS_";
5592 Result
+= CDecl
->getNameAsString();
5596 Result
+= "\t,0,0,0,0\n";
5599 // class metadata generation.
5600 Result
+= "\nstatic struct _objc_class _OBJC_CLASS_";
5601 Result
+= CDecl
->getNameAsString();
5602 Result
+= " __attribute__ ((used, section (\"__OBJC, __class\")))= "
5603 "{\n\t&_OBJC_METACLASS_";
5604 Result
+= CDecl
->getNameAsString();
5607 Result
+= SuperClass
->getNameAsString();
5609 Result
+= CDecl
->getNameAsString();
5613 Result
+= ", 0, \"";
5614 Result
+= CDecl
->getNameAsString();
5617 // 'info' field is initialized to CLS_CLASS(1) for class
5619 if (!ObjCSynthesizedStructs
.count(CDecl
))
5622 // class has size. Must synthesize its size.
5623 Result
+= ",sizeof(struct ";
5624 Result
+= CDecl
->getNameAsString();
5625 if (LangOpts
.MicrosoftExt
)
5630 Result
+= ", (struct _objc_ivar_list *)&_OBJC_INSTANCE_VARIABLES_";
5631 Result
+= CDecl
->getNameAsString();
5636 if (IDecl
->instmeth_begin() != IDecl
->instmeth_end()) {
5637 Result
+= ", (struct _objc_method_list *)&_OBJC_INSTANCE_METHODS_";
5638 Result
+= CDecl
->getNameAsString();
5639 Result
+= ", 0\n\t";
5643 if (CDecl
->protocol_begin() != CDecl
->protocol_end()) {
5644 Result
+= ", (struct _objc_protocol_list*)&_OBJC_CLASS_PROTOCOLS_";
5645 Result
+= CDecl
->getNameAsString();
5646 Result
+= ", 0,0\n";
5649 Result
+= ",0,0,0\n";
5653 void RewriteObjCFragileABI::RewriteMetaDataIntoBuffer(std::string
&Result
) {
5654 int ClsDefCount
= ClassImplementation
.size();
5655 int CatDefCount
= CategoryImplementation
.size();
5657 // For each implemented class, write out all its meta data.
5658 for (int i
= 0; i
< ClsDefCount
; i
++)
5659 RewriteObjCClassMetaData(ClassImplementation
[i
], Result
);
5661 // For each implemented category, write out all its meta data.
5662 for (int i
= 0; i
< CatDefCount
; i
++)
5663 RewriteObjCCategoryImplDecl(CategoryImplementation
[i
], Result
);
5665 // Write objc_symtab metadata
5673 void *defs[cls_def_cnt + cat_def_cnt];
5677 Result
+= "\nstruct _objc_symtab {\n";
5678 Result
+= "\tlong sel_ref_cnt;\n";
5679 Result
+= "\tSEL *refs;\n";
5680 Result
+= "\tshort cls_def_cnt;\n";
5681 Result
+= "\tshort cat_def_cnt;\n";
5682 Result
+= "\tvoid *defs[" + utostr(ClsDefCount
+ CatDefCount
)+ "];\n";
5685 Result
+= "static struct _objc_symtab "
5686 "_OBJC_SYMBOLS __attribute__((used, section (\"__OBJC, __symbols\")))= {\n";
5687 Result
+= "\t0, 0, " + utostr(ClsDefCount
)
5688 + ", " + utostr(CatDefCount
) + "\n";
5689 for (int i
= 0; i
< ClsDefCount
; i
++) {
5690 Result
+= "\t,&_OBJC_CLASS_";
5691 Result
+= ClassImplementation
[i
]->getNameAsString();
5695 for (int i
= 0; i
< CatDefCount
; i
++) {
5696 Result
+= "\t,&_OBJC_CATEGORY_";
5697 Result
+= CategoryImplementation
[i
]->getClassInterface()->getNameAsString();
5699 Result
+= CategoryImplementation
[i
]->getNameAsString();
5705 // Write objc_module metadata
5708 struct _objc_module {
5712 struct _objc_symtab *symtab;
5716 Result
+= "\nstruct _objc_module {\n";
5717 Result
+= "\tlong version;\n";
5718 Result
+= "\tlong size;\n";
5719 Result
+= "\tconst char *name;\n";
5720 Result
+= "\tstruct _objc_symtab *symtab;\n";
5722 Result
+= "static struct _objc_module "
5723 "_OBJC_MODULES __attribute__ ((used, section (\"__OBJC, __module_info\")))= {\n";
5724 Result
+= "\t" + utostr(OBJC_ABI_VERSION
) +
5725 ", sizeof(struct _objc_module), \"\", &_OBJC_SYMBOLS\n";
5728 if (LangOpts
.MicrosoftExt
) {
5729 if (ProtocolExprDecls
.size()) {
5730 Result
+= "#pragma section(\".objc_protocol$B\",long,read,write)\n";
5731 Result
+= "#pragma data_seg(push, \".objc_protocol$B\")\n";
5732 for (llvm::SmallPtrSet
<ObjCProtocolDecl
*,8>::iterator I
= ProtocolExprDecls
.begin(),
5733 E
= ProtocolExprDecls
.end(); I
!= E
; ++I
) {
5734 Result
+= "static struct _objc_protocol *_POINTER_OBJC_PROTOCOL_";
5735 Result
+= (*I
)->getNameAsString();
5736 Result
+= " = &_OBJC_PROTOCOL_";
5737 Result
+= (*I
)->getNameAsString();
5740 Result
+= "#pragma data_seg(pop)\n\n";
5742 Result
+= "#pragma section(\".objc_module_info$B\",long,read,write)\n";
5743 Result
+= "#pragma data_seg(push, \".objc_module_info$B\")\n";
5744 Result
+= "static struct _objc_module *_POINTER_OBJC_MODULES = ";
5745 Result
+= "&_OBJC_MODULES;\n";
5746 Result
+= "#pragma data_seg(pop)\n\n";
5750 /// RewriteObjCCategoryImplDecl - Rewrite metadata for each category
5752 void RewriteObjCFragileABI::RewriteObjCCategoryImplDecl(ObjCCategoryImplDecl
*IDecl
,
5753 std::string
&Result
) {
5754 ObjCInterfaceDecl
*ClassDecl
= IDecl
->getClassInterface();
5755 // Find category declaration for this implementation.
5756 ObjCCategoryDecl
*CDecl
;
5757 for (CDecl
= ClassDecl
->getCategoryList(); CDecl
;
5758 CDecl
= CDecl
->getNextClassCategory())
5759 if (CDecl
->getIdentifier() == IDecl
->getIdentifier())
5762 std::string FullCategoryName
= ClassDecl
->getNameAsString();
5763 FullCategoryName
+= '_';
5764 FullCategoryName
+= IDecl
->getNameAsString();
5766 // Build _objc_method_list for class's instance methods if needed
5767 SmallVector
<ObjCMethodDecl
*, 32>
5768 InstanceMethods(IDecl
->instmeth_begin(), IDecl
->instmeth_end());
5770 // If any of our property implementations have associated getters or
5771 // setters, produce metadata for them as well.
5772 for (ObjCImplDecl::propimpl_iterator Prop
= IDecl
->propimpl_begin(),
5773 PropEnd
= IDecl
->propimpl_end();
5774 Prop
!= PropEnd
; ++Prop
) {
5775 if (Prop
->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic
)
5777 if (!Prop
->getPropertyIvarDecl())
5779 ObjCPropertyDecl
*PD
= Prop
->getPropertyDecl();
5782 if (ObjCMethodDecl
*Getter
= PD
->getGetterMethodDecl())
5783 InstanceMethods
.push_back(Getter
);
5784 if (PD
->isReadOnly())
5786 if (ObjCMethodDecl
*Setter
= PD
->getSetterMethodDecl())
5787 InstanceMethods
.push_back(Setter
);
5789 RewriteObjCMethodsMetaData(InstanceMethods
.begin(), InstanceMethods
.end(),
5790 true, "CATEGORY_", FullCategoryName
.c_str(),
5793 // Build _objc_method_list for class's class methods if needed
5794 RewriteObjCMethodsMetaData(IDecl
->classmeth_begin(), IDecl
->classmeth_end(),
5795 false, "CATEGORY_", FullCategoryName
.c_str(),
5798 // Protocols referenced in class declaration?
5799 // Null CDecl is case of a category implementation with no category interface
5801 RewriteObjCProtocolListMetaData(CDecl
->getReferencedProtocols(), "CATEGORY",
5802 FullCategoryName
, Result
);
5803 /* struct _objc_category {
5804 char *category_name;
5806 struct _objc_method_list *instance_methods;
5807 struct _objc_method_list *class_methods;
5808 struct _objc_protocol_list *protocols;
5809 // Objective-C 1.0 extensions
5810 uint32_t size; // sizeof (struct _objc_category)
5811 struct _objc_property_list *instance_properties; // category's own
5816 static bool objc_category
= false;
5817 if (!objc_category
) {
5818 Result
+= "\nstruct _objc_category {\n";
5819 Result
+= "\tchar *category_name;\n";
5820 Result
+= "\tchar *class_name;\n";
5821 Result
+= "\tstruct _objc_method_list *instance_methods;\n";
5822 Result
+= "\tstruct _objc_method_list *class_methods;\n";
5823 Result
+= "\tstruct _objc_protocol_list *protocols;\n";
5824 Result
+= "\tunsigned int size;\n";
5825 Result
+= "\tstruct _objc_property_list *instance_properties;\n";
5827 objc_category
= true;
5829 Result
+= "\nstatic struct _objc_category _OBJC_CATEGORY_";
5830 Result
+= FullCategoryName
;
5831 Result
+= " __attribute__ ((used, section (\"__OBJC, __category\")))= {\n\t\"";
5832 Result
+= IDecl
->getNameAsString();
5833 Result
+= "\"\n\t, \"";
5834 Result
+= ClassDecl
->getNameAsString();
5837 if (IDecl
->instmeth_begin() != IDecl
->instmeth_end()) {
5838 Result
+= "\t, (struct _objc_method_list *)"
5839 "&_OBJC_CATEGORY_INSTANCE_METHODS_";
5840 Result
+= FullCategoryName
;
5844 Result
+= "\t, 0\n";
5845 if (IDecl
->classmeth_begin() != IDecl
->classmeth_end()) {
5846 Result
+= "\t, (struct _objc_method_list *)"
5847 "&_OBJC_CATEGORY_CLASS_METHODS_";
5848 Result
+= FullCategoryName
;
5852 Result
+= "\t, 0\n";
5854 if (CDecl
&& CDecl
->protocol_begin() != CDecl
->protocol_end()) {
5855 Result
+= "\t, (struct _objc_protocol_list *)&_OBJC_CATEGORY_PROTOCOLS_";
5856 Result
+= FullCategoryName
;
5860 Result
+= "\t, 0\n";
5861 Result
+= "\t, sizeof(struct _objc_category), 0\n};\n";
5864 // RewriteObjCMethodsMetaData - Rewrite methods metadata for instance or
5866 template<typename MethodIterator
>
5867 void RewriteObjCFragileABI::RewriteObjCMethodsMetaData(MethodIterator MethodBegin
,
5868 MethodIterator MethodEnd
,
5869 bool IsInstanceMethod
,
5871 StringRef ClassName
,
5872 std::string
&Result
) {
5873 if (MethodBegin
== MethodEnd
) return;
5875 if (!objc_impl_method
) {
5876 /* struct _objc_method {
5882 Result
+= "\nstruct _objc_method {\n";
5883 Result
+= "\tSEL _cmd;\n";
5884 Result
+= "\tchar *method_types;\n";
5885 Result
+= "\tvoid *_imp;\n";
5888 objc_impl_method
= true;
5891 // Build _objc_method_list for class's methods if needed
5894 struct _objc_method_list *next_method;
5896 struct _objc_method method_list[];
5899 unsigned NumMethods
= std::distance(MethodBegin
, MethodEnd
);
5900 Result
+= "\nstatic struct {\n";
5901 Result
+= "\tstruct _objc_method_list *next_method;\n";
5902 Result
+= "\tint method_count;\n";
5903 Result
+= "\tstruct _objc_method method_list[";
5904 Result
+= utostr(NumMethods
);
5905 Result
+= "];\n} _OBJC_";
5907 Result
+= IsInstanceMethod
? "INSTANCE" : "CLASS";
5908 Result
+= "_METHODS_";
5909 Result
+= ClassName
;
5910 Result
+= " __attribute__ ((used, section (\"__OBJC, __";
5911 Result
+= IsInstanceMethod
? "inst" : "cls";
5912 Result
+= "_meth\")))= ";
5913 Result
+= "{\n\t0, " + utostr(NumMethods
) + "\n";
5915 Result
+= "\t,{{(SEL)\"";
5916 Result
+= (*MethodBegin
)->getSelector().getAsString().c_str();
5917 std::string MethodTypeString
;
5918 Context
->getObjCEncodingForMethodDecl(*MethodBegin
, MethodTypeString
);
5920 Result
+= MethodTypeString
;
5921 Result
+= "\", (void *)";
5922 Result
+= MethodInternalNames
[*MethodBegin
];
5924 for (++MethodBegin
; MethodBegin
!= MethodEnd
; ++MethodBegin
) {
5925 Result
+= "\t ,{(SEL)\"";
5926 Result
+= (*MethodBegin
)->getSelector().getAsString().c_str();
5927 std::string MethodTypeString
;
5928 Context
->getObjCEncodingForMethodDecl(*MethodBegin
, MethodTypeString
);
5930 Result
+= MethodTypeString
;
5931 Result
+= "\", (void *)";
5932 Result
+= MethodInternalNames
[*MethodBegin
];
5935 Result
+= "\t }\n};\n";
5938 Stmt
*RewriteObjCFragileABI::RewriteObjCIvarRefExpr(ObjCIvarRefExpr
*IV
) {
5939 SourceRange OldRange
= IV
->getSourceRange();
5940 Expr
*BaseExpr
= IV
->getBase();
5942 // Rewrite the base, but without actually doing replaces.
5944 DisableReplaceStmtScope
S(*this);
5945 BaseExpr
= cast
<Expr
>(RewriteFunctionBodyOrGlobalInitializer(BaseExpr
));
5946 IV
->setBase(BaseExpr
);
5949 ObjCIvarDecl
*D
= IV
->getDecl();
5951 Expr
*Replacement
= IV
;
5953 if (BaseExpr
->getType()->isObjCObjectPointerType()) {
5954 const ObjCInterfaceType
*iFaceDecl
=
5955 dyn_cast
<ObjCInterfaceType
>(BaseExpr
->getType()->getPointeeType());
5956 assert(iFaceDecl
&& "RewriteObjCIvarRefExpr - iFaceDecl is null");
5957 // lookup which class implements the instance variable.
5958 ObjCInterfaceDecl
*clsDeclared
= 0;
5959 iFaceDecl
->getDecl()->lookupInstanceVariable(D
->getIdentifier(),
5961 assert(clsDeclared
&& "RewriteObjCIvarRefExpr(): Can't find class");
5963 // Synthesize an explicit cast to gain access to the ivar.
5964 std::string RecName
= clsDeclared
->getIdentifier()->getName();
5966 IdentifierInfo
*II
= &Context
->Idents
.get(RecName
);
5967 RecordDecl
*RD
= RecordDecl::Create(*Context
, TTK_Struct
, TUDecl
,
5968 SourceLocation(), SourceLocation(),
5970 assert(RD
&& "RewriteObjCIvarRefExpr(): Can't find RecordDecl");
5971 QualType castT
= Context
->getPointerType(Context
->getTagDeclType(RD
));
5972 CastExpr
*castExpr
= NoTypeInfoCStyleCastExpr(Context
, castT
,
5975 // Don't forget the parens to enforce the proper binding.
5976 ParenExpr
*PE
= new (Context
) ParenExpr(OldRange
.getBegin(),
5979 if (IV
->isFreeIvar() &&
5980 declaresSameEntity(CurMethodDef
->getClassInterface(), iFaceDecl
->getDecl())) {
5981 MemberExpr
*ME
= new (Context
) MemberExpr(PE
, true, D
,
5984 VK_LValue
, OK_Ordinary
);
5990 } else { // we are outside a method.
5991 assert(!IV
->isFreeIvar() && "Cannot have a free standing ivar outside a method");
5993 // Explicit ivar refs need to have a cast inserted.
5994 // FIXME: consider sharing some of this code with the code above.
5995 if (BaseExpr
->getType()->isObjCObjectPointerType()) {
5996 const ObjCInterfaceType
*iFaceDecl
=
5997 dyn_cast
<ObjCInterfaceType
>(BaseExpr
->getType()->getPointeeType());
5998 // lookup which class implements the instance variable.
5999 ObjCInterfaceDecl
*clsDeclared
= 0;
6000 iFaceDecl
->getDecl()->lookupInstanceVariable(D
->getIdentifier(),
6002 assert(clsDeclared
&& "RewriteObjCIvarRefExpr(): Can't find class");
6004 // Synthesize an explicit cast to gain access to the ivar.
6005 std::string RecName
= clsDeclared
->getIdentifier()->getName();
6007 IdentifierInfo
*II
= &Context
->Idents
.get(RecName
);
6008 RecordDecl
*RD
= RecordDecl::Create(*Context
, TTK_Struct
, TUDecl
,
6009 SourceLocation(), SourceLocation(),
6011 assert(RD
&& "RewriteObjCIvarRefExpr(): Can't find RecordDecl");
6012 QualType castT
= Context
->getPointerType(Context
->getTagDeclType(RD
));
6013 CastExpr
*castExpr
= NoTypeInfoCStyleCastExpr(Context
, castT
,
6016 // Don't forget the parens to enforce the proper binding.
6017 ParenExpr
*PE
= new (Context
) ParenExpr(IV
->getBase()->getLocStart(),
6018 IV
->getBase()->getLocEnd(), castExpr
);
6019 // Cannot delete IV->getBase(), since PE points to it.
6020 // Replace the old base with the cast. This is important when doing
6021 // embedded rewrites. For example, [newInv->_container addObject:0].
6026 ReplaceStmtWithRange(IV
, Replacement
, OldRange
);