25 #include "llvm/ADT/DenseSet.h"
26 #include "llvm/ADT/SmallPtrSet.h"
27 #include "llvm/ADT/StringExtras.h"
28 #include "llvm/Support/MemoryBuffer.h"
29 #include "llvm/Support/raw_ostream.h"
32 #ifdef CLANG_ENABLE_OBJC_REWRITER
34 using namespace clang;
54 BLOCK_NEEDS_FREE = (1 << 24),
57 BLOCK_IS_GC = (1 << 27),
59 BLOCK_HAS_DESCRIPTOR = (1 << 29)
61 static const int OBJC_ABI_VERSION = 7;
70 const char *MainFileStart, *MainFileEnd;
73 std::string InFileName;
74 std::unique_ptr<raw_ostream> OutFile;
79 unsigned RewriteFailedDiag;
81 unsigned NumObjCStringLiterals;
82 VarDecl *ConstantStringClassReference;
88 unsigned TryFinallyContainsReturnDiag;
109 SmallVector<ObjCImplementationDecl *, 8> ClassImplementation;
110 SmallVector<ObjCCategoryImplDecl *, 8> CategoryImplementation;
111 llvm::SmallPtrSet<ObjCInterfaceDecl*, 8> ObjCSynthesizedStructs;
112 llvm::SmallPtrSet<ObjCProtocolDecl*, 8> ObjCSynthesizedProtocols;
113 llvm::SmallPtrSet<ObjCInterfaceDecl*, 8> ObjCForwardDecls;
114 llvm::DenseMap<ObjCMethodDecl*, std::string> MethodInternalNames;
115 SmallVector<Stmt *, 32> Stmts;
116 SmallVector<int, 8> ObjCBcLabelNo;
118 llvm::SmallPtrSet<ObjCProtocolDecl *, 32> ProtocolExprDecls;
123 SmallVector<BlockExpr *, 32> Blocks;
124 SmallVector<int, 32> InnerDeclRefsCount;
125 SmallVector<DeclRefExpr *, 32> InnerDeclRefs;
127 SmallVector<DeclRefExpr *, 32> BlockDeclRefs;
130 SmallVector<ValueDecl *, 8> BlockByCopyDecls;
131 llvm::SmallPtrSet<ValueDecl *, 8> BlockByCopyDeclsPtrSet;
132 SmallVector<ValueDecl *, 8> BlockByRefDecls;
133 llvm::SmallPtrSet<ValueDecl *, 8> BlockByRefDeclsPtrSet;
134 llvm::DenseMap<ValueDecl *, unsigned> BlockByRefDeclNo;
135 llvm::SmallPtrSet<ValueDecl *, 8> ImportedBlockDecls;
136 llvm::SmallPtrSet<VarDecl *, 8> ImportedLocalExternalDecls;
138 llvm::DenseMap<BlockExpr *, std::string> RewrittenBlockExprs;
143 llvm::DenseMap<Stmt *, Stmt *> ReplacedNodes;
147 bool SilenceRewriteMacroWarning;
148 bool objc_impl_method;
150 bool DisableReplaceStmt;
151 class DisableReplaceStmtScope {
157 : R(R), SavedValue(R.DisableReplaceStmt) {
158 R.DisableReplaceStmt =
true;
161 ~DisableReplaceStmtScope() {
162 R.DisableReplaceStmt = SavedValue;
173 if (!
Class->isThisDeclarationADefinition()) {
174 RewriteForwardClassDecl(D);
180 if (!Proto->isThisDeclarationADefinition()) {
181 RewriteForwardProtocolDecl(D);
186 HandleTopLevelSingleDecl(*
I);
191 void HandleTopLevelSingleDecl(
Decl *D);
192 void HandleDeclInMainFile(
Decl *D);
193 RewriteObjC(std::string inFile, std::unique_ptr<raw_ostream> OS,
195 bool silenceMacroWarn);
199 void HandleTranslationUnit(
ASTContext &C)
override;
201 void ReplaceStmt(
Stmt *Old,
Stmt *New) {
202 ReplaceStmtWithRange(Old, New, Old->getSourceRange());
206 assert(Old !=
nullptr && New !=
nullptr &&
"Expected non-null Stmt's");
208 Stmt *ReplacingStmt = ReplacedNodes[Old];
212 if (DisableReplaceStmt)
216 int Size = Rewrite.getRangeSize(SrcRange);
219 << Old->getSourceRange();
224 llvm::raw_string_ostream
S(SStr);
226 const std::string &Str =
S.str();
229 if (!Rewrite.ReplaceText(SrcRange.
getBegin(), Size, Str)) {
230 ReplacedNodes[Old] = New;
233 if (SilenceRewriteMacroWarning)
236 << Old->getSourceRange();
240 bool InsertAfter =
true) {
242 if (!Rewrite.InsertText(Loc, Str, InsertAfter) ||
243 SilenceRewriteMacroWarning)
252 if (!Rewrite.ReplaceText(Start, OrigLength, Str) ||
253 SilenceRewriteMacroWarning)
261 void RewriteInclude();
263 void RewriteForwardClassDecl(
const SmallVectorImpl<Decl *> &DG);
265 const std::string &typedefString);
266 void RewriteImplementations();
271 void RewriteImplementationDecl(
Decl *Dcl);
274 void RewriteTypeIntoString(
QualType T, std::string &ResultStr,
276 void RewriteByRefString(std::string &ResultStr,
const std::string &
Name,
281 void RewriteForwardProtocolDecl(
const SmallVectorImpl<Decl *> &DG);
285 void RewriteBlockPointerType(std::string& Str,
QualType Type);
286 void RewriteBlockPointerTypeVariable(std::string& Str,
ValueDecl *VD);
288 void RewriteObjCQualifiedInterfaceTypes(
Decl *Dcl);
289 void RewriteTypeOfDecl(
VarDecl *VD);
290 void RewriteObjCQualifiedInterfaceTypes(
Expr *
E);
293 Stmt *RewriteFunctionBodyOrGlobalInitializer(
Stmt *
S);
301 void RewriteTryReturnStmts(
Stmt *
S);
302 void RewriteSyncReturnStmts(
Stmt *
S, std::string buf);
316 void RewriteBlockPointerDecl(
NamedDecl *VD);
317 void RewriteByRefVar(
VarDecl *VD);
325 void Initialize(
ASTContext &context)
override = 0;
328 virtual void RewriteMetaDataIntoBuffer(std::string &
Result) = 0;
344 virtual void RewriteIvarOffsetComputation(
ObjCIvarDecl *ivar,
350 ArrayRef<Expr *> Args,
356 SmallVectorImpl<QualType> &ArgTypes,
357 SmallVectorImpl<Expr*> &MsgExprs,
363 void SynthCountByEnumWithState(std::string &buf);
364 void SynthMsgSendFunctionDecl();
365 void SynthMsgSendSuperFunctionDecl();
366 void SynthMsgSendStretFunctionDecl();
367 void SynthMsgSendFpretFunctionDecl();
368 void SynthMsgSendSuperStretFunctionDecl();
369 void SynthGetClassFunctionDecl();
370 void SynthGetMetaClassFunctionDecl();
371 void SynthGetSuperClassFunctionDecl();
372 void SynthSelGetUidFunctionDecl();
373 void SynthSuperConstructorFunctionDecl();
375 std::string SynthesizeByrefCopyDestroyHelper(
VarDecl *VD,
int flag);
376 std::string SynthesizeBlockHelperFuncs(
BlockExpr *CE,
int i,
377 StringRef funcName, std::string Tag);
378 std::string SynthesizeBlockFunc(
BlockExpr *CE,
int i,
379 StringRef funcName, std::string Tag);
380 std::string SynthesizeBlockImpl(
BlockExpr *CE,
381 std::string Tag, std::string Desc);
382 std::string SynthesizeBlockDescriptor(std::string DescTag,
384 int i, StringRef funcName,
389 FunctionDecl *SynthBlockInitFunctionDecl(StringRef name);
391 const SmallVectorImpl<DeclRefExpr *> &InnerBlockDeclRefs);
395 void WarnAboutReturnGotoStmts(
Stmt *
S);
396 void HasReturnStmts(
Stmt *
S,
bool &hasReturns);
398 void InsertBlockLiteralsWithinFunction(
FunctionDecl *FD);
401 bool IsDeclStmtInForeachHeader(
DeclStmt *DS);
402 void CollectBlockDeclRefInfo(
BlockExpr *Exp);
403 void GetBlockDeclRefExprs(
Stmt *
S);
404 void GetInnerBlockDeclRefExprs(
Stmt *
S,
405 SmallVectorImpl<DeclRefExpr *> &InnerBlockDeclRefs,
406 llvm::SmallPtrSetImpl<const DeclContext *> &InnerContexts);
410 bool isTopLevelBlockPointerType(
QualType T) {
411 return isa<BlockPointerType>(T);
417 bool convertBlockPointerToFunctionPointer(
QualType &T) {
418 if (isTopLevelBlockPointerType(T)) {
426 bool needToScanForQualifiers(
QualType T);
428 QualType getConstantStringStructType();
430 bool BufferContainsPPDirectives(
const char *startBuf,
const char *endBuf);
432 void convertToUnqualifiedObjCType(
QualType &T) {
450 if (!LangOpts.ObjC1 && !LangOpts.ObjC2)
460 if (isa<ObjCInterfaceType>(PT->getPointeeType()) ||
461 PT->getPointeeType()->isObjCQualifiedIdType())
466 bool PointerTypeTakesAnyBlockArguments(
QualType QT);
467 bool PointerTypeTakesAnyObjCQualifiedType(
QualType QT);
468 void GetExtentOfArgList(
const char *
Name,
const char *&LParen,
469 const char *&RParen);
471 void QuoteDoublequotes(std::string &From, std::string &To) {
472 for (
unsigned i = 0; i < From.length(); i++) {
481 ArrayRef<QualType> args,
482 bool variadic =
false) {
509 RewriteObjCFragileABI(std::string inFile, std::unique_ptr<raw_ostream> OS,
511 bool silenceMacroWarn)
512 :
RewriteObjC(inFile, std::move(OS), D, LOpts, silenceMacroWarn) {}
514 ~RewriteObjCFragileABI()
override {}
515 void Initialize(
ASTContext &context)
override;
518 template<
typename MethodIterator>
519 void RewriteObjCMethodsMetaData(MethodIterator MethodBegin,
520 MethodIterator MethodEnd,
521 bool IsInstanceMethod,
526 StringRef prefix, StringRef ClassName,
527 std::string &
Result)
override;
528 void RewriteObjCProtocolListMetaData(
530 StringRef prefix, StringRef ClassName, std::string &
Result)
override;
532 std::string &
Result)
override;
533 void RewriteMetaDataIntoBuffer(std::string &
Result)
override;
535 std::string &
Result)
override;
539 std::string &
Result)
override;
544 void RewriteObjC::RewriteBlocksInFunctionProtoType(
QualType funcType,
547 = dyn_cast<FunctionProtoType>(funcType.
IgnoreParens())) {
548 for (
const auto &
I : fproto->param_types())
549 if (isTopLevelBlockPointerType(
I)) {
551 RewriteBlockPointerDecl(D);
559 if (PT && PointerTypeTakesAnyBlockArguments(funcType))
563 static bool IsHeaderFile(
const std::string &
Filename) {
564 std::string::size_type DotPos = Filename.rfind(
'.');
566 if (DotPos == std::string::npos) {
571 std::string Ext = std::string(Filename.begin()+DotPos+1, Filename.end());
574 return Ext ==
"h" || Ext ==
"hh" || Ext ==
"H";
579 bool silenceMacroWarn)
580 : Diags(D), LangOpts(LOpts), InFileName(inFile), OutFile(std::move(OS)),
581 SilenceRewriteMacroWarning(silenceMacroWarn) {
582 IsHeader = IsHeaderFile(inFile);
584 "rewriting sub-expression within a macro (may not be correct)");
585 TryFinallyContainsReturnDiag = Diags.getCustomDiagID(
587 "rewriter doesn't support user-specified control flow semantics "
588 "for @try/@finally (code may not execute properly)");
591 std::unique_ptr<ASTConsumer>
593 std::unique_ptr<raw_ostream> OS,
595 bool SilenceRewriteMacroWarning) {
596 return llvm::make_unique<RewriteObjCFragileABI>(
597 InFile, std::move(OS), Diags, LOpts, SilenceRewriteMacroWarning);
600 void RewriteObjC::InitializeCommon(
ASTContext &context) {
604 MsgSendFunctionDecl =
nullptr;
605 MsgSendSuperFunctionDecl =
nullptr;
606 MsgSendStretFunctionDecl =
nullptr;
607 MsgSendSuperStretFunctionDecl =
nullptr;
608 MsgSendFpretFunctionDecl =
nullptr;
609 GetClassFunctionDecl =
nullptr;
610 GetMetaClassFunctionDecl =
nullptr;
611 GetSuperClassFunctionDecl =
nullptr;
612 SelGetUidFunctionDecl =
nullptr;
613 CFStringFunctionDecl =
nullptr;
614 ConstantStringClassReference =
nullptr;
615 NSStringRecord =
nullptr;
616 CurMethodDef =
nullptr;
617 CurFunctionDef =
nullptr;
618 CurFunctionDeclToDeclareForBlock =
nullptr;
619 GlobalVarDecl =
nullptr;
620 SuperStructDecl =
nullptr;
621 ProtocolTypeDecl =
nullptr;
622 ConstantStringDecl =
nullptr;
624 SuperConstructorFunctionDecl =
nullptr;
625 NumObjCStringLiterals = 0;
626 PropParentMap =
nullptr;
627 CurrentBody =
nullptr;
628 DisableReplaceStmt =
false;
629 objc_impl_method =
false;
633 const llvm::MemoryBuffer *MainBuf =
SM->
getBuffer(MainFileID);
634 MainFileStart = MainBuf->getBufferStart();
635 MainFileEnd = MainBuf->getBufferEnd();
644 void RewriteObjC::HandleTopLevelSingleDecl(
Decl *D) {
645 if (Diags.hasErrorOccurred())
659 RewriteFunctionDecl(FD);
660 }
else if (
VarDecl *FVD = dyn_cast<VarDecl>(D)) {
662 if (FVD->getName() ==
"_NSConstantStringClassReference") {
663 ConstantStringClassReference = FVD;
667 if (
ID->isThisDeclarationADefinition())
668 RewriteInterfaceDecl(
ID);
670 RewriteCategoryDecl(CD);
672 if (PD->isThisDeclarationADefinition())
673 RewriteProtocolDecl(PD);
677 DIEnd = LSD->decls_end();
680 if (!IFace->isThisDeclarationADefinition()) {
681 SmallVector<Decl *, 8> DG;
684 if (isa<ObjCInterfaceDecl>(*DI) &&
685 !cast<ObjCInterfaceDecl>(*DI)->isThisDeclarationADefinition() &&
686 StartLoc == (*DI)->getLocStart())
692 }
while (DI != DIEnd);
693 RewriteForwardClassDecl(DG);
699 if (!Proto->isThisDeclarationADefinition()) {
700 SmallVector<Decl *, 8> DG;
703 if (isa<ObjCProtocolDecl>(*DI) &&
704 !cast<ObjCProtocolDecl>(*DI)->isThisDeclarationADefinition() &&
705 StartLoc == (*DI)->getLocStart())
711 }
while (DI != DIEnd);
712 RewriteForwardProtocolDecl(DG);
717 HandleTopLevelSingleDecl(*DI);
723 return HandleDeclInMainFile(D);
730 void RewriteObjC::RewriteInclude() {
733 const char *MainBufStart = MainBuf.begin();
734 const char *MainBufEnd = MainBuf.end();
735 size_t ImportLen = strlen(
"import");
738 for (
const char *BufPtr = MainBufStart; BufPtr < MainBufEnd; ++BufPtr) {
739 if (*BufPtr ==
'#') {
740 if (++BufPtr == MainBufEnd)
742 while (*BufPtr ==
' ' || *BufPtr ==
'\t')
743 if (++BufPtr == MainBufEnd)
745 if (!strncmp(BufPtr,
"import", ImportLen)) {
749 ReplaceText(ImportLoc, ImportLen,
"include");
756 static std::string getIvarAccessString(
ObjCIvarDecl *OID) {
761 S +=
"_IMPL *)self)->";
769 static bool objcGetPropertyDefined =
false;
770 static bool objcSetPropertyDefined =
false;
772 InsertText(startLoc,
"// ");
774 assert((*startBuf ==
'@') &&
"bogus @synthesize location");
775 const char *semiBuf = strchr(startBuf,
';');
776 assert((*semiBuf ==
';') &&
"@synthesize: can't find ';'");
791 bool GenGetProperty = !(Attributes & ObjCPropertyDecl::OBJC_PR_nonatomic) &&
792 (Attributes & (ObjCPropertyDecl::OBJC_PR_retain |
793 ObjCPropertyDecl::OBJC_PR_copy));
795 if (GenGetProperty && !objcGetPropertyDefined) {
796 objcGetPropertyDefined =
true;
798 Getr =
"\nextern \"C\" __declspec(dllimport) "
799 "id objc_getProperty(id, SEL, long, bool);\n";
806 if (GenGetProperty) {
819 for (
unsigned i = 0, e = FT->getNumParams(); i != e; ++i) {
821 std::string ParamStr =
825 if (FT->isVariadic()) {
826 if (FT->getNumParams())
835 Getr +=
"return (_TYPE)";
836 Getr +=
"objc_getProperty(self, _cmd, ";
837 RewriteIvarOffsetComputation(OID, Getr);
841 Getr +=
"return " + getIvarAccessString(OID);
843 InsertText(onePastSemiLoc, Getr);
851 bool GenSetProperty = Attributes & (ObjCPropertyDecl::OBJC_PR_retain |
852 ObjCPropertyDecl::OBJC_PR_copy);
853 if (GenSetProperty && !objcSetPropertyDefined) {
854 objcSetPropertyDefined =
true;
856 Setr =
"\nextern \"C\" __declspec(dllimport) "
857 "void objc_setProperty (id, SEL, long, id, bool, bool);\n";
865 if (GenSetProperty) {
866 Setr +=
"objc_setProperty (self, _cmd, ";
867 RewriteIvarOffsetComputation(OID, Setr);
871 if (Attributes & ObjCPropertyDecl::OBJC_PR_nonatomic)
875 if (Attributes & ObjCPropertyDecl::OBJC_PR_copy)
881 Setr += getIvarAccessString(OID) +
" = ";
885 InsertText(onePastSemiLoc, Setr);
889 std::string &typedefString) {
890 typedefString +=
"#ifndef _REWRITER_typedef_";
892 typedefString +=
"\n";
893 typedefString +=
"#define _REWRITER_typedef_";
895 typedefString +=
"\n";
896 typedefString +=
"typedef struct objc_object ";
898 typedefString +=
";\n#endif\n";
902 const std::string &typedefString) {
905 const char *semiPtr = strchr(startBuf,
';');
907 ReplaceText(startLoc, semiPtr-startBuf+1, typedefString);
910 void RewriteObjC::RewriteForwardClassDecl(
DeclGroupRef D) {
911 std::string typedefString;
914 if (I == D.
begin()) {
918 typedefString +=
"// @class ";
920 typedefString +=
";\n";
922 RewriteOneForwardClassDecl(ForwardDecl, typedefString);
925 RewriteForwardClassEpilogue(cast<ObjCInterfaceDecl>(*I), typedefString);
928 void RewriteObjC::RewriteForwardClassDecl(
const SmallVectorImpl<Decl *> &D) {
929 std::string typedefString;
930 for (
unsigned i = 0; i < D.size(); i++) {
933 typedefString +=
"// @class ";
935 typedefString +=
";\n";
937 RewriteOneForwardClassDecl(ForwardDecl, typedefString);
939 RewriteForwardClassEpilogue(cast<ObjCInterfaceDecl>(D[0]), typedefString);
942 void RewriteObjC::RewriteMethodDeclaration(
ObjCMethodDecl *Method) {
945 if (Method->isImplicit())
952 InsertText(LocStart,
"#if 0\n");
953 ReplaceText(LocEnd, 1,
";\n#endif\n");
955 InsertText(LocStart,
"// ");
962 ReplaceText(Loc, 0,
"// ");
970 ReplaceText(LocStart, 0,
"// ");
975 RewriteMethodDeclaration(I);
977 RewriteMethodDeclaration(I);
981 strlen(
"@end"),
"/* @end */");
989 ReplaceText(LocStart, 0,
"// ");
992 RewriteMethodDeclaration(I);
994 RewriteMethodDeclaration(I);
1000 ReplaceText(LocEnd, strlen(
"@end"),
"/* @end */");
1005 for (
const char *p = startBuf; p < endBuf; p++) {
1006 if (*p ==
'@' && !strncmp(p+1,
"optional", strlen(
"optional"))) {
1008 ReplaceText(OptionalLoc, strlen(
"@optional"),
"/* @optional */");
1011 else if (*p ==
'@' && !strncmp(p+1,
"required", strlen(
"required"))) {
1013 ReplaceText(OptionalLoc, strlen(
"@required"),
"/* @required */");
1019 void RewriteObjC::RewriteForwardProtocolDecl(
DeclGroupRef D) {
1022 llvm_unreachable(
"Invalid SourceLocation");
1024 ReplaceText(LocStart, 0,
"// ");
1028 RewriteObjC::RewriteForwardProtocolDecl(
const SmallVectorImpl<Decl *> &DG) {
1031 llvm_unreachable(
"Invalid SourceLocation");
1033 ReplaceText(LocStart, 0,
"// ");
1036 void RewriteObjC::RewriteTypeIntoString(
QualType T, std::string &ResultStr,
1061 std::string &ResultStr) {
1064 ResultStr +=
"\nstatic ";
1065 RewriteTypeIntoString(OMD->
getReturnType(), ResultStr, FPRetType);
1069 std::string NameStr;
1080 dyn_cast<ObjCCategoryImplDecl>(OMD->getDeclContext())) {
1087 int len = selString.size();
1088 for (
int i = 0; i < len; i++)
1089 if (selString[i] ==
':')
1091 NameStr += selString;
1094 MethodInternalNames[OMD] = NameStr;
1095 ResultStr += NameStr;
1104 if (!LangOpts.MicrosoftExt) {
1105 if (ObjCSynthesizedStructs.count(const_cast<ObjCInterfaceDecl*>(IDecl)))
1106 ResultStr +=
"struct ";
1116 ResultStr +=
" self, ";
1118 ResultStr +=
" _cmd";
1121 for (
const auto *PDecl : OMD->
parameters()) {
1123 if (PDecl->getType()->isObjCQualifiedIdType()) {
1130 (void)convertBlockPointerToFunctionPointer(QT);
1136 ResultStr +=
", ...";
1145 for (
unsigned i = 0, e = FT->getNumParams(); i != e; ++i) {
1146 if (i) ResultStr +=
", ";
1147 std::string ParamStr =
1149 ResultStr += ParamStr;
1151 if (FT->isVariadic()) {
1152 if (FT->getNumParams())
1163 void RewriteObjC::RewriteImplementationDecl(
Decl *OID) {
1167 InsertText(IMD ? IMD->getLocStart() : CID->getLocStart(),
"// ");
1169 for (
auto *OMD : IMD ? IMD->
instance_methods() : CID->instance_methods()) {
1170 std::string ResultStr;
1177 ReplaceText(LocStart, endBuf-startBuf, ResultStr);
1180 for (
auto *OMD : IMD ? IMD->
class_methods() : CID->class_methods()) {
1181 std::string ResultStr;
1188 ReplaceText(LocStart, endBuf-startBuf, ResultStr);
1190 for (
auto *I : IMD ? IMD->
property_impls() : CID->property_impls())
1191 RewritePropertyImplDecl(I, IMD, CID);
1193 InsertText(IMD ? IMD->getLocEnd() : CID->getLocEnd(),
"// ");
1197 std::string ResultStr;
1200 ResultStr =
"#ifndef _REWRITER_typedef_";
1203 ResultStr +=
"#define _REWRITER_typedef_";
1206 ResultStr +=
"typedef struct objc_object ";
1208 ResultStr +=
";\n#endif\n";
1212 RewriteObjCInternalStruct(ClassDecl, ResultStr);
1217 RewriteMethodDeclaration(I);
1219 RewriteMethodDeclaration(I);
1227 SourceRange OldRange = PseudoOp->getSourceRange();
1239 DisableReplaceStmtScope
S(*
this);
1245 Base = cast<OpaqueValueExpr>(Base)->getSourceExpr();
1246 Base = cast<Expr>(RewriteFunctionBodyOrGlobalInitializer(Base));
1251 RHS = cast<OpaqueValueExpr>(RHS)->getSourceExpr();
1252 RHS = cast<Expr>(RewriteFunctionBodyOrGlobalInitializer(RHS));
1256 SmallVector<SourceLocation, 1> SelLocs;
1261 case ObjCMessageExpr::Class:
1274 case ObjCMessageExpr::Instance:
1287 case ObjCMessageExpr::SuperClass:
1288 case ObjCMessageExpr::SuperInstance:
1305 ReplaceStmtWithRange(PseudoOp, Replacement, OldRange);
1310 SourceRange OldRange = PseudoOp->getSourceRange();
1319 Expr *Base =
nullptr;
1321 DisableReplaceStmtScope
S(*
this);
1326 Base = cast<OpaqueValueExpr>(Base)->getSourceExpr();
1327 Base = cast<Expr>(RewriteFunctionBodyOrGlobalInitializer(Base));
1332 SmallVector<SourceLocation, 1> SelLocs;
1333 SmallVector<Expr*, 1> Args;
1337 case ObjCMessageExpr::Class:
1350 case ObjCMessageExpr::Instance:
1363 case ObjCMessageExpr::SuperClass:
1364 case ObjCMessageExpr::SuperInstance:
1381 ReplaceStmtWithRange(PseudoOp, Replacement, OldRange);
1394 void RewriteObjC::SynthCountByEnumWithState(std::string &buf) {
1395 buf +=
"((unsigned int (*) (id, SEL, struct __objcFastEnumerationState *, "
1396 "id *, unsigned int))(void *)objc_msgSend)";
1398 buf +=
"((id)l_collection,\n\t\t";
1399 buf +=
"sel_registerName(\"countByEnumeratingWithState:objects:count:\"),";
1401 buf +=
"&enumState, "
1402 "(id *)__rw_items, (unsigned int)16)";
1409 if (Stmts.empty() || !isa<ObjCForCollectionStmt>(Stmts.back()))
1415 buf =
"goto __break_label_";
1416 buf += utostr(ObjCBcLabelNo.back());
1417 ReplaceText(startLoc, strlen(
"break"), buf);
1426 if (Stmts.empty() || !isa<ObjCForCollectionStmt>(Stmts.back()))
1432 buf =
"goto __continue_label_";
1433 buf += utostr(ObjCBcLabelNo.back());
1434 ReplaceText(startLoc, strlen(
"continue"), buf);
1473 assert(!Stmts.empty() &&
"ObjCForCollectionStmt - Statement stack empty");
1474 assert(isa<ObjCForCollectionStmt>(Stmts.back()) &&
1475 "ObjCForCollectionStmt Statement stack mismatch");
1476 assert(!ObjCBcLabelNo.empty() &&
1477 "ObjCForCollectionStmt - Label No stack empty");
1481 StringRef elementName;
1482 std::string elementTypeAsString;
1487 NamedDecl* D = cast<NamedDecl>(DS->getSingleDecl());
1488 QualType ElementType = cast<ValueDecl>(D)->getType();
1489 if (ElementType->isObjCQualifiedIdType() ||
1490 ElementType->isObjCQualifiedInterfaceType())
1492 elementTypeAsString =
"id";
1495 buf += elementTypeAsString;
1508 elementTypeAsString =
"id";
1514 buf +=
"struct __objcFastEnumerationState enumState = { 0 };\n\t";
1516 buf +=
"id __rw_items[16];\n\t";
1518 buf +=
"id l_collection = (id)";
1520 const char *startCollectionBuf = startBuf;
1521 startCollectionBuf += 3;
1522 startCollectionBuf = strchr(startCollectionBuf,
'(');
1523 startCollectionBuf++;
1525 while (*startCollectionBuf !=
' ' ||
1526 *(startCollectionBuf+1) !=
'i' || *(startCollectionBuf+2) !=
'n' ||
1527 (*(startCollectionBuf+3) !=
' ' &&
1528 *(startCollectionBuf+3) !=
'[' && *(startCollectionBuf+3) !=
'('))
1529 startCollectionBuf++;
1530 startCollectionBuf += 3;
1533 ReplaceText(startLoc, startCollectionBuf - startBuf, buf);
1551 buf +=
"unsigned long limit =\n\t\t";
1552 SynthCountByEnumWithState(buf);
1562 buf +=
"if (limit) {\n\t";
1563 buf +=
"unsigned long startMutations = *enumState.mutationsPtr;\n\t";
1564 buf +=
"do {\n\t\t";
1565 buf +=
"unsigned long counter = 0;\n\t\t";
1566 buf +=
"do {\n\t\t\t";
1567 buf +=
"if (startMutations != *enumState.mutationsPtr)\n\t\t\t\t";
1568 buf +=
"objc_enumerationMutation(l_collection);\n\t\t\t";
1571 buf += elementTypeAsString;
1572 buf +=
")enumState.itemsPtr[counter++];";
1574 ReplaceText(lparenLoc, 1, buf);
1588 buf +=
"__continue_label_";
1589 buf += utostr(ObjCBcLabelNo.back());
1592 buf +=
"} while (counter < limit);\n\t";
1593 buf +=
"} while (limit = ";
1594 SynthCountByEnumWithState(buf);
1598 buf += elementTypeAsString;
1600 buf +=
"__break_label_";
1601 buf += utostr(ObjCBcLabelNo.back());
1604 buf +=
"else\n\t\t";
1607 buf += elementTypeAsString;
1613 if (isa<CompoundStmt>(S->
getBody())) {
1615 InsertText(endBodyLoc, buf);
1625 const char *semiBuf = strchr(stmtBuf,
';');
1626 assert(semiBuf &&
"Can't find ';'");
1628 InsertText(endBodyLoc, buf);
1631 ObjCBcLabelNo.pop_back();
1646 assert((*startBuf ==
'@') &&
"bogus @synchronized location");
1649 buf =
"objc_sync_enter((id)";
1650 const char *lparenBuf = startBuf;
1651 while (*lparenBuf !=
'(') lparenBuf++;
1652 ReplaceText(startLoc, lparenBuf-startBuf+1, buf);
1658 while (*endBuf !=
')') endBuf--;
1662 buf +=
"/* @try scope begin */ \n{ struct _objc_exception_data {\n";
1663 buf +=
"int buf[18/*32-bit i386*/];\n";
1664 buf +=
"char *pointers[4];} _stack;\n";
1665 buf +=
"id volatile _rethrow = 0;\n";
1666 buf +=
"objc_exception_try_enter(&_stack);\n";
1667 buf +=
"if (!_setjmp(_stack.buf)) /* @try block continue */\n";
1668 ReplaceText(rparenLoc, 1, buf);
1672 assert((*startBuf ==
'}') &&
"bogus @synchronized block");
1674 buf =
"}\nelse {\n";
1675 buf +=
" _rethrow = objc_exception_extract(&_stack);\n";
1677 buf +=
"{ /* implicit finally clause */\n";
1678 buf +=
" if (!_rethrow) objc_exception_try_exit(&_stack);\n";
1680 std::string syncBuf;
1681 syncBuf +=
" objc_sync_exit(";
1687 ? CK_BlockPointerToObjCPointerCast
1688 : CK_CPointerToObjCPointerCast;
1691 std::string syncExprBufS;
1692 llvm::raw_string_ostream syncExprBuf(syncExprBufS);
1693 assert(syncExpr !=
nullptr &&
"Expected non-null Expr");
1694 syncExpr->printPretty(syncExprBuf,
nullptr,
PrintingPolicy(LangOpts));
1695 syncBuf += syncExprBuf.str();
1699 buf +=
"\n if (_rethrow) objc_exception_throw(_rethrow);\n";
1703 ReplaceText(lastCurlyLoc, 1, buf);
1705 bool hasReturns =
false;
1713 void RewriteObjC::WarnAboutReturnGotoStmts(
Stmt *S)
1716 for (
Stmt *SubStmt : S->children())
1718 WarnAboutReturnGotoStmts(SubStmt);
1720 if (isa<ReturnStmt>(S) || isa<GotoStmt>(S)) {
1722 TryFinallyContainsReturnDiag);
1726 void RewriteObjC::HasReturnStmts(
Stmt *S,
bool &hasReturns)
1729 for (
Stmt *SubStmt : S->children())
1731 HasReturnStmts(SubStmt, hasReturns);
1733 if (isa<ReturnStmt>(S))
1737 void RewriteObjC::RewriteTryReturnStmts(
Stmt *S) {
1739 for (
Stmt *SubStmt : S->children())
1741 RewriteTryReturnStmts(SubStmt);
1743 if (isa<ReturnStmt>(S)) {
1746 const char *semiBuf = strchr(startBuf,
';');
1747 assert((*semiBuf ==
';') &&
"RewriteTryReturnStmts: can't find ';'");
1751 buf =
"{ objc_exception_try_exit(&_stack); return";
1753 ReplaceText(startLoc, 6, buf);
1754 InsertText(onePastSemiLoc,
"}");
1758 void RewriteObjC::RewriteSyncReturnStmts(
Stmt *S, std::string syncExitBuf) {
1760 for (
Stmt *SubStmt : S->children())
1762 RewriteSyncReturnStmts(SubStmt, syncExitBuf);
1764 if (isa<ReturnStmt>(S)) {
1768 const char *semiBuf = strchr(startBuf,
';');
1769 assert((*semiBuf ==
';') &&
"RewriteSyncReturnStmts: can't find ';'");
1773 buf =
"{ objc_exception_try_exit(&_stack);";
1777 ReplaceText(startLoc, 6, buf);
1778 InsertText(onePastSemiLoc,
"}");
1787 assert((*startBuf ==
'@') &&
"bogus @try location");
1791 buf =
"/* @try scope begin */ { struct _objc_exception_data {\n";
1792 buf +=
"int buf[18/*32-bit i386*/];\n";
1793 buf +=
"char *pointers[4];} _stack;\n";
1794 buf +=
"id volatile _rethrow = 0;\n";
1795 buf +=
"objc_exception_try_enter(&_stack);\n";
1796 buf +=
"if (!_setjmp(_stack.buf)) /* @try block continue */\n";
1798 ReplaceText(startLoc, 4, buf);
1803 assert((*startBuf ==
'}') &&
"bogus @try block");
1808 buf =
" /* @catch begin */ else {\n";
1809 buf +=
" id _caught = objc_exception_extract(&_stack);\n";
1810 buf +=
" objc_exception_try_enter (&_stack);\n";
1811 buf +=
" if (_setjmp(_stack.buf))\n";
1812 buf +=
" _rethrow = objc_exception_extract(&_stack);\n";
1813 buf +=
" else { /* @catch continue */";
1815 InsertText(startLoc, buf);
1817 buf =
"}\nelse {\n";
1818 buf +=
" _rethrow = objc_exception_extract(&_stack);\n";
1820 ReplaceText(lastCurlyLoc, 1, buf);
1822 Stmt *lastCatchBody =
nullptr;
1834 assert((*startBuf ==
'@') &&
"bogus @catch location");
1836 const char *lParenLoc = strchr(startBuf,
'(');
1844 "bogus @catch paren location");
1845 assert((*bodyBuf ==
'{') &&
"bogus @catch body location");
1847 buf +=
"1) { id _tmp = _caught;";
1848 Rewrite.ReplaceText(startLoc, bodyBuf-startBuf+1, buf);
1849 }
else if (catchDecl) {
1853 ReplaceText(startLoc, lParenLoc-startBuf+1, buf);
1859 buf +=
"objc_exception_match((struct objc_class *)objc_getClass(\"";
1861 buf +=
"\"), (struct objc_object *)_caught)) { ";
1862 ReplaceText(startLoc, lParenLoc-startBuf+1, buf);
1871 assert((*rParenBuf ==
')') &&
"bogus @catch paren location");
1872 assert((*bodyBuf ==
'{') &&
"bogus @catch body location");
1876 ReplaceText(rParenLoc, bodyBuf-rParenBuf+1,
" = _caught;");
1878 llvm_unreachable(
"@catch rewrite bug");
1882 if (lastCatchBody) {
1885 "bogus @catch body location");
1889 buf =
"} /* last catch end */\n";
1891 buf +=
" _rethrow = _caught;\n";
1892 buf +=
" objc_exception_try_exit(&_stack);\n";
1893 buf +=
"} } /* @catch end */\n";
1896 InsertText(bodyLoc, buf);
1899 lastCurlyLoc = lastCatchBody->getLocEnd();
1902 startLoc = finalStmt->getLocStart();
1904 assert((*startBuf ==
'@') &&
"bogus @finally start");
1906 ReplaceText(startLoc, 8,
"/* @finally */");
1908 Stmt *body = finalStmt->getFinallyBody();
1912 "bogus @finally body location");
1914 "bogus @finally body location");
1917 InsertText(startLoc,
" if (!_rethrow) objc_exception_try_exit(&_stack);\n");
1919 InsertText(endLoc,
" if (_rethrow) objc_exception_throw(_rethrow);\n");
1922 lastCurlyLoc = body->getLocEnd();
1927 buf =
"{ /* implicit finally clause */\n";
1928 buf +=
" if (!_rethrow) objc_exception_try_exit(&_stack);\n";
1929 buf +=
" if (_rethrow) objc_exception_throw(_rethrow);\n";
1931 ReplaceText(lastCurlyLoc, 1, buf);
1936 bool hasReturns =
false;
1943 InsertText(lastCurlyLoc,
" } /* @try scope end */\n");
1955 assert((*startBuf ==
'@') &&
"bogus @throw location");
1960 buf =
"objc_exception_throw(";
1962 buf =
"objc_exception_throw(_caught";
1965 const char *wBuf = strchr(startBuf,
'w');
1966 assert((*wBuf ==
'w') &&
"@throw: can't find 'w'");
1967 ReplaceText(startLoc, wBuf-startBuf+1, buf);
1969 const char *semiBuf = strchr(startBuf,
';');
1970 assert((*semiBuf ==
';') &&
"@throw: can't find ';'");
1972 ReplaceText(semiLoc, 1,
");");
1978 std::string StrEncoding;
1981 ReplaceStmt(Exp, Replacement);
1989 if (!SelGetUidFunctionDecl)
1990 SynthSelGetUidFunctionDecl();
1991 assert(SelGetUidFunctionDecl &&
"Can't find sel_registerName() decl");
1993 SmallVector<Expr*, 8> SelExprs;
1995 CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl,
1997 ReplaceStmt(Exp, SelExp);
2003 RewriteObjC::SynthesizeCallToFunctionDecl(
FunctionDecl *FD,
2004 ArrayRef<Expr *> Args,
2028 static bool scanForProtocolRefs(
const char *startBuf,
const char *endBuf,
2029 const char *&startRef,
const char *&endRef) {
2030 while (startBuf < endBuf) {
2031 if (*startBuf ==
'<')
2032 startRef = startBuf;
2033 if (*startBuf ==
'>') {
2034 if (startRef && *startRef ==
'<') {
2045 static void scanToNextArgument(
const char *&argRef) {
2047 while (*argRef !=
')' && (*argRef !=
',' || angle > 0)) {
2050 else if (*argRef ==
'>')
2054 assert(angle == 0 &&
"scanToNextArgument - bad protocol type syntax");
2057 bool RewriteObjC::needToScanForQualifiers(
QualType T) {
2070 return needToScanForQualifiers(ElemTy);
2075 void RewriteObjC::RewriteObjCQualifiedInterfaceTypes(
Expr *E) {
2077 if (needToScanForQualifiers(Type)) {
2081 Loc = ECE->getLParenLoc();
2082 EndLoc = ECE->getRParenLoc();
2084 Loc = E->getLocStart();
2085 EndLoc = E->getLocEnd();
2093 const char *startRef =
nullptr, *endRef =
nullptr;
2094 if (scanForProtocolRefs(startBuf, endBuf, startRef, endRef)) {
2099 InsertText(LessLoc,
"/*");
2100 InsertText(GreaterLoc,
"*/");
2105 void RewriteObjC::RewriteObjCQualifiedInterfaceTypes(
Decl *Dcl) {
2109 if (
VarDecl *VD = dyn_cast<VarDecl>(Dcl)) {
2110 Loc = VD->getLocation();
2113 else if (
FunctionDecl *FD = dyn_cast<FunctionDecl>(Dcl)) {
2114 Loc = FD->getLocation();
2118 assert(funcType &&
"missing function type");
2124 else if (
FieldDecl *FD = dyn_cast<FieldDecl>(Dcl)) {
2125 Loc = FD->getLocation();
2131 if (needToScanForQualifiers(Type)) {
2135 const char *startBuf = endBuf;
2136 while (*startBuf !=
';' && *startBuf !=
'<' && startBuf != MainFileStart)
2138 const char *startRef =
nullptr, *endRef =
nullptr;
2139 if (scanForProtocolRefs(startBuf, endBuf, startRef, endRef)) {
2144 InsertText(LessLoc,
"/*");
2145 InsertText(GreaterLoc,
"*/");
2152 const char *startFuncBuf = startBuf;
2157 const char *endBuf = startBuf;
2159 scanToNextArgument(endBuf);
2160 const char *startRef =
nullptr, *endRef =
nullptr;
2161 if (scanForProtocolRefs(startBuf, endBuf, startRef, endRef)) {
2168 InsertText(LessLoc,
"/*");
2169 InsertText(GreaterLoc,
"*/");
2171 startBuf = ++endBuf;
2176 while (*startBuf && *startBuf !=
')' && *startBuf !=
',')
2183 void RewriteObjC::RewriteTypeOfDecl(
VarDecl *ND) {
2185 const Type* TypePtr = QT->
getAs<Type>();
2186 if (!isa<TypeOfExprType>(TypePtr))
2188 while (isa<TypeOfExprType>(TypePtr)) {
2189 const TypeOfExprType *TypeOfExprTypePtr = cast<TypeOfExprType>(TypePtr);
2191 TypePtr = QT->
getAs<Type>();
2200 TypeAsString +=
" " + Name +
" = ";
2204 startLoc = ECE->getLParenLoc();
2206 startLoc = E->getLocStart();
2209 ReplaceText(DeclLoc, endBuf-startBuf-1, TypeAsString);
2215 ReplaceText(DeclLoc, endBuf-startBuf-1, TypeAsString);
2220 void RewriteObjC::SynthSelGetUidFunctionDecl() {
2222 SmallVector<QualType, 16> ArgTys;
2229 SelGetUidIdent, getFuncType,
2233 void RewriteObjC::RewriteFunctionDecl(
FunctionDecl *FD) {
2236 FD->
getName() ==
"sel_registerName") {
2237 SelGetUidFunctionDecl = FD;
2240 RewriteObjCQualifiedInterfaceTypes(FD);
2243 void RewriteObjC::RewriteBlockPointerType(std::string& Str,
QualType Type) {
2245 const char *argPtr = TypeString.c_str();
2246 if (!strchr(argPtr,
'^')) {
2251 Str += (*argPtr ==
'^' ?
'*' : *argPtr);
2257 void RewriteObjC::RewriteBlockPointerTypeVariable(std::string& Str,
2261 const char *argPtr = TypeString.c_str();
2286 void RewriteObjC::RewriteBlockLiteralFunctionDecl(
FunctionDecl *FD) {
2292 QualType Type = proto->getReturnType();
2297 unsigned numArgs = proto->getNumParams();
2298 for (
unsigned i = 0; i < numArgs; i++) {
2299 QualType ArgType = proto->getParamType(i);
2300 RewriteBlockPointerType(FdStr, ArgType);
2305 InsertText(FunLocStart, FdStr);
2306 CurFunctionDeclToDeclareForBlock =
nullptr;
2310 void RewriteObjC::SynthSuperConstructorFunctionDecl() {
2311 if (SuperConstructorFunctionDecl)
2314 SmallVector<QualType, 16> ArgTys;
2316 assert(!argT.
isNull() &&
"Can't find 'id' type");
2317 ArgTys.push_back(argT);
2318 ArgTys.push_back(argT);
2324 msgSendIdent, msgSendType,
2329 void RewriteObjC::SynthMsgSendFunctionDecl() {
2331 SmallVector<QualType, 16> ArgTys;
2333 assert(!argT.
isNull() &&
"Can't find 'id' type");
2334 ArgTys.push_back(argT);
2336 assert(!argT.
isNull() &&
"Can't find 'SEL' type");
2337 ArgTys.push_back(argT);
2343 msgSendIdent, msgSendType,
2348 void RewriteObjC::SynthMsgSendSuperFunctionDecl() {
2350 SmallVector<QualType, 16> ArgTys;
2355 assert(!argT.isNull() &&
"Can't build 'struct objc_super *' type");
2356 ArgTys.push_back(argT);
2358 assert(!argT.isNull() &&
"Can't find 'SEL' type");
2359 ArgTys.push_back(argT);
2365 msgSendIdent, msgSendType,
2370 void RewriteObjC::SynthMsgSendStretFunctionDecl() {
2372 SmallVector<QualType, 16> ArgTys;
2374 assert(!argT.
isNull() &&
"Can't find 'id' type");
2375 ArgTys.push_back(argT);
2377 assert(!argT.
isNull() &&
"Can't find 'SEL' type");
2378 ArgTys.push_back(argT);
2384 msgSendIdent, msgSendType,
2390 void RewriteObjC::SynthMsgSendSuperStretFunctionDecl() {
2393 SmallVector<QualType, 16> ArgTys;
2398 assert(!argT.isNull() &&
"Can't build 'struct objc_super *' type");
2399 ArgTys.push_back(argT);
2401 assert(!argT.isNull() &&
"Can't find 'SEL' type");
2402 ArgTys.push_back(argT);
2409 msgSendType,
nullptr,
2414 void RewriteObjC::SynthMsgSendFpretFunctionDecl() {
2416 SmallVector<QualType, 16> ArgTys;
2418 assert(!argT.
isNull() &&
"Can't find 'id' type");
2419 ArgTys.push_back(argT);
2421 assert(!argT.
isNull() &&
"Can't find 'SEL' type");
2422 ArgTys.push_back(argT);
2428 msgSendIdent, msgSendType,
2433 void RewriteObjC::SynthGetClassFunctionDecl() {
2435 SmallVector<QualType, 16> ArgTys;
2442 getClassIdent, getClassType,
2447 void RewriteObjC::SynthGetSuperClassFunctionDecl() {
2450 SmallVector<QualType, 16> ArgTys;
2458 getClassType,
nullptr,
2463 void RewriteObjC::SynthGetMetaClassFunctionDecl() {
2465 SmallVector<QualType, 16> ArgTys;
2472 getClassIdent, getClassType,
2477 assert(Exp !=
nullptr &&
"Expected non-null ObjCStringLiteral");
2478 QualType strType = getConstantStringStructType();
2480 std::string S =
"__NSConstantStringImpl_";
2482 std::string tmpName = InFileName;
2484 for (i=0; i < tmpName.length(); i++) {
2485 char c = tmpName.at(i);
2492 S += utostr(NumObjCStringLiterals++);
2494 Preamble +=
"static __NSConstantStringImpl " +
S;
2495 Preamble +=
" __attribute__ ((section (\"__DATA, __cfstring\"))) = {__CFConstantStringClassReference,";
2496 Preamble +=
"0x000007c8,";
2498 std::string prettyBufS;
2499 llvm::raw_string_ostream prettyBuf(prettyBufS);
2501 Preamble += prettyBuf.str();
2516 CK_CPointerToObjCPointerCast, Unop);
2517 ReplaceStmt(Exp, cast);
2523 QualType RewriteObjC::getSuperStructType() {
2524 if (!SuperStructDecl) {
2536 for (
unsigned i = 0; i < 2; ++i) {
2540 FieldTypes[i],
nullptr,
2546 SuperStructDecl->completeDefinition();
2551 QualType RewriteObjC::getConstantStringStructType() {
2552 if (!ConstantStringDecl) {
2568 for (
unsigned i = 0; i < 4; ++i) {
2573 FieldTypes[i],
nullptr,
2579 ConstantStringDecl->completeDefinition();
2587 SmallVectorImpl<QualType> &ArgTypes,
2588 SmallVectorImpl<Expr*> &MsgExprs,
2599 QualType castType = getSimpleFunctionType(returnType, ArgTypes,
2603 cast = NoTypeInfoCStyleCastExpr(
Context, castType, CK_BitCast,
2618 if (!SelGetUidFunctionDecl)
2619 SynthSelGetUidFunctionDecl();
2620 if (!MsgSendFunctionDecl)
2621 SynthMsgSendFunctionDecl();
2622 if (!MsgSendSuperFunctionDecl)
2623 SynthMsgSendSuperFunctionDecl();
2624 if (!MsgSendStretFunctionDecl)
2625 SynthMsgSendStretFunctionDecl();
2626 if (!MsgSendSuperStretFunctionDecl)
2627 SynthMsgSendSuperStretFunctionDecl();
2628 if (!MsgSendFpretFunctionDecl)
2629 SynthMsgSendFpretFunctionDecl();
2630 if (!GetClassFunctionDecl)
2631 SynthGetClassFunctionDecl();
2632 if (!GetSuperClassFunctionDecl)
2633 SynthGetSuperClassFunctionDecl();
2634 if (!GetMetaClassFunctionDecl)
2635 SynthGetMetaClassFunctionDecl();
2642 QualType resultType = mDecl->getReturnType();
2644 MsgSendStretFlavor = MsgSendStretFunctionDecl;
2646 MsgSendFlavor = MsgSendFpretFunctionDecl;
2650 SmallVector<Expr*, 8> MsgExprs;
2652 case ObjCMessageExpr::SuperClass: {
2653 MsgSendFlavor = MsgSendSuperFunctionDecl;
2654 if (MsgSendStretFlavor)
2655 MsgSendStretFlavor = MsgSendSuperStretFunctionDecl;
2656 assert(MsgSendFlavor &&
"MsgSendFlavor is NULL!");
2660 SmallVector<Expr*, 4> InitExprs;
2663 InitExprs.push_back(
2674 SmallVector<Expr*, 8> ClsExprs;
2676 CallExpr *Cls = SynthesizeCallToFunctionDecl(GetMetaClassFunctionDecl,
2677 ClsExprs, StartLoc, EndLoc);
2683 ClsExprs.push_back(ArgExpr);
2684 Cls = SynthesizeCallToFunctionDecl(GetSuperClassFunctionDecl, ClsExprs,
2688 InitExprs.push_back(
2689 NoTypeInfoCStyleCastExpr(
Context,
2693 QualType superType = getSuperStructType();
2696 if (LangOpts.MicrosoftExt) {
2697 SynthSuperConstructorFunctionDecl();
2715 SuperRep = NoTypeInfoCStyleCastExpr(
Context,
2717 CK_BitCast, SuperRep);
2734 MsgExprs.push_back(SuperRep);
2738 case ObjCMessageExpr::Class: {
2739 SmallVector<Expr*, 8> ClsExprs;
2743 ClsExprs.push_back(getStringLiteral(clsName->
getName()));
2744 CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl, ClsExprs,
2746 MsgExprs.push_back(Cls);
2750 case ObjCMessageExpr::SuperInstance:{
2751 MsgSendFlavor = MsgSendSuperFunctionDecl;
2752 if (MsgSendStretFlavor)
2753 MsgSendStretFlavor = MsgSendSuperStretFunctionDecl;
2754 assert(MsgSendFlavor &&
"MsgSendFlavor is NULL!");
2756 SmallVector<Expr*, 4> InitExprs;
2758 InitExprs.push_back(
2768 SmallVector<Expr*, 8> ClsExprs;
2770 CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl, ClsExprs,
2777 ClsExprs.push_back(ArgExpr);
2778 Cls = SynthesizeCallToFunctionDecl(GetSuperClassFunctionDecl, ClsExprs,
2783 InitExprs.push_back(
2788 QualType superType = getSuperStructType();
2791 if (LangOpts.MicrosoftExt) {
2792 SynthSuperConstructorFunctionDecl();
2795 false, superType, VK_LValue,
2809 SuperRep = NoTypeInfoCStyleCastExpr(
Context,
2811 CK_BitCast, SuperRep);
2823 MsgExprs.push_back(SuperRep);
2827 case ObjCMessageExpr::Instance: {
2832 recExpr = CE->getSubExpr();
2835 ? CK_BlockPointerToObjCPointerCast
2836 : CK_CPointerToObjCPointerCast;
2840 MsgExprs.push_back(recExpr);
2846 SmallVector<Expr*, 8> SelExprs;
2848 CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl,
2849 SelExprs, StartLoc, EndLoc);
2850 MsgExprs.push_back(SelExp);
2853 for (
unsigned i = 0; i < Exp->
getNumArgs(); i++) {
2859 if (needToScanForQualifiers(type))
2862 (void)convertBlockPointerToFunctionPointer(type);
2867 CK = CK_IntegralToBoolean;
2870 CK = CK_BlockPointerToObjCPointerCast;
2872 CK = CK_CPointerToObjCPointerCast;
2880 userExpr = NoTypeInfoCStyleCastExpr(
Context, type, CK, userExpr);
2883 else if (
CStyleCastExpr *CE = dyn_cast<CStyleCastExpr>(userExpr)) {
2884 if (CE->getType()->isObjCQualifiedIdType()) {
2885 while ((CE = dyn_cast<CStyleCastExpr>(userExpr)))
2886 userExpr = CE->getSubExpr();
2889 CK = CK_IntegralToPointer;
2891 CK = CK_BlockPointerToObjCPointerCast;
2893 CK = CK_CPointerToObjCPointerCast;
2901 MsgExprs.push_back(userExpr);
2909 SmallVector<QualType, 8> ArgTypes;
2913 if (MsgSendFlavor == MsgSendSuperFunctionDecl)
2925 (void)convertBlockPointerToFunctionPointer(t);
2926 ArgTypes.push_back(t);
2929 convertToUnqualifiedObjCType(returnType);
2930 (void)convertBlockPointerToFunctionPointer(returnType);
2945 cast = NoTypeInfoCStyleCastExpr(
Context,
2953 getSimpleFunctionType(returnType, ArgTypes, MD ? MD->isVariadic() :
true);
2955 cast = NoTypeInfoCStyleCastExpr(
Context, castType, CK_BitCast,
2964 Stmt *ReplacingStmt = CE;
2965 if (MsgSendStretFlavor) {
2971 CallExpr *STCE = SynthMsgSendStretCallExpr(MsgSendStretFlavor,
2972 msgSendType, returnType,
2989 llvm::APInt(IntSize, 8),
3006 return ReplacingStmt;
3014 ReplaceStmt(Exp, ReplacingStmt);
3017 return ReplacingStmt;
3021 QualType RewriteObjC::getProtocolType() {
3022 if (!ProtocolTypeDecl) {
3051 ReplaceStmt(Exp, castExpr);
3057 bool RewriteObjC::BufferContainsPPDirectives(
const char *startBuf,
3058 const char *endBuf) {
3059 while (startBuf < endBuf) {
3060 if (*startBuf ==
'#') {
3062 for (++startBuf; startBuf[0] ==
' ' || startBuf[0] ==
'\t'; ++startBuf)
3064 if (!strncmp(startBuf,
"if", strlen(
"if")) ||
3065 !strncmp(startBuf,
"ifdef", strlen(
"ifdef")) ||
3066 !strncmp(startBuf,
"ifndef", strlen(
"ifndef")) ||
3067 !strncmp(startBuf,
"define", strlen(
"define")) ||
3068 !strncmp(startBuf,
"undef", strlen(
"undef")) ||
3069 !strncmp(startBuf,
"else", strlen(
"else")) ||
3070 !strncmp(startBuf,
"elif", strlen(
"elif")) ||
3071 !strncmp(startBuf,
"endif", strlen(
"endif")) ||
3072 !strncmp(startBuf,
"pragma", strlen(
"pragma")) ||
3073 !strncmp(startBuf,
"include", strlen(
"include")) ||
3074 !strncmp(startBuf,
"import", strlen(
"import")) ||
3075 !strncmp(startBuf,
"include_next", strlen(
"include_next")))
3086 std::string &Result) {
3087 assert(CDecl &&
"Class missing in SynthesizeObjCInternalStruct");
3088 assert(CDecl->
getName() !=
"" &&
3089 "Name missing in SynthesizeObjCInternalStruct");
3091 if (ObjCSynthesizedStructs.count(CDecl))
3104 (!RCDecl || !ObjCSynthesizedStructs.count(RCDecl))) {
3105 endBuf += Lexer::MeasureTokenLength(LocEnd, *
SM, LangOpts);
3106 ReplaceText(LocStart, endBuf-startBuf, Result);
3112 Result +=
"\nstruct ";
3114 if (LangOpts.MicrosoftExt)
3118 const char *cursor = strchr(startBuf,
'{');
3119 assert((cursor && endBuf)
3120 &&
"SynthesizeObjCInternalStruct - malformed @interface");
3136 if (BufferContainsPPDirectives(startBuf, cursor)) {
3140 endHeader += Lexer::MeasureTokenLength(L, *
SM, LangOpts);
3144 while (endHeader < cursor && *endHeader != '>
') endHeader++;
3147 // rewrite the original header
3148 ReplaceText(LocStart, endHeader-startBuf, Result);
3150 // rewrite the original header *without* disturbing the '{
'
3151 ReplaceText(LocStart, cursor-startBuf, Result);
3153 if (RCDecl && ObjCSynthesizedStructs.count(RCDecl)) {
3154 Result = "\n struct ";
3155 Result += RCDecl->getNameAsString();
3157 Result += RCDecl->getNameAsString();
3158 Result += "_IVARS;\n";
3160 // insert the super class structure definition.
3161 SourceLocation OnePastCurly =
3162 LocStart.getLocWithOffset(cursor-startBuf+1);
3163 InsertText(OnePastCurly, Result);
3165 cursor++; // past '{
'
3167 // Now comment out any visibility specifiers.
3168 while (cursor < endBuf) {
3169 if (*cursor == '@
') {
3170 SourceLocation atLoc = LocStart.getLocWithOffset(cursor-startBuf);
3172 for (++cursor; cursor[0] == ' ' || cursor[0] == '\t
'; ++cursor)
3175 // FIXME: presence of @public, etc. inside comment results in
3176 // this transformation as well, which is still correct c-code.
3177 if (!strncmp(cursor, "public", strlen("public")) ||
3178 !strncmp(cursor, "private", strlen("private")) ||
3179 !strncmp(cursor, "package", strlen("package")) ||
3180 !strncmp(cursor, "protected", strlen("protected")))
3181 InsertText(atLoc, "// ");
3183 // FIXME: If there are cases where '<
' is used in ivar declaration part
3184 // of user code, then scan the ivar list and use needToScanForQualifiers
3185 // for type checking.
3186 else if (*cursor == '<
') {
3187 SourceLocation atLoc = LocStart.getLocWithOffset(cursor-startBuf);
3188 InsertText(atLoc, "/* ");
3189 cursor = strchr(cursor, '>
');
3191 atLoc = LocStart.getLocWithOffset(cursor-startBuf);
3192 InsertText(atLoc, " */");
3193 } else if (*cursor == '^
') { // rewrite block specifier.
3194 SourceLocation caretLoc = LocStart.getLocWithOffset(cursor-startBuf);
3195 ReplaceText(caretLoc, 1, "*");
3199 // Don't forget to add a
';'!!
3202 endBuf += Lexer::MeasureTokenLength(LocEnd, *
SM, LangOpts);
3203 Result +=
" {\n struct ";
3207 Result +=
"_IVARS;\n};\n";
3208 ReplaceText(LocStart, endBuf-startBuf, Result);
3211 if (!ObjCSynthesizedStructs.insert(CDecl).second)
3212 llvm_unreachable(
"struct already synthesize- SynthesizeObjCInternalStruct");
3222 void RewriteObjC::RewriteImplementations() {
3223 int ClsDefCount = ClassImplementation.size();
3224 int CatDefCount = CategoryImplementation.size();
3227 for (
int i = 0; i < ClsDefCount; i++)
3228 RewriteImplementationDecl(ClassImplementation[i]);
3230 for (
int i = 0; i < CatDefCount; i++)
3231 RewriteImplementationDecl(CategoryImplementation[i]);
3234 void RewriteObjC::RewriteByRefString(std::string &ResultStr,
3235 const std::string &Name,
3237 assert(BlockByRefDeclNo.count(VD) &&
3238 "RewriteByRefString: ByRef decl missing");
3240 ResultStr +=
"struct ";
3241 ResultStr +=
"__Block_byref_" + Name +
3242 "_" + utostr(BlockByRefDeclNo[VD]) ;
3245 static bool HasLocalVariableExternalStorage(
ValueDecl *VD) {
3246 if (
VarDecl *Var = dyn_cast<VarDecl>(VD))
3247 return (Var->isFunctionOrMethodVarDecl() && !Var->hasLocalStorage());
3251 std::string RewriteObjC::SynthesizeBlockFunc(
BlockExpr *CE,
int i,
3256 std::string StructRef =
"struct " + Tag;
3258 funcName.str() +
"_" +
"block_func_" + utostr(i);
3262 if (isa<FunctionNoProtoType>(AFT)) {
3265 S +=
"(" + StructRef +
" *__cself)";
3267 S +=
"(" + StructRef +
" *__cself)";
3270 assert(FT &&
"SynthesizeBlockFunc: No function proto");
3273 S += StructRef +
" *__cself, ";
3274 std::string ParamStr;
3278 ParamStr = (*AI)->getNameAsString();
3280 (void)convertBlockPointerToFunctionPointer(QT);
3295 E = BlockByRefDecls.end(); I !=
E; ++
I) {
3297 std::string Name = (*I)->getNameAsString();
3298 std::string TypeString;
3299 RewriteByRefString(TypeString, Name, (*I));
3301 Name = TypeString +
Name;
3302 S += Name +
" = __cself->" + (*I)->getNameAsString() +
"; // bound by ref\n";
3306 E = BlockByCopyDecls.end(); I !=
E; ++
I) {
3318 if (isTopLevelBlockPointerType((*I)->getType())) {
3319 RewriteBlockPointerTypeVariable(S, (*I));
3321 RewriteBlockPointerType(S, (*I)->getType());
3323 S +=
"__cself->" + (*I)->getNameAsString() +
"; // bound by copy\n";
3326 std::string Name = (*I)->getNameAsString();
3328 if (HasLocalVariableExternalStorage(*I))
3331 S += Name +
" = __cself->" +
3332 (*I)->getNameAsString() +
"; // bound by copy\n";
3335 std::string RewrittenStr = RewrittenBlockExprs[CE];
3336 const char *cstr = RewrittenStr.c_str();
3337 while (*cstr++ !=
'{') ;
3343 std::string RewriteObjC::SynthesizeBlockHelperFuncs(
BlockExpr *CE,
int i,
3346 std::string StructRef =
"struct " + Tag;
3347 std::string S =
"static void __";
3350 S +=
"_block_copy_" + utostr(i);
3351 S +=
"(" + StructRef;
3352 S +=
"*dst, " + StructRef;
3354 for (
ValueDecl *VD : ImportedBlockDecls) {
3355 S +=
"_Block_object_assign((void*)&dst->";
3357 S +=
", (void*)src->";
3359 if (BlockByRefDeclsPtrSet.count(VD))
3368 S +=
"\nstatic void __";
3370 S +=
"_block_dispose_" + utostr(i);
3371 S +=
"(" + StructRef;
3373 for (
ValueDecl *VD : ImportedBlockDecls) {
3374 S +=
"_Block_object_dispose((void*)src->";
3376 if (BlockByRefDeclsPtrSet.count(VD))
3387 std::string RewriteObjC::SynthesizeBlockImpl(
BlockExpr *CE, std::string Tag,
3389 std::string S =
"\nstruct " + Tag;
3392 S +=
" {\n struct __block_impl impl;\n";
3393 S +=
" struct " + Desc;
3396 Constructor +=
"(void *fp, ";
3397 Constructor +=
"struct " + Desc;
3398 Constructor +=
" *desc";
3400 if (BlockDeclRefs.size()) {
3403 E = BlockByCopyDecls.end(); I !=
E; ++
I) {
3405 std::string FieldName = (*I)->getNameAsString();
3406 std::string ArgName =
"_" + FieldName;
3417 if (isTopLevelBlockPointerType((*I)->getType())) {
3418 S +=
"struct __block_impl *";
3419 Constructor +=
", void *" + ArgName;
3422 if (HasLocalVariableExternalStorage(*I))
3426 Constructor +=
", " + ArgName;
3428 S += FieldName +
";\n";
3432 E = BlockByRefDecls.end(); I !=
E; ++
I) {
3434 std::string FieldName = (*I)->getNameAsString();
3435 std::string ArgName =
"_" + FieldName;
3437 std::string TypeString;
3438 RewriteByRefString(TypeString, FieldName, (*I));
3440 FieldName = TypeString + FieldName;
3441 ArgName = TypeString + ArgName;
3442 Constructor +=
", " + ArgName;
3444 S += FieldName +
"; // by ref\n";
3447 Constructor +=
", int flags=0)";
3449 bool firsTime =
true;
3451 E = BlockByCopyDecls.end(); I !=
E; ++
I) {
3452 std::string Name = (*I)->getNameAsString();
3454 Constructor +=
" : ";
3458 Constructor +=
", ";
3459 if (isTopLevelBlockPointerType((*I)->getType()))
3460 Constructor += Name +
"((struct __block_impl *)_" + Name +
")";
3462 Constructor += Name +
"(_" + Name +
")";
3466 E = BlockByRefDecls.end(); I !=
E; ++
I) {
3467 std::string Name = (*I)->getNameAsString();
3469 Constructor +=
" : ";
3473 Constructor +=
", ";
3474 Constructor += Name +
"(_" + Name +
"->__forwarding)";
3477 Constructor +=
" {\n";
3479 Constructor +=
" impl.isa = &_NSConcreteGlobalBlock;\n";
3481 Constructor +=
" impl.isa = &_NSConcreteStackBlock;\n";
3482 Constructor +=
" impl.Flags = flags;\n impl.FuncPtr = fp;\n";
3484 Constructor +=
" Desc = desc;\n";
3487 Constructor +=
", int flags=0) {\n";
3489 Constructor +=
" impl.isa = &_NSConcreteGlobalBlock;\n";
3491 Constructor +=
" impl.isa = &_NSConcreteStackBlock;\n";
3492 Constructor +=
" impl.Flags = flags;\n impl.FuncPtr = fp;\n";
3493 Constructor +=
" Desc = desc;\n";
3496 Constructor +=
"}\n";
3502 std::string RewriteObjC::SynthesizeBlockDescriptor(std::string DescTag,
3503 std::string ImplTag,
int i,
3506 std::string S =
"\nstatic struct " + DescTag;
3508 S +=
" {\n unsigned long reserved;\n";
3509 S +=
" unsigned long Block_size;\n";
3511 S +=
" void (*copy)(struct ";
3512 S += ImplTag; S +=
"*, struct ";
3513 S += ImplTag; S +=
"*);\n";
3515 S +=
" void (*dispose)(struct ";
3516 S += ImplTag; S +=
"*);\n";
3520 S += DescTag +
"_DATA = { 0, sizeof(struct ";
3523 S +=
", __" + FunName.str() +
"_block_copy_" + utostr(i);
3524 S +=
", __" + FunName.str() +
"_block_dispose_" + utostr(i);
3530 void RewriteObjC::SynthesizeBlockLiterals(
SourceLocation FunLocStart,
3531 StringRef FunName) {
3533 if (CurFunctionDeclToDeclareForBlock && !Blocks.empty())
3534 RewriteBlockLiteralFunctionDecl(CurFunctionDeclToDeclareForBlock);
3535 bool RewriteSC = (GlobalVarDecl &&
3537 GlobalVarDecl->getStorageClass() ==
SC_Static &&
3538 GlobalVarDecl->getType().getCVRQualifiers());
3540 std::string SC(
" void __");
3541 SC += GlobalVarDecl->getNameAsString();
3543 InsertText(FunLocStart, SC);
3547 for (
unsigned i = 0, count=0; i < Blocks.size(); i++) {
3548 CollectBlockDeclRefInfo(Blocks[i]);
3551 for (
int j = 0; j < InnerDeclRefsCount[i]; j++) {
3554 BlockDeclRefs.push_back(Exp);
3555 if (!VD->hasAttr<BlocksAttr>() && !BlockByCopyDeclsPtrSet.count(VD)) {
3556 BlockByCopyDeclsPtrSet.insert(VD);
3557 BlockByCopyDecls.push_back(VD);
3559 if (VD->hasAttr<BlocksAttr>() && !BlockByRefDeclsPtrSet.count(VD)) {
3560 BlockByRefDeclsPtrSet.insert(VD);
3561 BlockByRefDecls.push_back(VD);
3565 if (VD->hasAttr<BlocksAttr>() ||
3568 ImportedBlockDecls.insert(VD);
3571 std::string ImplTag =
"__" + FunName.str() +
"_block_impl_" + utostr(i);
3572 std::string DescTag =
"__" + FunName.str() +
"_block_desc_" + utostr(i);
3574 std::string CI = SynthesizeBlockImpl(Blocks[i], ImplTag, DescTag);
3576 InsertText(FunLocStart, CI);
3578 std::string CF = SynthesizeBlockFunc(Blocks[i], i, FunName, ImplTag);
3580 InsertText(FunLocStart, CF);
3582 if (ImportedBlockDecls.size()) {
3583 std::string HF = SynthesizeBlockHelperFuncs(Blocks[i], i, FunName, ImplTag);
3584 InsertText(FunLocStart, HF);
3586 std::string BD = SynthesizeBlockDescriptor(DescTag, ImplTag, i, FunName,
3587 ImportedBlockDecls.size() > 0);
3588 InsertText(FunLocStart, BD);
3590 BlockDeclRefs.clear();
3591 BlockByRefDecls.clear();
3592 BlockByRefDeclsPtrSet.clear();
3593 BlockByCopyDecls.clear();
3594 BlockByCopyDeclsPtrSet.clear();
3595 ImportedBlockDecls.clear();
3601 if (GlobalVarDecl->getStorageClass() ==
SC_Static)
3603 if (GlobalVarDecl->getType().isConstQualified())
3605 if (GlobalVarDecl->getType().isVolatileQualified())
3607 if (GlobalVarDecl->getType().isRestrictQualified())
3609 InsertText(FunLocStart, SC);
3613 InnerDeclRefsCount.clear();
3614 InnerDeclRefs.clear();
3615 RewrittenBlockExprs.clear();
3618 void RewriteObjC::InsertBlockLiteralsWithinFunction(
FunctionDecl *FD) {
3620 StringRef FuncName = FD->
getName();
3622 SynthesizeBlockLiterals(FunLocStart, FuncName);
3625 static void BuildUniqueMethodName(std::string &Name,
3631 std::string::size_type loc = 0;
3632 while ((loc = Name.find(
":", loc)) != std::string::npos)
3633 Name.replace(loc, 1,
"_");
3636 void RewriteObjC::InsertBlockLiteralsWithinMethod(
ObjCMethodDecl *MD) {
3640 std::string FuncName;
3641 BuildUniqueMethodName(FuncName, MD);
3642 SynthesizeBlockLiterals(FunLocStart, FuncName);
3645 void RewriteObjC::GetBlockDeclRefExprs(
Stmt *S) {
3646 for (
Stmt *SubStmt : S->children())
3648 if (
BlockExpr *CBE = dyn_cast<BlockExpr>(SubStmt))
3649 GetBlockDeclRefExprs(CBE->getBody());
3651 GetBlockDeclRefExprs(SubStmt);
3656 HasLocalVariableExternalStorage(DRE->
getDecl()))
3658 BlockDeclRefs.push_back(DRE);
3661 void RewriteObjC::GetInnerBlockDeclRefExprs(
Stmt *S,
3662 SmallVectorImpl<DeclRefExpr *> &InnerBlockDeclRefs,
3663 llvm::SmallPtrSetImpl<const DeclContext *> &InnerContexts) {
3664 for (
Stmt *SubStmt : S->children())
3666 if (
BlockExpr *CBE = dyn_cast<BlockExpr>(SubStmt)) {
3667 InnerContexts.insert(cast<DeclContext>(CBE->getBlockDecl()));
3668 GetInnerBlockDeclRefExprs(CBE->getBody(),
3673 GetInnerBlockDeclRefExprs(SubStmt, InnerBlockDeclRefs, InnerContexts);
3676 if (
DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(S)) {
3678 HasLocalVariableExternalStorage(DRE->
getDecl())) {
3679 if (!InnerContexts.count(DRE->
getDecl()->getDeclContext()))
3680 InnerBlockDeclRefs.push_back(DRE);
3682 if (Var->isFunctionOrMethodVarDecl())
3683 ImportedLocalExternalDecls.insert(Var);
3696 SmallVector<QualType, 8> ArgTypes;
3698 bool HasBlockType = convertBlockPointerToFunctionPointer(Res);
3704 if (convertBlockPointerToFunctionPointer(t))
3705 HasBlockType =
true;
3706 ArgTypes.push_back(t);
3713 FuncType = getSimpleFunctionType(Res, ArgTypes);
3718 Stmt *RewriteObjC::SynthesizeBlockCall(
CallExpr *Exp,
const Expr *BlockExp) {
3722 if (
const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(BlockExp)) {
3724 }
else if (
const MemberExpr *MExpr = dyn_cast<MemberExpr>(BlockExp)) {
3727 else if (
const ParenExpr *PRE = dyn_cast<ParenExpr>(BlockExp)) {
3728 return SynthesizeBlockCall(Exp, PRE->getSubExpr());
3730 else if (
const ImplicitCastExpr *IEXPR = dyn_cast<ImplicitCastExpr>(BlockExp))
3733 dyn_cast<ConditionalOperator>(BlockExp)) {
3734 Expr *LHSExp = CEXPR->getLHS();
3735 Stmt *LHSStmt = SynthesizeBlockCall(Exp, LHSExp);
3736 Expr *RHSExp = CEXPR->getRHS();
3737 Stmt *RHSStmt = SynthesizeBlockCall(Exp, RHSExp);
3738 Expr *CONDExp = CEXPR->getCond();
3745 }
else if (
const ObjCIvarRefExpr *IRE = dyn_cast<ObjCIvarRefExpr>(BlockExp)) {
3748 = dyn_cast<PseudoObjectExpr>(BlockExp)) {
3751 assert(
false &&
"RewriteBlockClass: Bad type");
3753 assert(CPT &&
"RewriteBlockClass: Bad type");
3755 assert(FT &&
"RewriteBlockClass: Bad type");
3765 SmallVector<QualType, 8> ArgTypes;
3768 ArgTypes.push_back(PtrBlock);
3773 if (!convertBlockPointerToFunctionPointer(t))
3774 convertToUnqualifiedObjCType(t);
3775 ArgTypes.push_back(t);
3779 QualType PtrToFuncCastType = getSimpleFunctionType(Exp->
getType(), ArgTypes);
3785 const_cast<Expr*>(BlockExp));
3801 CastExpr *FunkCast = NoTypeInfoCStyleCastExpr(
Context, PtrToFuncCastType,
3805 SmallVector<Expr*, 8> BlkExprs;
3807 BlkExprs.push_back(BlkCast);
3811 BlkExprs.push_back(*I);
3837 HasLocalVariableExternalStorage(DeclRefExp->
getDecl());
3849 StringRef Name = VD->
getName();
3863 ReplaceStmt(DeclRefExp, PE);
3870 Stmt *RewriteObjC::RewriteLocalVariableExternalStorage(
DeclRefExpr *DRE) {
3872 if (
VarDecl *Var = dyn_cast<VarDecl>(VD))
3873 if (!ImportedLocalExternalDecls.count(Var))
3881 ReplaceStmt(DRE, PE);
3893 if (!Rewriter::isRewritable(LocStart) || !Rewriter::isRewritable(LocEnd))
3899 const Type* TypePtr = QT->
getAs<Type>();
3900 if (isa<TypeOfExprType>(TypePtr)) {
3901 const TypeOfExprType *TypeOfExprTypePtr = cast<TypeOfExprType>(TypePtr);
3903 std::string TypeAsString =
"(";
3904 RewriteBlockPointerType(TypeAsString, QT);
3905 TypeAsString +=
")";
3906 ReplaceText(LocStart, endBuf-startBuf+1, TypeAsString);
3910 const char *argPtr = startBuf;
3912 while (*argPtr++ && (argPtr < endBuf)) {
3917 ReplaceText(LocStart, 1,
"*");
3923 void RewriteObjC::RewriteBlockPointerFunctionArgs(
FunctionDecl *FD) {
3925 unsigned parenCount = 0;
3929 const char *startArgList = strchr(startBuf,
'(');
3931 assert((*startArgList ==
'(') &&
"Rewriter fuzzy parser confused");
3936 assert((DeclLoc.
isValid()) &&
"Invalid DeclLoc");
3938 const char *argPtr = startArgList;
3940 while (*argPtr++ && parenCount) {
3945 ReplaceText(DeclLoc, 1,
"*");
3957 bool RewriteObjC::PointerTypeTakesAnyBlockArguments(
QualType QT) {
3964 assert(BPT &&
"BlockPointerTypeTakeAnyBlockArguments(): not a block pointer type");
3969 if (isTopLevelBlockPointerType(I))
3975 bool RewriteObjC::PointerTypeTakesAnyObjCQualifiedType(
QualType QT) {
3982 assert(BPT &&
"BlockPointerTypeTakeAnyBlockArguments(): not a block pointer type");
3987 if (I->isObjCQualifiedIdType())
3989 if (I->isObjCObjectPointerType() &&
3990 I->getPointeeType()->isObjCQualifiedInterfaceType())
3998 void RewriteObjC::GetExtentOfArgList(
const char *Name,
const char *&LParen,
3999 const char *&RParen) {
4000 const char *argPtr = strchr(Name,
'(');
4001 assert((*argPtr ==
'(') &&
"Rewriter fuzzy parser confused");
4005 unsigned parenCount = 1;
4007 while (*argPtr && parenCount) {
4009 case '(': parenCount++;
break;
4010 case ')': parenCount--;
break;
4013 if (parenCount) argPtr++;
4015 assert((*argPtr ==
')') &&
"Rewriter fuzzy parser confused");
4019 void RewriteObjC::RewriteBlockPointerDecl(
NamedDecl *ND) {
4021 RewriteBlockPointerFunctionArgs(FD);
4027 if (
VarDecl *VD = dyn_cast<VarDecl>(ND))
4030 DeclT = TDD->getUnderlyingType();
4031 else if (
FieldDecl *FD = dyn_cast<FieldDecl>(ND))
4034 llvm_unreachable(
"RewriteBlockPointerDecl(): Decl type not yet handled");
4037 const char *endBuf = startBuf;
4039 while (*startBuf !=
'^' && *startBuf !=
';' && startBuf != MainFileStart)
4043 unsigned OrigLength=0;
4046 if (*startBuf ==
'^') {
4052 while (*startBuf !=
')') {
4060 if (PointerTypeTakesAnyBlockArguments(DeclT) ||
4061 PointerTypeTakesAnyObjCQualifiedType(DeclT)) {
4064 DeclLoc = ND->getLocation();
4066 const char *argListBegin, *argListEnd;
4067 GetExtentOfArgList(startBuf, argListBegin, argListEnd);
4068 while (argListBegin < argListEnd) {
4069 if (*argListBegin ==
'^')
4071 else if (*argListBegin ==
'<') {
4073 buf += *argListBegin++;
4075 while (*argListBegin !=
'>') {
4076 buf += *argListBegin++;
4079 buf += *argListBegin;
4083 buf += *argListBegin;
4090 ReplaceText(Start, OrigLength, buf);
4113 std::string RewriteObjC::SynthesizeByrefCopyDestroyHelper(
VarDecl *VD,
4116 if (CopyDestroyCache.count(flag))
4118 CopyDestroyCache.insert(flag);
4119 S =
"static void __Block_byref_id_object_copy_";
4121 S +=
"(void *dst, void *src) {\n";
4127 unsigned VoidPtrSize =
4131 S +=
" _Block_object_assign((char*)dst + ";
4132 S += utostr(offset);
4133 S +=
", *(void * *) ((char*)src + ";
4134 S += utostr(offset);
4139 S +=
"static void __Block_byref_id_object_dispose_";
4141 S +=
"(void *src) {\n";
4142 S +=
" _Block_object_dispose(*(void * *) ((char*)src + ";
4143 S += utostr(offset);
4168 void RewriteObjC::RewriteByRefVar(
VarDecl *ND) {
4171 if (CurFunctionDeclToDeclareForBlock)
4172 RewriteBlockLiteralFunctionDecl(CurFunctionDeclToDeclareForBlock);
4179 DeclLoc = ND->getLocation();
4185 std::string ByrefType;
4186 RewriteByRefString(ByrefType, Name, ND,
true);
4187 ByrefType +=
" {\n";
4188 ByrefType +=
" void *__isa;\n";
4189 RewriteByRefString(ByrefType, Name, ND);
4190 ByrefType +=
" *__forwarding;\n";
4191 ByrefType +=
" int __flags;\n";
4192 ByrefType +=
" int __size;\n";
4197 if (HasCopyAndDispose) {
4198 ByrefType +=
" void (*__Block_byref_id_object_copy)(void*, void*);\n";
4199 ByrefType +=
" void (*__Block_byref_id_object_dispose)(void*);\n";
4203 (void)convertBlockPointerToFunctionPointer(T);
4206 ByrefType +=
" " + Name +
";\n";
4207 ByrefType +=
"};\n";
4211 FunLocStart = CurFunctionDef->getTypeSpecStartLoc();
4213 assert(CurMethodDef &&
"RewriteByRefVar - CurMethodDef is null");
4214 FunLocStart = CurMethodDef->getLocStart();
4216 InsertText(FunLocStart, ByrefType);
4222 if (HasCopyAndDispose) {
4230 std::string HF = SynthesizeByrefCopyDestroyHelper(ND, flag);
4232 InsertText(FunLocStart, HF);
4238 bool hasInit = (ND->
getInit() !=
nullptr);
4240 if (HasCopyAndDispose)
4244 RewriteByRefString(ByrefType, Name, ND);
4245 std::string ForwardingCastType(
"(");
4246 ForwardingCastType += ByrefType +
" *)";
4248 ByrefType +=
" " + Name +
" = {(void*)";
4249 ByrefType += utostr(isa);
4250 ByrefType +=
"," + ForwardingCastType +
"&" + Name +
", ";
4251 ByrefType += utostr(flags);
4253 ByrefType +=
"sizeof(";
4254 RewriteByRefString(ByrefType, Name, ND);
4256 if (HasCopyAndDispose) {
4257 ByrefType +=
", __Block_byref_id_object_copy_";
4258 ByrefType += utostr(flag);
4259 ByrefType +=
", __Block_byref_id_object_dispose_";
4260 ByrefType += utostr(flag);
4262 ByrefType +=
"};\n";
4263 unsigned nameSize = Name.size();
4268 ReplaceText(DeclLoc, endBuf-startBuf+nameSize, ByrefType);
4274 startLoc = ECE->getLParenLoc();
4276 startLoc = E->getLocStart();
4279 ByrefType +=
" " +
Name;
4280 ByrefType +=
" = {(void*)";
4281 ByrefType += utostr(isa);
4282 ByrefType +=
"," + ForwardingCastType +
"&" + Name +
", ";
4283 ByrefType += utostr(flags);
4285 ByrefType +=
"sizeof(";
4286 RewriteByRefString(ByrefType, Name, ND);
4288 if (HasCopyAndDispose) {
4289 ByrefType +=
"__Block_byref_id_object_copy_";
4290 ByrefType += utostr(flag);
4291 ByrefType +=
", __Block_byref_id_object_dispose_";
4292 ByrefType += utostr(flag);
4295 ReplaceText(DeclLoc, endBuf-startBuf, ByrefType);
4306 const char *semiBuf = strchr(startInitializerBuf,
';');
4307 assert((*semiBuf ==
';') &&
"RewriteByRefVar: can't find ';'");
4311 InsertText(semiLoc,
"}");
4315 void RewriteObjC::CollectBlockDeclRefInfo(
BlockExpr *Exp) {
4317 GetBlockDeclRefExprs(Exp->
getBody());
4318 if (BlockDeclRefs.size()) {
4320 for (
unsigned i = 0; i < BlockDeclRefs.size(); i++)
4321 if (!BlockDeclRefs[i]->getDecl()->hasAttr<BlocksAttr>()) {
4322 if (!BlockByCopyDeclsPtrSet.count(BlockDeclRefs[i]->getDecl())) {
4323 BlockByCopyDeclsPtrSet.insert(BlockDeclRefs[i]->getDecl());
4324 BlockByCopyDecls.push_back(BlockDeclRefs[i]->getDecl());
4328 for (
unsigned i = 0; i < BlockDeclRefs.size(); i++)
4329 if (BlockDeclRefs[i]->getDecl()->hasAttr<BlocksAttr>()) {
4330 if (!BlockByRefDeclsPtrSet.count(BlockDeclRefs[i]->getDecl())) {
4331 BlockByRefDeclsPtrSet.insert(BlockDeclRefs[i]->getDecl());
4332 BlockByRefDecls.push_back(BlockDeclRefs[i]->getDecl());
4336 for (
unsigned i = 0; i < BlockDeclRefs.size(); i++)
4337 if (BlockDeclRefs[i]->getDecl()->hasAttr<BlocksAttr>() ||
4338 BlockDeclRefs[i]->getType()->isObjCObjectPointerType() ||
4339 BlockDeclRefs[i]->getType()->isBlockPointerType())
4340 ImportedBlockDecls.insert(BlockDeclRefs[i]->getDecl());
4344 FunctionDecl *RewriteObjC::SynthBlockInitFunctionDecl(StringRef name) {
4353 const SmallVectorImpl<DeclRefExpr *> &InnerBlockDeclRefs) {
4355 Blocks.push_back(Exp);
4357 CollectBlockDeclRefInfo(Exp);
4360 int countOfInnerDecls = 0;
4361 if (!InnerBlockDeclRefs.empty()) {
4362 for (
unsigned i = 0; i < InnerBlockDeclRefs.size(); i++) {
4365 if (!VD->hasAttr<BlocksAttr>() && !BlockByCopyDeclsPtrSet.count(VD)) {
4369 InnerDeclRefs.push_back(Exp); countOfInnerDecls++;
4370 BlockDeclRefs.push_back(Exp);
4371 BlockByCopyDeclsPtrSet.insert(VD);
4372 BlockByCopyDecls.push_back(VD);
4374 if (VD->hasAttr<BlocksAttr>() && !BlockByRefDeclsPtrSet.count(VD)) {
4375 InnerDeclRefs.push_back(Exp); countOfInnerDecls++;
4376 BlockDeclRefs.push_back(Exp);
4377 BlockByRefDeclsPtrSet.insert(VD);
4378 BlockByRefDecls.push_back(VD);
4382 for (
unsigned i = 0; i < InnerBlockDeclRefs.size(); i++)
4383 if (InnerBlockDeclRefs[i]->getDecl()->hasAttr<BlocksAttr>() ||
4384 InnerBlockDeclRefs[i]->getType()->isObjCObjectPointerType() ||
4385 InnerBlockDeclRefs[i]->getType()->isBlockPointerType())
4386 ImportedBlockDecls.insert(InnerBlockDeclRefs[i]->getDecl());
4388 InnerDeclRefsCount.push_back(countOfInnerDecls);
4390 std::string FuncName;
4394 else if (CurMethodDef)
4395 BuildUniqueMethodName(FuncName, CurMethodDef);
4396 else if (GlobalVarDecl)
4397 FuncName = std::string(GlobalVarDecl->getNameAsString());
4399 std::string BlockNumber = utostr(Blocks.size()-1);
4401 std::string Tag =
"__" + FuncName +
"_block_impl_" + BlockNumber;
4402 std::string Func =
"__" + FuncName +
"_block_func_" + BlockNumber;
4405 QualType BFT = convertFunctionTypeOfBlocks(Exp->getFunctionType());
4412 FD = SynthBlockInitFunctionDecl(Tag);
4416 SmallVector<Expr*, 4> InitExprs;
4419 FD = SynthBlockInitFunctionDecl(Func);
4424 InitExprs.push_back(castExpr);
4427 std::string DescData =
"__" + FuncName +
"_block_desc_" + BlockNumber +
"_DATA";
4443 InitExprs.push_back(DescRefExpr);
4446 if (BlockDeclRefs.size()) {
4450 E = BlockByCopyDecls.end(); I !=
E; ++
I) {
4451 if (isObjCType((*I)->getType())) {
4453 FD = SynthBlockInitFunctionDecl((*I)->getName());
4456 if (HasLocalVariableExternalStorage(*I)) {
4462 }
else if (isTopLevelBlockPointerType((*I)->getType())) {
4463 FD = SynthBlockInitFunctionDecl((*I)->getName());
4469 FD = SynthBlockInitFunctionDecl((*I)->getName());
4472 if (HasLocalVariableExternalStorage(*I)) {
4479 InitExprs.push_back(Exp);
4483 E = BlockByRefDecls.end(); I !=
E; ++
I) {
4486 std::string RecName;
4487 RewriteByRefString(RecName, Name, ND,
true);
4489 +
sizeof(
"struct"));
4493 assert(RD &&
"SynthBlockInitExpr(): Can't find RecordDecl");
4496 FD = SynthBlockInitFunctionDecl((*I)->getName());
4499 bool isNestedCapturedVar =
false;
4501 for (
const auto &CI : block->
captures()) {
4502 const VarDecl *variable = CI.getVariable();
4503 if (variable == ND && CI.isNested()) {
4504 assert (CI.isByRef() &&
4505 "SynthBlockInitExpr - captured block variable is not byref");
4506 isNestedCapturedVar =
true;
4512 if (!isNestedCapturedVar)
4516 Exp = NoTypeInfoCStyleCastExpr(
Context, castT, CK_BitCast, Exp);
4517 InitExprs.push_back(Exp);
4520 if (ImportedBlockDecls.size()) {
4527 InitExprs.push_back(FlagExp);
4534 NewRep = NoTypeInfoCStyleCastExpr(
Context, FType, CK_BitCast,
4536 BlockDeclRefs.clear();
4537 BlockByRefDecls.clear();
4538 BlockByRefDeclsPtrSet.clear();
4539 BlockByCopyDecls.clear();
4540 BlockByCopyDeclsPtrSet.clear();
4541 ImportedBlockDecls.clear();
4545 bool RewriteObjC::IsDeclStmtInForeachHeader(
DeclStmt *DS) {
4547 dyn_cast<ObjCForCollectionStmt>(Stmts.back()))
4548 return CS->getElement() == DS;
4556 Stmt *RewriteObjC::RewriteFunctionBodyOrGlobalInitializer(
Stmt *S) {
4557 if (isa<SwitchStmt>(S) || isa<WhileStmt>(S) ||
4558 isa<DoStmt>(S) || isa<ForStmt>(S))
4560 else if (isa<ObjCForCollectionStmt>(S)) {
4562 ObjCBcLabelNo.push_back(++BcLabelCount);
4569 return RewritePropertyOrImplicitSetter(PseudoOp);
4571 return RewritePropertyOrImplicitGetter(PseudoOp);
4573 }
else if (
ObjCIvarRefExpr *IvarRefExpr = dyn_cast<ObjCIvarRefExpr>(S)) {
4574 return RewriteObjCIvarRefExpr(IvarRefExpr);
4580 for (
Stmt *&childStmt : S->children())
4582 Stmt *newStmt = RewriteFunctionBodyOrGlobalInitializer(childStmt);
4584 childStmt = newStmt;
4588 if (
BlockExpr *BE = dyn_cast<BlockExpr>(S)) {
4589 SmallVector<DeclRefExpr *, 8> InnerBlockDeclRefs;
4590 llvm::SmallPtrSet<const DeclContext *, 8> InnerContexts;
4591 InnerContexts.insert(BE->getBlockDecl());
4592 ImportedLocalExternalDecls.clear();
4593 GetInnerBlockDeclRefExprs(BE->getBody(),
4594 InnerBlockDeclRefs, InnerContexts);
4596 Stmt *SaveCurrentBody = CurrentBody;
4597 CurrentBody = BE->getBody();
4598 PropParentMap =
nullptr;
4604 bool saveDisableReplaceStmt = DisableReplaceStmt;
4605 DisableReplaceStmt =
false;
4606 RewriteFunctionBodyOrGlobalInitializer(BE->getBody());
4607 DisableReplaceStmt = saveDisableReplaceStmt;
4608 CurrentBody = SaveCurrentBody;
4609 PropParentMap =
nullptr;
4610 ImportedLocalExternalDecls.clear();
4612 std::string Str = Rewrite.getRewrittenText(BE->getSourceRange());
4613 RewrittenBlockExprs[BE] = Str;
4615 Stmt *blockTranscribed = SynthBlockInitExpr(BE, InnerBlockDeclRefs);
4618 ReplaceStmt(S, blockTranscribed);
4619 return blockTranscribed;
4623 return RewriteAtEncode(AtEncode);
4626 return RewriteAtSelector(AtSelector);
4629 return RewriteObjCStringLiteral(AtString);
4640 std::string messString;
4641 messString +=
"// ";
4642 messString.append(startBuf, endBuf-startBuf+1);
4651 return RewriteMessageExpr(MessExpr);
4655 return RewriteObjCTryStmt(StmtTry);
4658 return RewriteObjCSynchronizedStmt(StmtTry);
4661 return RewriteObjCThrowStmt(StmtThrow);
4664 return RewriteObjCProtocolExpr(ProtocolExp);
4667 dyn_cast<ObjCForCollectionStmt>(S))
4668 return RewriteObjCForCollectionStmt(StmtForCollection,
4671 dyn_cast<BreakStmt>(S))
4672 return RewriteBreakStmt(StmtBreakStmt);
4674 dyn_cast<ContinueStmt>(S))
4675 return RewriteContinueStmt(StmtContinueStmt);
4679 if (
DeclStmt *DS = dyn_cast<DeclStmt>(S)) {
4689 if (Stmts.empty() || !IsDeclStmtInForeachHeader(DS))
4690 RewriteObjCQualifiedInterfaceTypes(*DS->
decl_begin());
4693 for (
auto *SD : DS->
decls()) {
4694 if (
ValueDecl *ND = dyn_cast<ValueDecl>(SD)) {
4695 if (isTopLevelBlockPointerType(ND->
getType()))
4696 RewriteBlockPointerDecl(ND);
4698 CheckFunctionPointerDecl(ND->
getType(), ND);
4699 if (
VarDecl *VD = dyn_cast<VarDecl>(SD)) {
4700 if (VD->hasAttr<BlocksAttr>()) {
4701 static unsigned uniqueByrefDeclCount = 0;
4702 assert(!BlockByRefDeclNo.count(ND) &&
4703 "RewriteFunctionBodyOrGlobalInitializer: Duplicate byref decl");
4704 BlockByRefDeclNo[ND] = uniqueByrefDeclCount++;
4705 RewriteByRefVar(VD);
4708 RewriteTypeOfDecl(VD);
4712 if (isTopLevelBlockPointerType(TD->getUnderlyingType()))
4713 RewriteBlockPointerDecl(TD);
4714 else if (TD->getUnderlyingType()->isFunctionPointerType())
4715 CheckFunctionPointerDecl(TD->getUnderlyingType(), TD);
4721 RewriteObjCQualifiedInterfaceTypes(CE);
4723 if (isa<SwitchStmt>(S) || isa<WhileStmt>(
S) ||
4724 isa<DoStmt>(S) || isa<ForStmt>(
S)) {
4725 assert(!Stmts.empty() &&
"Statement stack is empty");
4726 assert ((isa<SwitchStmt>(Stmts.back()) || isa<WhileStmt>(Stmts.back()) ||
4727 isa<DoStmt>(Stmts.back()) || isa<ForStmt>(Stmts.back()))
4728 &&
"Statement stack mismatch");
4732 if (
DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(S)) {
4734 if (VD->hasAttr<BlocksAttr>())
4735 return RewriteBlockDeclRefExpr(DRE);
4736 if (HasLocalVariableExternalStorage(VD))
4737 return RewriteLocalVariableExternalStorage(DRE);
4740 if (
CallExpr *CE = dyn_cast<CallExpr>(S)) {
4743 ReplaceStmt(S, BlockCall);
4748 RewriteCastExpr(CE);
4757 llvm::raw_string_ostream Buf(SStr);
4758 Replacement->printPretty(Buf);
4759 const std::string &Str = Buf.str();
4761 printf(
"CAST = %s\n", &Str[0]);
4762 InsertText(ICE->
getSubExpr()->getLocStart(), Str);
4771 void RewriteObjC::RewriteRecordBody(
RecordDecl *RD) {
4772 for (
auto *FD : RD->
fields()) {
4773 if (isTopLevelBlockPointerType(FD->
getType()))
4774 RewriteBlockPointerDecl(FD);
4777 RewriteObjCQualifiedInterfaceTypes(FD);
4783 void RewriteObjC::HandleDeclInMainFile(
Decl *D) {
4784 switch (D->getKind()) {
4785 case Decl::Function: {
4793 RewriteBlocksInFunctionProtoType(FD->
getType(), FD);
4800 CurFunctionDef = FD;
4801 CurFunctionDeclToDeclareForBlock = FD;
4804 cast_or_null<CompoundStmt>(RewriteFunctionBodyOrGlobalInitializer(Body));
4806 CurrentBody =
nullptr;
4807 if (PropParentMap) {
4808 delete PropParentMap;
4809 PropParentMap =
nullptr;
4813 InsertBlockLiteralsWithinFunction(FD);
4814 CurFunctionDef =
nullptr;
4815 CurFunctionDeclToDeclareForBlock =
nullptr;
4819 case Decl::ObjCMethod: {
4825 cast_or_null<CompoundStmt>(RewriteFunctionBodyOrGlobalInitializer(Body));
4827 CurrentBody =
nullptr;
4828 if (PropParentMap) {
4829 delete PropParentMap;
4830 PropParentMap =
nullptr;
4832 InsertBlockLiteralsWithinMethod(MD);
4833 CurMethodDef =
nullptr;
4837 case Decl::ObjCImplementation: {
4839 ClassImplementation.push_back(CI);
4842 case Decl::ObjCCategoryImpl: {
4844 CategoryImplementation.push_back(CI);
4848 VarDecl *VD = cast<VarDecl>(D);
4849 RewriteObjCQualifiedInterfaceTypes(VD);
4850 if (isTopLevelBlockPointerType(VD->
getType()))
4851 RewriteBlockPointerDecl(VD);
4853 CheckFunctionPointerDecl(VD->
getType(), VD);
4856 RewriteCastExpr(CE);
4862 RewriteRecordBody(RD);
4867 RewriteFunctionBodyOrGlobalInitializer(VD->
getInit());
4868 CurrentBody =
nullptr;
4869 if (PropParentMap) {
4870 delete PropParentMap;
4871 PropParentMap =
nullptr;
4874 GlobalVarDecl =
nullptr;
4878 RewriteCastExpr(CE);
4884 case Decl::Typedef: {
4886 if (isTopLevelBlockPointerType(TD->getUnderlyingType()))
4887 RewriteBlockPointerDecl(TD);
4888 else if (TD->getUnderlyingType()->isFunctionPointerType())
4889 CheckFunctionPointerDecl(TD->getUnderlyingType(), TD);
4893 case Decl::CXXRecord:
4894 case Decl::Record: {
4897 RewriteRecordBody(RD);
4906 void RewriteObjC::HandleTranslationUnit(
ASTContext &
C) {
4907 if (Diags.hasErrorOccurred())
4915 RewriteObjCProtocolMetaData(ProtDecl,
"",
"", Preamble);
4918 if (ClassImplementation.size() || CategoryImplementation.size())
4919 RewriteImplementations();
4924 Rewrite.getRewriteBufferFor(MainFileID)) {
4926 *OutFile << std::string(RewriteBuf->begin(), RewriteBuf->end());
4928 llvm::errs() <<
"No changes\n";
4931 if (ClassImplementation.size() || CategoryImplementation.size() ||
4932 ProtocolExprDecls.size()) {
4934 std::string ResultStr;
4935 RewriteMetaDataIntoBuffer(ResultStr);
4937 *OutFile << ResultStr;
4942 void RewriteObjCFragileABI::Initialize(
ASTContext &context) {
4943 InitializeCommon(context);
4948 Preamble =
"#pragma once\n";
4949 Preamble +=
"struct objc_selector; struct objc_class;\n";
4950 Preamble +=
"struct __rw_objc_super { struct objc_object *object; ";
4951 Preamble +=
"struct objc_object *superClass; ";
4952 if (LangOpts.MicrosoftExt) {
4954 Preamble +=
"__rw_objc_super(struct objc_object *o, struct objc_object *s) "
4956 Preamble +=
"object(o), superClass(s) {} ";
4959 Preamble +=
"#ifndef _REWRITER_typedef_Protocol\n";
4960 Preamble +=
"typedef struct objc_object Protocol;\n";
4961 Preamble +=
"#define _REWRITER_typedef_Protocol\n";
4962 Preamble +=
"#endif\n";
4963 if (LangOpts.MicrosoftExt) {
4964 Preamble +=
"#define __OBJC_RW_DLLIMPORT extern \"C\" __declspec(dllimport)\n";
4965 Preamble +=
"#define __OBJC_RW_STATICIMPORT extern \"C\"\n";
4967 Preamble +=
"#define __OBJC_RW_DLLIMPORT extern\n";
4968 Preamble +=
"__OBJC_RW_DLLIMPORT struct objc_object *objc_msgSend";
4969 Preamble +=
"(struct objc_object *, struct objc_selector *, ...);\n";
4970 Preamble +=
"__OBJC_RW_DLLIMPORT struct objc_object *objc_msgSendSuper";
4971 Preamble +=
"(struct objc_super *, struct objc_selector *, ...);\n";
4972 Preamble +=
"__OBJC_RW_DLLIMPORT struct objc_object* objc_msgSend_stret";
4973 Preamble +=
"(struct objc_object *, struct objc_selector *, ...);\n";
4974 Preamble +=
"__OBJC_RW_DLLIMPORT struct objc_object* objc_msgSendSuper_stret";
4975 Preamble +=
"(struct objc_super *, struct objc_selector *, ...);\n";
4976 Preamble +=
"__OBJC_RW_DLLIMPORT double objc_msgSend_fpret";
4977 Preamble +=
"(struct objc_object *, struct objc_selector *, ...);\n";
4978 Preamble +=
"__OBJC_RW_DLLIMPORT struct objc_object *objc_getClass";
4979 Preamble +=
"(const char *);\n";
4980 Preamble +=
"__OBJC_RW_DLLIMPORT struct objc_class *class_getSuperclass";
4981 Preamble +=
"(struct objc_class *);\n";
4982 Preamble +=
"__OBJC_RW_DLLIMPORT struct objc_object *objc_getMetaClass";
4983 Preamble +=
"(const char *);\n";
4984 Preamble +=
"__OBJC_RW_DLLIMPORT void objc_exception_throw(struct objc_object *);\n";
4985 Preamble +=
"__OBJC_RW_DLLIMPORT void objc_exception_try_enter(void *);\n";
4986 Preamble +=
"__OBJC_RW_DLLIMPORT void objc_exception_try_exit(void *);\n";
4987 Preamble +=
"__OBJC_RW_DLLIMPORT struct objc_object *objc_exception_extract(void *);\n";
4988 Preamble +=
"__OBJC_RW_DLLIMPORT int objc_exception_match";
4989 Preamble +=
"(struct objc_class *, struct objc_object *);\n";
4991 Preamble +=
"__OBJC_RW_DLLIMPORT int objc_sync_enter(struct objc_object *);\n";
4992 Preamble +=
"__OBJC_RW_DLLIMPORT int objc_sync_exit(struct objc_object *);\n";
4993 Preamble +=
"__OBJC_RW_DLLIMPORT Protocol *objc_getProtocol(const char *);\n";
4994 Preamble +=
"#ifndef __FASTENUMERATIONSTATE\n";
4995 Preamble +=
"struct __objcFastEnumerationState {\n\t";
4996 Preamble +=
"unsigned long state;\n\t";
4997 Preamble +=
"void **itemsPtr;\n\t";
4998 Preamble +=
"unsigned long *mutationsPtr;\n\t";
4999 Preamble +=
"unsigned long extra[5];\n};\n";
5000 Preamble +=
"__OBJC_RW_DLLIMPORT void objc_enumerationMutation(struct objc_object *);\n";
5001 Preamble +=
"#define __FASTENUMERATIONSTATE\n";
5002 Preamble +=
"#endif\n";
5003 Preamble +=
"#ifndef __NSCONSTANTSTRINGIMPL\n";
5004 Preamble +=
"struct __NSConstantStringImpl {\n";
5005 Preamble +=
" int *isa;\n";
5006 Preamble +=
" int flags;\n";
5007 Preamble +=
" char *str;\n";
5008 Preamble +=
" long length;\n";
5010 Preamble +=
"#ifdef CF_EXPORT_CONSTANT_STRING\n";
5011 Preamble +=
"extern \"C\" __declspec(dllexport) int __CFConstantStringClassReference[];\n";
5012 Preamble +=
"#else\n";
5013 Preamble +=
"__OBJC_RW_DLLIMPORT int __CFConstantStringClassReference[];\n";
5014 Preamble +=
"#endif\n";
5015 Preamble +=
"#define __NSCONSTANTSTRINGIMPL\n";
5016 Preamble +=
"#endif\n";
5018 Preamble +=
"#ifndef BLOCK_IMPL\n";
5019 Preamble +=
"#define BLOCK_IMPL\n";
5020 Preamble +=
"struct __block_impl {\n";
5021 Preamble +=
" void *isa;\n";
5022 Preamble +=
" int Flags;\n";
5023 Preamble +=
" int Reserved;\n";
5024 Preamble +=
" void *FuncPtr;\n";
5026 Preamble +=
"// Runtime copy/destroy helper functions (from Block_private.h)\n";
5027 Preamble +=
"#ifdef __OBJC_EXPORT_BLOCKS\n";
5028 Preamble +=
"extern \"C\" __declspec(dllexport) "
5029 "void _Block_object_assign(void *, const void *, const int);\n";
5030 Preamble +=
"extern \"C\" __declspec(dllexport) void _Block_object_dispose(const void *, const int);\n";
5031 Preamble +=
"extern \"C\" __declspec(dllexport) void *_NSConcreteGlobalBlock[32];\n";
5032 Preamble +=
"extern \"C\" __declspec(dllexport) void *_NSConcreteStackBlock[32];\n";
5033 Preamble +=
"#else\n";
5034 Preamble +=
"__OBJC_RW_DLLIMPORT void _Block_object_assign(void *, const void *, const int);\n";
5035 Preamble +=
"__OBJC_RW_DLLIMPORT void _Block_object_dispose(const void *, const int);\n";
5036 Preamble +=
"__OBJC_RW_DLLIMPORT void *_NSConcreteGlobalBlock[32];\n";
5037 Preamble +=
"__OBJC_RW_DLLIMPORT void *_NSConcreteStackBlock[32];\n";
5038 Preamble +=
"#endif\n";
5039 Preamble +=
"#endif\n";
5040 if (LangOpts.MicrosoftExt) {
5041 Preamble +=
"#undef __OBJC_RW_DLLIMPORT\n";
5042 Preamble +=
"#undef __OBJC_RW_STATICIMPORT\n";
5043 Preamble +=
"#ifndef KEEP_ATTRIBUTES\n";
5044 Preamble +=
"#define __attribute__(X)\n";
5045 Preamble +=
"#endif\n";
5046 Preamble +=
"#define __weak\n";
5049 Preamble +=
"#define __block\n";
5050 Preamble +=
"#define __weak\n";
5054 Preamble +=
"\n#define __OFFSETOFIVAR__(TYPE, MEMBER) ((long long) &((TYPE *)0)->MEMBER)\n";
5059 void RewriteObjCFragileABI::RewriteIvarOffsetComputation(
ObjCIvarDecl *ivar,
5060 std::string &Result) {
5066 Result +=
"__OFFSETOFIVAR__(struct ";
5068 if (LangOpts.MicrosoftExt)
5077 void RewriteObjCFragileABI::RewriteObjCProtocolMetaData(
5079 StringRef ClassName, std::string &Result) {
5080 static bool objc_protocol_methods =
false;
5089 Result +=
"\nstruct _protocol_methods {\n";
5090 Result +=
"\tstruct objc_selector *_cmd;\n";
5091 Result +=
"\tchar *method_types;\n";
5094 objc_protocol_methods =
true;
5111 Result +=
"\nstatic struct {\n";
5112 Result +=
"\tint protocol_method_count;\n";
5113 Result +=
"\tstruct _protocol_methods protocol_methods[";
5114 Result += utostr(NumMethods);
5115 Result +=
"];\n} _OBJC_PROTOCOL_INSTANCE_METHODS_";
5117 Result +=
" __attribute__ ((used, section (\"__OBJC, __cat_inst_meth\")))= "
5118 "{\n\t" + utostr(NumMethods) +
"\n";
5121 for (ObjCProtocolDecl::instmeth_iterator
5125 Result +=
"\t ,{{(struct objc_selector *)\"";
5127 Result +=
"\t ,{(struct objc_selector *)\"";
5128 Result += (*I)->getSelector().getAsString();
5129 std::string MethodTypeString;
5132 Result += MethodTypeString;
5135 Result +=
"\t }\n};\n";
5141 if (NumMethods > 0) {
5147 Result +=
"\nstatic struct {\n";
5148 Result +=
"\tint protocol_method_count;\n";
5149 Result +=
"\tstruct _protocol_methods protocol_methods[";
5150 Result += utostr(NumMethods);
5151 Result +=
"];\n} _OBJC_PROTOCOL_CLASS_METHODS_";
5153 Result +=
" __attribute__ ((used, section (\"__OBJC, __cat_cls_meth\")))= "
5155 Result += utostr(NumMethods);
5159 for (ObjCProtocolDecl::classmeth_iterator
5163 Result +=
"\t ,{{(struct objc_selector *)\"";
5165 Result +=
"\t ,{(struct objc_selector *)\"";
5166 Result += (*I)->getSelector().getAsString();
5167 std::string MethodTypeString;
5170 Result += MethodTypeString;
5173 Result +=
"\t }\n};\n";
5186 static bool objc_protocol =
false;
5187 if (!objc_protocol) {
5188 Result +=
"\nstruct _objc_protocol {\n";
5189 Result +=
"\tstruct _objc_protocol_extension *isa;\n";
5190 Result +=
"\tchar *protocol_name;\n";
5191 Result +=
"\tstruct _objc_protocol **protocol_list;\n";
5192 Result +=
"\tstruct _objc_protocol_method_list *instance_methods;\n";
5193 Result +=
"\tstruct _objc_protocol_method_list *class_methods;\n";
5196 objc_protocol =
true;
5199 Result +=
"\nstatic struct _objc_protocol _OBJC_PROTOCOL_";
5201 Result +=
" __attribute__ ((used, section (\"__OBJC, __protocol\")))= "
5204 Result +=
"\", 0, ";
5206 Result +=
"(struct _objc_protocol_method_list *)&_OBJC_PROTOCOL_INSTANCE_METHODS_";
5213 Result +=
"(struct _objc_protocol_method_list *)&_OBJC_PROTOCOL_CLASS_METHODS_";
5223 llvm_unreachable(
"protocol already synthesized");
5226 void RewriteObjCFragileABI::RewriteObjCProtocolListMetaData(
5228 StringRef prefix, StringRef ClassName,
5229 std::string &Result) {
5230 if (Protocols.
empty())
return;
5232 for (
unsigned i = 0; i != Protocols.
size(); i++)
5233 RewriteObjCProtocolMetaData(Protocols[i], prefix, ClassName, Result);
5242 Result +=
"\nstatic struct {\n";
5243 Result +=
"\tstruct _objc_protocol_list *next;\n";
5244 Result +=
"\tint protocol_count;\n";
5245 Result +=
"\tstruct _objc_protocol *class_protocols[";
5246 Result += utostr(Protocols.
size());
5247 Result +=
"];\n} _OBJC_";
5249 Result +=
"_PROTOCOLS_";
5250 Result += ClassName;
5251 Result +=
" __attribute__ ((used, section (\"__OBJC, __cat_cls_meth\")))= "
5253 Result += utostr(Protocols.
size());
5256 Result +=
"\t,{&_OBJC_PROTOCOL_";
5257 Result += Protocols[0]->getNameAsString();
5260 for (
unsigned i = 1; i != Protocols.
size(); i++) {
5261 Result +=
"\t ,&_OBJC_PROTOCOL_";
5262 Result += Protocols[i]->getNameAsString();
5265 Result +=
"\t }\n};\n";
5269 std::string &Result) {
5276 RewriteObjCInternalStruct(CDecl, Result);
5284 static bool objc_ivar =
false;
5292 Result +=
"\nstruct _objc_ivar {\n";
5293 Result +=
"\tchar *ivar_name;\n";
5294 Result +=
"\tchar *ivar_type;\n";
5295 Result +=
"\tint ivar_offset;\n";
5306 Result +=
"\nstatic struct {\n";
5307 Result +=
"\tint ivar_count;\n";
5308 Result +=
"\tstruct _objc_ivar ivar_list[";
5309 Result += utostr(NumIvars);
5310 Result +=
"];\n} _OBJC_INSTANCE_VARIABLES_";
5312 Result +=
" __attribute__ ((used, section (\"__OBJC, __instance_vars\")))= "
5314 Result += utostr(NumIvars);
5318 SmallVector<ObjCIvarDecl *, 8> IVars;
5320 for (
auto *IV : IDecl->
ivars())
5321 IVars.push_back(IV);
5328 Result +=
"\t,{{\"";
5329 Result += IVI->getNameAsString();
5331 std::string TmpString, StrEncoding;
5333 QuoteDoublequotes(TmpString, StrEncoding);
5334 Result += StrEncoding;
5336 RewriteIvarOffsetComputation(*IVI, Result);
5338 for (++IVI; IVI != IVE; ++IVI) {
5339 Result +=
"\t ,{\"";
5340 Result += IVI->getNameAsString();
5342 std::string TmpString, StrEncoding;
5344 QuoteDoublequotes(TmpString, StrEncoding);
5345 Result += StrEncoding;
5347 RewriteIvarOffsetComputation(*IVI, Result);
5351 Result +=
"\t }\n};\n";
5355 SmallVector<ObjCMethodDecl *, 32> InstanceMethods(IDecl->
instance_methods());
5360 if (Prop->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic)
5362 if (!Prop->getPropertyIvarDecl())
5368 if (!Getter->isDefined())
5369 InstanceMethods.push_back(Getter);
5373 if (!Setter->isDefined())
5374 InstanceMethods.push_back(Setter);
5376 RewriteObjCMethodsMetaData(InstanceMethods.begin(), InstanceMethods.end(),
5377 true,
"", IDecl->
getName(), Result);
5381 false,
"", IDecl->
getName(), Result);
5385 "CLASS", CDecl->
getName(), Result);
5403 static bool objc_class =
false;
5405 Result +=
"\nstruct _objc_class {\n";
5406 Result +=
"\tstruct _objc_class *isa;\n";
5407 Result +=
"\tconst char *super_class_name;\n";
5408 Result +=
"\tchar *name;\n";
5409 Result +=
"\tlong version;\n";
5410 Result +=
"\tlong info;\n";
5411 Result +=
"\tlong instance_size;\n";
5412 Result +=
"\tstruct _objc_ivar_list *ivars;\n";
5413 Result +=
"\tstruct _objc_method_list *methods;\n";
5414 Result +=
"\tstruct objc_cache *cache;\n";
5415 Result +=
"\tstruct _objc_protocol_list *protocols;\n";
5416 Result +=
"\tconst char *ivar_layout;\n";
5417 Result +=
"\tstruct _objc_class_ext *ext;\n";
5425 while (SuperClass) {
5426 RootClass = SuperClass;
5431 Result +=
"\nstatic struct _objc_class _OBJC_METACLASS_";
5433 Result +=
" __attribute__ ((used, section (\"__OBJC, __meta_class\")))= "
5434 "{\n\t(struct _objc_class *)\"";
5446 Result +=
", 0, \"";
5452 Result +=
", 0,2, sizeof(struct _objc_class), 0";
5454 Result +=
"\n\t, (struct _objc_method_list *)&_OBJC_CLASS_METHODS_";
5461 Result +=
"\t,0, (struct _objc_protocol_list *)&_OBJC_CLASS_PROTOCOLS_";
5466 Result +=
"\t,0,0,0,0\n";
5470 Result +=
"\nstatic struct _objc_class _OBJC_CLASS_";
5472 Result +=
" __attribute__ ((used, section (\"__OBJC, __class\")))= "
5473 "{\n\t&_OBJC_METACLASS_";
5483 Result +=
", 0, \"";
5489 if (!ObjCSynthesizedStructs.count(CDecl))
5493 Result +=
",sizeof(struct ";
5495 if (LangOpts.MicrosoftExt)
5500 Result +=
", (struct _objc_ivar_list *)&_OBJC_INSTANCE_VARIABLES_";
5507 Result +=
", (struct _objc_method_list *)&_OBJC_INSTANCE_METHODS_";
5509 Result +=
", 0\n\t";
5514 Result +=
", (struct _objc_protocol_list*)&_OBJC_CLASS_PROTOCOLS_";
5516 Result +=
", 0,0\n";
5519 Result +=
",0,0,0\n";
5523 void RewriteObjCFragileABI::RewriteMetaDataIntoBuffer(std::string &Result) {
5524 int ClsDefCount = ClassImplementation.size();
5525 int CatDefCount = CategoryImplementation.size();
5528 for (
int i = 0; i < ClsDefCount; i++)
5529 RewriteObjCClassMetaData(ClassImplementation[i], Result);
5532 for (
int i = 0; i < CatDefCount; i++)
5533 RewriteObjCCategoryImplDecl(CategoryImplementation[i], Result);
5547 Result +=
"\nstruct _objc_symtab {\n";
5548 Result +=
"\tlong sel_ref_cnt;\n";
5549 Result +=
"\tSEL *refs;\n";
5550 Result +=
"\tshort cls_def_cnt;\n";
5551 Result +=
"\tshort cat_def_cnt;\n";
5552 Result +=
"\tvoid *defs[" + utostr(ClsDefCount + CatDefCount)+
"];\n";
5555 Result +=
"static struct _objc_symtab "
5556 "_OBJC_SYMBOLS __attribute__((used, section (\"__OBJC, __symbols\")))= {\n";
5557 Result +=
"\t0, 0, " + utostr(ClsDefCount)
5558 +
", " + utostr(CatDefCount) +
"\n";
5559 for (
int i = 0; i < ClsDefCount; i++) {
5560 Result +=
"\t,&_OBJC_CLASS_";
5561 Result += ClassImplementation[i]->getNameAsString();
5565 for (
int i = 0; i < CatDefCount; i++) {
5566 Result +=
"\t,&_OBJC_CATEGORY_";
5567 Result += CategoryImplementation[i]->getClassInterface()->getNameAsString();
5569 Result += CategoryImplementation[i]->getNameAsString();
5586 Result +=
"\nstruct _objc_module {\n";
5587 Result +=
"\tlong version;\n";
5588 Result +=
"\tlong size;\n";
5589 Result +=
"\tconst char *name;\n";
5590 Result +=
"\tstruct _objc_symtab *symtab;\n";
5592 Result +=
"static struct _objc_module "
5593 "_OBJC_MODULES __attribute__ ((used, section (\"__OBJC, __module_info\")))= {\n";
5594 Result +=
"\t" + utostr(OBJC_ABI_VERSION) +
5595 ", sizeof(struct _objc_module), \"\", &_OBJC_SYMBOLS\n";
5598 if (LangOpts.MicrosoftExt) {
5599 if (ProtocolExprDecls.size()) {
5600 Result +=
"#pragma section(\".objc_protocol$B\",long,read,write)\n";
5601 Result +=
"#pragma data_seg(push, \".objc_protocol$B\")\n";
5603 Result +=
"static struct _objc_protocol *_POINTER_OBJC_PROTOCOL_";
5604 Result += ProtDecl->getNameAsString();
5605 Result +=
" = &_OBJC_PROTOCOL_";
5606 Result += ProtDecl->getNameAsString();
5609 Result +=
"#pragma data_seg(pop)\n\n";
5611 Result +=
"#pragma section(\".objc_module_info$B\",long,read,write)\n";
5612 Result +=
"#pragma data_seg(push, \".objc_module_info$B\")\n";
5613 Result +=
"static struct _objc_module *_POINTER_OBJC_MODULES = ";
5614 Result +=
"&_OBJC_MODULES;\n";
5615 Result +=
"#pragma data_seg(pop)\n\n";
5622 std::string &Result) {
5629 FullCategoryName +=
'_';
5633 SmallVector<ObjCMethodDecl *, 32> InstanceMethods(IDecl->
instance_methods());
5638 if (Prop->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic)
5640 if (!Prop->getPropertyIvarDecl())
5646 InstanceMethods.push_back(Getter);
5650 InstanceMethods.push_back(Setter);
5652 RewriteObjCMethodsMetaData(InstanceMethods.begin(), InstanceMethods.end(),
5653 true,
"CATEGORY_", FullCategoryName.c_str(),
5658 false,
"CATEGORY_", FullCategoryName.c_str(),
5665 FullCategoryName, Result);
5679 static bool objc_category =
false;
5680 if (!objc_category) {
5681 Result +=
"\nstruct _objc_category {\n";
5682 Result +=
"\tchar *category_name;\n";
5683 Result +=
"\tchar *class_name;\n";
5684 Result +=
"\tstruct _objc_method_list *instance_methods;\n";
5685 Result +=
"\tstruct _objc_method_list *class_methods;\n";
5686 Result +=
"\tstruct _objc_protocol_list *protocols;\n";
5687 Result +=
"\tunsigned int size;\n";
5688 Result +=
"\tstruct _objc_property_list *instance_properties;\n";
5690 objc_category =
true;
5692 Result +=
"\nstatic struct _objc_category _OBJC_CATEGORY_";
5693 Result += FullCategoryName;
5694 Result +=
" __attribute__ ((used, section (\"__OBJC, __category\")))= {\n\t\"";
5696 Result +=
"\"\n\t, \"";
5701 Result +=
"\t, (struct _objc_method_list *)"
5702 "&_OBJC_CATEGORY_INSTANCE_METHODS_";
5703 Result += FullCategoryName;
5707 Result +=
"\t, 0\n";
5709 Result +=
"\t, (struct _objc_method_list *)"
5710 "&_OBJC_CATEGORY_CLASS_METHODS_";
5711 Result += FullCategoryName;
5715 Result +=
"\t, 0\n";
5718 Result +=
"\t, (struct _objc_protocol_list *)&_OBJC_CATEGORY_PROTOCOLS_";
5719 Result += FullCategoryName;
5723 Result +=
"\t, 0\n";
5724 Result +=
"\t, sizeof(struct _objc_category), 0\n};\n";
5729 template<
typename MethodIterator>
5730 void RewriteObjCFragileABI::RewriteObjCMethodsMetaData(MethodIterator MethodBegin,
5731 MethodIterator MethodEnd,
5732 bool IsInstanceMethod,
5734 StringRef ClassName,
5735 std::string &Result) {
5736 if (MethodBegin == MethodEnd)
return;
5738 if (!objc_impl_method) {
5745 Result +=
"\nstruct _objc_method {\n";
5746 Result +=
"\tSEL _cmd;\n";
5747 Result +=
"\tchar *method_types;\n";
5748 Result +=
"\tvoid *_imp;\n";
5751 objc_impl_method =
true;
5762 unsigned NumMethods =
std::distance(MethodBegin, MethodEnd);
5763 Result +=
"\nstatic struct {\n";
5764 Result +=
"\tstruct _objc_method_list *next_method;\n";
5765 Result +=
"\tint method_count;\n";
5766 Result +=
"\tstruct _objc_method method_list[";
5767 Result += utostr(NumMethods);
5768 Result +=
"];\n} _OBJC_";
5770 Result += IsInstanceMethod ?
"INSTANCE" :
"CLASS";
5771 Result +=
"_METHODS_";
5772 Result += ClassName;
5773 Result +=
" __attribute__ ((used, section (\"__OBJC, __";
5774 Result += IsInstanceMethod ?
"inst" :
"cls";
5775 Result +=
"_meth\")))= ";
5776 Result +=
"{\n\t0, " + utostr(NumMethods) +
"\n";
5778 Result +=
"\t,{{(SEL)\"";
5779 Result += (*MethodBegin)->getSelector().getAsString().c_str();
5780 std::string MethodTypeString;
5783 Result += MethodTypeString;
5784 Result +=
"\", (void *)";
5785 Result += MethodInternalNames[*MethodBegin];
5787 for (++MethodBegin; MethodBegin != MethodEnd; ++MethodBegin) {
5788 Result +=
"\t ,{(SEL)\"";
5789 Result += (*MethodBegin)->getSelector().getAsString().c_str();
5790 std::string MethodTypeString;
5793 Result += MethodTypeString;
5794 Result +=
"\", (void *)";
5795 Result += MethodInternalNames[*MethodBegin];
5798 Result +=
"\t }\n};\n";
5807 DisableReplaceStmtScope
S(*
this);
5808 BaseExpr = cast<Expr>(RewriteFunctionBodyOrGlobalInitializer(BaseExpr));
5814 Expr *Replacement = IV;
5819 assert(iFaceDecl &&
"RewriteObjCIvarRefExpr - iFaceDecl is null");
5824 assert(clsDeclared &&
"RewriteObjCIvarRefExpr(): Can't find class");
5833 assert(RD &&
"RewriteObjCIvarRefExpr(): Can't find RecordDecl");
5853 assert(!IV->
isFreeIvar() &&
"Cannot have a free standing ivar outside a method");
5864 assert(clsDeclared &&
"RewriteObjCIvarRefExpr(): Can't find class");
5867 std::string RecName = clsDeclared->getIdentifier()->getName();
5873 assert(RD &&
"RewriteObjCIvarRefExpr(): Can't find RecordDecl");
5888 ReplaceStmtWithRange(IV, Replacement, OldRange);
5892 #endif // CLANG_ENABLE_OBJC_REWRITER
SourceLocation getEnd() const
const Expr * getBase() const
ObjCInterfaceDecl * getDecl() const
Get the declaration of this interface.
FunctionDecl - An instance of this class is created to represent a function declaration or definition...
classmeth_iterator classmeth_end() const
StringRef getName() const
getName - Get the name of identifier for this declaration as a StringRef.
Expr * getSyntacticForm()
Return the syntactic form of this expression, i.e.
SourceLocation getLocStart() const LLVM_READONLY
PointerType - C99 6.7.5.1 - Pointer Declarators.
const ObjCAtFinallyStmt * getFinallyStmt() const
Retrieve the @finally statement, if any.
A (possibly-)qualified type.
ArrayRef< Capture > captures() const
QualType getCallResultType(const ASTContext &Context) const
Determine the type of an expression that calls a function of this type.
ObjCInterfaceDecl * getClassInterface()
bool isBitField() const
Determines whether this field is a bitfield.
ASTConsumer - This is an abstract interface that should be implemented by clients that read ASTs...
SourceLocation getLocation() const
QualType getClassReceiver() const
Returns the type of a class message send, or NULL if the message is not a class message.
IdentifierInfo * getIdentifier() const
getIdentifier - Get the identifier that names this declaration, if there is one.
CanQual< T > getUnqualifiedType() const
Retrieve the unqualified form of this type.
FunctionType - C99 6.7.5.3 - Function Declarators.
bool isThisDeclarationADefinition() const
Determine whether this particular declaration of this class is actually also a definition.
CanQualType getSizeType() const
Return the unique type for "size_t" (C99 7.17), defined in <stddef.h>.
Defines the SourceManager interface.
bool isRecordType() const
const char * getCharacterData(SourceLocation SL, bool *Invalid=nullptr) const
Return a pointer to the start of the specified location in the appropriate spelling MemoryBuffer...
param_iterator param_end()
llvm::MemoryBuffer * getBuffer(FileID FID, SourceLocation Loc, bool *Invalid=nullptr) const
Return the buffer for the specified FileID.
ParenExpr - This represents a parethesized expression, e.g.
void getSelectorLocs(SmallVectorImpl< SourceLocation > &SelLocs) const
std::string getAsString() const
FullSourceLoc getFullLoc(SourceLocation Loc) const
The base class of the type hierarchy.
bool isObjCQualifiedClassType() const
Represents Objective-C's @throw statement.
SourceLocation getLocStart() const LLVM_READONLY
instmeth_iterator instmeth_begin() const
const Expr * getInit() const
bool isBooleanType() const
A container of type source information.
bool isBlockPointerType() const
static StringLiteral * Create(const ASTContext &C, StringRef Str, StringKind Kind, bool Pascal, QualType Ty, const SourceLocation *Loc, unsigned NumStrs)
This is the "fully general" constructor that allows representation of strings formed from multiple co...
SourceLocation getLocStart() const LLVM_READONLY
float __ovld __cnfn distance(float p0, float p1)
Returns the distance between p0 and p1.
VarDecl - An instance of this class is created to represent a variable declaration or definition...
CompoundLiteralExpr - [C99 6.5.2.5].
Extra information about a function prototype.
SourceLocation getLocStart() const LLVM_READONLY
QualType getObjCClassType() const
Represents the Objective-C Class type.
const FunctionProtoType * getFunctionType() const
getFunctionType - Return the underlying function type for this block.
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
ObjCMethodDecl - Represents an instance or class method declaration.
RewriteBuffer - As code is rewritten, SourceBuffer's from the original input with modifications get a...
Expr * IgnoreImplicit() LLVM_READONLY
IgnoreImplicit - Skip past any implicit AST nodes which might surround this expression.
Describes how types, statements, expressions, and declarations should be printed. ...
void getAsStringInternal(std::string &Str, const PrintingPolicy &Policy) const
SourceLocation getLocation() const
QualType getFunctionNoProtoType(QualType ResultTy, const FunctionType::ExtInfo &Info) const
Return a K&R style C function type like 'int()'.
IdentifierInfo * getIdentifier() const
getIdentifier - Get the identifier that names the category interface associated with this implementat...
SourceLocation getLocStart() const LLVM_READONLY
QualType withConst() const
Retrieves a version of this type with const applied.
unsigned getNumParams() const
Kind getPropertyImplementation() const
unsigned ivar_size() const
RecordDecl - Represents a struct/union/class.
ObjCProtocolDecl * getCanonicalDecl() override
Retrieves the canonical declaration of this Objective-C protocol.
One of these records is kept for each identifier that is lexed.
ObjCProtocolDecl * getProtocol() const
const ObjCInterfaceDecl * getContainingInterface() const
Return the class interface that this ivar is logically contained in; this is either the interface whe...
class LLVM_ALIGNAS(8) DependentTemplateSpecializationType const IdentifierInfo * Name
Represents a template specialization type whose template cannot be resolved, e.g. ...
Represents a class type in Objective C.
StringRef getBufferData(FileID FID, bool *Invalid=nullptr) const
Return a StringRef to the source buffer data for the specified FileID.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
unsigned getNumSemanticExprs() const
protocol_iterator protocol_begin() const
std::string getNameAsString() const
Get the name of the class associated with this interface.
FieldDecl - An instance of this class is created by Sema::ActOnField to represent a member of a struc...
bool isCompleteDefinition() const
isCompleteDefinition - Return true if this decl has its body fully specified.
StringLiteral * getString()
const Stmt * getBody() const
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
QualType getTypeDeclType(const TypeDecl *Decl, const TypeDecl *PrevDecl=nullptr) const
Return the unique reference to the type for the specified type declaration.
An r-value expression (a pr-value in the C++11 taxonomy) produces a temporary value.
SourceLocation getSuperLoc() const
Retrieve the location of the 'super' keyword for a class or instance message to 'super', otherwise an invalid source location.
const VarDecl * getCatchParamDecl() const
Represents Objective-C's @catch statement.
const CompoundStmt * getSynchBody() const
Describes an C or C++ initializer list.
param_type_range param_types() const
SourceLocation getLocWithOffset(int Offset) const
Return a source location with the specified offset from this SourceLocation.
const LangOptions & getLangOpts() const
SourceLocation getSuperClassLoc() const
Retrieve the starting location of the superclass.
protocol_iterator protocol_end() const
QualType getReturnType() const
QualType getSuperType() const
Retrieve the type referred to by 'super'.
field_range fields() const
std::unique_ptr< ASTConsumer > CreateObjCRewriter(const std::string &InFile, std::unique_ptr< raw_ostream > OS, DiagnosticsEngine &Diags, const LangOptions &LOpts, bool SilenceRewriteMacroWarning)
Concrete class used by the front-end to report problems and issues.
Represents a typeof (or typeof) expression (a GCC extension).
TypeDecl - Represents a declaration of a type.
A builtin binary operation expression such as "x + y" or "x <= y".
Selector getSelector() const
bool isOverloadedOperator() const
isOverloadedOperator - Whether this function declaration represents an C++ overloaded operator...
std::string getNameAsString() const
getNameAsString - Get a human-readable name for the declaration, even if it is one of the special kin...
ObjCStringLiteral, used for Objective-C string literals i.e.
ObjCProtocolDecl * getDefinition()
Retrieve the definition of this protocol, if any.
bool declaresSameEntity(const Decl *D1, const Decl *D2)
Determine whether two declarations declare the same entity.
const Stmt * getCatchBody() const
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
CompoundStmt * getCompoundBody()
Represents an Objective-C protocol declaration.
const ObjCAtCatchStmt * getCatchStmt(unsigned I) const
Retrieve a @catch statement.
SourceLocation getLocEnd() const LLVM_READONLY
An ordinary object is located at an address in memory.
Represents an ObjC class declaration.
SourceLocation getLocEnd() const LLVM_READONLY
propimpl_range property_impls() const
Represents a linkage specification.
detail::InMemoryDirectory::const_iterator I
PropertyAttributeKind getPropertyAttributes() const
SourceLocation getAtStartLoc() const
SourceLocation getAtLoc() const
SourceRange getAtEndRange() const
ObjCPropertyImplDecl - Represents implementation declaration of a property in a class or category imp...
bool isThisDeclarationADefinition() const
Determine whether this particular declaration is also the definition.
ConditionalOperator - The ?: ternary operator.
SourceLocation getLocStart() const LLVM_READONLY
SourceLocation getLocEnd() const LLVM_READONLY
CompoundStmt - This represents a group of statements like { stmt stmt }.
QualType getParamType(unsigned i) const
Represents a prototype with parameter type info, e.g.
CastKind
CastKind - The kind of operation required for a conversion.
UnaryExprOrTypeTraitExpr - expression with either a type or (unevaluated) expression operand...
void getObjCEncodingForType(QualType T, std::string &S, const FieldDecl *Field=nullptr, QualType *NotEncodedT=nullptr) const
Emit the Objective-CC type encoding for the given type T into S.
SourceLocation getTypeSpecStartLoc() const
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee...
bool isFunctionPointerType() const
QualType getObjCInterfaceType(const ObjCInterfaceDecl *Decl, ObjCInterfaceDecl *PrevDecl=nullptr) const
getObjCInterfaceType - Return the unique reference to the type for the specified ObjC interface decl...
bool isRealFloatingType() const
Floating point categories.
const ObjCMethodDecl * getMethodDecl() const
SourceLocation getLocStart() const LLVM_READONLY
BlockDecl - This represents a block literal declaration, which is like an unnamed FunctionDecl...
QualType getPointeeType() const
ValueDecl - Represent the declaration of a variable (in which case it is an lvalue) a function (in wh...
Expr - This represents one expression.
StringRef getName() const
Return the actual identifier string.
ObjCIvarDecl * getPropertyIvarDecl() const
protocol_iterator protocol_begin() const
SourceLocation getRParenLoc() const
BlockExpr - Adaptor class for mixing a BlockDecl with expressions.
TranslationUnitDecl * getTranslationUnitDecl() const
bool isObjCGCWeak() const
true when Type is objc's weak.
Expr * getUnderlyingExpr() const
Represents Objective-C's @synchronized statement.
ObjCSelectorExpr used for @selector in Objective-C.
unsigned getExpansionLineNumber(SourceLocation Loc, bool *Invalid=nullptr) const
bool isWrittenInMainFile(SourceLocation Loc) const
Returns true if the spelling location for the given location is in the main file buffer.
classmeth_iterator classmeth_begin() const
Selector getSelector() const
Defines the clang::IdentifierInfo, clang::IdentifierTable, and clang::Selector interfaces.
ObjCIvarDecl * lookupInstanceVariable(IdentifierInfo *IVarName, ObjCInterfaceDecl *&ClassDeclared)
bool isInstanceMethod() const
bool isa(CodeGen::Address addr)
QualType getObjCIdType() const
Represents the Objective-CC id type.
An expression that sends a message to the given Objective-C object or class.
UnaryOperator - This represents the unary-expression's (except sizeof and alignof), the postinc/postdec operators from postfix-expression, and various extensions.
instmeth_iterator instmeth_end() const
unsigned ivar_size() const
The result type of a method or function.
CStyleCastExpr - An explicit cast in C (C99 6.5.4) or a C-style cast in C++ (C++ [expr.cast]), which uses the syntax (Type)expr.
Expr * getArg(unsigned Arg)
getArg - Return the specified argument.
const clang::PrintingPolicy & getPrintingPolicy() const
SourceLocation getRightLoc() const
ivar_iterator ivar_begin() const
ivar_iterator ivar_begin() const
param_iterator param_begin()
ArrayRef< ParmVarDecl * > parameters() const
Stmt * getBody(const FunctionDecl *&Definition) const
getBody - Retrieve the body (definition) of the function.
ivar_iterator ivar_end() const
PseudoObjectExpr - An expression which accesses a pseudo-object l-value.
Encodes a location in the source.
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
const TemplateArgument * iterator
StringRef getName() const
getName - Get the name of identifier for the class interface associated with this implementation as a...
static LLVM_READONLY bool isAlphanumeric(unsigned char c)
Return true if this character is an ASCII letter or digit: [a-zA-Z0-9].
Interfaces are the core concept in Objective-C for object oriented design.
ivar_iterator ivar_end() const
bool isValid() const
Return true if this is a valid SourceLocation object.
static OMPLinearClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, OpenMPLinearClauseKind Modifier, SourceLocation ModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL, ArrayRef< Expr * > PL, ArrayRef< Expr * > IL, Expr *Step, Expr *CalcStep, Stmt *PreInit, Expr *PostUpdate)
Creates clause with a list of variables VL and a linear step Step.
TypeSourceInfo * getTrivialTypeSourceInfo(QualType T, SourceLocation Loc=SourceLocation()) const
Allocate a TypeSourceInfo where all locations have been initialized to a given location, which defaults to the empty location.
bool refersToEnclosingVariableOrCapture() const
Does this DeclRefExpr refer to an enclosing local or a captured variable?
DeclStmt - Adaptor class for mixing declarations with statements and expressions. ...
TypeSourceInfo * getClassReceiverTypeInfo() const
Returns a type-source information of a class message send, or NULL if the message is not a class mess...
SourceLocation getLocStart() const LLVM_READONLY
bool isIntegralType(const ASTContext &Ctx) const
Determine whether this type is an integral type.
ObjCCategoryDecl - Represents a category declaration.
const ObjCInterfaceDecl * getClassInterface() const
decl_iterator decl_begin()
ObjCProtocolExpr used for protocol expression in Objective-C.
std::string getAsString() const
Derive the full selector name (e.g.
Represents one property declaration in an Objective-C interface.
ImplicitCastExpr - Allows us to explicitly represent implicit type conversions, which have no direct ...
QualType getReturnType() const
SourceLocation getBegin() const
const T * castAs() const
Member-template castAs<specific type>.
FileID getMainFileID() const
Returns the FileID of the main source file.
const BlockDecl * getBlockDecl() const
unsigned TypeAlias
Whether this template specialization type is a substituted type alias.
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
QualType getObjCInstanceType()
Retrieve the Objective-C "instancetype" type, if already known; otherwise, returns a NULL type;...
QualType getPointeeType() const
QualType getFunctionType(QualType ResultTy, ArrayRef< QualType > Args, const FunctionProtoType::ExtProtoInfo &EPI) const
Return a normal function type with a typed argument list.
QualType getObjCSelType() const
Retrieve the type that corresponds to the predefined Objective-C 'SEL' type.
decl_iterator - Iterates through the declarations stored within this context.
Expr * getInstanceReceiver()
Returns the object expression (receiver) for an instance message, or null for a message that is not a...
Base class for declarations which introduce a typedef-name.
Expr * getResultExpr()
Return the result-bearing expression, or null if there is none.
An opaque identifier used by SourceManager which refers to a source file (MemoryBuffer) along with it...
instmeth_range instance_methods() const
ObjCCategoryDecl * FindCategoryDeclaration(IdentifierInfo *CategoryId) const
FindCategoryDeclaration - Finds category declaration in the list of categories for this class and ret...
SourceLocation getLParenLoc() const
unsigned getByteLength() const
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
SourceLocation getLocStart() const LLVM_READONLY
std::string getNameAsString() const
Get the name of the class associated with this interface.
QualType IgnoreParens() const
Returns the specified type after dropping any outer-level parentheses.
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
const Expr * getSynchExpr() const
bool hasDefinition() const
Determine whether this protocol has a definition.
U cast(CodeGen::Address addr)
int printf(__constant const char *st,...)
bool isThisDeclarationADefinition() const
isThisDeclarationADefinition - Returns whether this specific declaration of the function is also a de...
Selector getSelector() const
detail::InMemoryDirectory::const_iterator E
SourceLocation getEndOfDefinitionLoc() const
CanQualType getCanonicalType(QualType T) const
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
specific_decl_iterator - Iterates over a subrange of declarations stored in a DeclContext, providing only those that are of type SpecificDecl (or a class derived from it).
Expr * IgnoreParenImpCasts() LLVM_READONLY
IgnoreParenImpCasts - Ignore parentheses and implicit casts.
Defines the Diagnostic-related interfaces.
Represents a pointer to an Objective C object.
SourceLocation getRParenLoc() const
ObjCImplementationDecl - Represents a class definition - this is where method definitions are specifi...
ObjCMethodDecl * getGetterMethodDecl() const
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
SourceLocation getLeftLoc() const
const T * getAs() const
Member-template getAs<specific type>'.
Represents Objective-C's collection statement.
ObjCMethodDecl * getSetterMethodDecl() const
ObjCEncodeExpr, used for @encode in Objective-C.
static CStyleCastExpr * Create(const ASTContext &Context, QualType T, ExprValueKind VK, CastKind K, Expr *Op, const CXXCastPath *BasePath, TypeSourceInfo *WrittenTy, SourceLocation L, SourceLocation R)
instprop_range instance_properties() const
bool isObjCQualifiedIdType() const
MutableArrayRef< ParmVarDecl * >::iterator param_iterator
ObjCInterfaceDecl * getCanonicalDecl() override
Retrieves the canonical declaration of this Objective-C class.
Represents Objective-C's @finally statement.
uint64_t getCharWidth() const
Return the size of the character type, in bits.
const ObjCProtocolList & getReferencedProtocols() const
ExprIterator arg_iterator
unsigned getNumArgs() const
Return the number of actual arguments in this message, not counting the receiver. ...
protocol_iterator protocol_end() const
QualType getTagDeclType(const TagDecl *Decl) const
Return the unique reference to the type for the specified TagDecl (struct/union/class/enum) decl...
bool getObjCEncodingForMethodDecl(const ObjCMethodDecl *Decl, std::string &S, bool Extended=false) const
Emit the encoded type for the method declaration Decl into S.
unsigned getNumCatchStmts() const
Retrieve the number of @catch statements in this try-catch-finally block.
SourceLocation getRParenLoc() const
ObjCIvarRefExpr - A reference to an ObjC instance variable.
SourceManager & getSourceManager()
X
Add a minimal nested name specifier fixit hint to allow lookup of a tag name from an outer enclosing ...
ObjCPropertyDecl * getPropertyDecl() const
classmeth_range class_methods() const
const internal::VariadicDynCastAllOfMatcher< Stmt, CastExpr > castExpr
Matches any cast nodes of Clang's AST.
Rewriter - This is the main interface to the rewrite buffers.
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
bool isImplicitInterfaceDecl() const
isImplicitInterfaceDecl - check that this is an implicitly declared ObjCInterfaceDecl node...
ContinueStmt - This represents a continue.
bool isReadOnly() const
isReadOnly - Return true iff the property has a setter.
bool isObjCObjectPointerType() const
QualType getEncodedType() const
ObjCIvarDecl - Represents an ObjC instance variable.
bool isImplicit() const
Indicates whether the message send was implicitly generated by the implementation.
Represents Objective-C's @try ... @catch ... @finally statement.
const Expr * getThrowExpr() const
StringLiteral - This represents a string literal expression, e.g.
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
ObjCInterfaceDecl * getSuperClass() const
const Stmt * getTryBody() const
Retrieve the @try body.
TranslationUnitDecl - The top declaration context.
A reference to a declared variable, function, enum, etc.
ExprValueKind getValueKind() const
getValueKind - The value kind that this expression produces.
QualType getConstantArrayType(QualType EltTy, const llvm::APInt &ArySize, ArrayType::ArraySizeModifier ASM, unsigned IndexTypeQuals) const
Return the unique reference to the type for a constant array of the specified element type...
BreakStmt - This represents a break.
Expr * getSemanticExpr(unsigned index)
SourceLocation getLocForStartOfFile(FileID FID) const
Return the source location corresponding to the first byte of the specified file. ...
An l-value expression is a reference to an object with independent storage.
A trivial tuple used to represent a source range.
NamedDecl - This represents a decl with a name.
SourceLocation getLocStart() const LLVM_READONLY
SourceLocation getExpansionLoc(SourceLocation Loc) const
Given a SourceLocation object Loc, return the expansion location referenced by the ID...
SourceLocation getLocStart() const LLVM_READONLY
bool isNull() const
Return true if this QualType doesn't point to a type yet.
const ObjCObjectPointerType * getAsObjCInterfacePointerType() const
ReceiverKind getReceiverKind() const
Determine the kind of receiver that this message is being sent to.
ObjCCategoryImplDecl - An object of this class encapsulates a category @implementation declaration...
This class handles loading and caching of source files into memory.
QualType getBaseElementType(const ArrayType *VAT) const
Return the innermost element type of an array type.
bool isObjCQualifiedInterfaceType() const
bool BlockRequiresCopying(QualType Ty, const VarDecl *D)
Returns true iff we need copy/dispose helpers for the given type.
const ObjCProtocolList & getReferencedProtocols() const
bool isPointerType() const