23 #include "clang/Config/config.h"
26 #include "llvm/ADT/DenseSet.h"
27 #include "llvm/ADT/SmallPtrSet.h"
28 #include "llvm/ADT/StringExtras.h"
29 #include "llvm/Support/MemoryBuffer.h"
30 #include "llvm/Support/raw_ostream.h"
33 #if CLANG_ENABLE_OBJC_REWRITER
35 using namespace clang;
56 BLOCK_NEEDS_FREE = (1 << 24),
59 BLOCK_IS_GC = (1 << 27),
61 BLOCK_HAS_DESCRIPTOR = (1 << 29)
71 const char *MainFileStart, *MainFileEnd;
75 std::unique_ptr<raw_ostream> OutFile;
80 Expr *GlobalConstructionExp;
81 unsigned RewriteFailedDiag;
82 unsigned GlobalBlockRewriteFailedDiag;
84 unsigned NumObjCStringLiterals;
85 VarDecl *ConstantStringClassReference;
91 unsigned TryFinallyContainsReturnDiag;
143 llvm::DenseMap<ValueDecl *, unsigned> BlockByRefDeclNo;
147 llvm::DenseMap<BlockExpr *, std::string> RewrittenBlockExprs;
153 llvm::DenseMap<const ObjCIvarDecl* , unsigned> IvarGroupNumber;
156 llvm::DenseMap<std::pair<const ObjCInterfaceDecl*, unsigned>,
QualType> GroupRecordType;
162 llvm::DenseMap<Stmt *, Stmt *> ReplacedNodes;
166 bool SilenceRewriteMacroWarning;
167 bool GenerateLineInfo;
168 bool objc_impl_method;
170 bool DisableReplaceStmt;
171 class DisableReplaceStmtScope {
172 RewriteModernObjC &R;
176 DisableReplaceStmtScope(RewriteModernObjC &R)
177 : R(R), SavedValue(R.DisableReplaceStmt) {
178 R.DisableReplaceStmt =
true;
180 ~DisableReplaceStmtScope() {
181 R.DisableReplaceStmt = SavedValue;
187 llvm::DenseMap<ObjCMethodDecl*, std::string> MethodInternalNames;
193 if (!
Class->isThisDeclarationADefinition()) {
194 RewriteForwardClassDecl(D);
198 ObjCInterfacesSeen.push_back(Class);
204 if (!Proto->isThisDeclarationADefinition()) {
205 RewriteForwardProtocolDecl(D);
215 if (FDecl->isThisDeclarationADefinition() &&
217 !FDecl->isTopLevelDeclInObjCContainer()) {
218 FunctionDefinitionsSeen.push_back(FDecl);
222 HandleTopLevelSingleDecl(*I);
227 void HandleTopLevelDeclInObjCContainer(
DeclGroupRef D)
override {
230 if (isTopLevelBlockPointerType(TD->getUnderlyingType()))
231 RewriteBlockPointerDecl(TD);
232 else if (TD->getUnderlyingType()->isFunctionPointerType())
233 CheckFunctionPointerDecl(TD->getUnderlyingType(), TD);
235 RewriteObjCQualifiedInterfaceTypes(TD);
240 void HandleTopLevelSingleDecl(
Decl *D);
241 void HandleDeclInMainFile(
Decl *D);
242 RewriteModernObjC(
std::string inFile, std::unique_ptr<raw_ostream> OS,
244 bool silenceMacroWarn,
bool LineInfo);
246 ~RewriteModernObjC()
override {}
248 void HandleTranslationUnit(
ASTContext &C)
override;
250 void ReplaceStmt(
Stmt *Old,
Stmt *New) {
255 assert(Old !=
nullptr && New !=
nullptr &&
"Expected non-null Stmt's");
257 Stmt *ReplacingStmt = ReplacedNodes[Old];
261 if (DisableReplaceStmt)
273 llvm::raw_string_ostream S(SStr);
279 ReplacedNodes[Old] = New;
282 if (SilenceRewriteMacroWarning)
289 bool InsertAfter =
true) {
291 if (!
Rewrite.InsertText(Loc, Str, InsertAfter) ||
292 SilenceRewriteMacroWarning)
301 if (!
Rewrite.ReplaceText(Start, OrigLength, Str) ||
302 SilenceRewriteMacroWarning)
310 void RewriteInclude();
311 void RewriteLineDirective(
const Decl *D);
318 void RewriteImplementations();
323 void RewriteImplementationDecl(
Decl *Dcl);
340 void RewriteObjCQualifiedInterfaceTypes(
Decl *Dcl);
341 void RewriteTypeOfDecl(
VarDecl *VD);
342 void RewriteObjCQualifiedInterfaceTypes(
Expr *E);
347 Stmt *RewriteFunctionBodyOrGlobalInitializer(
Stmt *S);
368 void RewriteImplicitCastObjCExpr(
CastExpr *IE);
380 QualType SynthesizeBitfieldGroupStructType(
388 void RewriteBlockPointerDecl(
NamedDecl *VD);
389 void RewriteByRefVar(
VarDecl *VD,
bool firstDecl,
bool lastDecl);
399 bool &IsNamedDefinition);
408 void Initialize(
ASTContext &context)
override;
428 void SynthMsgSendFunctionDecl();
429 void SynthMsgSendSuperFunctionDecl();
430 void SynthMsgSendStretFunctionDecl();
431 void SynthMsgSendFpretFunctionDecl();
432 void SynthMsgSendSuperStretFunctionDecl();
433 void SynthGetClassFunctionDecl();
434 void SynthGetMetaClassFunctionDecl();
435 void SynthGetSuperClassFunctionDecl();
436 void SynthSelGetUidFunctionDecl();
437 void SynthSuperConstructorFunctionDecl();
440 template<
typename MethodIterator>
441 void RewriteObjCMethodsMetaData(MethodIterator MethodBegin,
442 MethodIterator MethodEnd,
443 bool IsInstanceMethod,
451 void RewriteClassSetupInitHook(
std::string &Result);
453 void RewriteMetaDataIntoBuffer(
std::string &Result);
457 void RewriteCategorySetupInitHook(
std::string &Result);
474 int i, StringRef funcName,
485 void WarnAboutReturnGotoStmts(
Stmt *S);
487 void InsertBlockLiteralsWithinFunction(
FunctionDecl *FD);
490 bool IsDeclStmtInForeachHeader(
DeclStmt *DS);
491 void CollectBlockDeclRefInfo(
BlockExpr *Exp);
492 void GetBlockDeclRefExprs(
Stmt *S);
493 void GetInnerBlockDeclRefExprs(
Stmt *S,
495 llvm::SmallPtrSetImpl<const DeclContext *> &InnerContexts);
499 bool isTopLevelBlockPointerType(
QualType T) {
500 return isa<BlockPointerType>(T);
506 bool convertBlockPointerToFunctionPointer(
QualType &T) {
507 if (isTopLevelBlockPointerType(T)) {
515 bool convertObjCTypeToCStyleType(
QualType &T);
517 bool needToScanForQualifiers(
QualType T);
519 QualType getConstantStringStructType();
522 void convertToUnqualifiedObjCType(
QualType &T) {
553 if (isa<ObjCInterfaceType>(PT->getPointeeType()) ||
554 PT->getPointeeType()->isObjCQualifiedIdType())
560 bool PointerTypeTakesAnyBlockArguments(
QualType QT);
561 bool PointerTypeTakesAnyObjCQualifiedType(
QualType QT);
562 void GetExtentOfArgList(
const char *Name,
const char *&LParen,
563 const char *&RParen);
566 for (
unsigned i = 0; i < From.length(); i++) {
576 bool variadic =
false) {
593 bool ImplementationIsNonLazy(
const ObjCImplDecl *OD)
const {
609 void RewriteModernObjC::RewriteBlocksInFunctionProtoType(
QualType funcType,
612 = dyn_cast<FunctionProtoType>(funcType.
IgnoreParens())) {
613 for (
const auto &I : fproto->param_types())
614 if (isTopLevelBlockPointerType(I)) {
616 RewriteBlockPointerDecl(D);
622 void RewriteModernObjC::CheckFunctionPointerDecl(
QualType funcType,
NamedDecl *ND) {
624 if (PT && PointerTypeTakesAnyBlockArguments(funcType))
629 std::string::size_type DotPos =
Filename.rfind(
'.');
631 if (DotPos == std::string::npos) {
639 return Ext ==
"h" || Ext ==
"hh" || Ext ==
"H";
642 RewriteModernObjC::RewriteModernObjC(
std::string inFile,
643 std::unique_ptr<raw_ostream> OS,
646 bool silenceMacroWarn,
bool LineInfo)
647 : Diags(D), LangOpts(LOpts), InFileName(inFile), OutFile(
std::move(
OS)),
648 SilenceRewriteMacroWarning(silenceMacroWarn), GenerateLineInfo(LineInfo) {
651 "rewriting sub-expression within a macro (may not be correct)");
655 "rewriting block literal declared in global scope is not implemented");
659 "rewriter doesn't support user-specified control flow semantics "
660 "for @try/@finally (code may not execute properly)");
664 const std::string &InFile, std::unique_ptr<raw_ostream> OS,
666 bool SilenceRewriteMacroWarning,
bool LineInfo) {
667 return std::make_unique<RewriteModernObjC>(InFile, std::move(OS), Diags,
668 LOpts, SilenceRewriteMacroWarning,
672 void RewriteModernObjC::InitializeCommon(
ASTContext &context) {
676 MsgSendFunctionDecl =
nullptr;
677 MsgSendSuperFunctionDecl =
nullptr;
678 MsgSendStretFunctionDecl =
nullptr;
679 MsgSendSuperStretFunctionDecl =
nullptr;
680 MsgSendFpretFunctionDecl =
nullptr;
681 GetClassFunctionDecl =
nullptr;
682 GetMetaClassFunctionDecl =
nullptr;
683 GetSuperClassFunctionDecl =
nullptr;
684 SelGetUidFunctionDecl =
nullptr;
685 CFStringFunctionDecl =
nullptr;
686 ConstantStringClassReference =
nullptr;
687 NSStringRecord =
nullptr;
688 CurMethodDef =
nullptr;
689 CurFunctionDef =
nullptr;
690 GlobalVarDecl =
nullptr;
691 GlobalConstructionExp =
nullptr;
692 SuperStructDecl =
nullptr;
693 ProtocolTypeDecl =
nullptr;
694 ConstantStringDecl =
nullptr;
696 SuperConstructorFunctionDecl =
nullptr;
697 NumObjCStringLiterals = 0;
698 PropParentMap =
nullptr;
699 CurrentBody =
nullptr;
700 DisableReplaceStmt =
false;
701 objc_impl_method =
false;
704 MainFileID =
SM->getMainFileID();
705 llvm::MemoryBufferRef MainBuf =
SM->getBufferOrFake(MainFileID);
706 MainFileStart = MainBuf.getBufferStart();
707 MainFileEnd = MainBuf.getBufferEnd();
716 void RewriteModernObjC::HandleTopLevelSingleDecl(
Decl *D) {
724 Loc =
SM->getExpansionLoc(Loc);
731 RewriteFunctionDecl(FD);
732 }
else if (
VarDecl *FVD = dyn_cast<VarDecl>(D)) {
734 if (FVD->getName() ==
"_NSConstantStringClassReference") {
735 ConstantStringClassReference = FVD;
739 RewriteCategoryDecl(CD);
741 if (PD->isThisDeclarationADefinition())
742 RewriteProtocolDecl(PD);
746 DIEnd = LSD->decls_end();
749 if (!IFace->isThisDeclarationADefinition()) {
753 if (isa<ObjCInterfaceDecl>(*DI) &&
754 !cast<ObjCInterfaceDecl>(*DI)->isThisDeclarationADefinition() &&
755 StartLoc == (*DI)->getBeginLoc())
761 }
while (DI != DIEnd);
762 RewriteForwardClassDecl(DG);
767 ObjCInterfacesSeen.push_back(IFace);
774 if (!Proto->isThisDeclarationADefinition()) {
778 if (isa<ObjCProtocolDecl>(*DI) &&
779 !cast<ObjCProtocolDecl>(*DI)->isThisDeclarationADefinition() &&
780 StartLoc == (*DI)->getBeginLoc())
786 }
while (DI != DIEnd);
787 RewriteForwardProtocolDecl(DG);
792 HandleTopLevelSingleDecl(*DI);
797 if (
SM->isWrittenInMainFile(Loc))
798 return HandleDeclInMainFile(D);
805 void RewriteModernObjC::RewriteInclude() {
807 StringRef MainBuf =
SM->getBufferData(MainFileID);
808 const char *MainBufStart = MainBuf.begin();
809 const char *MainBufEnd = MainBuf.end();
810 size_t ImportLen = strlen(
"import");
813 for (
const char *BufPtr = MainBufStart; BufPtr < MainBufEnd; ++BufPtr) {
814 if (*BufPtr ==
'#') {
815 if (++BufPtr == MainBufEnd)
817 while (*BufPtr ==
' ' || *BufPtr ==
'\t')
818 if (++BufPtr == MainBufEnd)
820 if (!strncmp(BufPtr,
"import", ImportLen)) {
824 ReplaceText(ImportLoc, ImportLen,
"include");
833 Result +=
"OBJC_IVAR_$_";
846 ObjCIvarBitfieldGroupOffset(D, IvarOffsetName);
853 IvarT = GetGroupRecordTypeForObjCIvarBitfield(D);
855 if (!isa<TypedefType>(IvarT) && IvarT->
isRecordType()) {
863 CDecl = CatDecl->getClassInterface();
870 unsigned UnsignedIntSize =
872 Expr *
Zero = IntegerLiteral::Create(*Context,
875 Zero = NoTypeInfoCStyleCastExpr(Context, PtrStructIMPL, CK_BitCast,
Zero);
889 convertObjCTypeToCStyleType(IvarT);
896 S +=
"((char *)self + ";
920 static bool objcGetPropertyDefined =
false;
921 static bool objcSetPropertyDefined =
false;
926 InsertText(startLoc,
"// ");
927 const char *startBuf =
SM->getCharacterData(startLoc);
928 assert((*startBuf ==
'@') &&
"bogus @synthesize location");
929 const char *semiBuf = strchr(startBuf,
';');
930 assert((*semiBuf ==
';') &&
"@synthesize: can't find ';'");
941 assert(IMD && OID &&
"Synthesized ivars must be attached to @implementation");
945 bool GenGetProperty =
950 if (GenGetProperty && !objcGetPropertyDefined) {
951 objcGetPropertyDefined =
true;
953 Getr =
"\nextern \"C\" __declspec(dllimport) "
954 "id objc_getProperty(id, SEL, long, bool);\n";
961 if (GenGetProperty) {
974 for (
unsigned i = 0, e = FT->getNumParams(); i != e; ++i) {
980 if (FT->isVariadic()) {
981 if (FT->getNumParams())
990 Getr +=
"return (_TYPE)";
991 Getr +=
"objc_getProperty(self, _cmd, ";
992 RewriteIvarOffsetComputation(OID, Getr);
998 InsertText(startGetterSetterLoc, Getr);
1009 if (GenSetProperty && !objcSetPropertyDefined) {
1010 objcSetPropertyDefined =
true;
1012 Setr =
"\nextern \"C\" __declspec(dllimport) "
1013 "void objc_setProperty (id, SEL, long, id, bool, bool);\n";
1021 if (GenSetProperty) {
1022 Setr +=
"objc_setProperty (self, _cmd, ";
1023 RewriteIvarOffsetComputation(OID, Setr);
1041 InsertText(startGetterSetterLoc, Setr);
1046 typedefString +=
"\n#ifndef _REWRITER_typedef_";
1048 typedefString +=
"\n";
1049 typedefString +=
"#define _REWRITER_typedef_";
1051 typedefString +=
"\n";
1052 typedefString +=
"typedef struct objc_object ";
1055 typedefString +=
";\ntypedef struct {} _objc_exc_";
1057 typedefString +=
";\n#endif\n";
1060 void RewriteModernObjC::RewriteForwardClassEpilogue(
ObjCInterfaceDecl *ClassDecl,
1063 const char *startBuf =
SM->getCharacterData(startLoc);
1064 const char *semiPtr = strchr(startBuf,
';');
1066 ReplaceText(startLoc, semiPtr-startBuf+1, typedefString);
1069 void RewriteModernObjC::RewriteForwardClassDecl(
DeclGroupRef D) {
1073 if (I == D.
begin()) {
1077 typedefString +=
"// @class ";
1078 typedefString += ForwardDecl->getNameAsString();
1079 typedefString +=
";";
1084 HandleTopLevelSingleDecl(*I);
1087 RewriteForwardClassEpilogue(cast<ObjCInterfaceDecl>(*I), typedefString);
1090 void RewriteModernObjC::RewriteForwardClassDecl(
1093 for (
unsigned i = 0; i < D.size(); i++) {
1096 typedefString +=
"// @class ";
1098 typedefString +=
";";
1102 RewriteForwardClassEpilogue(cast<ObjCInterfaceDecl>(D[0]), typedefString);
1105 void RewriteModernObjC::RewriteMethodDeclaration(
ObjCMethodDecl *Method) {
1113 if (
SM->getExpansionLineNumber(LocEnd) >
1114 SM->getExpansionLineNumber(LocStart)) {
1115 InsertText(LocStart,
"#if 0\n");
1116 ReplaceText(LocEnd, 1,
";\n#endif\n");
1118 InsertText(LocStart,
"// ");
1125 ReplaceText(Loc, 0,
"// ");
1134 ReplaceText(LocStart, 1,
"/** ");
1138 ReplaceText(LocStart, 0,
"// ");
1145 RewriteMethodDeclaration(I);
1147 RewriteMethodDeclaration(I);
1151 strlen(
"@end"),
"/* @end */\n");
1159 ReplaceText(LocStart, 0,
"// ");
1162 RewriteMethodDeclaration(I);
1164 RewriteMethodDeclaration(I);
1170 ReplaceText(LocEnd, strlen(
"@end"),
"/* @end */\n");
1173 const char *startBuf =
SM->getCharacterData(LocStart);
1174 const char *endBuf =
SM->getCharacterData(LocEnd);
1175 for (
const char *p = startBuf; p < endBuf; p++) {
1176 if (*p ==
'@' && !strncmp(p+1,
"optional", strlen(
"optional"))) {
1178 ReplaceText(OptionalLoc, strlen(
"@optional"),
"/* @optional */");
1181 else if (*p ==
'@' && !strncmp(p+1,
"required", strlen(
"required"))) {
1183 ReplaceText(OptionalLoc, strlen(
"@required"),
"/* @required */");
1189 void RewriteModernObjC::RewriteForwardProtocolDecl(
DeclGroupRef D) {
1192 llvm_unreachable(
"Invalid SourceLocation");
1194 ReplaceText(LocStart, 0,
"// ");
1201 llvm_unreachable(
"Invalid SourceLocation");
1203 ReplaceText(LocStart, 0,
"// ");
1234 ResultStr +=
"\nstatic ";
1235 RewriteTypeIntoString(OMD->
getReturnType(), ResultStr, FPRetType);
1257 int len = selString.size();
1258 for (
int i = 0; i < len; i++)
1259 if (selString[i] ==
':')
1261 NameStr += selString;
1264 MethodInternalNames[OMD] = NameStr;
1265 ResultStr += NameStr;
1274 if (!LangOpts.MicrosoftExt) {
1276 ResultStr +=
"struct ";
1286 ResultStr +=
" self, ";
1288 ResultStr +=
" _cmd";
1291 for (
const auto *PDecl : OMD->
parameters()) {
1293 if (PDecl->getType()->isObjCQualifiedIdType()) {
1300 (void)convertBlockPointerToFunctionPointer(QT);
1306 ResultStr +=
", ...";
1315 for (
unsigned i = 0, e = FT->getNumParams(); i != e; ++i) {
1316 if (i) ResultStr +=
", ";
1319 ResultStr += ParamStr;
1321 if (FT->isVariadic()) {
1322 if (FT->getNumParams())
1333 void RewriteModernObjC::RewriteImplementationDecl(
Decl *OID) {
1336 assert((IMD || CID) &&
"Unknown implementation type");
1358 const char *startBuf =
SM->getCharacterData(LocStart);
1359 const char *endBuf =
SM->getCharacterData(LocEnd);
1360 ReplaceText(LocStart, endBuf-startBuf, ResultStr);
1371 const char *startBuf =
SM->getCharacterData(LocStart);
1372 const char *endBuf =
SM->getCharacterData(LocEnd);
1373 ReplaceText(LocStart, endBuf-startBuf, ResultStr);
1376 RewritePropertyImplDecl(I, IMD, CID);
1383 if (ObjCSynthesizedStructs.count(ClassDecl))
1387 while (SuperClass) {
1388 RewriteInterfaceDecl(SuperClass);
1395 RewriteIvarOffsetSymbols(ClassDecl, ResultStr);
1397 RewriteObjCInternalStruct(ClassDecl, ResultStr);
1404 RewriteMethodDeclaration(I);
1406 RewriteMethodDeclaration(I);
1428 DisableReplaceStmtScope S(*
this);
1434 Base = cast<OpaqueValueExpr>(
Base)->getSourceExpr();
1435 Base = cast<Expr>(RewriteFunctionBodyOrGlobalInitializer(
Base));
1439 for (
unsigned i = 0; i < numArgs; i++) {
1441 if (isa<OpaqueValueExpr>(Arg))
1442 Arg = cast<OpaqueValueExpr>(Arg)->getSourceExpr();
1443 Arg = cast<Expr>(RewriteFunctionBodyOrGlobalInitializer(Arg));
1444 Args.push_back(Arg);
1454 case ObjCMessageExpr::Class:
1455 NewMsg = ObjCMessageExpr::Create(*Context, OldMsg->
getType(),
1467 case ObjCMessageExpr::Instance:
1468 NewMsg = ObjCMessageExpr::Create(*Context, OldMsg->
getType(),
1480 case ObjCMessageExpr::SuperClass:
1481 case ObjCMessageExpr::SuperInstance:
1482 NewMsg = ObjCMessageExpr::Create(*Context, OldMsg->
getType(),
1497 Stmt *Replacement = SynthMessageExpr(NewMsg);
1498 ReplaceStmtWithRange(PseudoOp, Replacement, OldRange);
1515 DisableReplaceStmtScope S(*
this);
1519 Base = cast<OpaqueValueExpr>(
Base)->getSourceExpr();
1520 Base = cast<Expr>(RewriteFunctionBodyOrGlobalInitializer(
Base));
1523 for (
unsigned i = 0; i < numArgs; i++) {
1525 if (isa<OpaqueValueExpr>(Arg))
1526 Arg = cast<OpaqueValueExpr>(Arg)->getSourceExpr();
1527 Arg = cast<Expr>(RewriteFunctionBodyOrGlobalInitializer(Arg));
1528 Args.push_back(Arg);
1537 case ObjCMessageExpr::Class:
1538 NewMsg = ObjCMessageExpr::Create(*Context, OldMsg->
getType(),
1550 case ObjCMessageExpr::Instance:
1551 NewMsg = ObjCMessageExpr::Create(*Context, OldMsg->
getType(),
1563 case ObjCMessageExpr::SuperClass:
1564 case ObjCMessageExpr::SuperInstance:
1565 NewMsg = ObjCMessageExpr::Create(*Context, OldMsg->
getType(),
1580 Stmt *Replacement = SynthMessageExpr(NewMsg);
1581 ReplaceStmtWithRange(PseudoOp, Replacement, OldRange);
1594 void RewriteModernObjC::SynthCountByEnumWithState(
std::string &buf) {
1595 buf +=
"((_WIN_NSUInteger (*) (id, SEL, struct __objcFastEnumerationState *, "
1596 "id *, _WIN_NSUInteger))(void *)objc_msgSend)";
1598 buf +=
"((id)l_collection,\n\t\t";
1599 buf +=
"sel_registerName(\"countByEnumeratingWithState:objects:count:\"),";
1601 buf +=
"&enumState, "
1602 "(id *)__rw_items, (_WIN_NSUInteger)16)";
1609 if (Stmts.empty() || !isa<ObjCForCollectionStmt>(Stmts.back()))
1615 buf =
"goto __break_label_";
1616 buf += utostr(ObjCBcLabelNo.back());
1617 ReplaceText(startLoc, strlen(
"break"), buf);
1622 void RewriteModernObjC::ConvertSourceLocationToLineDirective(
1625 if (Loc.
isFileID() && GenerateLineInfo) {
1626 LineString +=
"\n#line ";
1628 LineString += utostr(PLoc.
getLine());
1629 LineString +=
" \"";
1630 LineString += Lexer::Stringify(PLoc.
getFilename());
1631 LineString +=
"\"\n";
1639 if (Stmts.empty() || !isa<ObjCForCollectionStmt>(Stmts.back()))
1645 buf =
"goto __continue_label_";
1646 buf += utostr(ObjCBcLabelNo.back());
1647 ReplaceText(startLoc, strlen(
"continue"), buf);
1686 assert(!Stmts.empty() &&
"ObjCForCollectionStmt - Statement stack empty");
1687 assert(isa<ObjCForCollectionStmt>(Stmts.back()) &&
1688 "ObjCForCollectionStmt Statement stack mismatch");
1689 assert(!ObjCBcLabelNo.empty() &&
1690 "ObjCForCollectionStmt - Label No stack empty");
1693 const char *startBuf =
SM->getCharacterData(startLoc);
1694 StringRef elementName;
1699 ConvertSourceLocationToLineDirective(ForEachLoc, buf);
1701 if (
DeclStmt *DS = dyn_cast<DeclStmt>(S->getElement())) {
1703 NamedDecl* D = cast<NamedDecl>(DS->getSingleDecl());
1704 QualType ElementType = cast<ValueDecl>(D)->getType();
1708 elementTypeAsString =
"id";
1711 buf += elementTypeAsString;
1718 DeclRefExpr *DR = cast<DeclRefExpr>(S->getElement());
1724 elementTypeAsString =
"id";
1730 buf +=
"struct __objcFastEnumerationState enumState = { 0 };\n\t";
1732 buf +=
"id __rw_items[16];\n\t";
1734 buf +=
"id l_collection = (id)";
1736 const char *startCollectionBuf = startBuf;
1737 startCollectionBuf += 3;
1738 startCollectionBuf = strchr(startCollectionBuf,
'(');
1739 startCollectionBuf++;
1741 while (*startCollectionBuf !=
' ' ||
1742 *(startCollectionBuf+1) !=
'i' || *(startCollectionBuf+2) !=
'n' ||
1743 (*(startCollectionBuf+3) !=
' ' &&
1744 *(startCollectionBuf+3) !=
'[' && *(startCollectionBuf+3) !=
'('))
1745 startCollectionBuf++;
1746 startCollectionBuf += 3;
1749 ReplaceText(startLoc, startCollectionBuf - startBuf, buf);
1752 const char *rparenBuf =
SM->getCharacterData(rightParenLoc);
1767 buf +=
"_WIN_NSUInteger limit =\n\t\t";
1768 SynthCountByEnumWithState(buf);
1778 buf +=
"if (limit) {\n\t";
1779 buf +=
"unsigned long startMutations = *enumState.mutationsPtr;\n\t";
1780 buf +=
"do {\n\t\t";
1781 buf +=
"unsigned long counter = 0;\n\t\t";
1782 buf +=
"do {\n\t\t\t";
1783 buf +=
"if (startMutations != *enumState.mutationsPtr)\n\t\t\t\t";
1784 buf +=
"objc_enumerationMutation(l_collection);\n\t\t\t";
1787 buf += elementTypeAsString;
1788 buf +=
")enumState.itemsPtr[counter++];";
1790 ReplaceText(lparenLoc, 1, buf);
1804 buf +=
"__continue_label_";
1805 buf += utostr(ObjCBcLabelNo.back());
1808 buf +=
"} while (counter < limit);\n\t";
1809 buf +=
"} while ((limit = ";
1810 SynthCountByEnumWithState(buf);
1814 buf += elementTypeAsString;
1816 buf +=
"__break_label_";
1817 buf += utostr(ObjCBcLabelNo.back());
1820 buf +=
"else\n\t\t";
1823 buf += elementTypeAsString;
1829 if (isa<CompoundStmt>(S->getBody())) {
1831 InsertText(endBodyLoc, buf);
1840 const char *stmtBuf =
SM->getCharacterData(OrigEnd);
1841 const char *semiBuf = strchr(stmtBuf,
';');
1842 assert(semiBuf &&
"Can't find ';'");
1844 InsertText(endBodyLoc, buf);
1847 ObjCBcLabelNo.pop_back();
1852 buf +=
"{ struct _FIN { _FIN(id reth) : rethrow(reth) {}\n";
1853 buf +=
"\t~_FIN() { if (rethrow) objc_exception_throw(rethrow); }\n";
1854 buf +=
"\tid rethrow;\n";
1855 buf +=
"\t} _fin_force_rethow(_rethrow);";
1867 const char *startBuf =
SM->getCharacterData(startLoc);
1869 assert((*startBuf ==
'@') &&
"bogus @synchronized location");
1873 ConvertSourceLocationToLineDirective(SynchLoc, buf);
1874 buf +=
"{ id _rethrow = 0; id _sync_obj = (id)";
1876 const char *lparenBuf = startBuf;
1877 while (*lparenBuf !=
'(') lparenBuf++;
1878 ReplaceText(startLoc, lparenBuf-startBuf+1, buf);
1880 buf =
"; objc_sync_enter(_sync_obj);\n";
1881 buf +=
"try {\n\tstruct _SYNC_EXIT { _SYNC_EXIT(id arg) : sync_exit(arg) {}";
1882 buf +=
"\n\t~_SYNC_EXIT() {objc_sync_exit(sync_exit);}";
1883 buf +=
"\n\tid sync_exit;";
1884 buf +=
"\n\t} _sync_exit(_sync_obj);\n";
1890 const char *RParenExprLocBuf =
SM->getCharacterData(RParenExprLoc);
1891 while (*RParenExprLocBuf !=
')') RParenExprLocBuf--;
1895 const char *LBraceLocBuf =
SM->getCharacterData(LBranceLoc);
1896 assert (*LBraceLocBuf ==
'{');
1897 ReplaceText(RParenExprLoc, (LBraceLocBuf -
SM->getCharacterData(RParenExprLoc) + 1), buf);
1900 assert((*
SM->getCharacterData(startRBraceLoc) ==
'}') &&
1901 "bogus @synchronized block");
1903 buf =
"} catch (id e) {_rethrow = e;}\n";
1908 ReplaceText(startRBraceLoc, 1, buf);
1913 void RewriteModernObjC::WarnAboutReturnGotoStmts(
Stmt *S)
1916 for (
Stmt *SubStmt : S->children())
1918 WarnAboutReturnGotoStmts(SubStmt);
1920 if (isa<ReturnStmt>(S) || isa<GotoStmt>(S)) {
1922 TryFinallyContainsReturnDiag);
1928 ReplaceText(startLoc, strlen(
"@autoreleasepool"),
"/* @autoreleasepool */");
1929 ReplaceText(S->getSubStmt()->getBeginLoc(), 1,
1930 "{ __AtAutoreleasePool __autoreleasepool; ");
1937 bool noCatch = S->getNumCatchStmts() == 0;
1940 ConvertSourceLocationToLineDirective(TryLocation, buf);
1944 buf +=
"{ id volatile _rethrow = 0;\n";
1946 buf +=
"{ id volatile _rethrow = 0;\ntry {\n";
1951 const char *startBuf =
SM->getCharacterData(startLoc);
1953 assert((*startBuf ==
'@') &&
"bogus @try location");
1955 ReplaceText(startLoc, 1, buf);
1958 ReplaceText(startLoc, 1,
"");
1960 for (
unsigned I = 0, N = S->getNumCatchStmts(); I != N; ++I) {
1965 bool AtRemoved =
false;
1973 ConvertSourceLocationToLineDirective(Catch->
getBeginLoc(), Result);
1975 startBuf =
SM->getCharacterData(startLoc);
1976 assert((*startBuf ==
'@') &&
"bogus @catch location");
1978 const char *rParenBuf =
SM->getCharacterData(rParenLoc);
1984 ReplaceText(startLoc, rParenBuf-startBuf+1, Result);
1995 ReplaceText(lBraceLoc, 1, Result);
2002 ReplaceText(startLoc, 1,
"");
2010 ConvertSourceLocationToLineDirective(FinallyLoc, buf);
2011 buf +=
"catch (id e) {_rethrow = e;}\n";
2015 ConvertSourceLocationToLineDirective(FinallyLoc, buf);
2016 buf +=
"catch (id e) {_rethrow = e;}\n";
2020 ReplaceText(startFinalLoc, 8, buf);
2025 ReplaceText(startFinalBodyLoc, 1, buf);
2028 ReplaceText(endFinalBodyLoc, 1,
"}\n}");
2030 WarnAboutReturnGotoStmts(S->getTryBody());
2042 const char *startBuf =
SM->getCharacterData(startLoc);
2044 assert((*startBuf ==
'@') &&
"bogus @throw location");
2048 if (S->getThrowExpr())
2049 buf =
"objc_exception_throw(";
2054 const char *wBuf = strchr(startBuf,
'w');
2055 assert((*wBuf ==
'w') &&
"@throw: can't find 'w'");
2056 ReplaceText(startLoc, wBuf-startBuf+1, buf);
2059 const char *endBuf =
SM->getCharacterData(endLoc);
2060 const char *semiBuf = strchr(endBuf,
';');
2061 assert((*semiBuf ==
';') &&
"@throw: can't find ';'");
2063 if (S->getThrowExpr())
2064 ReplaceText(semiLoc, 1,
");");
2072 Expr *Replacement = getStringLiteral(StrEncoding);
2073 ReplaceStmt(Exp, Replacement);
2081 if (!SelGetUidFunctionDecl)
2082 SynthSelGetUidFunctionDecl();
2083 assert(SelGetUidFunctionDecl &&
"Can't find sel_registerName() decl");
2087 CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl,
2089 ReplaceStmt(Exp, SelExp);
2095 RewriteModernObjC::SynthesizeCallToFunctionDecl(
FunctionDecl *FD,
2109 ImplicitCastExpr::Create(*Context, pToFunc, CK_FunctionToPointerDecay,
2114 CallExpr::Create(*Context, ICE, Args, FT->getCallResultType(*Context),
2120 const char *&startRef,
const char *&endRef) {
2121 while (startBuf < endBuf) {
2122 if (*startBuf ==
'<')
2123 startRef = startBuf;
2124 if (*startBuf ==
'>') {
2125 if (startRef && *startRef ==
'<') {
2138 while (*argRef !=
')' && (*argRef !=
',' || angle > 0)) {
2141 else if (*argRef ==
'>')
2145 assert(angle == 0 &&
"scanToNextArgument - bad protocol type syntax");
2148 bool RewriteModernObjC::needToScanForQualifiers(
QualType T) {
2161 return needToScanForQualifiers(ElemTy);
2166 void RewriteModernObjC::RewriteObjCQualifiedInterfaceTypes(
Expr *E) {
2168 if (needToScanForQualifiers(
Type)) {
2172 Loc = ECE->getLParenLoc();
2173 EndLoc = ECE->getRParenLoc();
2182 const char *startBuf =
SM->getCharacterData(Loc);
2183 const char *endBuf =
SM->getCharacterData(EndLoc);
2184 const char *startRef =
nullptr, *endRef =
nullptr;
2190 InsertText(LessLoc,
"/*");
2191 InsertText(GreaterLoc,
"*/");
2196 void RewriteModernObjC::RewriteObjCQualifiedInterfaceTypes(
Decl *Dcl) {
2200 if (
VarDecl *VD = dyn_cast<VarDecl>(Dcl)) {
2204 else if (
FunctionDecl *FD = dyn_cast<FunctionDecl>(Dcl)) {
2209 assert(funcType &&
"missing function type");
2210 proto = dyn_cast<FunctionProtoType>(funcType);
2215 else if (
FieldDecl *FD = dyn_cast<FieldDecl>(Dcl)) {
2220 Loc = TD->getLocation();
2221 Type = TD->getUnderlyingType();
2226 if (needToScanForQualifiers(
Type)) {
2229 const char *endBuf =
SM->getCharacterData(Loc);
2230 const char *startBuf = endBuf;
2231 while (*startBuf !=
';' && *startBuf !=
'<' && startBuf != MainFileStart)
2233 const char *startRef =
nullptr, *endRef =
nullptr;
2239 InsertText(LessLoc,
"/*");
2240 InsertText(GreaterLoc,
"*/");
2246 const char *startBuf =
SM->getCharacterData(Loc);
2247 const char *startFuncBuf = startBuf;
2252 const char *endBuf = startBuf;
2255 const char *startRef =
nullptr, *endRef =
nullptr;
2263 InsertText(LessLoc,
"/*");
2264 InsertText(GreaterLoc,
"*/");
2266 startBuf = ++endBuf;
2271 while (*startBuf && *startBuf !=
')' && *startBuf !=
',')
2278 void RewriteModernObjC::RewriteTypeOfDecl(
VarDecl *ND) {
2281 if (!isa<TypeOfExprType>(TypePtr))
2283 while (isa<TypeOfExprType>(TypePtr)) {
2284 const TypeOfExprType *TypeOfExprTypePtr = cast<TypeOfExprType>(TypePtr);
2292 const char *startBuf =
SM->getCharacterData(DeclLoc);
2295 TypeAsString +=
" " + Name +
" = ";
2299 startLoc = ECE->getLParenLoc();
2302 startLoc =
SM->getExpansionLoc(startLoc);
2303 const char *endBuf =
SM->getCharacterData(startLoc);
2304 ReplaceText(DeclLoc, endBuf-startBuf-1, TypeAsString);
2308 X =
SM->getExpansionLoc(
X);
2309 const char *endBuf =
SM->getCharacterData(
X);
2310 ReplaceText(DeclLoc, endBuf-startBuf-1, TypeAsString);
2315 void RewriteModernObjC::SynthSelGetUidFunctionDecl() {
2321 SelGetUidFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
2324 SelGetUidIdent, getFuncType,
2328 void RewriteModernObjC::RewriteFunctionDecl(
FunctionDecl *FD) {
2331 FD->
getName() ==
"sel_registerName") {
2332 SelGetUidFunctionDecl = FD;
2335 RewriteObjCQualifiedInterfaceTypes(FD);
2340 const char *argPtr = TypeString.c_str();
2341 if (!strchr(argPtr,
'^')) {
2346 Str += (*argPtr ==
'^' ?
'*' : *argPtr);
2352 void RewriteModernObjC::RewriteBlockPointerTypeVariable(
std::string& Str,
2356 const char *argPtr = TypeString.c_str();
2381 void RewriteModernObjC::RewriteBlockLiteralFunctionDecl(
FunctionDecl *FD) {
2392 unsigned numArgs = proto->getNumParams();
2393 for (
unsigned i = 0; i < numArgs; i++) {
2394 QualType ArgType = proto->getParamType(i);
2395 RewriteBlockPointerType(FdStr, ArgType);
2400 FdStr += (numArgs > 0) ?
", ...);\n" :
"...);\n";
2404 InsertText(FunLocStart, FdStr);
2408 void RewriteModernObjC::SynthSuperConstructorFunctionDecl() {
2409 if (SuperConstructorFunctionDecl)
2414 assert(!argT.
isNull() &&
"Can't find 'id' type");
2415 ArgTys.push_back(argT);
2416 ArgTys.push_back(argT);
2419 SuperConstructorFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
2422 msgSendIdent, msgSendType,
2427 void RewriteModernObjC::SynthMsgSendFunctionDecl() {
2431 assert(!argT.
isNull() &&
"Can't find 'id' type");
2432 ArgTys.push_back(argT);
2434 assert(!argT.
isNull() &&
"Can't find 'SEL' type");
2435 ArgTys.push_back(argT);
2438 MsgSendFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
2441 msgSendIdent, msgSendType,
nullptr,
2446 void RewriteModernObjC::SynthMsgSendSuperFunctionDecl() {
2449 ArgTys.push_back(Context->
VoidTy);
2452 MsgSendSuperFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
2455 msgSendIdent, msgSendType,
2460 void RewriteModernObjC::SynthMsgSendStretFunctionDecl() {
2464 assert(!argT.
isNull() &&
"Can't find 'id' type");
2465 ArgTys.push_back(argT);
2467 assert(!argT.
isNull() &&
"Can't find 'SEL' type");
2468 ArgTys.push_back(argT);
2471 MsgSendStretFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
2474 msgSendIdent, msgSendType,
2480 void RewriteModernObjC::SynthMsgSendSuperStretFunctionDecl() {
2482 &Context->
Idents.
get(
"objc_msgSendSuper_stret");
2484 ArgTys.push_back(Context->
VoidTy);
2487 MsgSendSuperStretFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
2491 msgSendType,
nullptr,
2496 void RewriteModernObjC::SynthMsgSendFpretFunctionDecl() {
2500 assert(!argT.
isNull() &&
"Can't find 'id' type");
2501 ArgTys.push_back(argT);
2503 assert(!argT.
isNull() &&
"Can't find 'SEL' type");
2504 ArgTys.push_back(argT);
2507 MsgSendFpretFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
2510 msgSendIdent, msgSendType,
2515 void RewriteModernObjC::SynthGetClassFunctionDecl() {
2521 GetClassFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
2524 getClassIdent, getClassType,
2529 void RewriteModernObjC::SynthGetSuperClassFunctionDecl() {
2531 &Context->
Idents.
get(
"class_getSuperclass");
2536 GetSuperClassFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
2540 getClassType,
nullptr,
2545 void RewriteModernObjC::SynthGetMetaClassFunctionDecl() {
2551 GetMetaClassFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
2554 getClassIdent, getClassType,
2559 assert (Exp !=
nullptr &&
"Expected non-null ObjCStringLiteral");
2560 QualType strType = getConstantStringStructType();
2566 for (i=0; i < tmpName.length(); i++) {
2567 char c = tmpName.at(i);
2574 S += utostr(NumObjCStringLiterals++);
2576 Preamble +=
"static __NSConstantStringImpl " + S;
2577 Preamble +=
" __attribute__ ((section (\"__DATA, __cfstring\"))) = {__CFConstantStringClassReference,";
2581 llvm::raw_string_ostream prettyBuf(prettyBufS);
2592 Expr *Unop = UnaryOperator::Create(
2593 const_cast<ASTContext &
>(*Context), DRE, UO_AddrOf,
2598 CK_CPointerToObjCPointerCast, Unop);
2599 ReplaceStmt(Exp,
cast);
2608 Expr *FlagExp = IntegerLiteral::Create(*Context,
2612 CK_BitCast, FlagExp);
2615 ReplaceStmt(Exp, PE);
2621 if (!SelGetUidFunctionDecl)
2622 SynthSelGetUidFunctionDecl();
2624 if (!MsgSendFunctionDecl)
2625 SynthMsgSendFunctionDecl();
2626 if (!GetClassFunctionDecl)
2627 SynthGetClassFunctionDecl();
2642 ClsExprs.push_back(getStringLiteral(clsName->
getName()));
2643 CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl, ClsExprs,
2645 MsgExprs.push_back(Cls);
2652 CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl,
2653 SelExprs, StartLoc, EndLoc);
2654 MsgExprs.push_back(SelExp);
2663 CK = CK_IntegralToBoolean;
2664 subExpr = NoTypeInfoCStyleCastExpr(Context,
type, CK, subExpr);
2666 MsgExprs.push_back(subExpr);
2671 for (
const auto PI : BoxingMethod->
parameters())
2672 ArgTypes.push_back(PI->getType());
2687 getSimpleFunctionType(returnType, ArgTypes, BoxingMethod->
isVariadic());
2689 cast = NoTypeInfoCStyleCastExpr(Context, castType, CK_BitCast,
2696 CallExpr *CE = CallExpr::Create(*Context, PE, MsgExprs, FT->getReturnType(),
2698 ReplaceStmt(Exp, CE);
2704 if (!SelGetUidFunctionDecl)
2705 SynthSelGetUidFunctionDecl();
2707 if (!MsgSendFunctionDecl)
2708 SynthMsgSendFunctionDecl();
2709 if (!GetClassFunctionDecl)
2710 SynthGetClassFunctionDecl();
2719 getSimpleFunctionType(Context->
VoidTy, IntQT,
true);
2720 std::string NSArrayFName(
"__NSContainer_literal");
2721 FunctionDecl *NSArrayFD = SynthBlockInitFunctionDecl(NSArrayFName);
2727 unsigned UnsignedIntSize =
2729 Expr *count = IntegerLiteral::Create(*Context,
2732 InitExprs.push_back(count);
2733 for (
unsigned i = 0; i < NumElements; i++)
2735 Expr *NSArrayCallExpr =
2736 CallExpr::Create(*Context, NSArrayDRE, InitExprs, NSArrayFType,
VK_LValue,
2746 MemberExpr::CreateImplicit(*Context, NSArrayCallExpr,
false, ARRFD,
2750 NoTypeInfoCStyleCastExpr(Context,
2765 ClsExprs.push_back(getStringLiteral(clsName->
getName()));
2766 CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl, ClsExprs,
2768 MsgExprs.push_back(Cls);
2776 CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl,
2777 SelExprs, StartLoc, EndLoc);
2778 MsgExprs.push_back(SelExp);
2781 MsgExprs.push_back(ArrayLiteralObjects);
2784 Expr *cnt = IntegerLiteral::Create(*Context,
2787 MsgExprs.push_back(cnt);
2792 for (
const auto *PI : ArrayMethod->
parameters())
2793 ArgTypes.push_back(PI->getType());
2808 getSimpleFunctionType(returnType, ArgTypes, ArrayMethod->
isVariadic());
2810 cast = NoTypeInfoCStyleCastExpr(Context, castType, CK_BitCast,
2819 ReplaceStmt(Exp, CE);
2825 if (!SelGetUidFunctionDecl)
2826 SynthSelGetUidFunctionDecl();
2828 if (!MsgSendFunctionDecl)
2829 SynthMsgSendFunctionDecl();
2830 if (!GetClassFunctionDecl)
2831 SynthGetClassFunctionDecl();
2840 getSimpleFunctionType(Context->
VoidTy, IntQT,
true);
2842 FunctionDecl *NSDictFD = SynthBlockInitFunctionDecl(NSDictFName);
2850 unsigned UnsignedIntSize =
2852 Expr *count = IntegerLiteral::Create(*Context,
2855 KeyExprs.push_back(count);
2856 ValueExprs.push_back(count);
2857 for (
unsigned i = 0; i < NumElements; i++) {
2859 KeyExprs.push_back(Element.
Key);
2860 ValueExprs.push_back(Element.
Value);
2864 Expr *NSValueCallExpr =
2865 CallExpr::Create(*Context, NSDictDRE, ValueExprs, NSDictFType,
VK_LValue,
2875 MemberExpr::CreateImplicit(*Context, NSValueCallExpr,
false, ARRFD,
2879 NoTypeInfoCStyleCastExpr(Context,
2882 DictLiteralValueME);
2884 Expr *NSKeyCallExpr =
2885 CallExpr::Create(*Context, NSDictDRE, KeyExprs, NSDictFType,
VK_LValue,
2889 MemberExpr::CreateImplicit(*Context, NSKeyCallExpr,
false, ARRFD,
2893 NoTypeInfoCStyleCastExpr(Context,
2908 ClsExprs.push_back(getStringLiteral(clsName->
getName()));
2909 CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl, ClsExprs,
2911 MsgExprs.push_back(Cls);
2918 CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl,
2919 SelExprs, StartLoc, EndLoc);
2920 MsgExprs.push_back(SelExp);
2923 MsgExprs.push_back(DictValueObjects);
2926 MsgExprs.push_back(DictKeyObjects);
2929 Expr *cnt = IntegerLiteral::Create(*Context,
2932 MsgExprs.push_back(cnt);
2937 for (
const auto *PI : DictMethod->
parameters()) {
2941 convertToUnqualifiedObjCType(PointeeTy);
2944 ArgTypes.push_back(T);
2960 getSimpleFunctionType(returnType, ArgTypes, DictMethod->
isVariadic());
2962 cast = NoTypeInfoCStyleCastExpr(Context, castType, CK_BitCast,
2971 ReplaceStmt(Exp, CE);
2978 QualType RewriteModernObjC::getSuperStructType() {
2979 if (!SuperStructDecl) {
2980 SuperStructDecl = RecordDecl::Create(*Context,
TTK_Struct, TUDecl,
2982 &Context->
Idents.
get(
"__rw_objc_super"));
2991 for (
unsigned i = 0; i < 2; ++i) {
2992 SuperStructDecl->
addDecl(FieldDecl::Create(*Context, SuperStructDecl,
2995 FieldTypes[i],
nullptr,
3006 QualType RewriteModernObjC::getConstantStringStructType() {
3007 if (!ConstantStringDecl) {
3008 ConstantStringDecl = RecordDecl::Create(*Context,
TTK_Struct, TUDecl,
3010 &Context->
Idents.
get(
"__NSConstantStringImpl"));
3016 FieldTypes[1] = Context->
IntTy;
3020 FieldTypes[3] = Context->
LongTy;
3023 for (
unsigned i = 0; i < 4; ++i) {
3024 ConstantStringDecl->
addDecl(FieldDecl::Create(*Context,
3028 FieldTypes[i],
nullptr,
3048 if (!LSD->getRBraceLoc().isValid())
3049 return LSD->getExternLoc();
3052 R.RewriteBlockLiteralFunctionDecl(FD);
3056 void RewriteModernObjC::RewriteLineDirective(
const Decl *D) {
3060 if (Location.
isFileID() && GenerateLineInfo) {
3063 LineString += utostr(PLoc.
getLine());
3064 LineString +=
" \"";
3065 LineString += Lexer::Stringify(PLoc.
getFilename());
3066 if (isa<ObjCMethodDecl>(D))
3068 else LineString +=
"\"\n";
3071 if (
const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
3076 if (!LSD->getRBraceLoc().isValid())
3077 Location = LSD->getExternLoc();
3080 InsertText(Location, LineString);
3094 Expr *RewriteModernObjC::SynthMsgSendStretCallExpr(
FunctionDecl *MsgSendStretFlavor,
3100 QualType FuncType = getSimpleFunctionType(
3101 returnType, ArgTypes, Method ? Method->
isVariadic() :
false);
3105 static unsigned stretCount=0;
3108 "extern \"C\" void * __cdecl memset(void *_Dst, int _Val, size_t _Size);\n";
3109 str +=
"namespace {\n";
3110 str +=
"struct "; str +=
name;
3113 str +=
"(id receiver, SEL sel";
3114 for (
unsigned i = 2; i < ArgTypes.size(); i++) {
3115 std::string ArgName =
"arg"; ArgName += utostr(i);
3117 str +=
", "; str += ArgName;
3120 for (
unsigned i = ArgTypes.size(); i < MsgExprs.size(); i++) {
3121 std::string ArgName =
"arg"; ArgName += utostr(i);
3122 MsgExprs[i]->getType().getAsStringInternal(ArgName,
3124 str +=
", "; str += ArgName;
3128 str +=
"\t unsigned size = sizeof(";
3131 str +=
"\t if (size == 1 || size == 2 || size == 4 || size == 8)\n";
3134 str +=
")(void *)objc_msgSend)(receiver, sel";
3135 for (
unsigned i = 2; i < ArgTypes.size(); i++) {
3136 str +=
", arg"; str += utostr(i);
3139 for (
unsigned i = ArgTypes.size(); i < MsgExprs.size(); i++) {
3140 str +=
", arg"; str += utostr(i);
3144 str +=
"\t else if (receiver == 0)\n";
3145 str +=
"\t memset((void*)&s, 0, sizeof(s));\n";
3149 str +=
")(void *)objc_msgSend_stret)(receiver, sel";
3150 for (
unsigned i = 2; i < ArgTypes.size(); i++) {
3151 str +=
", arg"; str += utostr(i);
3154 for (
unsigned i = ArgTypes.size(); i < MsgExprs.size(); i++) {
3155 str +=
", arg"; str += utostr(i);
3162 str +=
"};\n};\n\n";
3167 assert(CurMethodDef &&
"SynthMsgSendStretCallExpr - CurMethodDef is null");
3171 InsertText(FunLocStart, str);
3182 CallExpr::Create(*Context, DRE, MsgExprs, castType,
VK_LValue,
3188 returnType,
nullptr,
3200 if (!SelGetUidFunctionDecl)
3201 SynthSelGetUidFunctionDecl();
3202 if (!MsgSendFunctionDecl)
3203 SynthMsgSendFunctionDecl();
3204 if (!MsgSendSuperFunctionDecl)
3205 SynthMsgSendSuperFunctionDecl();
3206 if (!MsgSendStretFunctionDecl)
3207 SynthMsgSendStretFunctionDecl();
3208 if (!MsgSendSuperStretFunctionDecl)
3209 SynthMsgSendSuperStretFunctionDecl();
3210 if (!MsgSendFpretFunctionDecl)
3211 SynthMsgSendFpretFunctionDecl();
3212 if (!GetClassFunctionDecl)
3213 SynthGetClassFunctionDecl();
3214 if (!GetSuperClassFunctionDecl)
3215 SynthGetSuperClassFunctionDecl();
3216 if (!GetMetaClassFunctionDecl)
3217 SynthGetMetaClassFunctionDecl();
3224 QualType resultType = mDecl->getReturnType();
3226 MsgSendStretFlavor = MsgSendStretFunctionDecl;
3228 MsgSendFlavor = MsgSendFpretFunctionDecl;
3234 case ObjCMessageExpr::SuperClass: {
3235 MsgSendFlavor = MsgSendSuperFunctionDecl;
3236 if (MsgSendStretFlavor)
3237 MsgSendStretFlavor = MsgSendSuperStretFunctionDecl;
3238 assert(MsgSendFlavor &&
"MsgSendFlavor is NULL!");
3245 InitExprs.push_back(
3260 CallExpr *Cls = SynthesizeCallToFunctionDecl(GetMetaClassFunctionDecl,
3261 ClsExprs, StartLoc, EndLoc);
3263 ClsExprs.push_back(Cls);
3264 Cls = SynthesizeCallToFunctionDecl(GetSuperClassFunctionDecl, ClsExprs,
3269 InitExprs.push_back(
3270 NoTypeInfoCStyleCastExpr(Context,
3274 QualType superType = getSuperStructType();
3277 if (LangOpts.MicrosoftExt) {
3278 SynthSuperConstructorFunctionDecl();
3281 DeclRefExpr(*Context, SuperConstructorFunctionDecl,
false, superType,
3284 CallExpr::Create(*Context, DRE, InitExprs, superType,
VK_LValue,
3292 SuperRep = UnaryOperator::Create(
3293 const_cast<ASTContext &
>(*Context), SuperRep, UO_AddrOf,
3296 SuperRep = NoTypeInfoCStyleCastExpr(Context,
3298 CK_BitCast, SuperRep);
3310 SuperRep = UnaryOperator::Create(
3311 const_cast<ASTContext &
>(*Context), SuperRep, UO_AddrOf,
3315 MsgExprs.push_back(SuperRep);
3319 case ObjCMessageExpr::Class: {
3324 ClsExprs.push_back(getStringLiteral(clsName->
getName()));
3325 CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl, ClsExprs,
3327 CastExpr *ArgExpr = NoTypeInfoCStyleCastExpr(Context,
3330 MsgExprs.push_back(ArgExpr);
3334 case ObjCMessageExpr::SuperInstance:{
3335 MsgSendFlavor = MsgSendSuperFunctionDecl;
3336 if (MsgSendStretFlavor)
3337 MsgSendStretFlavor = MsgSendSuperStretFunctionDecl;
3338 assert(MsgSendFlavor &&
"MsgSendFlavor is NULL!");
3342 InitExprs.push_back(
3356 CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl, ClsExprs,
3359 ClsExprs.push_back(Cls);
3360 Cls = SynthesizeCallToFunctionDecl(GetSuperClassFunctionDecl, ClsExprs,
3365 InitExprs.push_back(
3370 QualType superType = getSuperStructType();
3373 if (LangOpts.MicrosoftExt) {
3374 SynthSuperConstructorFunctionDecl();
3377 DeclRefExpr(*Context, SuperConstructorFunctionDecl,
false, superType,
3380 CallExpr::Create(*Context, DRE, InitExprs, superType,
VK_LValue,
3388 SuperRep = UnaryOperator::Create(
3389 const_cast<ASTContext &
>(*Context), SuperRep, UO_AddrOf,
3392 SuperRep = NoTypeInfoCStyleCastExpr(Context,
3394 CK_BitCast, SuperRep);
3406 MsgExprs.push_back(SuperRep);
3410 case ObjCMessageExpr::Instance: {
3415 recExpr = CE->getSubExpr();
3418 ? CK_BlockPointerToObjCPointerCast
3419 : CK_CPointerToObjCPointerCast;
3421 recExpr = NoTypeInfoCStyleCastExpr(Context, Context->
getObjCIdType(),
3423 MsgExprs.push_back(recExpr);
3431 CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl,
3432 SelExprs, StartLoc, EndLoc);
3433 MsgExprs.push_back(SelExp);
3436 for (
unsigned i = 0; i < Exp->
getNumArgs(); i++) {
3442 if (needToScanForQualifiers(
type))
3445 (void)convertBlockPointerToFunctionPointer(
type);
3449 type->isBooleanType()) {
3450 CK = CK_IntegralToBoolean;
3451 }
else if (
type->isObjCObjectPointerType()) {
3453 CK = CK_BlockPointerToObjCPointerCast;
3455 CK = CK_CPointerToObjCPointerCast;
3463 userExpr = NoTypeInfoCStyleCastExpr(Context,
type, CK, userExpr);
3466 else if (
CStyleCastExpr *CE = dyn_cast<CStyleCastExpr>(userExpr)) {
3467 if (CE->getType()->isObjCQualifiedIdType()) {
3468 while ((CE = dyn_cast<CStyleCastExpr>(userExpr)))
3469 userExpr = CE->getSubExpr();
3472 CK = CK_IntegralToPointer;
3474 CK = CK_BlockPointerToObjCPointerCast;
3476 CK = CK_CPointerToObjCPointerCast;
3480 userExpr = NoTypeInfoCStyleCastExpr(Context, Context->
getObjCIdType(),
3484 MsgExprs.push_back(userExpr);
3496 if (MsgSendFlavor == MsgSendSuperFunctionDecl)
3497 ArgTypes.push_back(Context->
getPointerType(getSuperStructType()));
3508 (void)convertBlockPointerToFunctionPointer(t);
3509 ArgTypes.push_back(t);
3512 convertToUnqualifiedObjCType(returnType);
3513 (void)convertBlockPointerToFunctionPointer(returnType);
3528 cast = NoTypeInfoCStyleCastExpr(Context,
3536 getSimpleFunctionType(returnType, ArgTypes, MD ? MD->
isVariadic() :
true);
3538 cast = NoTypeInfoCStyleCastExpr(Context, castType, CK_BitCast,
3547 Stmt *ReplacingStmt = CE;
3548 if (MsgSendStretFlavor) {
3554 Expr *STCE = SynthMsgSendStretCallExpr(MsgSendStretFlavor,
3558 ReplacingStmt = STCE;
3561 return ReplacingStmt;
3565 Stmt *ReplacingStmt =
3569 ReplaceStmt(Exp, ReplacingStmt);
3572 return ReplacingStmt;
3576 QualType RewriteModernObjC::getProtocolType() {
3577 if (!ProtocolTypeDecl) {
3580 ProtocolTypeDecl = TypedefDecl::Create(*Context, TUDecl,
3593 std::string Name =
"_OBJC_PROTOCOL_REFERENCE_$_" +
3613 bool &IsNamedDefinition) {
3617 if (
RecordDecl *RD = dyn_cast<RecordDecl>(Tag)) {
3621 IsNamedDefinition =
true;
3626 if (
EnumDecl *ED = dyn_cast<EnumDecl>(Tag)) {
3627 if (!ED || !ED->getDeclName().getAsIdentifierInfo())
3629 IsNamedDefinition =
true;
3630 TagLocation = ED->getLocation();
3639 bool RewriteModernObjC::RewriteObjCFieldDeclType(
QualType &
Type,
3641 if (isa<TypedefType>(
Type)) {
3648 return RewriteObjCFieldDeclType(ElemTy, Result);
3654 Result +=
"\n\tstruct ";
3656 Result +=
"\n\tunion ";
3658 assert(
false &&
"class not allowed as an ivar type");
3661 if (GlobalDefinedTags.count(RD)) {
3667 for (
auto *FD : RD->
fields())
3668 RewriteObjCFieldDecl(FD, Result);
3676 Result +=
"\n\tenum ";
3678 if (GlobalDefinedTags.count(ED)) {
3686 Result +=
"\t"; Result += EC->
getName(); Result +=
" = ";
3688 Result += Val.toString(10);
3697 convertObjCTypeToCStyleType(
Type);
3709 bool EleboratedType = RewriteObjCFieldDeclType(
Type, Result);
3710 if (!EleboratedType)
3714 Result +=
" : "; Result += utostr(
fieldDecl->getBitWidthValue(*Context));
3722 Result += utostr(Dim.getZExtValue());
3737 if (isa<TypedefType>(
Type))
3742 auto *IDecl = dyn_cast<ObjCContainerDecl>(
fieldDecl->getDeclContext());
3753 if (GlobalDefinedTags.count(TD))
3756 bool IsNamedDefinition =
false;
3757 if (IsTagDefinedInsideClass(IDecl, TD, IsNamedDefinition)) {
3758 RewriteObjCFieldDeclType(
Type, Result);
3761 if (IsNamedDefinition)
3762 GlobalDefinedTags.insert(TD);
3766 unsigned RewriteModernObjC::ObjCIvarBitfieldGroupNo(
ObjCIvarDecl *IV) {
3768 if (ObjCInterefaceHasBitfieldGroups.count(CDecl)) {
3769 return IvarGroupNumber[IV];
3771 unsigned GroupNo = 0;
3775 IVars.push_back(IVD);
3777 for (
unsigned i = 0, e = IVars.size(); i < e; i++)
3778 if (IVars[i]->isBitField()) {
3779 IvarGroupNumber[IVars[i++]] = ++GroupNo;
3780 while (i < e && IVars[i]->isBitField())
3781 IvarGroupNumber[IVars[i++]] = GroupNo;
3786 ObjCInterefaceHasBitfieldGroups.insert(CDecl);
3787 return IvarGroupNumber[IV];
3790 QualType RewriteModernObjC::SynthesizeBitfieldGroupStructType(
3794 ObjCIvarBitfieldGroupType(IV, StructTagName);
3799 for (
unsigned i=0, e = IVars.size(); i < e; i++) {
3813 unsigned GroupNo = ObjCIvarBitfieldGroupNo(IV);
3814 std::pair<const ObjCInterfaceDecl*, unsigned> tuple = std::make_pair(CDecl, GroupNo);
3815 if (GroupRecordType.count(tuple))
3816 return GroupRecordType[tuple];
3821 if (IVD->isBitField())
3824 if (!IVars.empty()) {
3825 unsigned GroupNo = ObjCIvarBitfieldGroupNo(IVars[0]);
3827 GroupRecordType[std::make_pair(CDecl, GroupNo)] =
3828 SynthesizeBitfieldGroupStructType(IVars[0], IVars);
3833 if (!IVars.empty()) {
3835 unsigned GroupNo = ObjCIvarBitfieldGroupNo(IVars[0]);
3836 GroupRecordType[std::make_pair(CDecl, GroupNo)] =
3837 SynthesizeBitfieldGroupStructType(IVars[0], IVars);
3839 QualType RetQT = GroupRecordType[tuple];
3840 assert(!RetQT.
isNull() &&
"GetGroupRecordTypeForObjCIvarBitfield struct type is NULL");
3847 void RewriteModernObjC::ObjCIvarBitfieldGroupDecl(
ObjCIvarDecl *IV,
3851 Result +=
"__GRBF_";
3852 unsigned GroupNo = ObjCIvarBitfieldGroupNo(IV);
3853 Result += utostr(GroupNo);
3859 void RewriteModernObjC::ObjCIvarBitfieldGroupType(
ObjCIvarDecl *IV,
3864 unsigned GroupNo = ObjCIvarBitfieldGroupNo(IV);
3865 Result += utostr(GroupNo);
3871 void RewriteModernObjC::ObjCIvarBitfieldGroupOffset(
ObjCIvarDecl *IV,
3873 Result +=
"OBJC_IVAR_$_";
3874 ObjCIvarBitfieldGroupDecl(IV, Result);
3877 #define SKIP_BITFIELDS(IX, ENDIX, VEC) { \
3878 while ((IX < ENDIX) && VEC[IX]->isBitField()) \
3888 assert(CDecl &&
"Class missing in SynthesizeObjCInternalStruct");
3889 assert(CDecl->
getName() !=
"" &&
3890 "Name missing in SynthesizeObjCInternalStruct");
3895 IVars.push_back(IVD);
3900 const char *startBuf =
SM->getCharacterData(LocStart);
3901 const char *endBuf =
SM->getCharacterData(LocEnd);
3906 (!RCDecl || !ObjCSynthesizedStructs.count(RCDecl))) {
3907 endBuf += Lexer::MeasureTokenLength(LocEnd, *
SM, LangOpts);
3908 ReplaceText(LocStart, endBuf-startBuf, Result);
3915 for (
unsigned i = 0, e = IVars.size(); i < e; i++)
3916 RewriteLocallyDefinedNamedAggregates(IVars[i], Result);
3920 for (
unsigned i = 0, e = IVars.size(); i < e; i++)
3921 if (IVars[i]->isBitField()) {
3923 QualType QT = GetGroupRecordTypeForObjCIvarBitfield(IV);
3924 RewriteObjCFieldDeclType(QT, Result);
3930 Result +=
"\nstruct ";
3932 Result +=
"_IMPL {\n";
3934 if (RCDecl && ObjCSynthesizedStructs.count(RCDecl)) {
3937 Result +=
"_IVARS;\n";
3940 for (
unsigned i = 0, e = IVars.size(); i < e; i++) {
3941 if (IVars[i]->isBitField()) {
3943 Result +=
"\tstruct ";
3944 ObjCIvarBitfieldGroupType(IV, Result); Result +=
" ";
3945 ObjCIvarBitfieldGroupDecl(IV, Result); Result +=
";\n";
3950 RewriteObjCFieldDecl(IVars[i], Result);
3954 endBuf += Lexer::MeasureTokenLength(LocEnd, *
SM, LangOpts);
3955 ReplaceText(LocStart, endBuf-startBuf, Result);
3957 if (!ObjCSynthesizedStructs.insert(CDecl).second)
3958 llvm_unreachable(
"struct already synthesize- RewriteObjCInternalStruct");
3975 unsigned GroupNo = 0;
3976 if (IvarDecl->isBitField()) {
3977 GroupNo = ObjCIvarBitfieldGroupNo(IvarDecl);
3978 if (GroupSymbolOutput.count(std::make_pair(IDecl, GroupNo)))
3982 if (LangOpts.MicrosoftExt)
3983 Result +=
"__declspec(allocate(\".objc_ivar$B\")) ";
3984 Result +=
"extern \"C\" ";
3985 if (LangOpts.MicrosoftExt &&
3986 IvarDecl->getAccessControl() != ObjCIvarDecl::Private &&
3987 IvarDecl->getAccessControl() != ObjCIvarDecl::Package)
3988 Result +=
"__declspec(dllimport) ";
3990 Result +=
"unsigned long ";
3991 if (IvarDecl->isBitField()) {
3992 ObjCIvarBitfieldGroupOffset(IvarDecl, Result);
3993 GroupSymbolOutput.insert(std::make_pair(IDecl, GroupNo));
4008 void RewriteModernObjC::RewriteImplementations() {
4009 int ClsDefCount = ClassImplementation.size();
4010 int CatDefCount = CategoryImplementation.size();
4013 for (
int i = 0; i < ClsDefCount; i++) {
4018 "Legacy implicit interface rewriting not supported in moder abi");
4019 RewriteImplementationDecl(OIMP);
4022 for (
int i = 0; i < CatDefCount; i++) {
4027 "Legacy implicit interface rewriting not supported in moder abi");
4028 RewriteImplementationDecl(CIMP);
4032 void RewriteModernObjC::RewriteByRefString(
std::string &ResultStr,
4035 assert(BlockByRefDeclNo.count(VD) &&
4036 "RewriteByRefString: ByRef decl missing");
4038 ResultStr +=
"struct ";
4039 ResultStr +=
"__Block_byref_" + Name +
4040 "_" + utostr(BlockByRefDeclNo[VD]) ;
4044 if (
VarDecl *Var = dyn_cast<VarDecl>(VD))
4045 return (Var->isFunctionOrMethodVarDecl() && !Var->hasLocalStorage());
4057 ConvertSourceLocationToLineDirective(BlockLoc, S);
4060 funcName.str() +
"_block_func_" + utostr(i);
4064 if (isa<FunctionNoProtoType>(AFT)) {
4067 S +=
"(" + StructRef +
" *__cself)";
4069 S +=
"(" + StructRef +
" *__cself)";
4072 assert(FT &&
"SynthesizeBlockFunc: No function proto");
4075 S += StructRef +
" *__cself, ";
4080 ParamStr = (*AI)->getNameAsString();
4082 (void)convertBlockPointerToFunctionPointer(QT);
4097 E = BlockByRefDecls.end(); I != E; ++I) {
4101 RewriteByRefString(TypeString, Name, (*I));
4103 Name = TypeString + Name;
4104 S += Name +
" = __cself->" + (*I)->getNameAsString() +
"; // bound by ref\n";
4108 E = BlockByCopyDecls.end(); I != E; ++I) {
4120 if (isTopLevelBlockPointerType((*I)->getType())) {
4121 RewriteBlockPointerTypeVariable(S, (*I));
4123 RewriteBlockPointerType(S, (*I)->getType());
4125 S +=
"__cself->" + (*I)->getNameAsString() +
"; // bound by copy\n";
4133 S += Name +
" = __cself->" +
4134 (*I)->getNameAsString() +
"; // bound by copy\n";
4137 std::string RewrittenStr = RewrittenBlockExprs[CE];
4138 const char *cstr = RewrittenStr.c_str();
4139 while (*cstr++ !=
'{') ;
4152 S +=
"_block_copy_" + utostr(i);
4153 S +=
"(" + StructRef;
4154 S +=
"*dst, " + StructRef;
4156 for (
ValueDecl *VD : ImportedBlockDecls) {
4157 S +=
"_Block_object_assign((void*)&dst->";
4159 S +=
", (void*)src->";
4161 if (BlockByRefDeclsPtrSet.count(VD))
4170 S +=
"\nstatic void __";
4172 S +=
"_block_dispose_" + utostr(i);
4173 S +=
"(" + StructRef;
4175 for (
ValueDecl *VD : ImportedBlockDecls) {
4176 S +=
"_Block_object_dispose((void*)src->";
4178 if (BlockByRefDeclsPtrSet.count(VD))
4194 S +=
" {\n struct __block_impl impl;\n";
4195 S +=
" struct " + Desc;
4202 if (BlockDeclRefs.size()) {
4205 E = BlockByCopyDecls.end(); I != E; ++I) {
4219 if (isTopLevelBlockPointerType((*I)->getType())) {
4220 S +=
"struct __block_impl *";
4230 S += FieldName +
";\n";
4234 E = BlockByRefDecls.end(); I != E; ++I) {
4240 RewriteByRefString(TypeString, FieldName, (*I));
4242 FieldName = TypeString + FieldName;
4243 ArgName = TypeString + ArgName;
4246 S += FieldName +
"; // by ref\n";
4251 bool firsTime =
true;
4253 E = BlockByCopyDecls.end(); I != E; ++I) {
4261 if (isTopLevelBlockPointerType((*I)->getType()))
4262 Constructor += Name +
"((struct __block_impl *)_" + Name +
")";
4268 E = BlockByRefDecls.end(); I != E; ++I) {
4276 Constructor += Name +
"(_" + Name +
"->__forwarding)";
4281 Constructor +=
" impl.isa = &_NSConcreteGlobalBlock;\n";
4283 Constructor +=
" impl.isa = &_NSConcreteStackBlock;\n";
4284 Constructor +=
" impl.Flags = flags;\n impl.FuncPtr = fp;\n";
4291 Constructor +=
" impl.isa = &_NSConcreteGlobalBlock;\n";
4293 Constructor +=
" impl.isa = &_NSConcreteStackBlock;\n";
4294 Constructor +=
" impl.Flags = flags;\n impl.FuncPtr = fp;\n";
4310 S +=
" {\n size_t reserved;\n";
4311 S +=
" size_t Block_size;\n";
4313 S +=
" void (*copy)(struct ";
4314 S += ImplTag; S +=
"*, struct ";
4315 S += ImplTag; S +=
"*);\n";
4317 S +=
" void (*dispose)(struct ";
4318 S += ImplTag; S +=
"*);\n";
4322 S += DescTag +
"_DATA = { 0, sizeof(struct ";
4325 S +=
", __" + FunName.str() +
"_block_copy_" + utostr(i);
4326 S +=
", __" + FunName.str() +
"_block_dispose_" + utostr(i);
4332 void RewriteModernObjC::SynthesizeBlockLiterals(
SourceLocation FunLocStart,
4333 StringRef FunName) {
4334 bool RewriteSC = (GlobalVarDecl &&
4342 InsertText(FunLocStart, SC);
4346 for (
unsigned i = 0, count=0; i < Blocks.size(); i++) {
4347 CollectBlockDeclRefInfo(Blocks[i]);
4350 for (
int j = 0; j < InnerDeclRefsCount[i]; j++) {
4353 BlockDeclRefs.push_back(Exp);
4354 if (!VD->
hasAttr<BlocksAttr>()) {
4355 if (!BlockByCopyDeclsPtrSet.count(VD)) {
4356 BlockByCopyDeclsPtrSet.insert(VD);
4357 BlockByCopyDecls.push_back(VD);
4362 if (!BlockByRefDeclsPtrSet.count(VD)) {
4363 BlockByRefDeclsPtrSet.insert(VD);
4364 BlockByRefDecls.push_back(VD);
4371 ImportedBlockDecls.insert(VD);
4374 std::string ImplTag =
"__" + FunName.str() +
"_block_impl_" + utostr(i);
4375 std::string DescTag =
"__" + FunName.str() +
"_block_desc_" + utostr(i);
4377 std::string CI = SynthesizeBlockImpl(Blocks[i], ImplTag, DescTag);
4379 InsertText(FunLocStart, CI);
4381 std::string CF = SynthesizeBlockFunc(Blocks[i], i, FunName, ImplTag);
4383 InsertText(FunLocStart, CF);
4385 if (ImportedBlockDecls.size()) {
4386 std::string HF = SynthesizeBlockHelperFuncs(Blocks[i], i, FunName, ImplTag);
4387 InsertText(FunLocStart, HF);
4389 std::string BD = SynthesizeBlockDescriptor(DescTag, ImplTag, i, FunName,
4390 ImportedBlockDecls.size() > 0);
4391 InsertText(FunLocStart, BD);
4393 BlockDeclRefs.clear();
4394 BlockByRefDecls.clear();
4395 BlockByRefDeclsPtrSet.clear();
4396 BlockByCopyDecls.clear();
4397 BlockByCopyDeclsPtrSet.clear();
4398 ImportedBlockDecls.clear();
4412 InsertText(FunLocStart, SC);
4414 if (GlobalConstructionExp) {
4420 Tag +=
"_block_impl_";
4421 Tag += utostr(Blocks.size()-1);
4423 globalBuf += Tag; globalBuf +=
" ";
4426 llvm::raw_string_ostream constructorExprBuf(SStr);
4427 GlobalConstructionExp->
printPretty(constructorExprBuf,
nullptr,
4429 globalBuf += constructorExprBuf.str();
4431 InsertText(FunLocStart, globalBuf);
4432 GlobalConstructionExp =
nullptr;
4436 InnerDeclRefsCount.clear();
4437 InnerDeclRefs.clear();
4438 RewrittenBlockExprs.clear();
4441 void RewriteModernObjC::InsertBlockLiteralsWithinFunction(
FunctionDecl *FD) {
4445 StringRef FuncName = FD->
getName();
4447 SynthesizeBlockLiterals(FunLocStart, FuncName);
4456 std::string::size_type loc = 0;
4457 while ((loc = Name.find(
':', loc)) != std::string::npos)
4458 Name.replace(loc, 1,
"_");
4461 void RewriteModernObjC::InsertBlockLiteralsWithinMethod(
ObjCMethodDecl *MD) {
4467 SynthesizeBlockLiterals(FunLocStart, FuncName);
4470 void RewriteModernObjC::GetBlockDeclRefExprs(
Stmt *S) {
4471 for (
Stmt *SubStmt : S->children())
4473 if (
BlockExpr *CBE = dyn_cast<BlockExpr>(SubStmt))
4474 GetBlockDeclRefExprs(CBE->getBody());
4476 GetBlockDeclRefExprs(SubStmt);
4483 BlockDeclRefs.push_back(DRE);
4486 void RewriteModernObjC::GetInnerBlockDeclRefExprs(
Stmt *S,
4488 llvm::SmallPtrSetImpl<const DeclContext *> &InnerContexts) {
4489 for (
Stmt *SubStmt : S->children())
4491 if (
BlockExpr *CBE = dyn_cast<BlockExpr>(SubStmt)) {
4492 InnerContexts.insert(cast<DeclContext>(CBE->getBlockDecl()));
4493 GetInnerBlockDeclRefExprs(CBE->getBody(),
4498 GetInnerBlockDeclRefExprs(SubStmt, InnerBlockDeclRefs, InnerContexts);
4501 if (
DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(S)) {
4505 InnerBlockDeclRefs.push_back(DRE);
4507 if (Var->isFunctionOrMethodVarDecl())
4508 ImportedLocalExternalDecls.insert(Var);
4516 bool RewriteModernObjC::convertObjCTypeToCStyleType(
QualType &T) {
4518 convertBlockPointerToFunctionPointer(T);
4524 T = convertFunctionTypeOfBlocks(FT);
4530 convertToUnqualifiedObjCType(T);
4544 bool modified = convertObjCTypeToCStyleType(Res);
4550 if (convertObjCTypeToCStyleType(t))
4552 ArgTypes.push_back(t);
4557 FuncType = getSimpleFunctionType(Res, ArgTypes);
4562 Stmt *RewriteModernObjC::SynthesizeBlockCall(
CallExpr *Exp,
const Expr *BlockExp) {
4566 if (
const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(BlockExp)) {
4568 }
else if (
const MemberExpr *MExpr = dyn_cast<MemberExpr>(BlockExp)) {
4571 else if (
const ParenExpr *PRE = dyn_cast<ParenExpr>(BlockExp)) {
4572 return SynthesizeBlockCall(Exp, PRE->getSubExpr());
4574 else if (
const ImplicitCastExpr *IEXPR = dyn_cast<ImplicitCastExpr>(BlockExp))
4577 dyn_cast<ConditionalOperator>(BlockExp)) {
4578 Expr *LHSExp = CEXPR->getLHS();
4579 Stmt *LHSStmt = SynthesizeBlockCall(Exp, LHSExp);
4580 Expr *RHSExp = CEXPR->getRHS();
4581 Stmt *RHSStmt = SynthesizeBlockCall(Exp, RHSExp);
4582 Expr *CONDExp = CEXPR->getCond();
4589 }
else if (
const ObjCIvarRefExpr *IRE = dyn_cast<ObjCIvarRefExpr>(BlockExp)) {
4592 = dyn_cast<PseudoObjectExpr>(BlockExp)) {
4595 assert(
false &&
"RewriteBlockClass: Bad type");
4597 assert(CPT &&
"RewriteBlockClass: Bad type");
4599 assert(FT &&
"RewriteBlockClass: Bad type");
4612 ArgTypes.push_back(PtrBlock);
4617 if (!convertBlockPointerToFunctionPointer(t))
4618 convertToUnqualifiedObjCType(t);
4619 ArgTypes.push_back(t);
4623 QualType PtrToFuncCastType = getSimpleFunctionType(Exp->
getType(), ArgTypes);
4627 CastExpr *BlkCast = NoTypeInfoCStyleCastExpr(Context, PtrBlock,
4629 const_cast<Expr*
>(BlockExp));
4644 CastExpr *FunkCast = NoTypeInfoCStyleCastExpr(Context, PtrToFuncCastType,
4650 BlkExprs.push_back(BlkCast);
4653 E = Exp->
arg_end(); I != E; ++I) {
4654 BlkExprs.push_back(*I);
4675 Stmt *RewriteModernObjC::RewriteBlockDeclRefExpr(
DeclRefExpr *DeclRefExp) {
4691 StringRef Name = VD->
getName();
4697 ME = MemberExpr::CreateImplicit(*Context, ME,
true, FD, DeclRefExp->
getType(),
4704 ReplaceStmt(DeclRefExp, PE);
4711 Stmt *RewriteModernObjC::RewriteLocalVariableExternalStorage(
DeclRefExpr *DRE) {
4713 if (
VarDecl *Var = dyn_cast<VarDecl>(VD))
4714 if (!ImportedLocalExternalDecls.count(Var))
4716 Expr *Exp = UnaryOperator::Create(
4722 ReplaceStmt(DRE, PE);
4734 if (!Rewriter::isRewritable(LocStart) || !Rewriter::isRewritable(LocEnd))
4737 const char *startBuf =
SM->getCharacterData(LocStart);
4738 const char *endBuf =
SM->getCharacterData(LocEnd);
4741 if (isa<TypeOfExprType>(TypePtr)) {
4742 const TypeOfExprType *TypeOfExprTypePtr = cast<TypeOfExprType>(TypePtr);
4745 RewriteBlockPointerType(TypeAsString, QT);
4746 TypeAsString +=
")";
4747 ReplaceText(LocStart, endBuf-startBuf+1, TypeAsString);
4751 const char *argPtr = startBuf;
4753 while (*argPtr++ && (argPtr < endBuf)) {
4758 ReplaceText(LocStart, 1,
"*");
4764 void RewriteModernObjC::RewriteImplicitCastObjCExpr(
CastExpr *IC) {
4766 if (
CastKind != CK_BlockPointerToObjCPointerCast &&
4767 CastKind != CK_AnyPointerToBlockPointerCast)
4771 (void)convertBlockPointerToFunctionPointer(QT);
4779 void RewriteModernObjC::RewriteBlockPointerFunctionArgs(
FunctionDecl *FD) {
4781 unsigned parenCount = 0;
4784 const char *startBuf =
SM->getCharacterData(DeclLoc);
4785 const char *startArgList = strchr(startBuf,
'(');
4787 assert((*startArgList ==
'(') &&
"Rewriter fuzzy parser confused");
4792 assert((DeclLoc.
isValid()) &&
"Invalid DeclLoc");
4794 const char *argPtr = startArgList;
4796 while (*argPtr++ && parenCount) {
4801 ReplaceText(DeclLoc, 1,
"*");
4813 bool RewriteModernObjC::PointerTypeTakesAnyBlockArguments(
QualType QT) {
4820 assert(BPT &&
"BlockPointerTypeTakeAnyBlockArguments(): not a block pointer type");
4825 if (isTopLevelBlockPointerType(I))
4831 bool RewriteModernObjC::PointerTypeTakesAnyObjCQualifiedType(
QualType QT) {
4838 assert(BPT &&
"BlockPointerTypeTakeAnyBlockArguments(): not a block pointer type");
4843 if (I->isObjCQualifiedIdType())
4845 if (I->isObjCObjectPointerType() &&
4846 I->getPointeeType()->isObjCQualifiedInterfaceType())
4854 void RewriteModernObjC::GetExtentOfArgList(
const char *Name,
const char *&LParen,
4855 const char *&RParen) {
4856 const char *argPtr = strchr(Name,
'(');
4857 assert((*argPtr ==
'(') &&
"Rewriter fuzzy parser confused");
4861 unsigned parenCount = 1;
4863 while (*argPtr && parenCount) {
4865 case '(': parenCount++;
break;
4866 case ')': parenCount--;
break;
4869 if (parenCount) argPtr++;
4871 assert((*argPtr ==
')') &&
"Rewriter fuzzy parser confused");
4875 void RewriteModernObjC::RewriteBlockPointerDecl(
NamedDecl *ND) {
4877 RewriteBlockPointerFunctionArgs(FD);
4883 if (
VarDecl *VD = dyn_cast<VarDecl>(ND))
4886 DeclT = TDD->getUnderlyingType();
4887 else if (
FieldDecl *FD = dyn_cast<FieldDecl>(ND))
4890 llvm_unreachable(
"RewriteBlockPointerDecl(): Decl type not yet handled");
4892 const char *startBuf =
SM->getCharacterData(DeclLoc);
4893 const char *endBuf = startBuf;
4895 while (*startBuf !=
'^' && *startBuf !=
';' && startBuf != MainFileStart)
4899 unsigned OrigLength=0;
4902 if (*startBuf ==
'^') {
4908 while (*startBuf !=
')') {
4916 if (PointerTypeTakesAnyBlockArguments(DeclT) ||
4917 PointerTypeTakesAnyObjCQualifiedType(DeclT)) {
4921 startBuf =
SM->getCharacterData(DeclLoc);
4922 const char *argListBegin, *argListEnd;
4923 GetExtentOfArgList(startBuf, argListBegin, argListEnd);
4924 while (argListBegin < argListEnd) {
4925 if (*argListBegin ==
'^')
4927 else if (*argListBegin ==
'<') {
4929 buf += *argListBegin++;
4931 while (*argListBegin !=
'>') {
4932 buf += *argListBegin++;
4935 buf += *argListBegin;
4939 buf += *argListBegin;
4946 ReplaceText(Start, OrigLength, buf);
4972 if (CopyDestroyCache.count(flag))
4974 CopyDestroyCache.insert(flag);
4975 S =
"static void __Block_byref_id_object_copy_";
4977 S +=
"(void *dst, void *src) {\n";
4983 unsigned VoidPtrSize =
4986 unsigned offset = (VoidPtrSize*4 + IntSize + IntSize)/Context->
getCharWidth();
4987 S +=
" _Block_object_assign((char*)dst + ";
4988 S += utostr(offset);
4989 S +=
", *(void * *) ((char*)src + ";
4990 S += utostr(offset);
4995 S +=
"static void __Block_byref_id_object_dispose_";
4997 S +=
"(void *src) {\n";
4998 S +=
" _Block_object_dispose(*(void * *) ((char*)src + ";
4999 S += utostr(offset);
5024 void RewriteModernObjC::RewriteByRefVar(
VarDecl *ND,
bool firstDecl,
5033 const char *startBuf =
SM->getCharacterData(DeclLoc);
5035 X =
SM->getExpansionLoc(
X);
5036 const char *endBuf =
SM->getCharacterData(
X);
5039 RewriteByRefString(ByrefType, Name, ND,
true);
5040 ByrefType +=
" {\n";
5041 ByrefType +=
" void *__isa;\n";
5042 RewriteByRefString(ByrefType, Name, ND);
5043 ByrefType +=
" *__forwarding;\n";
5044 ByrefType +=
" int __flags;\n";
5045 ByrefType +=
" int __size;\n";
5050 if (HasCopyAndDispose) {
5051 ByrefType +=
" void (*__Block_byref_id_object_copy)(void*, void*);\n";
5052 ByrefType +=
" void (*__Block_byref_id_object_dispose)(void*);\n";
5056 (void)convertBlockPointerToFunctionPointer(T);
5059 ByrefType +=
" " + Name +
";\n";
5060 ByrefType +=
"};\n";
5066 assert(CurMethodDef &&
"RewriteByRefVar - CurMethodDef is null");
5069 InsertText(FunLocStart, ByrefType);
5075 if (HasCopyAndDispose) {
5083 std::string HF = SynthesizeByrefCopyDestroyHelper(ND, flag);
5091 bool hasInit = (ND->
getInit() !=
nullptr);
5102 if (HasCopyAndDispose)
5106 RewriteByRefString(ByrefType, Name, ND);
5108 ForwardingCastType += ByrefType +
" *)";
5109 ByrefType +=
" " + Name +
" = {(void*)";
5110 ByrefType += utostr(
isa);
5111 ByrefType +=
"," + ForwardingCastType +
"&" + Name +
", ";
5112 ByrefType += utostr(flags);
5114 ByrefType +=
"sizeof(";
5115 RewriteByRefString(ByrefType, Name, ND);
5117 if (HasCopyAndDispose) {
5118 ByrefType +=
", __Block_byref_id_object_copy_";
5119 ByrefType += utostr(flag);
5120 ByrefType +=
", __Block_byref_id_object_dispose_";
5121 ByrefType += utostr(flag);
5129 const char *startDeclBuf =
SM->getCharacterData(DeclLoc);
5130 const char *commaBuf = startDeclBuf;
5131 while (*commaBuf !=
',')
5133 assert((*commaBuf ==
',') &&
"RewriteByRefVar: can't find ','");
5135 startBuf = commaBuf;
5139 ByrefType +=
"};\n";
5140 unsigned nameSize = Name.size();
5145 ReplaceText(DeclLoc, endBuf-startBuf+nameSize, ByrefType);
5152 startLoc = ECE->getLParenLoc();
5155 startLoc =
SM->getExpansionLoc(startLoc);
5156 endBuf =
SM->getCharacterData(startLoc);
5157 ReplaceText(DeclLoc, endBuf-startBuf, ByrefType);
5159 const char separator = lastDecl ?
';' :
',';
5160 const char *startInitializerBuf =
SM->getCharacterData(startLoc);
5161 const char *separatorBuf = strchr(startInitializerBuf, separator);
5162 assert((*separatorBuf == separator) &&
5163 "RewriteByRefVar: can't find ';' or ','");
5167 InsertText(separatorLoc, lastDecl ?
"}" :
"};\n");
5171 void RewriteModernObjC::CollectBlockDeclRefInfo(
BlockExpr *Exp) {
5173 GetBlockDeclRefExprs(Exp->
getBody());
5174 if (BlockDeclRefs.size()) {
5176 for (
unsigned i = 0; i < BlockDeclRefs.size(); i++)
5177 if (!BlockDeclRefs[i]->getDecl()->hasAttr<BlocksAttr>()) {
5178 if (!BlockByCopyDeclsPtrSet.count(BlockDeclRefs[i]->getDecl())) {
5179 BlockByCopyDeclsPtrSet.insert(BlockDeclRefs[i]->getDecl());
5180 BlockByCopyDecls.push_back(BlockDeclRefs[i]->getDecl());
5184 for (
unsigned i = 0; i < BlockDeclRefs.size(); i++)
5185 if (BlockDeclRefs[i]->getDecl()->hasAttr<BlocksAttr>()) {
5186 if (!BlockByRefDeclsPtrSet.count(BlockDeclRefs[i]->getDecl())) {
5187 BlockByRefDeclsPtrSet.insert(BlockDeclRefs[i]->getDecl());
5188 BlockByRefDecls.push_back(BlockDeclRefs[i]->getDecl());
5192 for (
unsigned i = 0; i < BlockDeclRefs.size(); i++)
5193 if (BlockDeclRefs[i]->getDecl()->hasAttr<BlocksAttr>() ||
5194 BlockDeclRefs[i]->getType()->isObjCObjectPointerType() ||
5195 BlockDeclRefs[i]->getType()->isBlockPointerType())
5196 ImportedBlockDecls.insert(BlockDeclRefs[i]->getDecl());
5200 FunctionDecl *RewriteModernObjC::SynthBlockInitFunctionDecl(StringRef
name) {
5212 Blocks.push_back(Exp);
5214 CollectBlockDeclRefInfo(Exp);
5217 int countOfInnerDecls = 0;
5218 if (!InnerBlockDeclRefs.empty()) {
5219 for (
unsigned i = 0; i < InnerBlockDeclRefs.size(); i++) {
5222 if (!VD->
hasAttr<BlocksAttr>() && !BlockByCopyDeclsPtrSet.count(VD)) {
5226 InnerDeclRefs.push_back(Exp); countOfInnerDecls++;
5227 BlockDeclRefs.push_back(Exp);
5228 BlockByCopyDeclsPtrSet.insert(VD);
5229 BlockByCopyDecls.push_back(VD);
5231 if (VD->
hasAttr<BlocksAttr>() && !BlockByRefDeclsPtrSet.count(VD)) {
5232 InnerDeclRefs.push_back(Exp); countOfInnerDecls++;
5233 BlockDeclRefs.push_back(Exp);
5234 BlockByRefDeclsPtrSet.insert(VD);
5235 BlockByRefDecls.push_back(VD);
5239 for (
unsigned i = 0; i < InnerBlockDeclRefs.size(); i++)
5240 if (InnerBlockDeclRefs[i]->getDecl()->hasAttr<BlocksAttr>() ||
5241 InnerBlockDeclRefs[i]->getType()->isObjCObjectPointerType() ||
5242 InnerBlockDeclRefs[i]->getType()->isBlockPointerType())
5243 ImportedBlockDecls.insert(InnerBlockDeclRefs[i]->getDecl());
5245 InnerDeclRefsCount.push_back(countOfInnerDecls);
5251 else if (CurMethodDef)
5253 else if (GlobalVarDecl)
5256 bool GlobalBlockExpr =
5259 if (GlobalBlockExpr && !GlobalVarDecl) {
5261 GlobalBlockExpr =
false;
5264 std::string BlockNumber = utostr(Blocks.size()-1);
5266 std::string Func =
"__" + FuncName +
"_block_func_" + BlockNumber;
5269 QualType BFT = convertFunctionTypeOfBlocks(Exp->getFunctionType());
5278 if (GlobalBlockExpr)
5282 Tag += FuncName +
"_block_impl_" + BlockNumber;
5284 FD = SynthBlockInitFunctionDecl(Tag);
5291 FD = SynthBlockInitFunctionDecl(Func);
5299 std::string DescData =
"__" + FuncName +
"_block_desc_" + BlockNumber +
"_DATA";
5301 VarDecl *NewVD = VarDecl::Create(
5310 InitExprs.push_back(DescRefExpr);
5313 if (BlockDeclRefs.size()) {
5317 E = BlockByCopyDecls.end(); I != E; ++I) {
5318 if (isObjCType((*I)->getType())) {
5320 FD = SynthBlockInitFunctionDecl((*I)->getName());
5326 Exp = UnaryOperator::Create(
5330 }
else if (isTopLevelBlockPointerType((*I)->getType())) {
5331 FD = SynthBlockInitFunctionDecl((*I)->getName());
5334 Exp = NoTypeInfoCStyleCastExpr(Context, Context->
VoidPtrTy,
5337 FD = SynthBlockInitFunctionDecl((*I)->getName());
5343 Exp = UnaryOperator::Create(
5349 InitExprs.push_back(Exp);
5353 E = BlockByRefDecls.end(); I != E; ++I) {
5357 RewriteByRefString(RecName, Name, ND,
true);
5359 +
sizeof(
"struct"));
5363 assert(RD &&
"SynthBlockInitExpr(): Can't find RecordDecl");
5366 FD = SynthBlockInitFunctionDecl((*I)->getName());
5369 bool isNestedCapturedVar =
false;
5371 for (
const auto &CI : block->
captures()) {
5372 const VarDecl *variable = CI.getVariable();
5373 if (variable == ND && CI.isNested()) {
5374 assert (CI.isByRef() &&
5375 "SynthBlockInitExpr - captured block variable is not byref");
5376 isNestedCapturedVar =
true;
5382 if (!isNestedCapturedVar)
5383 Exp = UnaryOperator::Create(
5384 const_cast<ASTContext &
>(*Context), Exp, UO_AddrOf,
5387 Exp = NoTypeInfoCStyleCastExpr(Context, castT, CK_BitCast, Exp);
5388 InitExprs.push_back(Exp);
5391 if (ImportedBlockDecls.size()) {
5396 Expr *FlagExp = IntegerLiteral::Create(*Context,
llvm::APInt(IntSize, flag),
5398 InitExprs.push_back(FlagExp);
5400 NewRep = CallExpr::Create(*Context, DRE, InitExprs, FType,
VK_LValue,
5403 if (GlobalBlockExpr) {
5404 assert (!GlobalConstructionExp &&
5405 "SynthBlockInitExpr - GlobalConstructionExp must be null");
5406 GlobalConstructionExp = NewRep;
5410 NewRep = UnaryOperator::Create(
5411 const_cast<ASTContext &
>(*Context), NewRep, UO_AddrOf,
5414 NewRep = NoTypeInfoCStyleCastExpr(Context, FType, CK_BitCast,
5420 BlockDeclRefs.clear();
5421 BlockByRefDecls.clear();
5422 BlockByRefDeclsPtrSet.clear();
5423 BlockByCopyDecls.clear();
5424 BlockByCopyDeclsPtrSet.clear();
5425 ImportedBlockDecls.clear();
5429 bool RewriteModernObjC::IsDeclStmtInForeachHeader(
DeclStmt *DS) {
5431 dyn_cast<ObjCForCollectionStmt>(Stmts.back()))
5432 return CS->getElement() == DS;
5440 Stmt *RewriteModernObjC::RewriteFunctionBodyOrGlobalInitializer(
Stmt *S) {
5441 if (isa<SwitchStmt>(S) || isa<WhileStmt>(S) ||
5442 isa<DoStmt>(S) || isa<ForStmt>(S))
5444 else if (isa<ObjCForCollectionStmt>(S)) {
5446 ObjCBcLabelNo.push_back(++BcLabelCount);
5453 return RewritePropertyOrImplicitSetter(PseudoOp);
5455 return RewritePropertyOrImplicitGetter(PseudoOp);
5457 }
else if (
ObjCIvarRefExpr *IvarRefExpr = dyn_cast<ObjCIvarRefExpr>(S)) {
5458 return RewriteObjCIvarRefExpr(IvarRefExpr);
5460 else if (isa<OpaqueValueExpr>(S))
5461 S = cast<OpaqueValueExpr>(S)->getSourceExpr();
5466 for (
Stmt *&childStmt : S->children())
5468 Stmt *newStmt = RewriteFunctionBodyOrGlobalInitializer(childStmt);
5470 childStmt = newStmt;
5474 if (
BlockExpr *BE = dyn_cast<BlockExpr>(S)) {
5477 InnerContexts.insert(BE->getBlockDecl());
5478 ImportedLocalExternalDecls.clear();
5479 GetInnerBlockDeclRefExprs(BE->getBody(),
5480 InnerBlockDeclRefs, InnerContexts);
5482 Stmt *SaveCurrentBody = CurrentBody;
5483 CurrentBody = BE->getBody();
5484 PropParentMap =
nullptr;
5490 bool saveDisableReplaceStmt = DisableReplaceStmt;
5491 DisableReplaceStmt =
false;
5492 RewriteFunctionBodyOrGlobalInitializer(BE->getBody());
5493 DisableReplaceStmt = saveDisableReplaceStmt;
5494 CurrentBody = SaveCurrentBody;
5495 PropParentMap =
nullptr;
5496 ImportedLocalExternalDecls.clear();
5499 RewrittenBlockExprs[BE] = Str;
5501 Stmt *blockTranscribed = SynthBlockInitExpr(BE, InnerBlockDeclRefs);
5504 ReplaceStmt(S, blockTranscribed);
5505 return blockTranscribed;
5509 return RewriteAtEncode(AtEncode);
5512 return RewriteAtSelector(AtSelector);
5515 return RewriteObjCStringLiteral(AtString);
5518 return RewriteObjCBoolLiteralExpr(BoolLitExpr);
5521 return RewriteObjCBoxedExpr(BoxedExpr);
5524 return RewriteObjCArrayLiteralExpr(ArrayLitExpr);
5527 dyn_cast<ObjCDictionaryLiteral>(S))
5528 return RewriteObjCDictionaryLiteralExpr(DictionaryLitExpr);
5536 const char *startBuf =
SM->getCharacterData(startLoc);
5537 const char *endBuf =
SM->getCharacterData(endLoc);
5540 messString +=
"// ";
5541 messString.append(startBuf, endBuf-startBuf+1);
5550 return RewriteMessageExpr(MessExpr);
5554 dyn_cast<ObjCAutoreleasePoolStmt>(S)) {
5555 return RewriteObjCAutoreleasePoolStmt(StmtAutoRelease);
5559 return RewriteObjCTryStmt(StmtTry);
5562 return RewriteObjCSynchronizedStmt(StmtTry);
5565 return RewriteObjCThrowStmt(StmtThrow);
5568 return RewriteObjCProtocolExpr(ProtocolExp);
5571 dyn_cast<ObjCForCollectionStmt>(S))
5572 return RewriteObjCForCollectionStmt(StmtForCollection,
5575 dyn_cast<BreakStmt>(S))
5576 return RewriteBreakStmt(StmtBreakStmt);
5578 dyn_cast<ContinueStmt>(S))
5579 return RewriteContinueStmt(StmtContinueStmt);
5583 if (
DeclStmt *DS = dyn_cast<DeclStmt>(S)) {
5593 if (Stmts.empty() || !IsDeclStmtInForeachHeader(DS))
5594 RewriteObjCQualifiedInterfaceTypes(*DS->
decl_begin());
5600 if (
ValueDecl *ND = dyn_cast<ValueDecl>(SD)) {
5601 if (isTopLevelBlockPointerType(ND->
getType()))
5602 RewriteBlockPointerDecl(ND);
5604 CheckFunctionPointerDecl(ND->
getType(), ND);
5605 if (
VarDecl *VD = dyn_cast<VarDecl>(SD)) {
5606 if (VD->
hasAttr<BlocksAttr>()) {
5607 static unsigned uniqueByrefDeclCount = 0;
5608 assert(!BlockByRefDeclNo.count(ND) &&
5609 "RewriteFunctionBodyOrGlobalInitializer: Duplicate byref decl");
5610 BlockByRefDeclNo[ND] = uniqueByrefDeclCount++;
5611 RewriteByRefVar(VD, (DI == DS->
decl_begin()), ((DI+1) == DE));
5614 RewriteTypeOfDecl(VD);
5618 if (isTopLevelBlockPointerType(TD->getUnderlyingType()))
5619 RewriteBlockPointerDecl(TD);
5620 else if (TD->getUnderlyingType()->isFunctionPointerType())
5621 CheckFunctionPointerDecl(TD->getUnderlyingType(), TD);
5627 RewriteObjCQualifiedInterfaceTypes(CE);
5629 if (isa<SwitchStmt>(S) || isa<WhileStmt>(S) ||
5630 isa<DoStmt>(S) || isa<ForStmt>(S)) {
5631 assert(!Stmts.empty() &&
"Statement stack is empty");
5632 assert ((isa<SwitchStmt>(Stmts.back()) || isa<WhileStmt>(Stmts.back()) ||
5633 isa<DoStmt>(Stmts.back()) || isa<ForStmt>(Stmts.back()))
5634 &&
"Statement stack mismatch");
5638 if (
DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(S)) {
5640 if (VD->
hasAttr<BlocksAttr>())
5641 return RewriteBlockDeclRefExpr(DRE);