23#include "clang/Config/config.h"
26#include "llvm/ADT/DenseSet.h"
27#include "llvm/ADT/SetVector.h"
28#include "llvm/ADT/SmallPtrSet.h"
29#include "llvm/ADT/StringExtras.h"
30#include "llvm/Support/MemoryBuffer.h"
31#include "llvm/Support/raw_ostream.h"
34#if CLANG_ENABLE_OBJC_REWRITER
57 BLOCK_NEEDS_FREE = (1 << 24),
58 BLOCK_HAS_COPY_DISPOSE = (1 << 25),
60 BLOCK_IS_GC = (1 << 27),
62 BLOCK_HAS_DESCRIPTOR = (1 << 29)
72 const char *MainFileStart, *MainFileEnd;
75 std::string InFileName;
76 std::unique_ptr<raw_ostream> OutFile;
81 Expr *GlobalConstructionExp;
82 unsigned RewriteFailedDiag;
83 unsigned GlobalBlockRewriteFailedDiag;
85 unsigned NumObjCStringLiterals;
86 VarDecl *ConstantStringClassReference;
92 unsigned TryFinallyContainsReturnDiag;
144 llvm::DenseMap<ValueDecl *, unsigned> BlockByRefDeclNo;
148 llvm::DenseMap<BlockExpr *, std::string> RewrittenBlockExprs;
154 llvm::DenseMap<const ObjCIvarDecl* , unsigned> IvarGroupNumber;
157 llvm::DenseMap<std::pair<const ObjCInterfaceDecl*, unsigned>,
QualType> GroupRecordType;
163 llvm::DenseMap<Stmt *, Stmt *> ReplacedNodes;
167 bool SilenceRewriteMacroWarning;
168 bool GenerateLineInfo;
169 bool objc_impl_method;
171 bool DisableReplaceStmt;
172 class DisableReplaceStmtScope {
173 RewriteModernObjC &R;
177 DisableReplaceStmtScope(RewriteModernObjC &R)
178 : R(R), SavedValue(R.DisableReplaceStmt) {
179 R.DisableReplaceStmt =
true;
181 ~DisableReplaceStmtScope() {
182 R.DisableReplaceStmt = SavedValue;
188 llvm::DenseMap<ObjCMethodDecl*, std::string> MethodInternalNames;
194 if (!
Class->isThisDeclarationADefinition()) {
195 RewriteForwardClassDecl(D);
199 ObjCInterfacesSeen.push_back(Class);
205 if (!Proto->isThisDeclarationADefinition()) {
206 RewriteForwardProtocolDecl(D);
216 if (FDecl->isThisDeclarationADefinition() &&
218 !FDecl->isTopLevelDeclInObjCContainer()) {
219 FunctionDefinitionsSeen.push_back(FDecl);
223 HandleTopLevelSingleDecl(*I);
228 void HandleTopLevelDeclInObjCContainer(
DeclGroupRef D)
override {
231 if (isTopLevelBlockPointerType(TD->getUnderlyingType()))
232 RewriteBlockPointerDecl(TD);
233 else if (TD->getUnderlyingType()->isFunctionPointerType())
234 CheckFunctionPointerDecl(TD->getUnderlyingType(), TD);
236 RewriteObjCQualifiedInterfaceTypes(TD);
241 void HandleTopLevelSingleDecl(
Decl *D);
242 void HandleDeclInMainFile(
Decl *D);
243 RewriteModernObjC(std::string inFile, std::unique_ptr<raw_ostream>
OS,
245 bool silenceMacroWarn,
bool LineInfo);
247 ~RewriteModernObjC()
override {}
249 void HandleTranslationUnit(
ASTContext &C)
override;
251 void ReplaceStmt(
Stmt *Old,
Stmt *New) {
256 assert(Old !=
nullptr && New !=
nullptr &&
"Expected non-null Stmt's");
258 Stmt *ReplacingStmt = ReplacedNodes[Old];
262 if (DisableReplaceStmt)
274 llvm::raw_string_ostream S(SStr);
276 const std::string &Str = S.str();
280 ReplacedNodes[Old] = New;
283 if (SilenceRewriteMacroWarning)
290 bool InsertAfter =
true) {
292 if (!
Rewrite.InsertText(Loc, Str, InsertAfter) ||
293 SilenceRewriteMacroWarning)
296 Diags.
Report(Context->getFullLoc(Loc), RewriteFailedDiag);
302 if (!
Rewrite.ReplaceText(Start, OrigLength, Str) ||
303 SilenceRewriteMacroWarning)
306 Diags.
Report(Context->getFullLoc(Start), RewriteFailedDiag);
311 void RewriteInclude();
312 void RewriteLineDirective(
const Decl *D);
314 std::string &LineString);
318 const std::string &typedefString);
319 void RewriteImplementations();
324 void RewriteImplementationDecl(
Decl *Dcl);
327 void RewriteTypeIntoString(
QualType T, std::string &ResultStr,
329 void RewriteByRefString(std::string &ResultStr,
const std::string &Name,
338 void RewriteBlockPointerType(std::string& Str,
QualType Type);
339 void RewriteBlockPointerTypeVariable(std::string& Str,
ValueDecl *VD);
341 void RewriteObjCQualifiedInterfaceTypes(
Decl *Dcl);
342 void RewriteTypeOfDecl(
VarDecl *VD);
343 void RewriteObjCQualifiedInterfaceTypes(
Expr *E);
348 Stmt *RewriteFunctionBodyOrGlobalInitializer(
Stmt *S);
369 void RewriteImplicitCastObjCExpr(
CastExpr *IE);
374 void ObjCIvarBitfieldGroupDecl(
ObjCIvarDecl *IV, std::string &Result);
376 void ObjCIvarBitfieldGroupType(
ObjCIvarDecl *IV, std::string &Result);
378 void ObjCIvarBitfieldGroupOffset(
ObjCIvarDecl *IV, std::string &Result);
381 QualType SynthesizeBitfieldGroupStructType(
389 void RewriteBlockPointerDecl(
NamedDecl *VD);
390 void RewriteByRefVar(
VarDecl *VD,
bool firstDecl,
bool lastDecl);
396 std::string &Result);
398 void RewriteObjCFieldDecl(
FieldDecl *fieldDecl, std::string &Result);
400 bool &IsNamedDefinition);
401 void RewriteLocallyDefinedNamedAggregates(
FieldDecl *fieldDecl,
402 std::string &Result);
404 bool RewriteObjCFieldDeclType(
QualType &
Type, std::string &Result);
407 std::string &Result);
409 void Initialize(
ASTContext &context)
override;
428 void SynthCountByEnumWithState(std::string &buf);
429 void SynthMsgSendFunctionDecl();
430 void SynthMsgSendSuperFunctionDecl();
431 void SynthMsgSendStretFunctionDecl();
432 void SynthMsgSendFpretFunctionDecl();
433 void SynthMsgSendSuperStretFunctionDecl();
434 void SynthGetClassFunctionDecl();
435 void SynthGetMetaClassFunctionDecl();
436 void SynthGetSuperClassFunctionDecl();
437 void SynthSelGetUidFunctionDecl();
438 void SynthSuperConstructorFunctionDecl();
441 template<
typename MethodIterator>
442 void RewriteObjCMethodsMetaData(MethodIterator MethodBegin,
443 MethodIterator MethodEnd,
444 bool IsInstanceMethod,
447 std::string &Result);
449 std::string &Result);
451 std::string &Result);
452 void RewriteClassSetupInitHook(std::string &Result);
454 void RewriteMetaDataIntoBuffer(std::string &Result);
455 void WriteImageInfo(std::string &Result);
457 std::string &Result);
458 void RewriteCategorySetupInitHook(std::string &Result);
462 std::string &Result);
466 std::string SynthesizeByrefCopyDestroyHelper(
VarDecl *VD,
int flag);
467 std::string SynthesizeBlockHelperFuncs(
BlockExpr *CE,
int i,
468 StringRef funcName, std::string Tag);
469 std::string SynthesizeBlockFunc(
BlockExpr *CE,
int i,
470 StringRef funcName, std::string Tag);
471 std::string SynthesizeBlockImpl(
BlockExpr *CE,
472 std::string Tag, std::string Desc);
473 std::string SynthesizeBlockDescriptor(std::string DescTag,
475 int i, StringRef funcName,
480 FunctionDecl *SynthBlockInitFunctionDecl(StringRef name);
486 void WarnAboutReturnGotoStmts(
Stmt *S);
488 void InsertBlockLiteralsWithinFunction(
FunctionDecl *FD);
491 bool IsDeclStmtInForeachHeader(
DeclStmt *DS);
492 void CollectBlockDeclRefInfo(
BlockExpr *Exp);
493 void GetBlockDeclRefExprs(
Stmt *S);
494 void GetInnerBlockDeclRefExprs(
Stmt *S,
496 llvm::SmallPtrSetImpl<const DeclContext *> &InnerContexts);
500 bool isTopLevelBlockPointerType(
QualType T) {
501 return isa<BlockPointerType>(T);
507 bool convertBlockPointerToFunctionPointer(
QualType &T) {
508 if (isTopLevelBlockPointerType(T)) {
510 T = Context->getPointerType(BPT->getPointeeType());
516 bool convertObjCTypeToCStyleType(
QualType &T);
518 bool needToScanForQualifiers(
QualType T);
520 QualType getConstantStringStructType();
523 void convertToUnqualifiedObjCType(
QualType &T) {
526 T = isConst ? Context->getObjCIdType().withConst()
527 : Context->getObjCIdType();
530 T = Context->getObjCClassType();
537 T = Context->getPointerType(T);
547 QualType OCT = Context->getCanonicalType(T).getUnqualifiedType();
549 if (OCT == Context->getCanonicalType(Context->getObjCIdType()) ||
550 OCT == Context->getCanonicalType(Context->getObjCClassType()))
554 if (isa<ObjCInterfaceType>(PT->getPointeeType()) ||
555 PT->getPointeeType()->isObjCQualifiedIdType())
561 bool PointerTypeTakesAnyBlockArguments(
QualType QT);
562 bool PointerTypeTakesAnyObjCQualifiedType(
QualType QT);
563 void GetExtentOfArgList(
const char *Name,
const char *&LParen,
564 const char *&RParen);
566 void QuoteDoublequotes(std::string &From, std::string &To) {
567 for (
unsigned i = 0; i < From.length(); i++) {
577 bool variadic =
false) {
578 if (result == Context->getObjCInstanceType())
579 result = Context->getObjCIdType();
582 return Context->getFunctionType(result, args, fpi);
589 return CStyleCastExpr::Create(*Ctx, Ty, VK_PRValue, Kind, E,
nullptr,
594 bool ImplementationIsNonLazy(
const ObjCImplDecl *OD)
const {
596 Selector LoadSel = Context->Selectors.getSelector(0, &II);
601 QualType StrType = Context->getConstantArrayType(
602 Context->CharTy, llvm::APInt(32, Str.size() + 1),
nullptr,
603 ArrayType::Normal, 0);
604 return StringLiteral::Create(*Context, Str, StringLiteral::Ordinary,
610void RewriteModernObjC::RewriteBlocksInFunctionProtoType(
QualType funcType,
613 = dyn_cast<FunctionProtoType>(funcType.
IgnoreParens())) {
614 for (
const auto &I : fproto->param_types())
615 if (isTopLevelBlockPointerType(I)) {
617 RewriteBlockPointerDecl(D);
623void RewriteModernObjC::CheckFunctionPointerDecl(
QualType funcType,
NamedDecl *ND) {
625 if (PT && PointerTypeTakesAnyBlockArguments(funcType))
629static bool IsHeaderFile(
const std::string &
Filename) {
630 std::string::size_type DotPos =
Filename.rfind(
'.');
632 if (DotPos == std::string::npos) {
637 std::string Ext =
Filename.substr(DotPos + 1);
640 return Ext ==
"h" || Ext ==
"hh" || Ext ==
"H";
643RewriteModernObjC::RewriteModernObjC(std::string inFile,
644 std::unique_ptr<raw_ostream>
OS,
647 bool silenceMacroWarn,
bool LineInfo)
648 : Diags(D), LangOpts(LOpts), InFileName(inFile), OutFile(
std::move(
OS)),
649 SilenceRewriteMacroWarning(silenceMacroWarn), GenerateLineInfo(LineInfo) {
650 IsHeader = IsHeaderFile(inFile);
652 "rewriting sub-expression within a macro (may not be correct)");
655 GlobalBlockRewriteFailedDiag = Diags.
getCustomDiagID(DiagnosticsEngine::Warning,
656 "rewriting block literal declared in global scope is not implemented");
659 DiagnosticsEngine::Warning,
660 "rewriter doesn't support user-specified control flow semantics "
661 "for @try/@finally (code may not execute properly)");
665 const std::string &InFile, std::unique_ptr<raw_ostream>
OS,
667 bool SilenceRewriteMacroWarning,
bool LineInfo) {
668 return std::make_unique<RewriteModernObjC>(InFile, std::move(
OS), Diags,
669 LOpts, SilenceRewriteMacroWarning,
673void RewriteModernObjC::InitializeCommon(
ASTContext &context) {
675 SM = &Context->getSourceManager();
676 TUDecl = Context->getTranslationUnitDecl();
677 MsgSendFunctionDecl =
nullptr;
678 MsgSendSuperFunctionDecl =
nullptr;
679 MsgSendStretFunctionDecl =
nullptr;
680 MsgSendSuperStretFunctionDecl =
nullptr;
681 MsgSendFpretFunctionDecl =
nullptr;
682 GetClassFunctionDecl =
nullptr;
683 GetMetaClassFunctionDecl =
nullptr;
684 GetSuperClassFunctionDecl =
nullptr;
685 SelGetUidFunctionDecl =
nullptr;
686 CFStringFunctionDecl =
nullptr;
687 ConstantStringClassReference =
nullptr;
688 NSStringRecord =
nullptr;
689 CurMethodDef =
nullptr;
690 CurFunctionDef =
nullptr;
691 GlobalVarDecl =
nullptr;
692 GlobalConstructionExp =
nullptr;
693 SuperStructDecl =
nullptr;
694 ProtocolTypeDecl =
nullptr;
695 ConstantStringDecl =
nullptr;
697 SuperConstructorFunctionDecl =
nullptr;
698 NumObjCStringLiterals = 0;
699 PropParentMap =
nullptr;
700 CurrentBody =
nullptr;
701 DisableReplaceStmt =
false;
702 objc_impl_method =
false;
705 MainFileID =
SM->getMainFileID();
706 llvm::MemoryBufferRef MainBuf =
SM->getBufferOrFake(MainFileID);
707 MainFileStart = MainBuf.getBufferStart();
708 MainFileEnd = MainBuf.getBufferEnd();
710 Rewrite.setSourceMgr(Context->getSourceManager(), Context->getLangOpts());
717void RewriteModernObjC::HandleTopLevelSingleDecl(
Decl *D) {
725 Loc =
SM->getExpansionLoc(Loc);
732 RewriteFunctionDecl(FD);
733 }
else if (
VarDecl *FVD = dyn_cast<VarDecl>(D)) {
735 if (FVD->getName() ==
"_NSConstantStringClassReference") {
736 ConstantStringClassReference = FVD;
740 RewriteCategoryDecl(CD);
742 if (PD->isThisDeclarationADefinition())
743 RewriteProtocolDecl(PD);
747 DIEnd = LSD->decls_end();
750 if (!IFace->isThisDeclarationADefinition()) {
754 if (isa<ObjCInterfaceDecl>(*DI) &&
755 !cast<ObjCInterfaceDecl>(*DI)->isThisDeclarationADefinition() &&
756 StartLoc == (*DI)->getBeginLoc())
762 }
while (DI != DIEnd);
763 RewriteForwardClassDecl(DG);
768 ObjCInterfacesSeen.push_back(IFace);
775 if (!Proto->isThisDeclarationADefinition()) {
779 if (isa<ObjCProtocolDecl>(*DI) &&
780 !cast<ObjCProtocolDecl>(*DI)->isThisDeclarationADefinition() &&
781 StartLoc == (*DI)->getBeginLoc())
787 }
while (DI != DIEnd);
788 RewriteForwardProtocolDecl(DG);
793 HandleTopLevelSingleDecl(*DI);
798 if (
SM->isWrittenInMainFile(Loc))
799 return HandleDeclInMainFile(D);
806void RewriteModernObjC::RewriteInclude() {
808 StringRef MainBuf =
SM->getBufferData(MainFileID);
809 const char *MainBufStart = MainBuf.begin();
810 const char *MainBufEnd = MainBuf.end();
811 size_t ImportLen = strlen(
"import");
814 for (
const char *BufPtr = MainBufStart; BufPtr < MainBufEnd; ++BufPtr) {
815 if (*BufPtr ==
'#') {
816 if (++BufPtr == MainBufEnd)
818 while (*BufPtr ==
' ' || *BufPtr ==
'\t')
819 if (++BufPtr == MainBufEnd)
821 if (!strncmp(BufPtr,
"import", ImportLen)) {
825 ReplaceText(ImportLoc, ImportLen,
"include");
834 Result +=
"OBJC_IVAR_$_";
841RewriteModernObjC::getIvarAccessString(
ObjCIvarDecl *D) {
845 std::string IvarOffsetName;
847 ObjCIvarBitfieldGroupOffset(D, IvarOffsetName);
849 WriteInternalIvarName(ClassDecl, D, IvarOffsetName);
851 std::string S =
"(*(";
854 IvarT = GetGroupRecordTypeForObjCIvarBitfield(D);
864 CDecl = CatDecl->getClassInterface();
865 std::string RecName = std::string(CDecl->getName());
868 RecordDecl::Create(*Context, TTK_Struct, TUDecl,
SourceLocation(),
870 QualType PtrStructIMPL = Context->getPointerType(Context->getTagDeclType(RD));
871 unsigned UnsignedIntSize =
872 static_cast<unsigned>(Context->getTypeSize(Context->UnsignedIntTy));
873 Expr *
Zero = IntegerLiteral::Create(*Context,
874 llvm::APInt(UnsignedIntSize, 0),
876 Zero = NoTypeInfoCStyleCastExpr(Context, PtrStructIMPL, CK_BitCast, Zero);
886 *Context, PE,
true, FD, FD->
getType(), VK_LValue, OK_Ordinary);
887 IvarT = Context->getDecltypeType(ME, ME->
getType());
890 convertObjCTypeToCStyleType(IvarT);
891 QualType castT = Context->getPointerType(IvarT);
892 std::string TypeString(castT.
getAsString(Context->getPrintingPolicy()));
897 S +=
"((char *)self + ";
921 static bool objcGetPropertyDefined =
false;
922 static bool objcSetPropertyDefined =
false;
927 InsertText(startLoc,
"// ");
928 const char *startBuf =
SM->getCharacterData(startLoc);
929 assert((*startBuf ==
'@') &&
"bogus @synthesize location");
930 const char *semiBuf = strchr(startBuf,
';');
931 assert((*semiBuf ==
';') &&
"@synthesize: can't find ';'");
942 assert(IMD && OID &&
"Synthesized ivars must be attached to @implementation");
945 if (mustSynthesizeSetterGetterMethod(IMD, PD,
true )) {
946 bool GenGetProperty =
947 !(Attributes & ObjCPropertyAttribute::kind_nonatomic) &&
948 (Attributes & (ObjCPropertyAttribute::kind_retain |
949 ObjCPropertyAttribute::kind_copy));
951 if (GenGetProperty && !objcGetPropertyDefined) {
952 objcGetPropertyDefined =
true;
954 Getr =
"\nextern \"C\" __declspec(dllimport) "
955 "id objc_getProperty(id, SEL, long, bool);\n";
962 if (GenGetProperty) {
975 for (
unsigned i = 0, e = FT->getNumParams(); i != e; ++i) {
977 std::string ParamStr =
978 FT->getParamType(i).getAsString(Context->getPrintingPolicy());
981 if (FT->isVariadic()) {
982 if (FT->getNumParams())
991 Getr +=
"return (_TYPE)";
992 Getr +=
"objc_getProperty(self, _cmd, ";
993 RewriteIvarOffsetComputation(OID, Getr);
997 Getr +=
"return " + getIvarAccessString(OID);
999 InsertText(startGetterSetterLoc, Getr);
1003 !mustSynthesizeSetterGetterMethod(IMD, PD,
false ))
1008 bool GenSetProperty = Attributes & (ObjCPropertyAttribute::kind_retain |
1009 ObjCPropertyAttribute::kind_copy);
1010 if (GenSetProperty && !objcSetPropertyDefined) {
1011 objcSetPropertyDefined =
true;
1013 Setr =
"\nextern \"C\" __declspec(dllimport) "
1014 "void objc_setProperty (id, SEL, long, id, bool, bool);\n";
1022 if (GenSetProperty) {
1023 Setr +=
"objc_setProperty (self, _cmd, ";
1024 RewriteIvarOffsetComputation(OID, Setr);
1028 if (Attributes & ObjCPropertyAttribute::kind_nonatomic)
1032 if (Attributes & ObjCPropertyAttribute::kind_copy)
1038 Setr += getIvarAccessString(OID) +
" = ";
1042 InsertText(startGetterSetterLoc, Setr);
1046 std::string &typedefString) {
1047 typedefString +=
"\n#ifndef _REWRITER_typedef_";
1049 typedefString +=
"\n";
1050 typedefString +=
"#define _REWRITER_typedef_";
1052 typedefString +=
"\n";
1053 typedefString +=
"typedef struct objc_object ";
1056 typedefString +=
";\ntypedef struct {} _objc_exc_";
1058 typedefString +=
";\n#endif\n";
1061void RewriteModernObjC::RewriteForwardClassEpilogue(
ObjCInterfaceDecl *ClassDecl,
1062 const std::string &typedefString) {
1064 const char *startBuf =
SM->getCharacterData(startLoc);
1065 const char *semiPtr = strchr(startBuf,
';');
1067 ReplaceText(startLoc, semiPtr-startBuf+1, typedefString);
1070void RewriteModernObjC::RewriteForwardClassDecl(
DeclGroupRef D) {
1071 std::string typedefString;
1074 if (I == D.
begin()) {
1078 typedefString +=
"// @class ";
1080 typedefString +=
";";
1082 RewriteOneForwardClassDecl(ForwardDecl, typedefString);
1085 HandleTopLevelSingleDecl(*I);
1088 RewriteForwardClassEpilogue(cast<ObjCInterfaceDecl>(*I), typedefString);
1091void RewriteModernObjC::RewriteForwardClassDecl(
1093 std::string typedefString;
1094 for (
unsigned i = 0; i < D.size(); i++) {
1097 typedefString +=
"// @class ";
1099 typedefString +=
";";
1101 RewriteOneForwardClassDecl(ForwardDecl, typedefString);
1103 RewriteForwardClassEpilogue(cast<ObjCInterfaceDecl>(D[0]), typedefString);
1106void RewriteModernObjC::RewriteMethodDeclaration(
ObjCMethodDecl *Method) {
1114 if (
SM->getExpansionLineNumber(LocEnd) >
1115 SM->getExpansionLineNumber(LocStart)) {
1116 InsertText(LocStart,
"#if 0\n");
1117 ReplaceText(LocEnd, 1,
";\n#endif\n");
1119 InsertText(LocStart,
"// ");
1126 ReplaceText(Loc, 0,
"// ");
1135 ReplaceText(LocStart, 1,
"/** ");
1139 ReplaceText(LocStart, 0,
"// ");
1146 RewriteMethodDeclaration(I);
1148 RewriteMethodDeclaration(I);
1152 strlen(
"@end"),
"/* @end */\n");
1160 ReplaceText(LocStart, 0,
"// ");
1163 RewriteMethodDeclaration(I);
1165 RewriteMethodDeclaration(I);
1171 ReplaceText(LocEnd, strlen(
"@end"),
"/* @end */\n");
1174 const char *startBuf =
SM->getCharacterData(LocStart);
1175 const char *endBuf =
SM->getCharacterData(LocEnd);
1176 for (
const char *p = startBuf; p < endBuf; p++) {
1177 if (*p ==
'@' && !strncmp(p+1,
"optional", strlen(
"optional"))) {
1179 ReplaceText(OptionalLoc, strlen(
"@optional"),
"/* @optional */");
1182 else if (*p ==
'@' && !strncmp(p+1,
"required", strlen(
"required"))) {
1184 ReplaceText(OptionalLoc, strlen(
"@required"),
"/* @required */");
1190void RewriteModernObjC::RewriteForwardProtocolDecl(
DeclGroupRef D) {
1193 llvm_unreachable(
"Invalid SourceLocation");
1195 ReplaceText(LocStart, 0,
"// ");
1202 llvm_unreachable(
"Invalid SourceLocation");
1204 ReplaceText(LocStart, 0,
"// ");
1207void RewriteModernObjC::RewriteTypeIntoString(
QualType T, std::string &ResultStr,
1227 ResultStr += T.
getAsString(Context->getPrintingPolicy());
1232 std::string &ResultStr) {
1235 ResultStr +=
"\nstatic ";
1236 RewriteTypeIntoString(OMD->
getReturnType(), ResultStr, FPRetType);
1240 std::string NameStr;
1258 int len = selString.size();
1259 for (
int i = 0; i < len; i++)
1260 if (selString[i] ==
':')
1262 NameStr += selString;
1265 MethodInternalNames[OMD] = NameStr;
1266 ResultStr += NameStr;
1273 QualType selfTy = Context->getObjCInterfaceType(IDecl);
1274 selfTy = Context->getPointerType(selfTy);
1275 if (!LangOpts.MicrosoftExt) {
1277 ResultStr +=
"struct ";
1284 ResultStr += Context->getObjCClassType().getAsString(
1285 Context->getPrintingPolicy());
1287 ResultStr +=
" self, ";
1288 ResultStr += Context->getObjCSelType().getAsString(Context->getPrintingPolicy());
1289 ResultStr +=
" _cmd";
1292 for (
const auto *PDecl : OMD->
parameters()) {
1294 if (PDecl->getType()->isObjCQualifiedIdType()) {
1301 (void)convertBlockPointerToFunctionPointer(QT);
1307 ResultStr +=
", ...";
1316 for (
unsigned i = 0, e = FT->getNumParams(); i != e; ++i) {
1317 if (i) ResultStr +=
", ";
1318 std::string ParamStr =
1319 FT->getParamType(i).getAsString(Context->getPrintingPolicy());
1320 ResultStr += ParamStr;
1322 if (FT->isVariadic()) {
1323 if (FT->getNumParams())
1334void RewriteModernObjC::RewriteImplementationDecl(
Decl *OID) {
1337 assert((IMD || CID) &&
"Unknown implementation type");
1354 std::string ResultStr;
1359 const char *startBuf =
SM->getCharacterData(LocStart);
1360 const char *endBuf =
SM->getCharacterData(LocEnd);
1361 ReplaceText(LocStart, endBuf-startBuf, ResultStr);
1367 std::string ResultStr;
1372 const char *startBuf =
SM->getCharacterData(LocStart);
1373 const char *endBuf =
SM->getCharacterData(LocEnd);
1374 ReplaceText(LocStart, endBuf-startBuf, ResultStr);
1377 RewritePropertyImplDecl(I, IMD, CID);
1384 if (ObjCSynthesizedStructs.count(ClassDecl))
1388 while (SuperClass) {
1389 RewriteInterfaceDecl(SuperClass);
1392 std::string ResultStr;
1395 RewriteOneForwardClassDecl(ClassDecl, ResultStr);
1396 RewriteIvarOffsetSymbols(ClassDecl, ResultStr);
1398 RewriteObjCInternalStruct(ClassDecl, ResultStr);
1405 RewriteMethodDeclaration(I);
1407 RewriteMethodDeclaration(I);
1429 DisableReplaceStmtScope S(*
this);
1435 Base = cast<OpaqueValueExpr>(
Base)->getSourceExpr();
1436 Base = cast<Expr>(RewriteFunctionBodyOrGlobalInitializer(
Base));
1440 for (
unsigned i = 0; i < numArgs; i++) {
1442 if (isa<OpaqueValueExpr>(Arg))
1443 Arg = cast<OpaqueValueExpr>(Arg)->getSourceExpr();
1444 Arg = cast<Expr>(RewriteFunctionBodyOrGlobalInitializer(Arg));
1445 Args.push_back(Arg);
1455 case ObjCMessageExpr::Class:
1456 NewMsg = ObjCMessageExpr::Create(*Context, OldMsg->
getType(),
1468 case ObjCMessageExpr::Instance:
1469 NewMsg = ObjCMessageExpr::Create(*Context, OldMsg->
getType(),
1481 case ObjCMessageExpr::SuperClass:
1482 case ObjCMessageExpr::SuperInstance:
1483 NewMsg = ObjCMessageExpr::Create(*Context, OldMsg->
getType(),
1498 Stmt *Replacement = SynthMessageExpr(NewMsg);
1499 ReplaceStmtWithRange(PseudoOp, Replacement, OldRange);
1516 DisableReplaceStmtScope S(*
this);
1520 Base = cast<OpaqueValueExpr>(
Base)->getSourceExpr();
1521 Base = cast<Expr>(RewriteFunctionBodyOrGlobalInitializer(
Base));
1524 for (
unsigned i = 0; i < numArgs; i++) {
1526 if (isa<OpaqueValueExpr>(Arg))
1527 Arg = cast<OpaqueValueExpr>(Arg)->getSourceExpr();
1528 Arg = cast<Expr>(RewriteFunctionBodyOrGlobalInitializer(Arg));
1529 Args.push_back(Arg);
1538 case ObjCMessageExpr::Class:
1539 NewMsg = ObjCMessageExpr::Create(*Context, OldMsg->
getType(),
1551 case ObjCMessageExpr::Instance:
1552 NewMsg = ObjCMessageExpr::Create(*Context, OldMsg->
getType(),
1564 case ObjCMessageExpr::SuperClass:
1565 case ObjCMessageExpr::SuperInstance:
1566 NewMsg = ObjCMessageExpr::Create(*Context, OldMsg->
getType(),
1581 Stmt *Replacement = SynthMessageExpr(NewMsg);
1582 ReplaceStmtWithRange(PseudoOp, Replacement, OldRange);
1595void RewriteModernObjC::SynthCountByEnumWithState(std::string &buf) {
1596 buf +=
"((_WIN_NSUInteger (*) (id, SEL, struct __objcFastEnumerationState *, "
1597 "id *, _WIN_NSUInteger))(void *)objc_msgSend)";
1599 buf +=
"((id)l_collection,\n\t\t";
1600 buf +=
"sel_registerName(\"countByEnumeratingWithState:objects:count:\"),";
1602 buf +=
"&enumState, "
1603 "(id *)__rw_items, (_WIN_NSUInteger)16)";
1610 if (Stmts.empty() || !isa<ObjCForCollectionStmt>(Stmts.back()))
1616 buf =
"goto __break_label_";
1617 buf += utostr(ObjCBcLabelNo.back());
1618 ReplaceText(startLoc, strlen(
"break"), buf);
1623void RewriteModernObjC::ConvertSourceLocationToLineDirective(
1625 std::string &LineString) {
1626 if (Loc.
isFileID() && GenerateLineInfo) {
1627 LineString +=
"\n#line ";
1629 LineString += utostr(PLoc.
getLine());
1630 LineString +=
" \"";
1631 LineString += Lexer::Stringify(PLoc.
getFilename());
1632 LineString +=
"\"\n";
1640 if (Stmts.empty() || !isa<ObjCForCollectionStmt>(Stmts.back()))
1646 buf =
"goto __continue_label_";
1647 buf += utostr(ObjCBcLabelNo.back());
1648 ReplaceText(startLoc, strlen(
"continue"), buf);
1687 assert(!Stmts.empty() &&
"ObjCForCollectionStmt - Statement stack empty");
1688 assert(isa<ObjCForCollectionStmt>(Stmts.back()) &&
1689 "ObjCForCollectionStmt Statement stack mismatch");
1690 assert(!ObjCBcLabelNo.empty() &&
1691 "ObjCForCollectionStmt - Label No stack empty");
1694 const char *startBuf =
SM->getCharacterData(startLoc);
1695 StringRef elementName;
1696 std::string elementTypeAsString;
1700 ConvertSourceLocationToLineDirective(ForEachLoc, buf);
1702 if (
DeclStmt *DS = dyn_cast<DeclStmt>(S->getElement())) {
1704 NamedDecl* D = cast<NamedDecl>(DS->getSingleDecl());
1705 QualType ElementType = cast<ValueDecl>(D)->getType();
1709 elementTypeAsString =
"id";
1711 elementTypeAsString = ElementType.
getAsString(Context->getPrintingPolicy());
1712 buf += elementTypeAsString;
1719 DeclRefExpr *DR = cast<DeclRefExpr>(S->getElement());
1725 elementTypeAsString =
"id";
1731 buf +=
"struct __objcFastEnumerationState enumState = { 0 };\n\t";
1733 buf +=
"id __rw_items[16];\n\t";
1735 buf +=
"id l_collection = (id)";
1737 const char *startCollectionBuf = startBuf;
1738 startCollectionBuf += 3;
1739 startCollectionBuf = strchr(startCollectionBuf,
'(');
1740 startCollectionBuf++;
1742 while (*startCollectionBuf !=
' ' ||
1743 *(startCollectionBuf+1) !=
'i' || *(startCollectionBuf+2) !=
'n' ||
1744 (*(startCollectionBuf+3) !=
' ' &&
1745 *(startCollectionBuf+3) !=
'[' && *(startCollectionBuf+3) !=
'('))
1746 startCollectionBuf++;
1747 startCollectionBuf += 3;
1750 ReplaceText(startLoc, startCollectionBuf - startBuf, buf);
1753 const char *rparenBuf =
SM->getCharacterData(rightParenLoc);
1768 buf +=
"_WIN_NSUInteger limit =\n\t\t";
1769 SynthCountByEnumWithState(buf);
1779 buf +=
"if (limit) {\n\t";
1780 buf +=
"unsigned long startMutations = *enumState.mutationsPtr;\n\t";
1781 buf +=
"do {\n\t\t";
1782 buf +=
"unsigned long counter = 0;\n\t\t";
1783 buf +=
"do {\n\t\t\t";
1784 buf +=
"if (startMutations != *enumState.mutationsPtr)\n\t\t\t\t";
1785 buf +=
"objc_enumerationMutation(l_collection);\n\t\t\t";
1788 buf += elementTypeAsString;
1789 buf +=
")enumState.itemsPtr[counter++];";
1791 ReplaceText(lparenLoc, 1, buf);
1805 buf +=
"__continue_label_";
1806 buf += utostr(ObjCBcLabelNo.back());
1809 buf +=
"} while (counter < limit);\n\t";
1810 buf +=
"} while ((limit = ";
1811 SynthCountByEnumWithState(buf);
1815 buf += elementTypeAsString;
1817 buf +=
"__break_label_";
1818 buf += utostr(ObjCBcLabelNo.back());
1821 buf +=
"else\n\t\t";
1824 buf += elementTypeAsString;
1830 if (isa<CompoundStmt>(S->getBody())) {
1832 InsertText(endBodyLoc, buf);
1841 const char *stmtBuf =
SM->getCharacterData(OrigEnd);
1842 const char *semiBuf = strchr(stmtBuf,
';');
1843 assert(semiBuf &&
"Can't find ';'");
1845 InsertText(endBodyLoc, buf);
1848 ObjCBcLabelNo.pop_back();
1852static void Write_RethrowObject(std::string &buf) {
1853 buf +=
"{ struct _FIN { _FIN(id reth) : rethrow(reth) {}\n";
1854 buf +=
"\t~_FIN() { if (rethrow) objc_exception_throw(rethrow); }\n";
1855 buf +=
"\tid rethrow;\n";
1856 buf +=
"\t} _fin_force_rethow(_rethrow);";
1868 const char *startBuf =
SM->getCharacterData(startLoc);
1870 assert((*startBuf ==
'@') &&
"bogus @synchronized location");
1874 ConvertSourceLocationToLineDirective(SynchLoc, buf);
1875 buf +=
"{ id _rethrow = 0; id _sync_obj = (id)";
1877 const char *lparenBuf = startBuf;
1878 while (*lparenBuf !=
'(') lparenBuf++;
1879 ReplaceText(startLoc, lparenBuf-startBuf+1, buf);
1881 buf =
"; objc_sync_enter(_sync_obj);\n";
1882 buf +=
"try {\n\tstruct _SYNC_EXIT { _SYNC_EXIT(id arg) : sync_exit(arg) {}";
1883 buf +=
"\n\t~_SYNC_EXIT() {objc_sync_exit(sync_exit);}";
1884 buf +=
"\n\tid sync_exit;";
1885 buf +=
"\n\t} _sync_exit(_sync_obj);\n";
1891 const char *RParenExprLocBuf =
SM->getCharacterData(RParenExprLoc);
1892 while (*RParenExprLocBuf !=
')') RParenExprLocBuf--;
1896 const char *LBraceLocBuf =
SM->getCharacterData(LBranceLoc);
1897 assert (*LBraceLocBuf ==
'{');
1898 ReplaceText(RParenExprLoc, (LBraceLocBuf -
SM->getCharacterData(RParenExprLoc) + 1), buf);
1901 assert((*
SM->getCharacterData(startRBraceLoc) ==
'}') &&
1902 "bogus @synchronized block");
1904 buf =
"} catch (id e) {_rethrow = e;}\n";
1905 Write_RethrowObject(buf);
1909 ReplaceText(startRBraceLoc, 1, buf);
1914void RewriteModernObjC::WarnAboutReturnGotoStmts(
Stmt *S)
1917 for (
Stmt *SubStmt : S->children())
1919 WarnAboutReturnGotoStmts(SubStmt);
1921 if (isa<ReturnStmt>(S) || isa<GotoStmt>(S)) {
1922 Diags.
Report(Context->getFullLoc(S->getBeginLoc()),
1923 TryFinallyContainsReturnDiag);
1929 ReplaceText(startLoc, strlen(
"@autoreleasepool"),
"/* @autoreleasepool */");
1930 ReplaceText(S->getSubStmt()->getBeginLoc(), 1,
1931 "{ __AtAutoreleasePool __autoreleasepool; ");
1938 bool noCatch = S->getNumCatchStmts() == 0;
1941 ConvertSourceLocationToLineDirective(TryLocation, buf);
1945 buf +=
"{ id volatile _rethrow = 0;\n";
1947 buf +=
"{ id volatile _rethrow = 0;\ntry {\n";
1952 const char *startBuf =
SM->getCharacterData(startLoc);
1954 assert((*startBuf ==
'@') &&
"bogus @try location");
1956 ReplaceText(startLoc, 1, buf);
1959 ReplaceText(startLoc, 1,
"");
1962 VarDecl *catchDecl = Catch->getCatchParamDecl();
1964 startLoc = Catch->getBeginLoc();
1965 bool AtRemoved =
false;
1974 ConvertSourceLocationToLineDirective(Catch->getBeginLoc(), Result);
1976 startBuf =
SM->getCharacterData(startLoc);
1977 assert((*startBuf ==
'@') &&
"bogus @catch location");
1979 const char *rParenBuf =
SM->getCharacterData(rParenLoc);
1985 ReplaceText(startLoc, rParenBuf-startBuf+1, Result);
1996 ReplaceText(lBraceLoc, 1, Result);
2003 ReplaceText(startLoc, 1,
"");
2011 ConvertSourceLocationToLineDirective(FinallyLoc, buf);
2012 buf +=
"catch (id e) {_rethrow = e;}\n";
2016 ConvertSourceLocationToLineDirective(FinallyLoc, buf);
2017 buf +=
"catch (id e) {_rethrow = e;}\n";
2021 ReplaceText(startFinalLoc, 8, buf);
2025 Write_RethrowObject(buf);
2026 ReplaceText(startFinalBodyLoc, 1, buf);
2029 ReplaceText(endFinalBodyLoc, 1,
"}\n}");
2031 WarnAboutReturnGotoStmts(S->getTryBody());
2043 const char *startBuf =
SM->getCharacterData(startLoc);
2045 assert((*startBuf ==
'@') &&
"bogus @throw location");
2049 if (S->getThrowExpr())
2050 buf =
"objc_exception_throw(";
2055 const char *wBuf = strchr(startBuf,
'w');
2056 assert((*wBuf ==
'w') &&
"@throw: can't find 'w'");
2057 ReplaceText(startLoc, wBuf-startBuf+1, buf);
2060 const char *endBuf =
SM->getCharacterData(endLoc);
2061 const char *semiBuf = strchr(endBuf,
';');
2062 assert((*semiBuf ==
';') &&
"@throw: can't find ';'");
2064 if (S->getThrowExpr())
2065 ReplaceText(semiLoc, 1,
");");
2071 std::string StrEncoding;
2072 Context->getObjCEncodingForType(Exp->
getEncodedType(), StrEncoding);
2073 Expr *Replacement = getStringLiteral(StrEncoding);
2074 ReplaceStmt(Exp, Replacement);
2082 if (!SelGetUidFunctionDecl)
2083 SynthSelGetUidFunctionDecl();
2084 assert(SelGetUidFunctionDecl &&
"Can't find sel_registerName() decl");
2088 CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl,
2090 ReplaceStmt(Exp, SelExp);
2096RewriteModernObjC::SynthesizeCallToFunctionDecl(
FunctionDecl *FD,
2108 QualType pToFunc = Context->getPointerType(msgSendType);
2110 ImplicitCastExpr::Create(*Context, pToFunc, CK_FunctionToPointerDecay,
2115 CallExpr::Create(*Context, ICE, Args, FT->getCallResultType(*Context),
2120static bool scanForProtocolRefs(
const char *startBuf,
const char *endBuf,
2121 const char *&startRef,
const char *&endRef) {
2122 while (startBuf < endBuf) {
2123 if (*startBuf ==
'<')
2124 startRef = startBuf;
2125 if (*startBuf ==
'>') {
2126 if (startRef && *startRef ==
'<') {
2137static void scanToNextArgument(
const char *&argRef) {
2139 while (*argRef !=
')' && (*argRef !=
',' || angle > 0)) {
2142 else if (*argRef ==
'>')
2146 assert(angle == 0 &&
"scanToNextArgument - bad protocol type syntax");
2149bool RewriteModernObjC::needToScanForQualifiers(
QualType T) {
2161 QualType ElemTy = Context->getBaseElementType(T);
2162 return needToScanForQualifiers(ElemTy);
2167void RewriteModernObjC::RewriteObjCQualifiedInterfaceTypes(
Expr *E) {
2169 if (needToScanForQualifiers(
Type)) {
2173 Loc = ECE->getLParenLoc();
2174 EndLoc = ECE->getRParenLoc();
2183 const char *startBuf =
SM->getCharacterData(Loc);
2184 const char *endBuf =
SM->getCharacterData(EndLoc);
2185 const char *startRef =
nullptr, *endRef =
nullptr;
2186 if (scanForProtocolRefs(startBuf, endBuf, startRef, endRef)) {
2191 InsertText(LessLoc,
"/*");
2192 InsertText(GreaterLoc,
"*/");
2197void RewriteModernObjC::RewriteObjCQualifiedInterfaceTypes(
Decl *Dcl) {
2201 if (
VarDecl *VD = dyn_cast<VarDecl>(Dcl)) {
2205 else if (
FunctionDecl *FD = dyn_cast<FunctionDecl>(Dcl)) {
2210 assert(funcType &&
"missing function type");
2211 proto = dyn_cast<FunctionProtoType>(funcType);
2216 else if (
FieldDecl *FD = dyn_cast<FieldDecl>(Dcl)) {
2221 Loc = TD->getLocation();
2222 Type = TD->getUnderlyingType();
2227 if (needToScanForQualifiers(
Type)) {
2230 const char *endBuf =
SM->getCharacterData(Loc);
2231 const char *startBuf = endBuf;
2232 while (*startBuf !=
';' && *startBuf !=
'<' && startBuf != MainFileStart)
2234 const char *startRef =
nullptr, *endRef =
nullptr;
2235 if (scanForProtocolRefs(startBuf, endBuf, startRef, endRef)) {
2240 InsertText(LessLoc,
"/*");
2241 InsertText(GreaterLoc,
"*/");
2247 const char *startBuf =
SM->getCharacterData(Loc);
2248 const char *startFuncBuf = startBuf;
2253 const char *endBuf = startBuf;
2255 scanToNextArgument(endBuf);
2256 const char *startRef =
nullptr, *endRef =
nullptr;
2257 if (scanForProtocolRefs(startBuf, endBuf, startRef, endRef)) {
2264 InsertText(LessLoc,
"/*");
2265 InsertText(GreaterLoc,
"*/");
2267 startBuf = ++endBuf;
2272 while (*startBuf && *startBuf !=
')' && *startBuf !=
',')
2279void RewriteModernObjC::RewriteTypeOfDecl(
VarDecl *ND) {
2282 if (!isa<TypeOfExprType>(TypePtr))
2284 while (isa<TypeOfExprType>(TypePtr)) {
2285 const TypeOfExprType *TypeOfExprTypePtr = cast<TypeOfExprType>(TypePtr);
2291 std::string TypeAsString(QT.
getAsString(Context->getPrintingPolicy()));
2293 const char *startBuf =
SM->getCharacterData(DeclLoc);
2296 TypeAsString +=
" " + Name +
" = ";
2300 startLoc = ECE->getLParenLoc();
2303 startLoc =
SM->getExpansionLoc(startLoc);
2304 const char *endBuf =
SM->getCharacterData(startLoc);
2305 ReplaceText(DeclLoc, endBuf-startBuf-1, TypeAsString);
2309 X =
SM->getExpansionLoc(
X);
2310 const char *endBuf =
SM->getCharacterData(
X);
2311 ReplaceText(DeclLoc, endBuf-startBuf-1, TypeAsString);
2316void RewriteModernObjC::SynthSelGetUidFunctionDecl() {
2317 IdentifierInfo *SelGetUidIdent = &Context->Idents.get(
"sel_registerName");
2319 ArgTys.push_back(Context->getPointerType(Context->CharTy.withConst()));
2321 getSimpleFunctionType(Context->getObjCSelType(), ArgTys);
2322 SelGetUidFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
2325 SelGetUidIdent, getFuncType,
2326 nullptr, SC_Extern);
2329void RewriteModernObjC::RewriteFunctionDecl(
FunctionDecl *FD) {
2332 FD->
getName() ==
"sel_registerName") {
2333 SelGetUidFunctionDecl = FD;
2336 RewriteObjCQualifiedInterfaceTypes(FD);
2339void RewriteModernObjC::RewriteBlockPointerType(std::string& Str,
QualType Type) {
2340 std::string TypeString(
Type.getAsString(Context->getPrintingPolicy()));
2341 const char *argPtr = TypeString.c_str();
2342 if (!strchr(argPtr,
'^')) {
2347 Str += (*argPtr ==
'^' ?
'*' : *argPtr);
2353void RewriteModernObjC::RewriteBlockPointerTypeVariable(std::string& Str,
2356 std::string TypeString(
Type.getAsString(Context->getPrintingPolicy()));
2357 const char *argPtr = TypeString.c_str();
2382void RewriteModernObjC::RewriteBlockLiteralFunctionDecl(
FunctionDecl *FD) {
2389 std::string FdStr =
Type.getAsString(Context->getPrintingPolicy());
2393 unsigned numArgs = proto->getNumParams();
2394 for (
unsigned i = 0; i < numArgs; i++) {
2395 QualType ArgType = proto->getParamType(i);
2396 RewriteBlockPointerType(FdStr, ArgType);
2401 FdStr += (numArgs > 0) ?
", ...);\n" :
"...);\n";
2405 InsertText(FunLocStart, FdStr);
2409void RewriteModernObjC::SynthSuperConstructorFunctionDecl() {
2410 if (SuperConstructorFunctionDecl)
2412 IdentifierInfo *msgSendIdent = &Context->Idents.get(
"__rw_objc_super");
2414 QualType argT = Context->getObjCIdType();
2415 assert(!argT.
isNull() &&
"Can't find 'id' type");
2416 ArgTys.push_back(argT);
2417 ArgTys.push_back(argT);
2418 QualType msgSendType = getSimpleFunctionType(Context->getObjCIdType(),
2420 SuperConstructorFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
2423 msgSendIdent, msgSendType,
2424 nullptr, SC_Extern);
2428void RewriteModernObjC::SynthMsgSendFunctionDecl() {
2429 IdentifierInfo *msgSendIdent = &Context->Idents.get(
"objc_msgSend");
2431 QualType argT = Context->getObjCIdType();
2432 assert(!argT.
isNull() &&
"Can't find 'id' type");
2433 ArgTys.push_back(argT);
2434 argT = Context->getObjCSelType();
2435 assert(!argT.
isNull() &&
"Can't find 'SEL' type");
2436 ArgTys.push_back(argT);
2437 QualType msgSendType = getSimpleFunctionType(Context->getObjCIdType(),
2439 MsgSendFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
2442 msgSendIdent, msgSendType,
nullptr,
2447void RewriteModernObjC::SynthMsgSendSuperFunctionDecl() {
2448 IdentifierInfo *msgSendIdent = &Context->Idents.get(
"objc_msgSendSuper");
2450 ArgTys.push_back(Context->VoidTy);
2451 QualType msgSendType = getSimpleFunctionType(Context->getObjCIdType(),
2453 MsgSendSuperFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
2456 msgSendIdent, msgSendType,
2457 nullptr, SC_Extern);
2461void RewriteModernObjC::SynthMsgSendStretFunctionDecl() {
2462 IdentifierInfo *msgSendIdent = &Context->Idents.get(
"objc_msgSend_stret");
2464 QualType argT = Context->getObjCIdType();
2465 assert(!argT.
isNull() &&
"Can't find 'id' type");
2466 ArgTys.push_back(argT);
2467 argT = Context->getObjCSelType();
2468 assert(!argT.
isNull() &&
"Can't find 'SEL' type");
2469 ArgTys.push_back(argT);
2470 QualType msgSendType = getSimpleFunctionType(Context->getObjCIdType(),
2472 MsgSendStretFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
2475 msgSendIdent, msgSendType,
2476 nullptr, SC_Extern);
2481void RewriteModernObjC::SynthMsgSendSuperStretFunctionDecl() {
2483 &Context->Idents.get(
"objc_msgSendSuper_stret");
2485 ArgTys.push_back(Context->VoidTy);
2486 QualType msgSendType = getSimpleFunctionType(Context->getObjCIdType(),
2488 MsgSendSuperStretFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
2492 msgSendType,
nullptr,
2497void RewriteModernObjC::SynthMsgSendFpretFunctionDecl() {
2498 IdentifierInfo *msgSendIdent = &Context->Idents.get(
"objc_msgSend_fpret");
2500 QualType argT = Context->getObjCIdType();
2501 assert(!argT.
isNull() &&
"Can't find 'id' type");
2502 ArgTys.push_back(argT);
2503 argT = Context->getObjCSelType();
2504 assert(!argT.
isNull() &&
"Can't find 'SEL' type");
2505 ArgTys.push_back(argT);
2506 QualType msgSendType = getSimpleFunctionType(Context->DoubleTy,
2508 MsgSendFpretFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
2511 msgSendIdent, msgSendType,
2512 nullptr, SC_Extern);
2516void RewriteModernObjC::SynthGetClassFunctionDecl() {
2517 IdentifierInfo *getClassIdent = &Context->Idents.get(
"objc_getClass");
2519 ArgTys.push_back(Context->getPointerType(Context->CharTy.withConst()));
2520 QualType getClassType = getSimpleFunctionType(Context->getObjCClassType(),
2522 GetClassFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
2525 getClassIdent, getClassType,
2526 nullptr, SC_Extern);
2530void RewriteModernObjC::SynthGetSuperClassFunctionDecl() {
2532 &Context->Idents.get(
"class_getSuperclass");
2534 ArgTys.push_back(Context->getObjCClassType());
2535 QualType getClassType = getSimpleFunctionType(Context->getObjCClassType(),
2537 GetSuperClassFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
2541 getClassType,
nullptr,
2546void RewriteModernObjC::SynthGetMetaClassFunctionDecl() {
2547 IdentifierInfo *getClassIdent = &Context->Idents.get(
"objc_getMetaClass");
2549 ArgTys.push_back(Context->getPointerType(Context->CharTy.withConst()));
2550 QualType getClassType = getSimpleFunctionType(Context->getObjCClassType(),
2552 GetMetaClassFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
2555 getClassIdent, getClassType,
2556 nullptr, SC_Extern);
2560 assert (Exp !=
nullptr &&
"Expected non-null ObjCStringLiteral");
2561 QualType strType = getConstantStringStructType();
2563 std::string S =
"__NSConstantStringImpl_";
2565 std::string tmpName = InFileName;
2567 for (i=0; i < tmpName.length(); i++) {
2568 char c = tmpName.at(i);
2575 S += utostr(NumObjCStringLiterals++);
2577 Preamble +=
"static __NSConstantStringImpl " + S;
2578 Preamble +=
" __attribute__ ((section (\"__DATA, __cfstring\"))) = {__CFConstantStringClassReference,";
2581 std::string prettyBufS;
2582 llvm::raw_string_ostream prettyBuf(prettyBufS);
2590 strType,
nullptr, SC_Static);
2593 Expr *Unop = UnaryOperator::Create(
2594 const_cast<ASTContext &
>(*Context), DRE, UO_AddrOf,
2595 Context->getPointerType(DRE->
getType()), VK_PRValue, OK_Ordinary,
2599 CK_CPointerToObjCPointerCast, Unop);
2600 ReplaceStmt(Exp, cast);
2607 static_cast<unsigned>(Context->getTypeSize(Context->IntTy));
2609 Expr *FlagExp = IntegerLiteral::Create(*Context,
2610 llvm::APInt(IntSize, Exp->
getValue()),
2612 CastExpr *
cast = NoTypeInfoCStyleCastExpr(Context, Context->ObjCBuiltinBoolTy,
2613 CK_BitCast, FlagExp);
2616 ReplaceStmt(Exp, PE);
2622 if (!SelGetUidFunctionDecl)
2623 SynthSelGetUidFunctionDecl();
2625 if (!MsgSendFunctionDecl)
2626 SynthMsgSendFunctionDecl();
2627 if (!GetClassFunctionDecl)
2628 SynthGetClassFunctionDecl();
2643 ClsExprs.push_back(getStringLiteral(clsName->
getName()));
2644 CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl, ClsExprs,
2646 MsgExprs.push_back(Cls);
2653 CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl,
2654 SelExprs, StartLoc, EndLoc);
2655 MsgExprs.push_back(SelExp);
2664 CK = CK_IntegralToBoolean;
2665 subExpr = NoTypeInfoCStyleCastExpr(Context, type, CK, subExpr);
2667 MsgExprs.push_back(subExpr);
2670 ArgTypes.push_back(Context->getObjCClassType());
2671 ArgTypes.push_back(Context->getObjCSelType());
2672 for (
const auto PI : BoxingMethod->
parameters())
2673 ArgTypes.push_back(PI->getType());
2681 *Context, MsgSendFlavor,
false, msgSendType, VK_LValue,
SourceLocation());
2684 Context, Context->getPointerType(Context->VoidTy), CK_BitCast, DRE);
2688 getSimpleFunctionType(returnType, ArgTypes, BoxingMethod->
isVariadic());
2689 castType = Context->getPointerType(castType);
2690 cast = NoTypeInfoCStyleCastExpr(Context, castType, CK_BitCast,
2697 CallExpr *CE = CallExpr::Create(*Context, PE, MsgExprs, FT->getReturnType(),
2699 ReplaceStmt(Exp, CE);
2705 if (!SelGetUidFunctionDecl)
2706 SynthSelGetUidFunctionDecl();
2708 if (!MsgSendFunctionDecl)
2709 SynthMsgSendFunctionDecl();
2710 if (!GetClassFunctionDecl)
2711 SynthGetClassFunctionDecl();
2720 getSimpleFunctionType(Context->VoidTy, IntQT,
true);
2721 std::string NSArrayFName(
"__NSContainer_literal");
2722 FunctionDecl *NSArrayFD = SynthBlockInitFunctionDecl(NSArrayFName);
2724 *Context, NSArrayFD,
false, NSArrayFType, VK_PRValue,
SourceLocation());
2728 unsigned UnsignedIntSize =
2729 static_cast<unsigned>(Context->getTypeSize(Context->UnsignedIntTy));
2730 Expr *count = IntegerLiteral::Create(*Context,
2731 llvm::APInt(UnsignedIntSize, NumElements),
2733 InitExprs.push_back(count);
2734 for (
unsigned i = 0; i < NumElements; i++)
2736 Expr *NSArrayCallExpr =
2737 CallExpr::Create(*Context, NSArrayDRE, InitExprs, NSArrayFType, VK_LValue,
2742 &Context->Idents.get(
"arr"),
2743 Context->getPointerType(Context->VoidPtrTy),
2747 MemberExpr::CreateImplicit(*Context, NSArrayCallExpr,
false, ARRFD,
2748 ARRFD->
getType(), VK_LValue, OK_Ordinary);
2749 QualType ConstIdT = Context->getObjCIdType().withConst();
2751 NoTypeInfoCStyleCastExpr(Context,
2752 Context->getPointerType(ConstIdT),
2766 ClsExprs.push_back(getStringLiteral(clsName->
getName()));
2767 CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl, ClsExprs,
2769 MsgExprs.push_back(Cls);
2777 CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl,
2778 SelExprs, StartLoc, EndLoc);
2779 MsgExprs.push_back(SelExp);
2782 MsgExprs.push_back(ArrayLiteralObjects);
2785 Expr *cnt = IntegerLiteral::Create(*Context,
2786 llvm::APInt(UnsignedIntSize, NumElements),
2788 MsgExprs.push_back(cnt);
2791 ArgTypes.push_back(Context->getObjCClassType());
2792 ArgTypes.push_back(Context->getObjCSelType());
2793 for (
const auto *PI : ArrayMethod->
parameters())
2794 ArgTypes.push_back(PI->getType());
2802 *Context, MsgSendFlavor,
false, msgSendType, VK_LValue,
SourceLocation());
2805 Context, Context->getPointerType(Context->VoidTy), CK_BitCast, DRE);
2809 getSimpleFunctionType(returnType, ArgTypes, ArrayMethod->
isVariadic());
2810 castType = Context->getPointerType(castType);
2811 cast = NoTypeInfoCStyleCastExpr(Context, castType, CK_BitCast,
2820 ReplaceStmt(Exp, CE);
2826 if (!SelGetUidFunctionDecl)
2827 SynthSelGetUidFunctionDecl();
2829 if (!MsgSendFunctionDecl)
2830 SynthMsgSendFunctionDecl();
2831 if (!GetClassFunctionDecl)
2832 SynthGetClassFunctionDecl();
2841 getSimpleFunctionType(Context->VoidTy, IntQT,
true);
2842 std::string NSDictFName(
"__NSContainer_literal");
2843 FunctionDecl *NSDictFD = SynthBlockInitFunctionDecl(NSDictFName);
2845 *Context, NSDictFD,
false, NSDictFType, VK_PRValue,
SourceLocation());
2851 unsigned UnsignedIntSize =
2852 static_cast<unsigned>(Context->getTypeSize(Context->UnsignedIntTy));
2853 Expr *count = IntegerLiteral::Create(*Context,
2854 llvm::APInt(UnsignedIntSize, NumElements),
2856 KeyExprs.push_back(count);
2857 ValueExprs.push_back(count);
2858 for (
unsigned i = 0; i < NumElements; i++) {
2860 KeyExprs.push_back(Element.
Key);
2861 ValueExprs.push_back(Element.
Value);
2865 Expr *NSValueCallExpr =
2866 CallExpr::Create(*Context, NSDictDRE, ValueExprs, NSDictFType, VK_LValue,
2871 &Context->Idents.get(
"arr"),
2872 Context->getPointerType(Context->VoidPtrTy),
2876 MemberExpr::CreateImplicit(*Context, NSValueCallExpr,
false, ARRFD,
2877 ARRFD->
getType(), VK_LValue, OK_Ordinary);
2878 QualType ConstIdT = Context->getObjCIdType().withConst();
2880 NoTypeInfoCStyleCastExpr(Context,
2881 Context->getPointerType(ConstIdT),
2883 DictLiteralValueME);
2885 Expr *NSKeyCallExpr =
2886 CallExpr::Create(*Context, NSDictDRE, KeyExprs, NSDictFType, VK_LValue,
2890 MemberExpr::CreateImplicit(*Context, NSKeyCallExpr,
false, ARRFD,
2891 ARRFD->
getType(), VK_LValue, OK_Ordinary);
2894 NoTypeInfoCStyleCastExpr(Context,
2895 Context->getPointerType(ConstIdT),
2909 ClsExprs.push_back(getStringLiteral(clsName->
getName()));
2910 CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl, ClsExprs,
2912 MsgExprs.push_back(Cls);
2919 CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl,
2920 SelExprs, StartLoc, EndLoc);
2921 MsgExprs.push_back(SelExp);
2924 MsgExprs.push_back(DictValueObjects);
2927 MsgExprs.push_back(DictKeyObjects);
2930 Expr *cnt = IntegerLiteral::Create(*Context,
2931 llvm::APInt(UnsignedIntSize, NumElements),
2933 MsgExprs.push_back(cnt);
2936 ArgTypes.push_back(Context->getObjCClassType());
2937 ArgTypes.push_back(Context->getObjCSelType());
2938 for (
const auto *PI : DictMethod->
parameters()) {
2942 convertToUnqualifiedObjCType(PointeeTy);
2943 T = Context->getPointerType(PointeeTy);
2945 ArgTypes.push_back(T);
2954 *Context, MsgSendFlavor,
false, msgSendType, VK_LValue,
SourceLocation());
2957 Context, Context->getPointerType(Context->VoidTy), CK_BitCast, DRE);
2961 getSimpleFunctionType(returnType, ArgTypes, DictMethod->
isVariadic());
2962 castType = Context->getPointerType(castType);
2963 cast = NoTypeInfoCStyleCastExpr(Context, castType, CK_BitCast,
2972 ReplaceStmt(Exp, CE);
2979QualType RewriteModernObjC::getSuperStructType() {
2980 if (!SuperStructDecl) {
2981 SuperStructDecl = RecordDecl::Create(*Context, TTK_Struct, TUDecl,
2983 &Context->Idents.get(
"__rw_objc_super"));
2987 FieldTypes[0] = Context->getObjCIdType();
2989 FieldTypes[1] = Context->getObjCIdType();
2992 for (
unsigned i = 0; i < 2; ++i) {
2993 SuperStructDecl->
addDecl(FieldDecl::Create(*Context, SuperStructDecl,
2996 FieldTypes[i],
nullptr,
3004 return Context->getTagDeclType(SuperStructDecl);
3007QualType RewriteModernObjC::getConstantStringStructType() {
3008 if (!ConstantStringDecl) {
3009 ConstantStringDecl = RecordDecl::Create(*Context, TTK_Struct, TUDecl,
3011 &Context->Idents.get(
"__NSConstantStringImpl"));
3015 FieldTypes[0] = Context->getObjCIdType();
3017 FieldTypes[1] = Context->IntTy;
3019 FieldTypes[2] = Context->getPointerType(Context->CharTy);
3021 FieldTypes[3] = Context->LongTy;
3024 for (
unsigned i = 0; i < 4; ++i) {
3025 ConstantStringDecl->
addDecl(FieldDecl::Create(*Context,
3029 FieldTypes[i],
nullptr,
3037 return Context->getTagDeclType(ConstantStringDecl);
3043static SourceLocation getFunctionSourceLocation (RewriteModernObjC &R,
3049 if (!LSD->getRBraceLoc().isValid())
3050 return LSD->getExternLoc();
3053 R.RewriteBlockLiteralFunctionDecl(FD);
3057void RewriteModernObjC::RewriteLineDirective(
const Decl *D) {
3061 if (Location.
isFileID() && GenerateLineInfo) {
3062 std::string LineString(
"\n#line ");
3064 LineString += utostr(PLoc.
getLine());
3065 LineString +=
" \"";
3066 LineString += Lexer::Stringify(PLoc.
getFilename());
3067 if (isa<ObjCMethodDecl>(D))
3069 else LineString +=
"\"\n";
3072 if (
const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
3077 if (!LSD->getRBraceLoc().isValid())
3078 Location = LSD->getExternLoc();
3081 InsertText(Location, LineString);
3095Expr *RewriteModernObjC::SynthMsgSendStretCallExpr(
FunctionDecl *MsgSendStretFlavor,
3101 QualType FuncType = getSimpleFunctionType(
3102 returnType, ArgTypes, Method ? Method->
isVariadic() :
false);
3103 QualType castType = Context->getPointerType(FuncType);
3106 static unsigned stretCount=0;
3107 std::string
name =
"__Stret";
name += utostr(stretCount);
3109 "extern \"C\" void * __cdecl memset(void *_Dst, int _Val, size_t _Size);\n";
3110 str +=
"namespace {\n";
3111 str +=
"struct "; str +=
name;
3114 str +=
"(id receiver, SEL sel";
3115 for (
unsigned i = 2; i < ArgTypes.size(); i++) {
3116 std::string ArgName =
"arg"; ArgName += utostr(i);
3117 ArgTypes[i].getAsStringInternal(ArgName, Context->getPrintingPolicy());
3118 str +=
", "; str += ArgName;
3121 for (
unsigned i = ArgTypes.size(); i < MsgExprs.size(); i++) {
3122 std::string ArgName =
"arg"; ArgName += utostr(i);
3123 MsgExprs[i]->getType().getAsStringInternal(ArgName,
3124 Context->getPrintingPolicy());
3125 str +=
", "; str += ArgName;
3129 str +=
"\t unsigned size = sizeof(";
3130 str += returnType.
getAsString(Context->getPrintingPolicy()); str +=
");\n";
3132 str +=
"\t if (size == 1 || size == 2 || size == 4 || size == 8)\n";
3134 str +=
"\t s = (("; str += castType.
getAsString(Context->getPrintingPolicy());
3135 str +=
")(void *)objc_msgSend)(receiver, sel";
3136 for (
unsigned i = 2; i < ArgTypes.size(); i++) {
3137 str +=
", arg"; str += utostr(i);
3140 for (
unsigned i = ArgTypes.size(); i < MsgExprs.size(); i++) {
3141 str +=
", arg"; str += utostr(i);
3145 str +=
"\t else if (receiver == 0)\n";
3146 str +=
"\t memset((void*)&s, 0, sizeof(s));\n";
3149 str +=
"\t s = (("; str += castType.
getAsString(Context->getPrintingPolicy());
3150 str +=
")(void *)objc_msgSend_stret)(receiver, sel";
3151 for (
unsigned i = 2; i < ArgTypes.size(); i++) {
3152 str +=
", arg"; str += utostr(i);
3155 for (
unsigned i = ArgTypes.size(); i < MsgExprs.size(); i++) {
3156 str +=
", arg"; str += utostr(i);
3161 str +=
"\t"; str += returnType.
getAsString(Context->getPrintingPolicy());
3163 str +=
"};\n};\n\n";
3166 FunLocStart = getFunctionSourceLocation(*
this, CurFunctionDef);
3168 assert(CurMethodDef &&
"SynthMsgSendStretCallExpr - CurMethodDef is null");
3172 InsertText(FunLocStart, str);
3179 ID, FuncType,
nullptr, SC_Extern,
false,
false);
3183 CallExpr::Create(*Context, DRE, MsgExprs, castType, VK_LValue,
3188 &Context->Idents.get(
"s"),
3189 returnType,
nullptr,
3193 *Context, STCE,
false, FieldD, FieldD->
getType(), VK_LValue, OK_Ordinary);
3201 if (!SelGetUidFunctionDecl)
3202 SynthSelGetUidFunctionDecl();
3203 if (!MsgSendFunctionDecl)
3204 SynthMsgSendFunctionDecl();
3205 if (!MsgSendSuperFunctionDecl)
3206 SynthMsgSendSuperFunctionDecl();
3207 if (!MsgSendStretFunctionDecl)
3208 SynthMsgSendStretFunctionDecl();
3209 if (!MsgSendSuperStretFunctionDecl)
3210 SynthMsgSendSuperStretFunctionDecl();
3211 if (!MsgSendFpretFunctionDecl)
3212 SynthMsgSendFpretFunctionDecl();
3213 if (!GetClassFunctionDecl)
3214 SynthGetClassFunctionDecl();
3215 if (!GetSuperClassFunctionDecl)
3216 SynthGetSuperClassFunctionDecl();
3217 if (!GetMetaClassFunctionDecl)
3218 SynthGetMetaClassFunctionDecl();
3225 QualType resultType = mDecl->getReturnType();
3227 MsgSendStretFlavor = MsgSendStretFunctionDecl;
3229 MsgSendFlavor = MsgSendFpretFunctionDecl;
3235 case ObjCMessageExpr::SuperClass: {
3236 MsgSendFlavor = MsgSendSuperFunctionDecl;
3237 if (MsgSendStretFlavor)
3238 MsgSendStretFlavor = MsgSendSuperStretFunctionDecl;
3239 assert(MsgSendFlavor &&
"MsgSendFlavor is NULL!");
3246 InitExprs.push_back(NoTypeInfoCStyleCastExpr(
3247 Context, Context->getObjCIdType(), CK_BitCast,
3249 Context->getObjCIdType(), VK_PRValue,
3256 CallExpr *Cls = SynthesizeCallToFunctionDecl(GetMetaClassFunctionDecl,
3257 ClsExprs, StartLoc, EndLoc);
3259 ClsExprs.push_back(Cls);
3260 Cls = SynthesizeCallToFunctionDecl(GetSuperClassFunctionDecl, ClsExprs,
3265 InitExprs.push_back(
3266 NoTypeInfoCStyleCastExpr(Context,
3267 Context->getObjCIdType(),
3270 QualType superType = getSuperStructType();
3273 if (LangOpts.MicrosoftExt) {
3274 SynthSuperConstructorFunctionDecl();
3277 DeclRefExpr(*Context, SuperConstructorFunctionDecl,
false, superType,
3280 CallExpr::Create(*Context, DRE, InitExprs, superType, VK_LValue,
3288 SuperRep = UnaryOperator::Create(
3289 const_cast<ASTContext &
>(*Context), SuperRep, UO_AddrOf,
3290 Context->getPointerType(SuperRep->
getType()), VK_PRValue, OK_Ordinary,
3292 SuperRep = NoTypeInfoCStyleCastExpr(Context,
3293 Context->getPointerType(superType),
3294 CK_BitCast, SuperRep);
3301 = Context->getTrivialTypeSourceInfo(superType);
3306 SuperRep = UnaryOperator::Create(
3307 const_cast<ASTContext &
>(*Context), SuperRep, UO_AddrOf,
3308 Context->getPointerType(SuperRep->
getType()), VK_PRValue, OK_Ordinary,
3311 MsgExprs.push_back(SuperRep);
3315 case ObjCMessageExpr::Class: {
3320 ClsExprs.push_back(getStringLiteral(clsName->
getName()));
3321 CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl, ClsExprs,
3323 CastExpr *ArgExpr = NoTypeInfoCStyleCastExpr(Context,
3324 Context->getObjCIdType(),
3326 MsgExprs.push_back(ArgExpr);
3330 case ObjCMessageExpr::SuperInstance:{
3331 MsgSendFlavor = MsgSendSuperFunctionDecl;
3332 if (MsgSendStretFlavor)
3333 MsgSendStretFlavor = MsgSendSuperStretFunctionDecl;
3334 assert(MsgSendFlavor &&
"MsgSendFlavor is NULL!");
3338 InitExprs.push_back(NoTypeInfoCStyleCastExpr(
3339 Context, Context->getObjCIdType(), CK_BitCast,
3341 Context->getObjCIdType(), VK_PRValue,
3348 CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl, ClsExprs,
3351 ClsExprs.push_back(Cls);
3352 Cls = SynthesizeCallToFunctionDecl(GetSuperClassFunctionDecl, ClsExprs,
3357 InitExprs.push_back(
3359 NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(),
3362 QualType superType = getSuperStructType();
3365 if (LangOpts.MicrosoftExt) {
3366 SynthSuperConstructorFunctionDecl();
3369 DeclRefExpr(*Context, SuperConstructorFunctionDecl,
false, superType,
3372 CallExpr::Create(*Context, DRE, InitExprs, superType, VK_LValue,
3380 SuperRep = UnaryOperator::Create(
3381 const_cast<ASTContext &
>(*Context), SuperRep, UO_AddrOf,
3382 Context->getPointerType(SuperRep->
getType()), VK_PRValue, OK_Ordinary,
3384 SuperRep = NoTypeInfoCStyleCastExpr(Context,
3385 Context->getPointerType(superType),
3386 CK_BitCast, SuperRep);
3393 = Context->getTrivialTypeSourceInfo(superType);
3397 MsgExprs.push_back(SuperRep);
3401 case ObjCMessageExpr::Instance: {
3406 recExpr = CE->getSubExpr();
3409 ? CK_BlockPointerToObjCPointerCast
3410 : CK_CPointerToObjCPointerCast;
3412 recExpr = NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(),
3414 MsgExprs.push_back(recExpr);
3422 CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl,
3423 SelExprs, StartLoc, EndLoc);
3424 MsgExprs.push_back(SelExp);
3427 for (
unsigned i = 0; i < Exp->
getNumArgs(); i++) {
3433 if (needToScanForQualifiers(type))
3434 type = Context->getObjCIdType();
3436 (void)convertBlockPointerToFunctionPointer(type);
3440 type->isBooleanType()) {
3441 CK = CK_IntegralToBoolean;
3442 }
else if (
type->isObjCObjectPointerType()) {
3444 CK = CK_BlockPointerToObjCPointerCast;
3446 CK = CK_CPointerToObjCPointerCast;
3454 userExpr = NoTypeInfoCStyleCastExpr(Context, type, CK, userExpr);
3457 else if (
CStyleCastExpr *CE = dyn_cast<CStyleCastExpr>(userExpr)) {
3458 if (CE->getType()->isObjCQualifiedIdType()) {
3459 while ((CE = dyn_cast<CStyleCastExpr>(userExpr)))
3460 userExpr = CE->getSubExpr();
3463 CK = CK_IntegralToPointer;
3465 CK = CK_BlockPointerToObjCPointerCast;
3467 CK = CK_CPointerToObjCPointerCast;
3471 userExpr = NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(),
3475 MsgExprs.push_back(userExpr);
3487 if (MsgSendFlavor == MsgSendSuperFunctionDecl)
3488 ArgTypes.push_back(Context->getPointerType(getSuperStructType()));
3490 ArgTypes.push_back(Context->getObjCIdType());
3491 ArgTypes.push_back(Context->getObjCSelType());
3496 ? Context->getObjCIdType()
3499 (void)convertBlockPointerToFunctionPointer(t);
3500 ArgTypes.push_back(t);
3503 convertToUnqualifiedObjCType(returnType);
3504 (void)convertBlockPointerToFunctionPointer(returnType);
3506 returnType = Context->getObjCIdType();
3513 *Context, MsgSendFlavor,
false, msgSendType, VK_LValue,
SourceLocation());
3519 cast = NoTypeInfoCStyleCastExpr(Context,
3520 Context->getPointerType(Context->VoidTy),
3527 getSimpleFunctionType(returnType, ArgTypes, MD ? MD->
isVariadic() :
true);
3528 castType = Context->getPointerType(castType);
3529 cast = NoTypeInfoCStyleCastExpr(Context, castType, CK_BitCast,
3538 Stmt *ReplacingStmt = CE;
3539 if (MsgSendStretFlavor) {
3545 Expr *STCE = SynthMsgSendStretCallExpr(MsgSendStretFlavor,
3549 ReplacingStmt = STCE;
3552 return ReplacingStmt;
3556 Stmt *ReplacingStmt =
3560 ReplaceStmt(Exp, ReplacingStmt);
3563 return ReplacingStmt;
3567QualType RewriteModernObjC::getProtocolType() {
3568 if (!ProtocolTypeDecl) {
3570 = Context->getTrivialTypeSourceInfo(Context->getObjCIdType());
3571 ProtocolTypeDecl = TypedefDecl::Create(*Context, TUDecl,
3573 &Context->Idents.get(
"Protocol"),
3576 return Context->getTypeDeclType(ProtocolTypeDecl);
3584 std::string Name =
"_OBJC_PROTOCOL_REFERENCE_$_" +
3589 nullptr, SC_Extern);
3593 Context, Context->getPointerType(DRE->
getType()), CK_BitCast, DRE);
3594 ReplaceStmt(Exp, castExpr);
3604 bool &IsNamedDefinition) {
3608 if (
RecordDecl *RD = dyn_cast<RecordDecl>(Tag)) {
3612 IsNamedDefinition =
true;
3614 return Context->getSourceManager().isBeforeInTranslationUnit(
3617 if (
EnumDecl *ED = dyn_cast<EnumDecl>(Tag)) {
3618 if (!ED || !ED->getDeclName().getAsIdentifierInfo())
3620 IsNamedDefinition =
true;
3621 TagLocation = ED->getLocation();
3622 return Context->getSourceManager().isBeforeInTranslationUnit(
3630bool RewriteModernObjC::RewriteObjCFieldDeclType(
QualType &
Type,
3631 std::string &Result) {
3639 return RewriteObjCFieldDeclType(ElemTy, Result);
3645 Result +=
"\n\tstruct ";
3647 Result +=
"\n\tunion ";
3649 assert(
false &&
"class not allowed as an ivar type");
3652 if (GlobalDefinedTags.count(RD)) {
3658 for (
auto *FD : RD->
fields())
3659 RewriteObjCFieldDecl(FD, Result);
3667 Result +=
"\n\tenum ";
3669 if (GlobalDefinedTags.count(ED)) {
3677 Result +=
"\t"; Result += EC->getName(); Result +=
" = ";
3678 Result +=
toString(EC->getInitVal(), 10);
3687 convertObjCTypeToCStyleType(
Type);
3694void RewriteModernObjC::RewriteObjCFieldDecl(
FieldDecl *fieldDecl,
3695 std::string &Result) {
3697 std::string Name =
fieldDecl->getNameAsString();
3699 bool EleboratedType = RewriteObjCFieldDeclType(
Type, Result);
3700 if (!EleboratedType)
3701 Type.getAsStringInternal(Name, Context->getPrintingPolicy());
3704 Result +=
" : "; Result += utostr(
fieldDecl->getBitWidthValue(*Context));
3711 llvm::APInt Dim = CAT->getSize();
3712 Result += utostr(Dim.getZExtValue());
3724void RewriteModernObjC::RewriteLocallyDefinedNamedAggregates(
FieldDecl *fieldDecl,
3725 std::string &Result) {
3730 Type = Context->getBaseElementType(
Type);
3732 auto *IDecl = dyn_cast<ObjCContainerDecl>(
fieldDecl->getDeclContext());
3743 if (GlobalDefinedTags.count(TD))
3746 bool IsNamedDefinition =
false;
3747 if (IsTagDefinedInsideClass(IDecl, TD, IsNamedDefinition)) {
3748 RewriteObjCFieldDeclType(
Type, Result);
3751 if (IsNamedDefinition)
3752 GlobalDefinedTags.insert(TD);
3756unsigned RewriteModernObjC::ObjCIvarBitfieldGroupNo(
ObjCIvarDecl *IV) {
3758 if (ObjCInterefaceHasBitfieldGroups.count(CDecl)) {
3759 return IvarGroupNumber[IV];
3761 unsigned GroupNo = 0;
3765 IVars.push_back(IVD);
3767 for (
unsigned i = 0, e = IVars.size(); i < e; i++)
3768 if (IVars[i]->isBitField()) {
3769 IvarGroupNumber[IVars[i++]] = ++GroupNo;
3770 while (i < e && IVars[i]->isBitField())
3771 IvarGroupNumber[IVars[i++]] = GroupNo;
3776 ObjCInterefaceHasBitfieldGroups.insert(CDecl);
3777 return IvarGroupNumber[IV];
3780QualType RewriteModernObjC::SynthesizeBitfieldGroupStructType(
3783 std::string StructTagName;
3784 ObjCIvarBitfieldGroupType(IV, StructTagName);
3785 RecordDecl *RD = RecordDecl::Create(*Context, TTK_Struct,
3786 Context->getTranslationUnitDecl(),
3788 &Context->Idents.get(StructTagName));
3789 for (
unsigned i=0, e = IVars.size(); i < e; i++) {
3792 &Context->Idents.get(Ivar->
getName()),
3795 false, ICIS_NoInit));
3798 return Context->getTagDeclType(RD);
3803 unsigned GroupNo = ObjCIvarBitfieldGroupNo(IV);
3804 std::pair<const ObjCInterfaceDecl*, unsigned> tuple = std::make_pair(CDecl, GroupNo);
3805 if (GroupRecordType.count(tuple))
3806 return GroupRecordType[tuple];
3811 if (IVD->isBitField())
3814 if (!IVars.empty()) {
3815 unsigned GroupNo = ObjCIvarBitfieldGroupNo(IVars[0]);
3817 GroupRecordType[std::make_pair(CDecl, GroupNo)] =
3818 SynthesizeBitfieldGroupStructType(IVars[0], IVars);
3823 if (!IVars.empty()) {
3825 unsigned GroupNo = ObjCIvarBitfieldGroupNo(IVars[0]);
3826 GroupRecordType[std::make_pair(CDecl, GroupNo)] =
3827 SynthesizeBitfieldGroupStructType(IVars[0], IVars);
3829 QualType RetQT = GroupRecordType[tuple];
3830 assert(!RetQT.
isNull() &&
"GetGroupRecordTypeForObjCIvarBitfield struct type is NULL");
3837void RewriteModernObjC::ObjCIvarBitfieldGroupDecl(
ObjCIvarDecl *IV,
3838 std::string &Result) {
3841 Result +=
"__GRBF_";
3842 unsigned GroupNo = ObjCIvarBitfieldGroupNo(IV);
3843 Result += utostr(GroupNo);
3849void RewriteModernObjC::ObjCIvarBitfieldGroupType(
ObjCIvarDecl *IV,
3850 std::string &Result) {
3854 unsigned GroupNo = ObjCIvarBitfieldGroupNo(IV);
3855 Result += utostr(GroupNo);
3861void RewriteModernObjC::ObjCIvarBitfieldGroupOffset(
ObjCIvarDecl *IV,
3862 std::string &Result) {
3863 Result +=
"OBJC_IVAR_$_";
3864 ObjCIvarBitfieldGroupDecl(IV, Result);
3867#define SKIP_BITFIELDS(IX, ENDIX, VEC) { \
3868 while ((IX < ENDIX) && VEC[IX]->isBitField()) \
3877 std::string &Result) {
3878 assert(CDecl &&
"Class missing in SynthesizeObjCInternalStruct");
3879 assert(CDecl->
getName() !=
"" &&
3880 "Name missing in SynthesizeObjCInternalStruct");
3885 IVars.push_back(IVD);
3890 const char *startBuf =
SM->getCharacterData(LocStart);
3891 const char *endBuf =
SM->getCharacterData(LocEnd);
3896 (!RCDecl || !ObjCSynthesizedStructs.count(RCDecl))) {
3897 endBuf += Lexer::MeasureTokenLength(LocEnd, *
SM, LangOpts);
3898 ReplaceText(LocStart, endBuf-startBuf, Result);
3905 for (
unsigned i = 0, e = IVars.size(); i < e; i++)
3906 RewriteLocallyDefinedNamedAggregates(IVars[i], Result);
3910 for (
unsigned i = 0, e = IVars.size(); i < e; i++)
3911 if (IVars[i]->isBitField()) {
3913 QualType QT = GetGroupRecordTypeForObjCIvarBitfield(IV);
3914 RewriteObjCFieldDeclType(QT, Result);
3917 SKIP_BITFIELDS(i , e, IVars);
3920 Result +=
"\nstruct ";
3922 Result +=
"_IMPL {\n";
3924 if (RCDecl && ObjCSynthesizedStructs.count(RCDecl)) {
3927 Result +=
"_IVARS;\n";
3930 for (
unsigned i = 0, e = IVars.size(); i < e; i++) {
3931 if (IVars[i]->isBitField()) {
3933 Result +=
"\tstruct ";
3934 ObjCIvarBitfieldGroupType(IV, Result); Result +=
" ";
3935 ObjCIvarBitfieldGroupDecl(IV, Result); Result +=
";\n";
3937 SKIP_BITFIELDS(i , e, IVars);
3940 RewriteObjCFieldDecl(IVars[i], Result);
3944 endBuf += Lexer::MeasureTokenLength(LocEnd, *
SM, LangOpts);
3945 ReplaceText(LocStart, endBuf-startBuf, Result);
3947 if (!ObjCSynthesizedStructs.insert(CDecl).second)
3948 llvm_unreachable(
"struct already synthesize- RewriteObjCInternalStruct");
3954 std::string &Result) {
3965 unsigned GroupNo = 0;
3967 GroupNo = ObjCIvarBitfieldGroupNo(IvarDecl);
3968 if (GroupSymbolOutput.count(std::make_pair(IDecl, GroupNo)))
3972 if (LangOpts.MicrosoftExt)
3973 Result +=
"__declspec(allocate(\".objc_ivar$B\")) ";
3974 Result +=
"extern \"C\" ";
3975 if (LangOpts.MicrosoftExt &&
3978 Result +=
"__declspec(dllimport) ";
3980 Result +=
"unsigned long ";
3982 ObjCIvarBitfieldGroupOffset(IvarDecl, Result);
3983 GroupSymbolOutput.insert(std::make_pair(IDecl, GroupNo));
3986 WriteInternalIvarName(CDecl, IvarDecl, Result);
3998void RewriteModernObjC::RewriteImplementations() {
3999 int ClsDefCount = ClassImplementation.size();
4000 int CatDefCount = CategoryImplementation.size();
4003 for (
int i = 0; i < ClsDefCount; i++) {
4008 "Legacy implicit interface rewriting not supported in moder abi");
4009 RewriteImplementationDecl(OIMP);
4012 for (
int i = 0; i < CatDefCount; i++) {
4017 "Legacy implicit interface rewriting not supported in moder abi");
4018 RewriteImplementationDecl(CIMP);
4022void RewriteModernObjC::RewriteByRefString(std::string &ResultStr,
4023 const std::string &Name,
4025 assert(BlockByRefDeclNo.count(VD) &&
4026 "RewriteByRefString: ByRef decl missing");
4028 ResultStr +=
"struct ";
4029 ResultStr +=
"__Block_byref_" + Name +
4030 "_" + utostr(BlockByRefDeclNo[VD]) ;
4033static bool HasLocalVariableExternalStorage(
ValueDecl *VD) {
4034 if (
VarDecl *Var = dyn_cast<VarDecl>(VD))
4035 return (Var->isFunctionOrMethodVarDecl() && !Var->hasLocalStorage());
4039std::string RewriteModernObjC::SynthesizeBlockFunc(
BlockExpr *CE,
int i,
4044 std::string StructRef =
"struct " + Tag;
4047 ConvertSourceLocationToLineDirective(BlockLoc, S);
4049 S +=
"static " + RT.
getAsString(Context->getPrintingPolicy()) +
" __" +
4050 funcName.str() +
"_block_func_" + utostr(i);
4054 if (isa<FunctionNoProtoType>(AFT)) {
4057 S +=
"(" + StructRef +
" *__cself)";
4059 S +=
"(" + StructRef +
" *__cself)";
4062 assert(FT &&
"SynthesizeBlockFunc: No function proto");
4065 S += StructRef +
" *__cself, ";
4066 std::string ParamStr;
4070 ParamStr = (*AI)->getNameAsString();
4072 (void)convertBlockPointerToFunctionPointer(QT);
4087 E = BlockByRefDecls.end(); I != E; ++I) {
4089 std::string Name = (*I)->getNameAsString();
4090 std::string TypeString;
4091 RewriteByRefString(TypeString, Name, (*I));
4093 Name = TypeString + Name;
4094 S += Name +
" = __cself->" + (*I)->getNameAsString() +
"; // bound by ref\n";
4098 E = BlockByCopyDecls.end(); I != E; ++I) {
4110 if (isTopLevelBlockPointerType((*I)->getType())) {
4111 RewriteBlockPointerTypeVariable(S, (*I));
4113 RewriteBlockPointerType(S, (*I)->getType());
4115 S +=
"__cself->" + (*I)->getNameAsString() +
"; // bound by copy\n";
4118 std::string Name = (*I)->getNameAsString();
4120 if (HasLocalVariableExternalStorage(*I))
4121 QT = Context->getPointerType(QT);
4123 S += Name +
" = __cself->" +
4124 (*I)->getNameAsString() +
"; // bound by copy\n";
4127 std::string RewrittenStr = RewrittenBlockExprs[CE];
4128 const char *cstr = RewrittenStr.c_str();
4129 while (*cstr++ !=
'{') ;
4135std::string RewriteModernObjC::SynthesizeBlockHelperFuncs(
BlockExpr *CE,
int i,
4138 std::string StructRef =
"struct " + Tag;
4139 std::string S =
"static void __";
4142 S +=
"_block_copy_" + utostr(i);
4143 S +=
"(" + StructRef;
4144 S +=
"*dst, " + StructRef;
4146 for (
ValueDecl *VD : ImportedBlockDecls) {
4147 S +=
"_Block_object_assign((void*)&dst->";
4149 S +=
", (void*)src->";
4151 if (BlockByRefDeclsPtrSet.count(VD))
4152 S +=
", " + utostr(BLOCK_FIELD_IS_BYREF) +
"/*BLOCK_FIELD_IS_BYREF*/);";
4154 S +=
", " + utostr(BLOCK_FIELD_IS_BLOCK) +
"/*BLOCK_FIELD_IS_BLOCK*/);";
4156 S +=
", " + utostr(BLOCK_FIELD_IS_OBJECT) +
"/*BLOCK_FIELD_IS_OBJECT*/);";
4160 S +=
"\nstatic void __";
4162 S +=
"_block_dispose_" + utostr(i);
4163 S +=
"(" + StructRef;
4165 for (
ValueDecl *VD : ImportedBlockDecls) {
4166 S +=
"_Block_object_dispose((void*)src->";
4168 if (BlockByRefDeclsPtrSet.count(VD))
4169 S +=
", " + utostr(BLOCK_FIELD_IS_BYREF) +
"/*BLOCK_FIELD_IS_BYREF*/);";
4171 S +=
", " + utostr(BLOCK_FIELD_IS_BLOCK) +
"/*BLOCK_FIELD_IS_BLOCK*/);";
4173 S +=
", " + utostr(BLOCK_FIELD_IS_OBJECT) +
"/*BLOCK_FIELD_IS_OBJECT*/);";
4179std::string RewriteModernObjC::SynthesizeBlockImpl(
BlockExpr *CE, std::string Tag,
4181 std::string S =
"\nstruct " + Tag;
4184 S +=
" {\n struct __block_impl impl;\n";
4185 S +=
" struct " + Desc;
4192 if (BlockDeclRefs.size()) {
4195 E = BlockByCopyDecls.end(); I != E; ++I) {
4197 std::string FieldName = (*I)->getNameAsString();
4198 std::string ArgName =
"_" + FieldName;
4209 if (isTopLevelBlockPointerType((*I)->getType())) {
4210 S +=
"struct __block_impl *";
4214 if (HasLocalVariableExternalStorage(*I))
4215 QT = Context->getPointerType(QT);
4220 S += FieldName +
";\n";
4224 E = BlockByRefDecls.end(); I != E; ++I) {
4226 std::string FieldName = (*I)->getNameAsString();
4227 std::string ArgName =
"_" + FieldName;
4229 std::string TypeString;
4230 RewriteByRefString(TypeString, FieldName, (*I));
4232 FieldName = TypeString + FieldName;
4233 ArgName = TypeString + ArgName;
4236 S += FieldName +
"; // by ref\n";
4241 bool firsTime =
true;
4243 E = BlockByCopyDecls.end(); I != E; ++I) {
4244 std::string Name = (*I)->getNameAsString();
4251 if (isTopLevelBlockPointerType((*I)->getType()))
4252 Constructor += Name +
"((struct __block_impl *)_" + Name +
")";
4258 E = BlockByRefDecls.end(); I != E; ++I) {
4259 std::string Name = (*I)->getNameAsString();
4266 Constructor += Name +
"(_" + Name +
"->__forwarding)";
4271 Constructor +=
" impl.isa = &_NSConcreteGlobalBlock;\n";
4273 Constructor +=
" impl.isa = &_NSConcreteStackBlock;\n";
4274 Constructor +=
" impl.Flags = flags;\n impl.FuncPtr = fp;\n";
4281 Constructor +=
" impl.isa = &_NSConcreteGlobalBlock;\n";
4283 Constructor +=
" impl.isa = &_NSConcreteStackBlock;\n";
4284 Constructor +=
" impl.Flags = flags;\n impl.FuncPtr = fp;\n";
4294std::string RewriteModernObjC::SynthesizeBlockDescriptor(std::string DescTag,
4295 std::string ImplTag,
int i,
4298 std::string S =
"\nstatic struct " + DescTag;
4300 S +=
" {\n size_t reserved;\n";
4301 S +=
" size_t Block_size;\n";
4303 S +=
" void (*copy)(struct ";
4304 S += ImplTag; S +=
"*, struct ";
4305 S += ImplTag; S +=
"*);\n";
4307 S +=
" void (*dispose)(struct ";
4308 S += ImplTag; S +=
"*);\n";
4312 S += DescTag +
"_DATA = { 0, sizeof(struct ";
4315 S +=
", __" + FunName.str() +
"_block_copy_" + utostr(i);
4316 S +=
", __" + FunName.str() +
"_block_dispose_" + utostr(i);
4322void RewriteModernObjC::SynthesizeBlockLiterals(
SourceLocation FunLocStart,
4323 StringRef FunName) {
4324 bool RewriteSC = (GlobalVarDecl &&
4329 std::string SC(
" void __");
4332 InsertText(FunLocStart, SC);
4336 for (
unsigned i = 0, count=0; i < Blocks.size(); i++) {
4337 CollectBlockDeclRefInfo(Blocks[i]);
4340 for (
int j = 0; j < InnerDeclRefsCount[i]; j++) {
4343 BlockDeclRefs.push_back(Exp);
4344 if (!VD->
hasAttr<BlocksAttr>()) {
4345 if (!BlockByCopyDeclsPtrSet.count(VD)) {
4346 BlockByCopyDeclsPtrSet.insert(VD);
4347 BlockByCopyDecls.push_back(VD);
4352 if (!BlockByRefDeclsPtrSet.count(VD)) {
4353 BlockByRefDeclsPtrSet.insert(VD);
4354 BlockByRefDecls.push_back(VD);
4361 ImportedBlockDecls.insert(VD);
4364 std::string ImplTag =
"__" + FunName.str() +
"_block_impl_" + utostr(i);
4365 std::string DescTag =
"__" + FunName.str() +
"_block_desc_" + utostr(i);
4367 std::string CI = SynthesizeBlockImpl(Blocks[i], ImplTag, DescTag);
4369 InsertText(FunLocStart, CI);
4371 std::string
CF = SynthesizeBlockFunc(Blocks[i], i, FunName, ImplTag);
4373 InsertText(FunLocStart, CF);
4375 if (ImportedBlockDecls.size()) {
4376 std::string HF = SynthesizeBlockHelperFuncs(Blocks[i], i, FunName, ImplTag);
4377 InsertText(FunLocStart, HF);
4379 std::string BD = SynthesizeBlockDescriptor(DescTag, ImplTag, i, FunName,
4380 ImportedBlockDecls.size() > 0);
4381 InsertText(FunLocStart, BD);
4383 BlockDeclRefs.clear();
4384 BlockByRefDecls.clear();
4385 BlockByRefDeclsPtrSet.clear();
4386 BlockByCopyDecls.clear();
4387 BlockByCopyDeclsPtrSet.clear();
4388 ImportedBlockDecls.clear();
4402 InsertText(FunLocStart, SC);
4404 if (GlobalConstructionExp) {
4408 std::string Tag =
"__";
4410 Tag +=
"_block_impl_";
4411 Tag += utostr(Blocks.size()-1);
4412 std::string globalBuf =
"static ";
4413 globalBuf += Tag; globalBuf +=
" ";
4416 llvm::raw_string_ostream constructorExprBuf(SStr);
4417 GlobalConstructionExp->
printPretty(constructorExprBuf,
nullptr,
4419 globalBuf += constructorExprBuf.str();
4421 InsertText(FunLocStart, globalBuf);
4422 GlobalConstructionExp =
nullptr;
4426 InnerDeclRefsCount.clear();
4427 InnerDeclRefs.clear();
4428 RewrittenBlockExprs.clear();
4431void RewriteModernObjC::InsertBlockLiteralsWithinFunction(
FunctionDecl *FD) {
4433 (!Blocks.empty()) ? getFunctionSourceLocation(*
this, FD)
4435 StringRef FuncName = FD->
getName();
4437 SynthesizeBlockLiterals(FunLocStart, FuncName);
4440static void BuildUniqueMethodName(std::string &Name,
4443 Name = std::string(IFace->
getName());
4446 std::string::size_type loc = 0;
4447 while ((loc = Name.find(
':', loc)) != std::string::npos)
4448 Name.replace(loc, 1,
"_");
4451void RewriteModernObjC::InsertBlockLiteralsWithinMethod(
ObjCMethodDecl *MD) {
4455 std::string FuncName;
4456 BuildUniqueMethodName(FuncName, MD);
4457 SynthesizeBlockLiterals(FunLocStart, FuncName);
4460void RewriteModernObjC::GetBlockDeclRefExprs(
Stmt *S) {
4461 for (
Stmt *SubStmt : S->children())
4463 if (
BlockExpr *CBE = dyn_cast<BlockExpr>(SubStmt))
4464 GetBlockDeclRefExprs(CBE->getBody());
4466 GetBlockDeclRefExprs(SubStmt);
4471 HasLocalVariableExternalStorage(DRE->
getDecl()))
4473 BlockDeclRefs.push_back(DRE);
4476void RewriteModernObjC::GetInnerBlockDeclRefExprs(
Stmt *S,
4478 llvm::SmallPtrSetImpl<const DeclContext *> &InnerContexts) {
4479 for (
Stmt *SubStmt : S->children())
4481 if (
BlockExpr *CBE = dyn_cast<BlockExpr>(SubStmt)) {
4482 InnerContexts.insert(cast<DeclContext>(CBE->getBlockDecl()));
4483 GetInnerBlockDeclRefExprs(CBE->getBody(),
4488 GetInnerBlockDeclRefExprs(SubStmt, InnerBlockDeclRefs, InnerContexts);
4491 if (
DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(S)) {
4493 HasLocalVariableExternalStorage(DRE->
getDecl())) {
4495 InnerBlockDeclRefs.push_back(DRE);
4497 if (Var->isFunctionOrMethodVarDecl())
4498 ImportedLocalExternalDecls.insert(Var);
4506bool RewriteModernObjC::convertObjCTypeToCStyleType(
QualType &T) {
4508 convertBlockPointerToFunctionPointer(T);
4514 T = convertFunctionTypeOfBlocks(FT);
4515 T = Context->getPointerType(T);
4520 convertToUnqualifiedObjCType(T);
4534 bool modified = convertObjCTypeToCStyleType(Res);
4540 if (convertObjCTypeToCStyleType(t))
4542 ArgTypes.push_back(t);
4547 FuncType = getSimpleFunctionType(Res, ArgTypes);
4552Stmt *RewriteModernObjC::SynthesizeBlockCall(
CallExpr *Exp,
const Expr *BlockExp) {
4556 if (
const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(BlockExp)) {
4558 }
else if (
const MemberExpr *MExpr = dyn_cast<MemberExpr>(BlockExp)) {
4561 else if (
const ParenExpr *PRE = dyn_cast<ParenExpr>(BlockExp)) {
4562 return SynthesizeBlockCall(Exp, PRE->getSubExpr());
4564 else if (
const ImplicitCastExpr *IEXPR = dyn_cast<ImplicitCastExpr>(BlockExp))
4567 dyn_cast<ConditionalOperator>(BlockExp)) {
4568 Expr *LHSExp = CEXPR->getLHS();
4569 Stmt *LHSStmt = SynthesizeBlockCall(Exp, LHSExp);
4570 Expr *RHSExp = CEXPR->getRHS();
4571 Stmt *RHSStmt = SynthesizeBlockCall(Exp, RHSExp);
4572 Expr *CONDExp = CEXPR->getCond();
4577 }
else if (
const ObjCIvarRefExpr *IRE = dyn_cast<ObjCIvarRefExpr>(BlockExp)) {
4580 = dyn_cast<PseudoObjectExpr>(BlockExp)) {
4583 assert(
false &&
"RewriteBlockClass: Bad type");
4585 assert(CPT &&
"RewriteBlockClass: Bad type");
4587 assert(FT &&
"RewriteBlockClass: Bad type");
4591 RecordDecl *RD = RecordDecl::Create(*Context, TTK_Struct, TUDecl,
4593 &Context->Idents.get(
"__block_impl"));
4594 QualType PtrBlock = Context->getPointerType(Context->getTagDeclType(RD));
4600 ArgTypes.push_back(PtrBlock);
4605 if (!convertBlockPointerToFunctionPointer(t))
4606 convertToUnqualifiedObjCType(t);
4607 ArgTypes.push_back(t);
4611 QualType PtrToFuncCastType = getSimpleFunctionType(Exp->
getType(), ArgTypes);
4613 PtrToFuncCastType = Context->getPointerType(PtrToFuncCastType);
4615 CastExpr *BlkCast = NoTypeInfoCStyleCastExpr(Context, PtrBlock,
4617 const_cast<Expr*
>(BlockExp));
4625 &Context->Idents.get(
"FuncPtr"),
4626 Context->VoidPtrTy,
nullptr,
4630 *Context, PE,
true, FD, FD->
getType(), VK_LValue, OK_Ordinary);
4632 CastExpr *FunkCast = NoTypeInfoCStyleCastExpr(Context, PtrToFuncCastType,
4638 BlkExprs.push_back(BlkCast);
4641 E = Exp->
arg_end(); I != E; ++I) {
4642 BlkExprs.push_back(*I);
4645 CallExpr::Create(*Context, PE, BlkExprs, Exp->
getType(), VK_PRValue,
4663Stmt *RewriteModernObjC::RewriteBlockDeclRefExpr(
DeclRefExpr *DeclRefExp) {
4668 HasLocalVariableExternalStorage(DeclRefExp->
getDecl());
4672 &Context->Idents.get(
"__forwarding"),
4673 Context->VoidPtrTy,
nullptr,
4677 *Context, DeclRefExp, isArrow, FD, FD->
getType(), VK_LValue, OK_Ordinary);
4679 StringRef Name = VD->
getName();
4681 &Context->Idents.get(Name),
4682 Context->VoidPtrTy,
nullptr,
4685 ME = MemberExpr::CreateImplicit(*Context, ME,
true, FD, DeclRefExp->
getType(),
4686 VK_LValue, OK_Ordinary);
4692 ReplaceStmt(DeclRefExp, PE);
4699Stmt *RewriteModernObjC::RewriteLocalVariableExternalStorage(
DeclRefExpr *DRE) {
4701 if (
VarDecl *Var = dyn_cast<VarDecl>(VD))
4702 if (!ImportedLocalExternalDecls.count(Var))
4704 Expr *Exp = UnaryOperator::Create(
4710 ReplaceStmt(DRE, PE);
4722 if (!Rewriter::isRewritable(LocStart) || !Rewriter::isRewritable(LocEnd))
4725 const char *startBuf =
SM->getCharacterData(LocStart);
4726 const char *endBuf =
SM->getCharacterData(LocEnd);
4729 if (isa<TypeOfExprType>(TypePtr)) {
4730 const TypeOfExprType *TypeOfExprTypePtr = cast<TypeOfExprType>(TypePtr);
4732 std::string TypeAsString =
"(";
4733 RewriteBlockPointerType(TypeAsString, QT);
4734 TypeAsString +=
")";
4735 ReplaceText(LocStart, endBuf-startBuf+1, TypeAsString);
4739 const char *argPtr = startBuf;
4741 while (*argPtr++ && (argPtr < endBuf)) {
4746 ReplaceText(LocStart, 1,
"*");
4752void RewriteModernObjC::RewriteImplicitCastObjCExpr(
CastExpr *IC) {
4754 if (
CastKind != CK_BlockPointerToObjCPointerCast &&
4755 CastKind != CK_AnyPointerToBlockPointerCast)
4759 (void)convertBlockPointerToFunctionPointer(QT);
4760 std::string TypeString(QT.
getAsString(Context->getPrintingPolicy()));
4761 std::string Str =
"(";
4767void RewriteModernObjC::RewriteBlockPointerFunctionArgs(
FunctionDecl *FD) {
4769 unsigned parenCount = 0;
4772 const char *startBuf =
SM->getCharacterData(DeclLoc);
4773 const char *startArgList = strchr(startBuf,
'(');
4775 assert((*startArgList ==
'(') &&
"Rewriter fuzzy parser confused");
4780 assert((DeclLoc.
isValid()) &&
"Invalid DeclLoc");
4782 const char *argPtr = startArgList;
4784 while (*argPtr++ && parenCount) {
4789 ReplaceText(DeclLoc, 1,
"*");
4801bool RewriteModernObjC::PointerTypeTakesAnyBlockArguments(
QualType QT) {
4808 assert(BPT &&
"BlockPointerTypeTakeAnyBlockArguments(): not a block pointer type");
4813 if (isTopLevelBlockPointerType(I))
4819bool RewriteModernObjC::PointerTypeTakesAnyObjCQualifiedType(
QualType QT) {
4826 assert(BPT &&
"BlockPointerTypeTakeAnyBlockArguments(): not a block pointer type");
4831 if (I->isObjCQualifiedIdType())
4833 if (I->isObjCObjectPointerType() &&
4834 I->getPointeeType()->isObjCQualifiedInterfaceType())
4842void RewriteModernObjC::GetExtentOfArgList(
const char *Name,
const char *&LParen,
4843 const char *&RParen) {
4844 const char *argPtr = strchr(Name,
'(');
4845 assert((*argPtr ==
'(') &&
"Rewriter fuzzy parser confused");
4849 unsigned parenCount = 1;
4851 while (*argPtr && parenCount) {
4853 case '(': parenCount++;
break;
4854 case ')': parenCount--;
break;
4857 if (parenCount) argPtr++;
4859 assert((*argPtr ==
')') &&
"Rewriter fuzzy parser confused");
4863void RewriteModernObjC::RewriteBlockPointerDecl(
NamedDecl *ND) {
4865 RewriteBlockPointerFunctionArgs(FD);
4871 if (
VarDecl *VD = dyn_cast<VarDecl>(ND))
4874 DeclT = TDD->getUnderlyingType();
4875 else if (
FieldDecl *FD = dyn_cast<FieldDecl>(ND))
4878 llvm_unreachable(
"RewriteBlockPointerDecl(): Decl type not yet handled");
4880 const char *startBuf =
SM->getCharacterData(DeclLoc);
4881 const char *endBuf = startBuf;
4883 while (*startBuf !=
'^' && *startBuf !=
';' && startBuf != MainFileStart)
4887 unsigned OrigLength=0;
4890 if (*startBuf ==
'^') {
4896 while (*startBuf !=
')') {
4904 if (PointerTypeTakesAnyBlockArguments(DeclT) ||
4905 PointerTypeTakesAnyObjCQualifiedType(DeclT)) {
4909 startBuf =
SM->getCharacterData(DeclLoc);
4910 const char *argListBegin, *argListEnd;
4911 GetExtentOfArgList(startBuf, argListBegin, argListEnd);
4912 while (argListBegin < argListEnd) {
4913 if (*argListBegin ==
'^')
4915 else if (*argListBegin ==
'<') {
4917 buf += *argListBegin++;
4919 while (*argListBegin !=
'>') {
4920 buf += *argListBegin++;
4923 buf += *argListBegin;
4927 buf += *argListBegin;
4934 ReplaceText(Start, OrigLength, buf);
4957std::string RewriteModernObjC::SynthesizeByrefCopyDestroyHelper(
VarDecl *VD,
4960 if (CopyDestroyCache.count(flag))
4962 CopyDestroyCache.insert(flag);
4963 S =
"static void __Block_byref_id_object_copy_";
4965 S +=
"(void *dst, void *src) {\n";
4970 static_cast<unsigned>(Context->getTypeSize(Context->IntTy));
4971 unsigned VoidPtrSize =
4972 static_cast<unsigned>(Context->getTypeSize(Context->VoidPtrTy));
4974 unsigned offset = (VoidPtrSize*4 + IntSize + IntSize)/Context->getCharWidth();
4975 S +=
" _Block_object_assign((char*)dst + ";
4976 S += utostr(offset);
4977 S +=
", *(void * *) ((char*)src + ";
4978 S += utostr(offset);
4983 S +=
"static void __Block_byref_id_object_dispose_";
4985 S +=
"(void *src) {\n";
4986 S +=
" _Block_object_dispose(*(void * *) ((char*)src + ";
4987 S += utostr(offset);
5012void RewriteModernObjC::RewriteByRefVar(
VarDecl *ND,
bool firstDecl,
5021 const char *startBuf =
SM->getCharacterData(DeclLoc);
5023 X =
SM->getExpansionLoc(
X);
5024 const char *endBuf =
SM->getCharacterData(
X);
5026 std::string ByrefType;
5027 RewriteByRefString(ByrefType, Name, ND,
true);
5028 ByrefType +=
" {\n";
5029 ByrefType +=
" void *__isa;\n";
5030 RewriteByRefString(ByrefType, Name, ND);
5031 ByrefType +=
" *__forwarding;\n";
5032 ByrefType +=
" int __flags;\n";
5033 ByrefType +=
" int __size;\n";
5037 bool HasCopyAndDispose = Context->BlockRequiresCopying(Ty, ND);
5038 if (HasCopyAndDispose) {
5039 ByrefType +=
" void (*__Block_byref_id_object_copy)(void*, void*);\n";
5040 ByrefType +=
" void (*__Block_byref_id_object_dispose)(void*);\n";
5044 (void)convertBlockPointerToFunctionPointer(T);
5047 ByrefType +=
" " + Name +
";\n";
5048 ByrefType +=
"};\n";
5052 FunLocStart = getFunctionSourceLocation(*
this, CurFunctionDef);
5054 assert(CurMethodDef &&
"RewriteByRefVar - CurMethodDef is null");
5057 InsertText(FunLocStart, ByrefType);
5063 if (HasCopyAndDispose) {
5071 std::string HF = SynthesizeByrefCopyDestroyHelper(ND, flag);
5079 bool hasInit = (ND->
getInit() !=
nullptr);
5090 if (HasCopyAndDispose)
5094 RewriteByRefString(ByrefType, Name, ND);
5095 std::string ForwardingCastType(
"(");
5096 ForwardingCastType += ByrefType +
" *)";
5097 ByrefType +=
" " + Name +
" = {(void*)";
5098 ByrefType += utostr(isa);
5099 ByrefType +=
"," + ForwardingCastType +
"&" + Name +
", ";
5100 ByrefType += utostr(flags);
5102 ByrefType +=
"sizeof(";
5103 RewriteByRefString(ByrefType, Name, ND);
5105 if (HasCopyAndDispose) {
5106 ByrefType +=
", __Block_byref_id_object_copy_";
5107 ByrefType += utostr(flag);
5108 ByrefType +=
", __Block_byref_id_object_dispose_";
5109 ByrefType += utostr(flag);
5117 const char *startDeclBuf =
SM->getCharacterData(DeclLoc);
5118 const char *commaBuf = startDeclBuf;
5119 while (*commaBuf !=
',')
5121 assert((*commaBuf ==
',') &&
"RewriteByRefVar: can't find ','");
5123 startBuf = commaBuf;
5127 ByrefType +=
"};\n";
5128 unsigned nameSize = Name.size();
5133 ReplaceText(DeclLoc, endBuf-startBuf+nameSize, ByrefType);
5140 startLoc = ECE->getLParenLoc();
5143 startLoc =
SM->getExpansionLoc(startLoc);
5144 endBuf =
SM->getCharacterData(startLoc);
5145 ReplaceText(DeclLoc, endBuf-startBuf, ByrefType);
5147 const char separator = lastDecl ?
';' :
',';
5148 const char *startInitializerBuf =
SM->getCharacterData(startLoc);
5149 const char *separatorBuf = strchr(startInitializerBuf, separator);
5150 assert((*separatorBuf == separator) &&
5151 "RewriteByRefVar: can't find ';' or ','");
5155 InsertText(separatorLoc, lastDecl ?
"}" :
"};\n");
5159void RewriteModernObjC::CollectBlockDeclRefInfo(
BlockExpr *Exp) {
5161 GetBlockDeclRefExprs(Exp->
getBody());
5162 if (BlockDeclRefs.size()) {
5164 for (
unsigned i = 0; i < BlockDeclRefs.size(); i++)
5165 if (!BlockDeclRefs[i]->getDecl()->hasAttr<BlocksAttr>()) {
5166 if (!BlockByCopyDeclsPtrSet.count(BlockDeclRefs[i]->getDecl())) {
5167 BlockByCopyDeclsPtrSet.insert(BlockDeclRefs[i]->getDecl());
5168 BlockByCopyDecls.push_back(BlockDeclRefs[i]->getDecl());
5172 for (
unsigned i = 0; i < BlockDeclRefs.size(); i++)
5173 if (BlockDeclRefs[i]->getDecl()->hasAttr<BlocksAttr>()) {
5174 if (!BlockByRefDeclsPtrSet.count(BlockDeclRefs[i]->getDecl())) {
5175 BlockByRefDeclsPtrSet.insert(BlockDeclRefs[i]->getDecl());
5176 BlockByRefDecls.push_back(BlockDeclRefs[i]->getDecl());
5180 for (
unsigned i = 0; i < BlockDeclRefs.size(); i++)
5181 if (BlockDeclRefs[i]->getDecl()->hasAttr<BlocksAttr>() ||
5182 BlockDeclRefs[i]->getType()->isObjCObjectPointerType() ||
5183 BlockDeclRefs[i]->getType()->isBlockPointerType())
5184 ImportedBlockDecls.insert(BlockDeclRefs[i]->getDecl());
5188FunctionDecl *RewriteModernObjC::SynthBlockInitFunctionDecl(StringRef name) {
5190 QualType FType = Context->getFunctionNoProtoType(Context->VoidPtrTy);
5200 Blocks.push_back(Exp);
5202 CollectBlockDeclRefInfo(Exp);
5205 int countOfInnerDecls = 0;
5206 if (!InnerBlockDeclRefs.empty()) {
5207 for (
unsigned i = 0; i < InnerBlockDeclRefs.size(); i++) {
5210 if (!VD->
hasAttr<BlocksAttr>() && !BlockByCopyDeclsPtrSet.count(VD)) {
5214 InnerDeclRefs.push_back(Exp); countOfInnerDecls++;
5215 BlockDeclRefs.push_back(Exp);
5216 BlockByCopyDeclsPtrSet.insert(VD);
5217 BlockByCopyDecls.push_back(VD);
5219 if (VD->
hasAttr<BlocksAttr>() && !BlockByRefDeclsPtrSet.count(VD)) {
5220 InnerDeclRefs.push_back(Exp); countOfInnerDecls++;
5221 BlockDeclRefs.push_back(Exp);
5222 BlockByRefDeclsPtrSet.insert(VD);
5223 BlockByRefDecls.push_back(VD);
5227 for (
unsigned i = 0; i < InnerBlockDeclRefs.size(); i++)
5228 if (InnerBlockDeclRefs[i]->getDecl()->hasAttr<BlocksAttr>() ||
5229 InnerBlockDeclRefs[i]->getType()->isObjCObjectPointerType() ||
5230 InnerBlockDeclRefs[i]->getType()->isBlockPointerType())
5231 ImportedBlockDecls.insert(InnerBlockDeclRefs[i]->getDecl());
5233 InnerDeclRefsCount.push_back(countOfInnerDecls);
5235 std::string FuncName;
5239 else if (CurMethodDef)
5240 BuildUniqueMethodName(FuncName, CurMethodDef);
5241 else if (GlobalVarDecl)
5244 bool GlobalBlockExpr =
5247 if (GlobalBlockExpr && !GlobalVarDecl) {
5249 GlobalBlockExpr =
false;
5252 std::string BlockNumber = utostr(Blocks.size()-1);
5254 std::string Func =
"__" + FuncName +
"_block_func_" + BlockNumber;
5257 QualType BFT = convertFunctionTypeOfBlocks(Exp->getFunctionType());
5258 QualType FType = Context->getPointerType(BFT);
5266 if (GlobalBlockExpr)
5270 Tag += FuncName +
"_block_impl_" + BlockNumber;
5272 FD = SynthBlockInitFunctionDecl(Tag);
5279 FD = SynthBlockInitFunctionDecl(Func);
5284 InitExprs.push_back(castExpr);
5287 std::string DescData =
"__" + FuncName +
"_block_desc_" + BlockNumber +
"_DATA";
5289 VarDecl *NewVD = VarDecl::Create(
5291 &Context->Idents.get(DescData), Context->VoidPtrTy,
nullptr, SC_Static);
5294 new (Context)
DeclRefExpr(*Context, NewVD,
false, Context->VoidPtrTy,
5296 UO_AddrOf, Context->getPointerType(Context->VoidPtrTy), VK_PRValue,
5298 InitExprs.push_back(DescRefExpr);
5301 if (BlockDeclRefs.size()) {
5305 E = BlockByCopyDecls.end(); I != E; ++I) {
5306 if (isObjCType((*I)->getType())) {
5308 FD = SynthBlockInitFunctionDecl((*I)->getName());
5311 if (HasLocalVariableExternalStorage(*I)) {
5313 QT = Context->getPointerType(QT);
5314 Exp = UnaryOperator::Create(
const_cast<ASTContext &
>(*Context), Exp,
5315 UO_AddrOf, QT, VK_PRValue, OK_Ordinary,
5319 }
else if (isTopLevelBlockPointerType((*I)->getType())) {
5320 FD = SynthBlockInitFunctionDecl((*I)->getName());
5323 Exp = NoTypeInfoCStyleCastExpr(Context, Context->VoidPtrTy,
5326 FD = SynthBlockInitFunctionDecl((*I)->getName());
5329 if (HasLocalVariableExternalStorage(*I)) {
5331 QT = Context->getPointerType(QT);
5332 Exp = UnaryOperator::Create(
const_cast<ASTContext &
>(*Context), Exp,
5333 UO_AddrOf, QT, VK_PRValue, OK_Ordinary,
5339 InitExprs.push_back(Exp);
5343 E = BlockByRefDecls.end(); I != E; ++I) {
5346 std::string RecName;
5347 RewriteByRefString(RecName, Name, ND,
true);
5349 +
sizeof(
"struct"));
5350 RecordDecl *RD = RecordDecl::Create(*Context, TTK_Struct, TUDecl,
5353 assert(RD &&
"SynthBlockInitExpr(): Can't find RecordDecl");
5354 QualType castT = Context->getPointerType(Context->getTagDeclType(RD));
5356 FD = SynthBlockInitFunctionDecl((*I)->getName());
5359 bool isNestedCapturedVar =
false;
5360 for (
const auto &CI : block->
captures()) {
5361 const VarDecl *variable = CI.getVariable();
5362 if (variable == ND && CI.isNested()) {
5363 assert(CI.isByRef() &&
5364 "SynthBlockInitExpr - captured block variable is not byref");
5365 isNestedCapturedVar =
true;
5371 if (!isNestedCapturedVar)
5372 Exp = UnaryOperator::Create(
5373 const_cast<ASTContext &
>(*Context), Exp, UO_AddrOf,
5374 Context->getPointerType(Exp->
getType()), VK_PRValue, OK_Ordinary,
5376 Exp = NoTypeInfoCStyleCastExpr(Context, castT, CK_BitCast, Exp);
5377 InitExprs.push_back(Exp);
5380 if (ImportedBlockDecls.size()) {
5384 static_cast<unsigned>(Context->getTypeSize(Context->IntTy));
5385 Expr *FlagExp = IntegerLiteral::Create(*Context, llvm::APInt(IntSize, flag),
5387 InitExprs.push_back(FlagExp);
5389 NewRep = CallExpr::Create(*Context, DRE, InitExprs, FType, VK_LValue,
5392 if (GlobalBlockExpr) {
5393 assert (!GlobalConstructionExp &&
5394 "SynthBlockInitExpr - GlobalConstructionExp must be null");
5395 GlobalConstructionExp = NewRep;
5399 NewRep = UnaryOperator::Create(
5400 const_cast<ASTContext &
>(*Context), NewRep, UO_AddrOf,
5401 Context->getPointerType(NewRep->
getType()), VK_PRValue, OK_Ordinary,
5403 NewRep = NoTypeInfoCStyleCastExpr(Context, FType, CK_BitCast,
5409 BlockDeclRefs.clear();
5410 BlockByRefDecls.clear();
5411 BlockByRefDeclsPtrSet.clear();
5412 BlockByCopyDecls.clear();
5413 BlockByCopyDeclsPtrSet.clear();
5414 ImportedBlockDecls.clear();
5418bool RewriteModernObjC::IsDeclStmtInForeachHeader(
DeclStmt *DS) {
5420 dyn_cast<ObjCForCollectionStmt>(Stmts.back()))
5421 return CS->getElement() == DS;
5429Stmt *RewriteModernObjC::RewriteFunctionBodyOrGlobalInitializer(
Stmt *S) {
5430 if (isa<SwitchStmt>(S) || isa<WhileStmt>(S) ||
5431 isa<DoStmt>(S) || isa<ForStmt>(S))
5433 else if (isa<ObjCForCollectionStmt>(S)) {
5435 ObjCBcLabelNo.push_back(++BcLabelCount);
5442 return RewritePropertyOrImplicitSetter(PseudoOp);
5444 return RewritePropertyOrImplicitGetter(PseudoOp);
5446 }
else if (
ObjCIvarRefExpr *IvarRefExpr = dyn_cast<ObjCIvarRefExpr>(S)) {
5447 return RewriteObjCIvarRefExpr(IvarRefExpr);
5449 else if (isa<OpaqueValueExpr>(S))
5450 S = cast<OpaqueValueExpr>(S)->getSourceExpr();
5455 for (
Stmt *&childStmt : S->children())
5457 Stmt *newStmt = RewriteFunctionBodyOrGlobalInitializer(childStmt);
5459 childStmt = newStmt;
5463 if (
BlockExpr *BE = dyn_cast<BlockExpr>(S)) {
5466 InnerContexts.insert(BE->getBlockDecl());
5467 ImportedLocalExternalDecls.clear();
5468 GetInnerBlockDeclRefExprs(BE->getBody(),
5469 InnerBlockDeclRefs, InnerContexts);
5471 Stmt *SaveCurrentBody = CurrentBody;
5472 CurrentBody = BE->getBody();
5473 PropParentMap =
nullptr;
5479 bool saveDisableReplaceStmt = DisableReplaceStmt;
5480 DisableReplaceStmt =
false;
5481 RewriteFunctionBodyOrGlobalInitializer(BE->getBody());
5482 DisableReplaceStmt = saveDisableReplaceStmt;
5483 CurrentBody = SaveCurrentBody;
5484 PropParentMap =
nullptr;
5485 ImportedLocalExternalDecls.clear();
5487 std::string Str =
Rewrite.getRewrittenText(BE->getSourceRange());
5488 RewrittenBlockExprs[BE] = Str;
5490 Stmt *blockTranscribed = SynthBlockInitExpr(BE, InnerBlockDeclRefs);
5493 ReplaceStmt(S, blockTranscribed);
5494 return blockTranscribed;
5498 return RewriteAtEncode(AtEncode);
5501 return RewriteAtSelector(AtSelector);
5504 return RewriteObjCStringLiteral(AtString);
5507 return RewriteObjCBoolLiteralExpr(BoolLitExpr);
5510 return RewriteObjCBoxedExpr(BoxedExpr);
5513 return RewriteObjCArrayLiteralExpr(ArrayLitExpr);
5516 dyn_cast<ObjCDictionaryLiteral>(S))
5517 return RewriteObjCDictionaryLiteralExpr(DictionaryLitExpr);
5525 const char *startBuf =
SM->getCharacterData(startLoc);
5526 const char *endBuf =
SM->getCharacterData(endLoc);
5528 std::string messString;
5529 messString +=
"// ";
5530 messString.append(startBuf, endBuf-startBuf+1);
5539 return RewriteMessageExpr(MessExpr);
5543 dyn_cast<ObjCAutoreleasePoolStmt>(S)) {
5544 return RewriteObjCAutoreleasePoolStmt(StmtAutoRelease);
5548 return RewriteObjCTryStmt(StmtTry);
5551 return RewriteObjCSynchronizedStmt(StmtTry);
5554 return RewriteObjCThrowStmt(StmtThrow);
5557 return RewriteObjCProtocolExpr(ProtocolExp);
5560 dyn_cast<ObjCForCollectionStmt>(S))
5561 return RewriteObjCForCollectionStmt(StmtForCollection,
5564 dyn_cast<BreakStmt>(S))
5565 return RewriteBreakStmt(StmtBreakStmt);
5567 dyn_cast<ContinueStmt>(S))
5568 return RewriteContinueStmt(StmtContinueStmt);
5572 if (
DeclStmt *DS = dyn_cast<DeclStmt>(S)) {
5582 if (Stmts.empty() || !IsDeclStmtInForeachHeader(DS))
5583 RewriteObjCQualifiedInterfaceTypes(*DS->
decl_begin());
5589 if (
ValueDecl *ND = dyn_cast<ValueDecl>(SD)) {
5590 if (isTopLevelBlockPointerType(ND->
getType()))
5591 RewriteBlockPointerDecl(ND);
5593 CheckFunctionPointerDecl(ND->
getType(), ND);
5594 if (
VarDecl *VD = dyn_cast<VarDecl>(SD)) {
5595 if (VD->
hasAttr<BlocksAttr>()) {
5596 static unsigned uniqueByrefDeclCount = 0;
5597 assert(!BlockByRefDeclNo.count(ND) &&
5598 "RewriteFunctionBodyOrGlobalInitializer: Duplicate byref decl");
5599 BlockByRefDeclNo[ND] = uniqueByrefDeclCount++;
5600 RewriteByRefVar(VD, (DI == DS->
decl_begin()), ((DI+1) == DE));
5603 RewriteTypeOfDecl(VD);
5607 if (isTopLevelBlockPointerType(TD->getUnderlyingType()))
5608 RewriteBlockPointerDecl(TD);
5610 CheckFunctionPointerDecl(TD->getUnderlyingType(), TD);
5616 RewriteObjCQualifiedInterfaceTypes(CE);
5618 if (isa<SwitchStmt>(S) || isa<WhileStmt>(S) ||
5619 isa<DoStmt>(S) || isa<ForStmt>(S)) {
5620 assert(!Stmts.empty() &&
"Statement stack is empty");
5621 assert ((isa<SwitchStmt>(Stmts.back()) || isa<WhileStmt>(Stmts.back()) ||
5622 isa<DoStmt>(Stmts.back()) || isa<ForStmt>(Stmts.back()))
5623 &&
"Statement stack mismatch");
5627 if (
DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(S)) {
5629 if (VD->
hasAttr<BlocksAttr>())
5630 return RewriteBlockDeclRefExpr(DRE);
5631 if (HasLocalVariableExternalStorage(VD))
5632 return RewriteLocalVariableExternalStorage(DRE);
5635 if (
CallExpr *CE = dyn_cast<CallExpr>(S)) {
5637 Stmt *BlockCall = SynthesizeBlockCall(CE, CE->getCallee());
5638 ReplaceStmt(S, BlockCall);
5643 RewriteCastExpr(CE);
5646 RewriteImplicitCastObjCExpr(ICE);
5656 llvm::raw_string_ostream Buf(SStr);
5658 const std::string &Str = Buf.str();
5660 printf(
"CAST = %s\n", &Str[0]);
5670void RewriteModernObjC::RewriteRecordBody(
RecordDecl *RD) {
5671 for (
auto *FD : RD->
fields()) {
5672 if (isTopLevelBlockPointerType(FD->
getType()))
5673 RewriteBlockPointerDecl(FD);
5676 RewriteObjCQualifiedInterfaceTypes(FD);
5682void RewriteModernObjC::HandleDeclInMainFile(
Decl *D) {
5684 case Decl::Function: {