24 #include "clang/Config/config.h"
27 #include "llvm/ADT/DenseSet.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 #ifdef CLANG_ENABLE_OBJC_REWRITER
36 using namespace clang;
57 BLOCK_NEEDS_FREE = (1 << 24),
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;
114 llvm::SmallPtrSet<ObjCInterfaceDecl*, 8> ObjCSynthesizedStructs;
115 llvm::SmallPtrSet<ObjCProtocolDecl*, 8> ObjCSynthesizedProtocols;
116 llvm::SmallPtrSet<ObjCInterfaceDecl*, 8> ObjCWrittenInterfaces;
117 llvm::SmallPtrSet<TagDecl*, 32> GlobalDefinedTags;
128 llvm::SmallPtrSet<ObjCProtocolDecl *, 32> ProtocolExprDecls;
141 llvm::SmallPtrSet<ValueDecl *, 8> BlockByCopyDeclsPtrSet;
143 llvm::SmallPtrSet<ValueDecl *, 8> BlockByRefDeclsPtrSet;
144 llvm::DenseMap<ValueDecl *, unsigned> BlockByRefDeclNo;
145 llvm::SmallPtrSet<ValueDecl *, 8> ImportedBlockDecls;
146 llvm::SmallPtrSet<VarDecl *, 8> ImportedLocalExternalDecls;
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)
266 int Size = Rewrite.getRangeSize(SrcRange);
274 llvm::raw_string_ostream
S(SStr);
276 const std::string &Str =
S.str();
279 if (!Rewrite.ReplaceText(SrcRange.
getBegin(), Size, Str)) {
280 ReplacedNodes[Old] = New;
283 if (SilenceRewriteMacroWarning)
290 bool InsertAfter =
true) {
292 if (!Rewrite.InsertText(Loc, Str, InsertAfter) ||
293 SilenceRewriteMacroWarning)
302 if (!Rewrite.ReplaceText(Start, OrigLength, Str) ||
303 SilenceRewriteMacroWarning)
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);
381 QualType SynthesizeBitfieldGroupStructType(
389 void RewriteBlockPointerDecl(
NamedDecl *VD);
390 void RewriteByRefVar(
VarDecl *VD,
bool firstDecl,
bool lastDecl);
400 bool &IsNamedDefinition);
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,
452 void RewriteClassSetupInitHook(std::string &
Result);
454 void RewriteMetaDataIntoBuffer(std::string &
Result);
455 void WriteImageInfo(std::string &
Result);
458 void RewriteCategorySetupInitHook(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)) {
516 bool convertObjCTypeToCStyleType(
QualType &T);
518 bool needToScanForQualifiers(
QualType T);
520 QualType getConstantStringStructType();
523 void convertToUnqualifiedObjCType(
QualType &T) {
544 if (!LangOpts.ObjC1 && !LangOpts.ObjC2)
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) {
593 bool ImplementationIsNonLazy(
const ObjCImplDecl *OD)
const {
609 void RewriteModernObjC::RewriteBlocksInFunctionProtoType(
QualType funcType,
612 = dyn_cast<FunctionProtoType>(funcType.
IgnoreParens())) {
613 for (
const auto &
I : fproto->param_types())
614 if (isTopLevelBlockPointerType(
I)) {
616 RewriteBlockPointerDecl(D);
622 void RewriteModernObjC::CheckFunctionPointerDecl(
QualType funcType,
NamedDecl *ND) {
624 if (PT && PointerTypeTakesAnyBlockArguments(funcType))
629 std::string::size_type DotPos = Filename.rfind(
'.');
631 if (DotPos == std::string::npos) {
636 std::string Ext = std::string(Filename.begin()+DotPos+1, Filename.end());
639 return Ext ==
"h" || Ext ==
"hh" || Ext ==
"H";
642 RewriteModernObjC::RewriteModernObjC(std::string inFile,
643 std::unique_ptr<raw_ostream> OS,
646 bool silenceMacroWarn,
bool LineInfo)
647 : Diags(D), LangOpts(LOpts), InFileName(inFile), OutFile(std::move(OS)),
648 SilenceRewriteMacroWarning(silenceMacroWarn), GenerateLineInfo(LineInfo) {
651 "rewriting sub-expression within a macro (may not be correct)");
655 "rewriting block literal declared in global scope is not implemented");
657 TryFinallyContainsReturnDiag = Diags.getCustomDiagID(
659 "rewriter doesn't support user-specified control flow semantics "
660 "for @try/@finally (code may not execute properly)");
664 const std::string &InFile, std::unique_ptr<raw_ostream> OS,
666 bool SilenceRewriteMacroWarning,
bool LineInfo) {
667 return llvm::make_unique<RewriteModernObjC>(InFile, std::move(OS), Diags,
668 LOpts, SilenceRewriteMacroWarning,
672 void RewriteModernObjC::InitializeCommon(
ASTContext &context) {
676 MsgSendFunctionDecl =
nullptr;
677 MsgSendSuperFunctionDecl =
nullptr;
678 MsgSendStretFunctionDecl =
nullptr;
679 MsgSendSuperStretFunctionDecl =
nullptr;
680 MsgSendFpretFunctionDecl =
nullptr;
681 GetClassFunctionDecl =
nullptr;
682 GetMetaClassFunctionDecl =
nullptr;
683 GetSuperClassFunctionDecl =
nullptr;
684 SelGetUidFunctionDecl =
nullptr;
685 CFStringFunctionDecl =
nullptr;
686 ConstantStringClassReference =
nullptr;
687 NSStringRecord =
nullptr;
688 CurMethodDef =
nullptr;
689 CurFunctionDef =
nullptr;
690 GlobalVarDecl =
nullptr;
691 GlobalConstructionExp =
nullptr;
692 SuperStructDecl =
nullptr;
693 ProtocolTypeDecl =
nullptr;
694 ConstantStringDecl =
nullptr;
696 SuperConstructorFunctionDecl =
nullptr;
697 NumObjCStringLiterals = 0;
698 PropParentMap =
nullptr;
699 CurrentBody =
nullptr;
700 DisableReplaceStmt =
false;
701 objc_impl_method =
false;
705 const llvm::MemoryBuffer *MainBuf =
SM->
getBuffer(MainFileID);
706 MainFileStart = MainBuf->getBufferStart();
707 MainFileEnd = MainBuf->getBufferEnd();
716 void RewriteModernObjC::HandleTopLevelSingleDecl(
Decl *D) {
717 if (Diags.hasErrorOccurred())
731 RewriteFunctionDecl(FD);
732 }
else if (
VarDecl *FVD = dyn_cast<VarDecl>(D)) {
734 if (FVD->getName() ==
"_NSConstantStringClassReference") {
735 ConstantStringClassReference = FVD;
739 RewriteCategoryDecl(CD);
741 if (PD->isThisDeclarationADefinition())
742 RewriteProtocolDecl(PD);
746 DIEnd = LSD->decls_end();
749 if (!IFace->isThisDeclarationADefinition()) {
753 if (isa<ObjCInterfaceDecl>(*DI) &&
754 !cast<ObjCInterfaceDecl>(*DI)->isThisDeclarationADefinition() &&
755 StartLoc == (*DI)->getLocStart())
761 }
while (DI != DIEnd);
762 RewriteForwardClassDecl(DG);
767 ObjCInterfacesSeen.push_back(IFace);
774 if (!Proto->isThisDeclarationADefinition()) {
778 if (isa<ObjCProtocolDecl>(*DI) &&
779 !cast<ObjCProtocolDecl>(*DI)->isThisDeclarationADefinition() &&
780 StartLoc == (*DI)->getLocStart())
786 }
while (DI != DIEnd);
787 RewriteForwardProtocolDecl(DG);
792 HandleTopLevelSingleDecl(*DI);
798 return HandleDeclInMainFile(D);
805 void RewriteModernObjC::RewriteInclude() {
808 const char *MainBufStart = MainBuf.begin();
809 const char *MainBufEnd = MainBuf.end();
810 size_t ImportLen = strlen(
"import");
813 for (
const char *BufPtr = MainBufStart; BufPtr < MainBufEnd; ++BufPtr) {
814 if (*BufPtr ==
'#') {
815 if (++BufPtr == MainBufEnd)
817 while (*BufPtr ==
' ' || *BufPtr ==
'\t')
818 if (++BufPtr == MainBufEnd)
820 if (!strncmp(BufPtr,
"import", ImportLen)) {
824 ReplaceText(ImportLoc, ImportLen,
"include");
833 Result +=
"OBJC_IVAR_$_";
844 std::string IvarOffsetName;
846 ObjCIvarBitfieldGroupOffset(D, IvarOffsetName);
850 std::string
S =
"(*(";
853 IvarT = GetGroupRecordTypeForObjCIvarBitfield(D);
855 if (!isa<TypedefType>(IvarT) && IvarT->
isRecordType()) {
864 CDecl = CatDecl->getClassInterface();
865 std::string RecName = CDecl->
getName();
871 unsigned UnsignedIntSize =
874 llvm::APInt(UnsignedIntSize, 0),
876 Zero = NoTypeInfoCStyleCastExpr(
Context, PtrStructIMPL, CK_BitCast, Zero);
891 convertObjCTypeToCStyleType(IvarT);
898 S +=
"((char *)self + ";
922 static bool objcGetPropertyDefined =
false;
923 static bool objcSetPropertyDefined =
false;
928 InsertText(startLoc,
"// ");
930 assert((*startBuf ==
'@') &&
"bogus @synthesize location");
931 const char *semiBuf = strchr(startBuf,
';');
932 assert((*semiBuf ==
';') &&
"@synthesize: can't find ';'");
944 assert(IMD && OID &&
"Synthesized ivars must be attached to @implementation");
948 bool GenGetProperty = !(Attributes & ObjCPropertyDecl::OBJC_PR_nonatomic) &&
949 (Attributes & (ObjCPropertyDecl::OBJC_PR_retain |
950 ObjCPropertyDecl::OBJC_PR_copy));
952 if (GenGetProperty && !objcGetPropertyDefined) {
953 objcGetPropertyDefined =
true;
955 Getr =
"\nextern \"C\" __declspec(dllimport) "
956 "id objc_getProperty(id, SEL, long, bool);\n";
963 if (GenGetProperty) {
976 for (
unsigned i = 0, e = FT->getNumParams(); i != e; ++i) {
978 std::string ParamStr =
982 if (FT->isVariadic()) {
983 if (FT->getNumParams())
992 Getr +=
"return (_TYPE)";
993 Getr +=
"objc_getProperty(self, _cmd, ";
994 RewriteIvarOffsetComputation(OID, Getr);
1000 InsertText(startGetterSetterLoc, Getr);
1009 bool GenSetProperty = Attributes & (ObjCPropertyDecl::OBJC_PR_retain |
1010 ObjCPropertyDecl::OBJC_PR_copy);
1011 if (GenSetProperty && !objcSetPropertyDefined) {
1012 objcSetPropertyDefined =
true;
1014 Setr =
"\nextern \"C\" __declspec(dllimport) "
1015 "void objc_setProperty (id, SEL, long, id, bool, bool);\n";
1023 if (GenSetProperty) {
1024 Setr +=
"objc_setProperty (self, _cmd, ";
1025 RewriteIvarOffsetComputation(OID, Setr);
1029 if (Attributes & ObjCPropertyDecl::OBJC_PR_nonatomic)
1033 if (Attributes & ObjCPropertyDecl::OBJC_PR_copy)
1043 InsertText(startGetterSetterLoc, Setr);
1047 std::string &typedefString) {
1048 typedefString +=
"\n#ifndef _REWRITER_typedef_";
1050 typedefString +=
"\n";
1051 typedefString +=
"#define _REWRITER_typedef_";
1053 typedefString +=
"\n";
1054 typedefString +=
"typedef struct objc_object ";
1057 typedefString +=
";\ntypedef struct {} _objc_exc_";
1059 typedefString +=
";\n#endif\n";
1062 void RewriteModernObjC::RewriteForwardClassEpilogue(
ObjCInterfaceDecl *ClassDecl,
1063 const std::string &typedefString) {
1066 const char *semiPtr = strchr(startBuf,
';');
1068 ReplaceText(startLoc, semiPtr-startBuf+1, typedefString);
1071 void RewriteModernObjC::RewriteForwardClassDecl(
DeclGroupRef D) {
1072 std::string typedefString;
1079 typedefString +=
"// @class ";
1080 typedefString += ForwardDecl->getNameAsString();
1081 typedefString +=
";";
1086 HandleTopLevelSingleDecl(*
I);
1089 RewriteForwardClassEpilogue(cast<ObjCInterfaceDecl>(*I), typedefString);
1092 void RewriteModernObjC::RewriteForwardClassDecl(
1094 std::string typedefString;
1095 for (
unsigned i = 0; i < D.size(); i++) {
1098 typedefString +=
"// @class ";
1100 typedefString +=
";";
1104 RewriteForwardClassEpilogue(cast<ObjCInterfaceDecl>(D[0]), typedefString);
1107 void RewriteModernObjC::RewriteMethodDeclaration(
ObjCMethodDecl *Method) {
1117 InsertText(LocStart,
"#if 0\n");
1118 ReplaceText(LocEnd, 1,
";\n#endif\n");
1120 InsertText(LocStart,
"// ");
1127 ReplaceText(Loc, 0,
"// ");
1136 ReplaceText(LocStart, 1,
"/** ");
1140 ReplaceText(LocStart, 0,
"// ");
1147 RewriteMethodDeclaration(I);
1149 RewriteMethodDeclaration(I);
1153 strlen(
"@end"),
"/* @end */\n");
1161 ReplaceText(LocStart, 0,
"// ");
1164 RewriteMethodDeclaration(I);
1166 RewriteMethodDeclaration(I);
1172 ReplaceText(LocEnd, strlen(
"@end"),
"/* @end */\n");
1177 for (
const char *p = startBuf; p < endBuf; p++) {
1178 if (*p ==
'@' && !strncmp(p+1,
"optional", strlen(
"optional"))) {
1180 ReplaceText(OptionalLoc, strlen(
"@optional"),
"/* @optional */");
1183 else if (*p ==
'@' && !strncmp(p+1,
"required", strlen(
"required"))) {
1185 ReplaceText(OptionalLoc, strlen(
"@required"),
"/* @required */");
1191 void RewriteModernObjC::RewriteForwardProtocolDecl(
DeclGroupRef D) {
1194 llvm_unreachable(
"Invalid SourceLocation");
1196 ReplaceText(LocStart, 0,
"// ");
1203 llvm_unreachable(
"Invalid SourceLocation");
1205 ReplaceText(LocStart, 0,
"// ");
1208 void RewriteModernObjC::RewriteTypeIntoString(
QualType T, std::string &ResultStr,
1233 std::string &ResultStr) {
1236 ResultStr +=
"\nstatic ";
1237 RewriteTypeIntoString(OMD->
getReturnType(), ResultStr, FPRetType);
1241 std::string NameStr;
1259 int len = selString.size();
1260 for (
int i = 0; i < len; i++)
1261 if (selString[i] ==
':')
1263 NameStr += selString;
1266 MethodInternalNames[OMD] = NameStr;
1267 ResultStr += NameStr;
1276 if (!LangOpts.MicrosoftExt) {
1277 if (ObjCSynthesizedStructs.count(const_cast<ObjCInterfaceDecl*>(IDecl)))
1278 ResultStr +=
"struct ";
1288 ResultStr +=
" self, ";
1290 ResultStr +=
" _cmd";
1293 for (
const auto *PDecl : OMD->
parameters()) {
1295 if (PDecl->getType()->isObjCQualifiedIdType()) {
1302 (void)convertBlockPointerToFunctionPointer(QT);
1308 ResultStr +=
", ...";
1317 for (
unsigned i = 0, e = FT->getNumParams(); i != e; ++i) {
1318 if (i) ResultStr +=
", ";
1319 std::string ParamStr =
1321 ResultStr += ParamStr;
1323 if (FT->isVariadic()) {
1324 if (FT->getNumParams())
1335 void RewriteModernObjC::RewriteImplementationDecl(
Decl *OID) {
1349 InsertText(CID->getLocStart(),
"// ");
1351 for (
auto *OMD : IMD ? IMD->
instance_methods() : CID->instance_methods()) {
1352 std::string ResultStr;
1359 ReplaceText(LocStart, endBuf-startBuf, ResultStr);
1362 for (
auto *OMD : IMD ? IMD->
class_methods() : CID->class_methods()) {
1363 std::string ResultStr;
1370 ReplaceText(LocStart, endBuf-startBuf, ResultStr);
1372 for (
auto *I : IMD ? IMD->
property_impls() : CID->property_impls())
1373 RewritePropertyImplDecl(I, IMD, CID);
1375 InsertText(IMD ? IMD->
getLocEnd() : CID->getLocEnd(),
"// ");
1380 if (ObjCSynthesizedStructs.count(ClassDecl))
1384 while (SuperClass) {
1385 RewriteInterfaceDecl(SuperClass);
1388 std::string ResultStr;
1392 RewriteIvarOffsetSymbols(ClassDecl, ResultStr);
1394 RewriteObjCInternalStruct(ClassDecl, ResultStr);
1401 RewriteMethodDeclaration(I);
1403 RewriteMethodDeclaration(I);
1425 DisableReplaceStmtScope
S(*
this);
1431 Base = cast<OpaqueValueExpr>(Base)->getSourceExpr();
1432 Base = cast<Expr>(RewriteFunctionBodyOrGlobalInitializer(Base));
1436 for (
unsigned i = 0; i < numArgs; i++) {
1438 if (isa<OpaqueValueExpr>(Arg))
1439 Arg = cast<OpaqueValueExpr>(Arg)->getSourceExpr();
1440 Arg = cast<Expr>(RewriteFunctionBodyOrGlobalInitializer(Arg));
1441 Args.push_back(Arg);
1451 case ObjCMessageExpr::Class:
1464 case ObjCMessageExpr::Instance:
1477 case ObjCMessageExpr::SuperClass:
1478 case ObjCMessageExpr::SuperInstance:
1495 ReplaceStmtWithRange(PseudoOp, Replacement, OldRange);
1509 Expr *Base =
nullptr;
1512 DisableReplaceStmtScope
S(*
this);
1516 Base = cast<OpaqueValueExpr>(Base)->getSourceExpr();
1517 Base = cast<Expr>(RewriteFunctionBodyOrGlobalInitializer(Base));
1520 for (
unsigned i = 0; i < numArgs; i++) {
1522 if (isa<OpaqueValueExpr>(Arg))
1523 Arg = cast<OpaqueValueExpr>(Arg)->getSourceExpr();
1524 Arg = cast<Expr>(RewriteFunctionBodyOrGlobalInitializer(Arg));
1525 Args.push_back(Arg);
1534 case ObjCMessageExpr::Class:
1547 case ObjCMessageExpr::Instance:
1560 case ObjCMessageExpr::SuperClass:
1561 case ObjCMessageExpr::SuperInstance:
1578 ReplaceStmtWithRange(PseudoOp, Replacement, OldRange);
1591 void RewriteModernObjC::SynthCountByEnumWithState(std::string &buf) {
1592 buf +=
"((_WIN_NSUInteger (*) (id, SEL, struct __objcFastEnumerationState *, "
1593 "id *, _WIN_NSUInteger))(void *)objc_msgSend)";
1595 buf +=
"((id)l_collection,\n\t\t";
1596 buf +=
"sel_registerName(\"countByEnumeratingWithState:objects:count:\"),";
1598 buf +=
"&enumState, "
1599 "(id *)__rw_items, (_WIN_NSUInteger)16)";
1606 if (Stmts.empty() || !isa<ObjCForCollectionStmt>(Stmts.back()))
1612 buf =
"goto __break_label_";
1613 buf += utostr(ObjCBcLabelNo.back());
1614 ReplaceText(startLoc, strlen(
"break"), buf);
1619 void RewriteModernObjC::ConvertSourceLocationToLineDirective(
1621 std::string &LineString) {
1622 if (Loc.
isFileID() && GenerateLineInfo) {
1623 LineString +=
"\n#line ";
1625 LineString += utostr(PLoc.
getLine());
1626 LineString +=
" \"";
1627 LineString += Lexer::Stringify(PLoc.
getFilename());
1628 LineString +=
"\"\n";
1636 if (Stmts.empty() || !isa<ObjCForCollectionStmt>(Stmts.back()))
1642 buf =
"goto __continue_label_";
1643 buf += utostr(ObjCBcLabelNo.back());
1644 ReplaceText(startLoc, strlen(
"continue"), buf);
1683 assert(!Stmts.empty() &&
"ObjCForCollectionStmt - Statement stack empty");
1684 assert(isa<ObjCForCollectionStmt>(Stmts.back()) &&
1685 "ObjCForCollectionStmt Statement stack mismatch");
1686 assert(!ObjCBcLabelNo.empty() &&
1687 "ObjCForCollectionStmt - Label No stack empty");
1691 StringRef elementName;
1692 std::string elementTypeAsString;
1696 ConvertSourceLocationToLineDirective(ForEachLoc, buf);
1700 NamedDecl* D = cast<NamedDecl>(DS->getSingleDecl());
1701 QualType ElementType = cast<ValueDecl>(D)->getType();
1702 if (ElementType->isObjCQualifiedIdType() ||
1703 ElementType->isObjCQualifiedInterfaceType())
1705 elementTypeAsString =
"id";
1708 buf += elementTypeAsString;
1721 elementTypeAsString =
"id";
1727 buf +=
"struct __objcFastEnumerationState enumState = { 0 };\n\t";
1729 buf +=
"id __rw_items[16];\n\t";
1731 buf +=
"id l_collection = (id)";
1733 const char *startCollectionBuf = startBuf;
1734 startCollectionBuf += 3;
1735 startCollectionBuf = strchr(startCollectionBuf,
'(');
1736 startCollectionBuf++;
1738 while (*startCollectionBuf !=
' ' ||
1739 *(startCollectionBuf+1) !=
'i' || *(startCollectionBuf+2) !=
'n' ||
1740 (*(startCollectionBuf+3) !=
' ' &&
1741 *(startCollectionBuf+3) !=
'[' && *(startCollectionBuf+3) !=
'('))
1742 startCollectionBuf++;
1743 startCollectionBuf += 3;
1746 ReplaceText(startLoc, startCollectionBuf - startBuf, buf);
1764 buf +=
"_WIN_NSUInteger limit =\n\t\t";
1765 SynthCountByEnumWithState(buf);
1775 buf +=
"if (limit) {\n\t";
1776 buf +=
"unsigned long startMutations = *enumState.mutationsPtr;\n\t";
1777 buf +=
"do {\n\t\t";
1778 buf +=
"unsigned long counter = 0;\n\t\t";
1779 buf +=
"do {\n\t\t\t";
1780 buf +=
"if (startMutations != *enumState.mutationsPtr)\n\t\t\t\t";
1781 buf +=
"objc_enumerationMutation(l_collection);\n\t\t\t";
1784 buf += elementTypeAsString;
1785 buf +=
")enumState.itemsPtr[counter++];";
1787 ReplaceText(lparenLoc, 1, buf);
1801 buf +=
"__continue_label_";
1802 buf += utostr(ObjCBcLabelNo.back());
1805 buf +=
"} while (counter < limit);\n\t";
1806 buf +=
"} while ((limit = ";
1807 SynthCountByEnumWithState(buf);
1811 buf += elementTypeAsString;
1813 buf +=
"__break_label_";
1814 buf += utostr(ObjCBcLabelNo.back());
1817 buf +=
"else\n\t\t";
1820 buf += elementTypeAsString;
1826 if (isa<CompoundStmt>(S->
getBody())) {
1828 InsertText(endBodyLoc, buf);
1838 const char *semiBuf = strchr(stmtBuf,
';');
1839 assert(semiBuf &&
"Can't find ';'");
1841 InsertText(endBodyLoc, buf);
1844 ObjCBcLabelNo.pop_back();
1849 buf +=
"{ struct _FIN { _FIN(id reth) : rethrow(reth) {}\n";
1850 buf +=
"\t~_FIN() { if (rethrow) objc_exception_throw(rethrow); }\n";
1851 buf +=
"\tid rethrow;\n";
1852 buf +=
"\t} _fin_force_rethow(_rethrow);";
1866 assert((*startBuf ==
'@') &&
"bogus @synchronized location");
1870 ConvertSourceLocationToLineDirective(SynchLoc, buf);
1871 buf +=
"{ id _rethrow = 0; id _sync_obj = (id)";
1873 const char *lparenBuf = startBuf;
1874 while (*lparenBuf !=
'(') lparenBuf++;
1875 ReplaceText(startLoc, lparenBuf-startBuf+1, buf);
1877 buf =
"; objc_sync_enter(_sync_obj);\n";
1878 buf +=
"try {\n\tstruct _SYNC_EXIT { _SYNC_EXIT(id arg) : sync_exit(arg) {}";
1879 buf +=
"\n\t~_SYNC_EXIT() {objc_sync_exit(sync_exit);}";
1880 buf +=
"\n\tid sync_exit;";
1881 buf +=
"\n\t} _sync_exit(_sync_obj);\n";
1888 while (*RParenExprLocBuf !=
')') RParenExprLocBuf--;
1893 assert (*LBraceLocBuf ==
'{');
1894 ReplaceText(RParenExprLoc, (LBraceLocBuf -
SM->
getCharacterData(RParenExprLoc) + 1), buf);
1898 "bogus @synchronized block");
1900 buf =
"} catch (id e) {_rethrow = e;}\n";
1905 ReplaceText(startRBraceLoc, 1, buf);
1910 void RewriteModernObjC::WarnAboutReturnGotoStmts(
Stmt *S)
1915 WarnAboutReturnGotoStmts(SubStmt);
1917 if (isa<ReturnStmt>(S) || isa<GotoStmt>(S)) {
1919 TryFinallyContainsReturnDiag);
1925 ReplaceText(startLoc, strlen(
"@autoreleasepool"),
"/* @autoreleasepool */");
1927 "{ __AtAutoreleasePool __autoreleasepool; ");
1937 ConvertSourceLocationToLineDirective(TryLocation, buf);
1941 buf +=
"{ id volatile _rethrow = 0;\n";
1943 buf +=
"{ id volatile _rethrow = 0;\ntry {\n";
1950 assert((*startBuf ==
'@') &&
"bogus @try location");
1952 ReplaceText(startLoc, 1, buf);
1955 ReplaceText(startLoc, 1,
"");
1962 bool AtRemoved =
false;
1973 assert((*startBuf ==
'@') &&
"bogus @catch location");
1981 ReplaceText(startLoc, rParenBuf-startBuf+1, Result);
1992 ReplaceText(lBraceLoc, 1, Result);
1999 ReplaceText(startLoc, 1,
"");
2007 ConvertSourceLocationToLineDirective(FinallyLoc, buf);
2008 buf +=
"catch (id e) {_rethrow = e;}\n";
2012 ConvertSourceLocationToLineDirective(FinallyLoc, buf);
2013 buf +=
"catch (id e) {_rethrow = e;}\n";
2017 ReplaceText(startFinalLoc, 8, buf);
2022 ReplaceText(startFinalBodyLoc, 1, buf);
2025 ReplaceText(endFinalBodyLoc, 1,
"}\n}");
2041 assert((*startBuf ==
'@') &&
"bogus @throw location");
2046 buf =
"objc_exception_throw(";
2051 const char *wBuf = strchr(startBuf,
'w');
2052 assert((*wBuf ==
'w') &&
"@throw: can't find 'w'");
2053 ReplaceText(startLoc, wBuf-startBuf+1, buf);
2057 const char *semiBuf = strchr(endBuf,
';');
2058 assert((*semiBuf ==
';') &&
"@throw: can't find ';'");
2061 ReplaceText(semiLoc, 1,
");");
2067 std::string StrEncoding;
2070 ReplaceStmt(Exp, Replacement);
2078 if (!SelGetUidFunctionDecl)
2079 SynthSelGetUidFunctionDecl();
2080 assert(SelGetUidFunctionDecl &&
"Can't find sel_registerName() decl");
2084 CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl,
2086 ReplaceStmt(Exp, SelExp);
2092 RewriteModernObjC::SynthesizeCallToFunctionDecl(
FunctionDecl *FD,
2118 const char *&startRef,
const char *&endRef) {
2119 while (startBuf < endBuf) {
2120 if (*startBuf ==
'<')
2121 startRef = startBuf;
2122 if (*startBuf ==
'>') {
2123 if (startRef && *startRef ==
'<') {
2136 while (*argRef !=
')' && (*argRef !=
',' || angle > 0)) {
2139 else if (*argRef ==
'>')
2143 assert(angle == 0 &&
"scanToNextArgument - bad protocol type syntax");
2146 bool RewriteModernObjC::needToScanForQualifiers(
QualType T) {
2159 return needToScanForQualifiers(ElemTy);
2164 void RewriteModernObjC::RewriteObjCQualifiedInterfaceTypes(
Expr *E) {
2166 if (needToScanForQualifiers(Type)) {
2170 Loc = ECE->getLParenLoc();
2171 EndLoc = ECE->getRParenLoc();
2182 const char *startRef =
nullptr, *endRef =
nullptr;
2188 InsertText(LessLoc,
"/*");
2189 InsertText(GreaterLoc,
"*/");
2194 void RewriteModernObjC::RewriteObjCQualifiedInterfaceTypes(
Decl *Dcl) {
2198 if (
VarDecl *VD = dyn_cast<VarDecl>(Dcl)) {
2202 else if (
FunctionDecl *FD = dyn_cast<FunctionDecl>(Dcl)) {
2207 assert(funcType &&
"missing function type");
2213 else if (
FieldDecl *FD = dyn_cast<FieldDecl>(Dcl)) {
2218 Loc = TD->getLocation();
2219 Type = TD->getUnderlyingType();
2224 if (needToScanForQualifiers(Type)) {
2228 const char *startBuf = endBuf;
2229 while (*startBuf !=
';' && *startBuf !=
'<' && startBuf != MainFileStart)
2231 const char *startRef =
nullptr, *endRef =
nullptr;
2237 InsertText(LessLoc,
"/*");
2238 InsertText(GreaterLoc,
"*/");
2245 const char *startFuncBuf = startBuf;
2250 const char *endBuf = startBuf;
2253 const char *startRef =
nullptr, *endRef =
nullptr;
2261 InsertText(LessLoc,
"/*");
2262 InsertText(GreaterLoc,
"*/");
2264 startBuf = ++endBuf;
2269 while (*startBuf && *startBuf !=
')' && *startBuf !=
',')
2276 void RewriteModernObjC::RewriteTypeOfDecl(
VarDecl *ND) {
2278 const Type* TypePtr = QT->
getAs<Type>();
2279 if (!isa<TypeOfExprType>(TypePtr))
2281 while (isa<TypeOfExprType>(TypePtr)) {
2282 const TypeOfExprType *TypeOfExprTypePtr = cast<TypeOfExprType>(TypePtr);
2284 TypePtr = QT->
getAs<Type>();
2293 TypeAsString +=
" " + Name +
" = ";
2297 startLoc = ECE->getLParenLoc();
2302 ReplaceText(DeclLoc, endBuf-startBuf-1, TypeAsString);
2308 ReplaceText(DeclLoc, endBuf-startBuf-1, TypeAsString);
2313 void RewriteModernObjC::SynthSelGetUidFunctionDecl() {
2322 SelGetUidIdent, getFuncType,
2326 void RewriteModernObjC::RewriteFunctionDecl(
FunctionDecl *FD) {
2329 FD->
getName() ==
"sel_registerName") {
2330 SelGetUidFunctionDecl = FD;
2333 RewriteObjCQualifiedInterfaceTypes(FD);
2336 void RewriteModernObjC::RewriteBlockPointerType(std::string& Str,
QualType Type) {
2338 const char *argPtr = TypeString.c_str();
2339 if (!strchr(argPtr,
'^')) {
2344 Str += (*argPtr ==
'^' ?
'*' : *argPtr);
2350 void RewriteModernObjC::RewriteBlockPointerTypeVariable(std::string& Str,
2354 const char *argPtr = TypeString.c_str();
2379 void RewriteModernObjC::RewriteBlockLiteralFunctionDecl(
FunctionDecl *FD) {
2385 QualType Type = proto->getReturnType();
2390 unsigned numArgs = proto->getNumParams();
2391 for (
unsigned i = 0; i < numArgs; i++) {
2392 QualType ArgType = proto->getParamType(i);
2393 RewriteBlockPointerType(FdStr, ArgType);
2398 FdStr += (numArgs > 0) ?
", ...);\n" :
"...);\n";
2402 InsertText(FunLocStart, FdStr);
2406 void RewriteModernObjC::SynthSuperConstructorFunctionDecl() {
2407 if (SuperConstructorFunctionDecl)
2412 assert(!argT.
isNull() &&
"Can't find 'id' type");
2413 ArgTys.push_back(argT);
2414 ArgTys.push_back(argT);
2420 msgSendIdent, msgSendType,
2425 void RewriteModernObjC::SynthMsgSendFunctionDecl() {
2429 assert(!argT.
isNull() &&
"Can't find 'id' type");
2430 ArgTys.push_back(argT);
2432 assert(!argT.
isNull() &&
"Can't find 'SEL' type");
2433 ArgTys.push_back(argT);
2439 msgSendIdent, msgSendType,
nullptr,
2444 void RewriteModernObjC::SynthMsgSendSuperFunctionDecl() {
2453 msgSendIdent, msgSendType,
2458 void RewriteModernObjC::SynthMsgSendStretFunctionDecl() {
2462 assert(!argT.
isNull() &&
"Can't find 'id' type");
2463 ArgTys.push_back(argT);
2465 assert(!argT.
isNull() &&
"Can't find 'SEL' type");
2466 ArgTys.push_back(argT);
2472 msgSendIdent, msgSendType,
2478 void RewriteModernObjC::SynthMsgSendSuperStretFunctionDecl() {
2489 msgSendType,
nullptr,
2494 void RewriteModernObjC::SynthMsgSendFpretFunctionDecl() {
2498 assert(!argT.
isNull() &&
"Can't find 'id' type");
2499 ArgTys.push_back(argT);
2501 assert(!argT.
isNull() &&
"Can't find 'SEL' type");
2502 ArgTys.push_back(argT);
2508 msgSendIdent, msgSendType,
2513 void RewriteModernObjC::SynthGetClassFunctionDecl() {
2522 getClassIdent, getClassType,
2527 void RewriteModernObjC::SynthGetSuperClassFunctionDecl() {
2538 getClassType,
nullptr,
2543 void RewriteModernObjC::SynthGetMetaClassFunctionDecl() {
2552 getClassIdent, getClassType,
2557 assert (Exp !=
nullptr &&
"Expected non-null ObjCStringLiteral");
2558 QualType strType = getConstantStringStructType();
2560 std::string S =
"__NSConstantStringImpl_";
2562 std::string tmpName = InFileName;
2564 for (i=0; i < tmpName.length(); i++) {
2565 char c = tmpName.at(i);
2572 S += utostr(NumObjCStringLiterals++);
2574 Preamble +=
"static __NSConstantStringImpl " +
S;
2575 Preamble +=
" __attribute__ ((section (\"__DATA, __cfstring\"))) = {__CFConstantStringClassReference,";
2576 Preamble +=
"0x000007c8,";
2578 std::string prettyBufS;
2579 llvm::raw_string_ostream prettyBuf(prettyBufS);
2581 Preamble += prettyBuf.str();
2596 CK_CPointerToObjCPointerCast, Unop);
2597 ReplaceStmt(Exp, cast);
2607 llvm::APInt(IntSize, Exp->
getValue()),
2610 CK_BitCast, FlagExp);
2613 ReplaceStmt(Exp, PE);
2619 if (!SelGetUidFunctionDecl)
2620 SynthSelGetUidFunctionDecl();
2622 if (!MsgSendFunctionDecl)
2623 SynthMsgSendFunctionDecl();
2624 if (!GetClassFunctionDecl)
2625 SynthGetClassFunctionDecl();
2640 ClsExprs.push_back(getStringLiteral(clsName->
getName()));
2641 CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl, ClsExprs,
2643 MsgExprs.push_back(Cls);
2650 CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl,
2651 SelExprs, StartLoc, EndLoc);
2652 MsgExprs.push_back(SelExp);
2661 CK = CK_IntegralToBoolean;
2662 subExpr = NoTypeInfoCStyleCastExpr(
Context, type, CK, subExpr);
2664 MsgExprs.push_back(subExpr);
2669 for (
const auto PI : BoxingMethod->
parameters())
2670 ArgTypes.push_back(PI->getType());
2686 getSimpleFunctionType(returnType, ArgTypes, BoxingMethod->
isVariadic());
2688 cast = NoTypeInfoCStyleCastExpr(
Context, castType, CK_BitCast,
2697 ReplaceStmt(Exp, CE);
2703 if (!SelGetUidFunctionDecl)
2704 SynthSelGetUidFunctionDecl();
2706 if (!MsgSendFunctionDecl)
2707 SynthMsgSendFunctionDecl();
2708 if (!GetClassFunctionDecl)
2709 SynthGetClassFunctionDecl();
2719 std::string NSArrayFName(
"__NSContainer_literal");
2720 FunctionDecl *NSArrayFD = SynthBlockInitFunctionDecl(NSArrayFName);
2727 unsigned UnsignedIntSize =
2730 llvm::APInt(UnsignedIntSize, NumElements),
2732 InitExprs.push_back(count);
2733 for (
unsigned i = 0; i < NumElements; i++)
2735 Expr *NSArrayCallExpr =
2750 NoTypeInfoCStyleCastExpr(
Context,
2765 ClsExprs.push_back(getStringLiteral(clsName->
getName()));
2766 CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl, ClsExprs,
2768 MsgExprs.push_back(Cls);
2776 CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl,
2777 SelExprs, StartLoc, EndLoc);
2778 MsgExprs.push_back(SelExp);
2781 MsgExprs.push_back(ArrayLiteralObjects);
2785 llvm::APInt(UnsignedIntSize, NumElements),
2787 MsgExprs.push_back(cnt);
2792 for (
const auto *PI : ArrayMethod->
parameters())
2793 ArgTypes.push_back(PI->getType());
2809 getSimpleFunctionType(returnType, ArgTypes, ArrayMethod->
isVariadic());
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();
2842 std::string NSDictFName(
"__NSContainer_literal");
2843 FunctionDecl *NSDictFD = SynthBlockInitFunctionDecl(NSDictFName);
2852 unsigned UnsignedIntSize =
2855 llvm::APInt(UnsignedIntSize, NumElements),
2857 KeyExprs.push_back(count);
2858 ValueExprs.push_back(count);
2859 for (
unsigned i = 0; i < NumElements; i++) {
2861 KeyExprs.push_back(Element.
Key);
2862 ValueExprs.push_back(Element.
Value);
2866 Expr *NSValueCallExpr =
2881 NoTypeInfoCStyleCastExpr(
Context,
2884 DictLiteralValueME);
2886 Expr *NSKeyCallExpr =
2895 NoTypeInfoCStyleCastExpr(
Context,
2910 ClsExprs.push_back(getStringLiteral(clsName->
getName()));
2911 CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl, ClsExprs,
2913 MsgExprs.push_back(Cls);
2920 CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl,
2921 SelExprs, StartLoc, EndLoc);
2922 MsgExprs.push_back(SelExp);
2925 MsgExprs.push_back(DictValueObjects);
2928 MsgExprs.push_back(DictKeyObjects);
2932 llvm::APInt(UnsignedIntSize, NumElements),
2934 MsgExprs.push_back(cnt);
2939 for (
const auto *PI : DictMethod->
parameters()) {
2943 convertToUnqualifiedObjCType(PointeeTy);
2946 ArgTypes.push_back(T);
2963 getSimpleFunctionType(returnType, ArgTypes, DictMethod->
isVariadic());
2965 cast = NoTypeInfoCStyleCastExpr(
Context, castType, CK_BitCast,
2974 ReplaceStmt(Exp, CE);
2981 QualType RewriteModernObjC::getSuperStructType() {
2982 if (!SuperStructDecl) {
2994 for (
unsigned i = 0; i < 2; ++i) {
2998 FieldTypes[i],
nullptr,
3004 SuperStructDecl->completeDefinition();
3009 QualType RewriteModernObjC::getConstantStringStructType() {
3010 if (!ConstantStringDecl) {
3026 for (
unsigned i = 0; i < 4; ++i) {
3031 FieldTypes[i],
nullptr,
3037 ConstantStringDecl->completeDefinition();
3051 if (!LSD->getRBraceLoc().isValid())
3052 return LSD->getExternLoc();
3055 R.RewriteBlockLiteralFunctionDecl(FD);
3059 void RewriteModernObjC::RewriteLineDirective(
const Decl *D) {
3063 if (Location.
isFileID() && GenerateLineInfo) {
3064 std::string LineString(
"\n#line ");
3066 LineString += utostr(PLoc.
getLine());
3067 LineString +=
" \"";
3068 LineString += Lexer::Stringify(PLoc.
getFilename());
3069 if (isa<ObjCMethodDecl>(D))
3071 else LineString +=
"\"\n";
3074 if (
const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
3079 if (!LSD->getRBraceLoc().isValid())
3080 Location = LSD->getExternLoc();
3083 InsertText(Location, LineString);
3097 Expr *RewriteModernObjC::SynthMsgSendStretCallExpr(
FunctionDecl *MsgSendStretFlavor,
3103 QualType castType = getSimpleFunctionType(returnType, ArgTypes,
3109 static unsigned stretCount=0;
3110 std::string name =
"__Stret"; name += utostr(stretCount);
3112 "extern \"C\" void * __cdecl memset(void *_Dst, int _Val, size_t _Size);\n";
3113 str +=
"namespace {\n";
3114 str +=
"struct "; str += name;
3117 str +=
"(id receiver, SEL sel";
3118 for (
unsigned i = 2; i < ArgTypes.size(); i++) {
3119 std::string ArgName =
"arg"; ArgName += utostr(i);
3121 str +=
", "; str += ArgName;
3124 for (
unsigned i = ArgTypes.size(); i < MsgExprs.size(); i++) {
3125 std::string ArgName =
"arg"; ArgName += utostr(i);
3126 MsgExprs[i]->getType().getAsStringInternal(ArgName,
3128 str +=
", "; str += ArgName;
3132 str +=
"\t unsigned size = sizeof(";
3135 str +=
"\t if (size == 1 || size == 2 || size == 4 || size == 8)\n";
3138 str +=
")(void *)objc_msgSend)(receiver, sel";
3139 for (
unsigned i = 2; i < ArgTypes.size(); i++) {
3140 str +=
", arg"; str += utostr(i);
3143 for (
unsigned i = ArgTypes.size(); i < MsgExprs.size(); i++) {
3144 str +=
", arg"; str += utostr(i);
3148 str +=
"\t else if (receiver == 0)\n";
3149 str +=
"\t memset((void*)&s, 0, sizeof(s));\n";
3153 str +=
")(void *)objc_msgSend_stret)(receiver, sel";
3154 for (
unsigned i = 2; i < ArgTypes.size(); i++) {
3155 str +=
", arg"; str += utostr(i);
3158 for (
unsigned i = ArgTypes.size(); i < MsgExprs.size(); i++) {
3159 str +=
", arg"; str += utostr(i);
3166 str +=
"};\n};\n\n";
3171 assert(CurMethodDef &&
"SynthMsgSendStretCallExpr - CurMethodDef is null");
3172 FunLocStart = CurMethodDef->getLocStart();
3175 InsertText(FunLocStart, str);
3191 returnType,
nullptr,
3204 if (!SelGetUidFunctionDecl)
3205 SynthSelGetUidFunctionDecl();
3206 if (!MsgSendFunctionDecl)
3207 SynthMsgSendFunctionDecl();
3208 if (!MsgSendSuperFunctionDecl)
3209 SynthMsgSendSuperFunctionDecl();
3210 if (!MsgSendStretFunctionDecl)
3211 SynthMsgSendStretFunctionDecl();
3212 if (!MsgSendSuperStretFunctionDecl)
3213 SynthMsgSendSuperStretFunctionDecl();
3214 if (!MsgSendFpretFunctionDecl)
3215 SynthMsgSendFpretFunctionDecl();
3216 if (!GetClassFunctionDecl)
3217 SynthGetClassFunctionDecl();
3218 if (!GetSuperClassFunctionDecl)
3219 SynthGetSuperClassFunctionDecl();
3220 if (!GetMetaClassFunctionDecl)
3221 SynthGetMetaClassFunctionDecl();
3228 QualType resultType = mDecl->getReturnType();
3230 MsgSendStretFlavor = MsgSendStretFunctionDecl;
3232 MsgSendFlavor = MsgSendFpretFunctionDecl;
3238 case ObjCMessageExpr::SuperClass: {
3239 MsgSendFlavor = MsgSendSuperFunctionDecl;
3240 if (MsgSendStretFlavor)
3241 MsgSendStretFlavor = MsgSendSuperStretFunctionDecl;
3242 assert(MsgSendFlavor &&
"MsgSendFlavor is NULL!");
3249 InitExprs.push_back(
3263 CallExpr *Cls = SynthesizeCallToFunctionDecl(GetMetaClassFunctionDecl,
3264 ClsExprs, StartLoc, EndLoc);
3266 ClsExprs.push_back(Cls);
3267 Cls = SynthesizeCallToFunctionDecl(GetSuperClassFunctionDecl, ClsExprs,
3272 InitExprs.push_back(
3273 NoTypeInfoCStyleCastExpr(
Context,
3277 QualType superType = getSuperStructType();
3280 if (LangOpts.MicrosoftExt) {
3281 SynthSuperConstructorFunctionDecl();
3299 SuperRep = NoTypeInfoCStyleCastExpr(
Context,
3301 CK_BitCast, SuperRep);
3318 MsgExprs.push_back(SuperRep);
3322 case ObjCMessageExpr::Class: {
3327 ClsExprs.push_back(getStringLiteral(clsName->
getName()));
3328 CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl, ClsExprs,
3333 MsgExprs.push_back(ArgExpr);
3337 case ObjCMessageExpr::SuperInstance:{
3338 MsgSendFlavor = MsgSendSuperFunctionDecl;
3339 if (MsgSendStretFlavor)
3340 MsgSendStretFlavor = MsgSendSuperStretFunctionDecl;
3341 assert(MsgSendFlavor &&
"MsgSendFlavor is NULL!");
3345 InitExprs.push_back(
3358 CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl, ClsExprs,
3361 ClsExprs.push_back(Cls);
3362 Cls = SynthesizeCallToFunctionDecl(GetSuperClassFunctionDecl, ClsExprs,
3367 InitExprs.push_back(
3372 QualType superType = getSuperStructType();
3375 if (LangOpts.MicrosoftExt) {
3376 SynthSuperConstructorFunctionDecl();
3379 false, superType, VK_LValue,
3393 SuperRep = NoTypeInfoCStyleCastExpr(
Context,
3395 CK_BitCast, SuperRep);
3407 MsgExprs.push_back(SuperRep);
3411 case ObjCMessageExpr::Instance: {
3416 recExpr = CE->getSubExpr();
3419 ? CK_BlockPointerToObjCPointerCast
3420 : CK_CPointerToObjCPointerCast;
3424 MsgExprs.push_back(recExpr);
3432 CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl,
3433 SelExprs, StartLoc, EndLoc);
3434 MsgExprs.push_back(SelExp);
3437 for (
unsigned i = 0; i < Exp->
getNumArgs(); i++) {
3443 if (needToScanForQualifiers(type))
3446 (void)convertBlockPointerToFunctionPointer(type);
3451 CK = CK_IntegralToBoolean;
3454 CK = CK_BlockPointerToObjCPointerCast;
3456 CK = CK_CPointerToObjCPointerCast;
3464 userExpr = NoTypeInfoCStyleCastExpr(
Context, type, CK, userExpr);
3467 else if (
CStyleCastExpr *CE = dyn_cast<CStyleCastExpr>(userExpr)) {
3468 if (CE->getType()->isObjCQualifiedIdType()) {
3469 while ((CE = dyn_cast<CStyleCastExpr>(userExpr)))
3470 userExpr = CE->getSubExpr();
3473 CK = CK_IntegralToPointer;
3475 CK = CK_BlockPointerToObjCPointerCast;
3477 CK = CK_CPointerToObjCPointerCast;
3485 MsgExprs.push_back(userExpr);
3497 if (MsgSendFlavor == MsgSendSuperFunctionDecl)
3509 (void)convertBlockPointerToFunctionPointer(t);
3510 ArgTypes.push_back(t);
3513 convertToUnqualifiedObjCType(returnType);
3514 (void)convertBlockPointerToFunctionPointer(returnType);
3529 cast = NoTypeInfoCStyleCastExpr(
Context,
3537 getSimpleFunctionType(returnType, ArgTypes, MD ? MD->isVariadic() :
true);
3539 cast = NoTypeInfoCStyleCastExpr(
Context, castType, CK_BitCast,
3548 Stmt *ReplacingStmt = CE;
3549 if (MsgSendStretFlavor) {
3555 Expr *STCE = SynthMsgSendStretCallExpr(MsgSendStretFlavor,
3559 ReplacingStmt = STCE;
3562 return ReplacingStmt;
3570 ReplaceStmt(Exp, ReplacingStmt);
3573 return ReplacingStmt;
3577 QualType RewriteModernObjC::getProtocolType() {
3578 if (!ProtocolTypeDecl) {
3594 std::string Name =
"_OBJC_PROTOCOL_REFERENCE_$_" +
3603 NoTypeInfoCStyleCastExpr(
3605 ReplaceStmt(Exp, castExpr);
3615 bool &IsNamedDefinition) {
3619 if (
RecordDecl *RD = dyn_cast<RecordDecl>(Tag)) {
3623 IsNamedDefinition =
true;
3628 if (
EnumDecl *ED = dyn_cast<EnumDecl>(Tag)) {
3629 if (!ED || !ED->getDeclName().getAsIdentifierInfo())
3631 IsNamedDefinition =
true;
3632 TagLocation = ED->getLocation();
3641 bool RewriteModernObjC::RewriteObjCFieldDeclType(
QualType &Type,
3642 std::string &Result) {
3643 if (isa<TypedefType>(Type)) {
3650 return RewriteObjCFieldDeclType(ElemTy, Result);
3656 Result +=
"\n\tstruct ";
3658 Result +=
"\n\tunion ";
3660 assert(
false &&
"class not allowed as an ivar type");
3663 if (GlobalDefinedTags.count(RD)) {
3669 for (
auto *FD : RD->
fields())
3670 RewriteObjCFieldDecl(FD, Result);
3678 Result +=
"\n\tenum ";
3680 if (GlobalDefinedTags.count(ED)) {
3688 Result +=
"\t"; Result += EC->getName(); Result +=
" = ";
3689 llvm::APSInt Val = EC->getInitVal();
3690 Result += Val.toString(10);
3699 convertObjCTypeToCStyleType(Type);
3707 std::string &Result) {
3711 bool EleboratedType = RewriteObjCFieldDeclType(Type, Result);
3712 if (!EleboratedType)
3723 llvm::APInt Dim = CAT->getSize();
3724 Result += utostr(Dim.getZExtValue());
3736 void RewriteModernObjC::RewriteLocallyDefinedNamedAggregates(
FieldDecl *fieldDecl,
3737 std::string &Result) {
3739 if (isa<TypedefType>(Type))
3755 if (GlobalDefinedTags.count(TD))
3758 bool IsNamedDefinition =
false;
3759 if (IsTagDefinedInsideClass(IDecl, TD, IsNamedDefinition)) {
3760 RewriteObjCFieldDeclType(Type, Result);
3763 if (IsNamedDefinition)
3764 GlobalDefinedTags.insert(TD);
3768 unsigned RewriteModernObjC::ObjCIvarBitfieldGroupNo(
ObjCIvarDecl *IV) {
3770 if (ObjCInterefaceHasBitfieldGroups.count(CDecl)) {
3771 return IvarGroupNumber[IV];
3773 unsigned GroupNo = 0;
3777 IVars.push_back(IVD);
3779 for (
unsigned i = 0, e = IVars.size(); i < e; i++)
3780 if (IVars[i]->isBitField()) {
3781 IvarGroupNumber[IVars[i++]] = ++GroupNo;
3782 while (i < e && IVars[i]->isBitField())
3783 IvarGroupNumber[IVars[i++]] = GroupNo;
3788 ObjCInterefaceHasBitfieldGroups.insert(CDecl);
3789 return IvarGroupNumber[IV];
3792 QualType RewriteModernObjC::SynthesizeBitfieldGroupStructType(
3795 std::string StructTagName;
3796 ObjCIvarBitfieldGroupType(IV, StructTagName);
3801 for (
unsigned i=0, e = IVars.size(); i < e; i++) {
3815 unsigned GroupNo = ObjCIvarBitfieldGroupNo(IV);
3816 std::pair<const ObjCInterfaceDecl*, unsigned> tuple = std::make_pair(CDecl, GroupNo);
3817 if (GroupRecordType.count(tuple))
3818 return GroupRecordType[tuple];
3823 if (IVD->isBitField())
3824 IVars.push_back(const_cast<ObjCIvarDecl *>(IVD));
3826 if (!IVars.empty()) {
3827 unsigned GroupNo = ObjCIvarBitfieldGroupNo(IVars[0]);
3829 GroupRecordType[std::make_pair(CDecl, GroupNo)] =
3830 SynthesizeBitfieldGroupStructType(IVars[0], IVars);
3835 if (!IVars.empty()) {
3837 unsigned GroupNo = ObjCIvarBitfieldGroupNo(IVars[0]);
3838 GroupRecordType[std::make_pair(CDecl, GroupNo)] =
3839 SynthesizeBitfieldGroupStructType(IVars[0], IVars);
3841 QualType RetQT = GroupRecordType[tuple];
3842 assert(!RetQT.
isNull() &&
"GetGroupRecordTypeForObjCIvarBitfield struct type is NULL");
3849 void RewriteModernObjC::ObjCIvarBitfieldGroupDecl(
ObjCIvarDecl *IV,
3850 std::string &Result) {
3853 Result +=
"__GRBF_";
3854 unsigned GroupNo = ObjCIvarBitfieldGroupNo(IV);
3855 Result += utostr(GroupNo);
3861 void RewriteModernObjC::ObjCIvarBitfieldGroupType(
ObjCIvarDecl *IV,
3862 std::string &Result) {
3866 unsigned GroupNo = ObjCIvarBitfieldGroupNo(IV);
3867 Result += utostr(GroupNo);
3873 void RewriteModernObjC::ObjCIvarBitfieldGroupOffset(
ObjCIvarDecl *IV,
3874 std::string &Result) {
3875 Result +=
"OBJC_IVAR_$_";
3876 ObjCIvarBitfieldGroupDecl(IV, Result);
3879 #define SKIP_BITFIELDS(IX, ENDIX, VEC) { \
3880 while ((IX < ENDIX) && VEC[IX]->isBitField()) \
3889 std::string &Result) {
3890 assert(CDecl &&
"Class missing in SynthesizeObjCInternalStruct");
3891 assert(CDecl->
getName() !=
"" &&
3892 "Name missing in SynthesizeObjCInternalStruct");
3897 IVars.push_back(IVD);
3908 (!RCDecl || !ObjCSynthesizedStructs.count(RCDecl))) {
3909 endBuf += Lexer::MeasureTokenLength(LocEnd, *
SM, LangOpts);
3910 ReplaceText(LocStart, endBuf-startBuf, Result);
3917 for (
unsigned i = 0, e = IVars.size(); i < e; i++)
3918 RewriteLocallyDefinedNamedAggregates(IVars[i], Result);
3922 for (
unsigned i = 0, e = IVars.size(); i < e; i++)
3923 if (IVars[i]->isBitField()) {
3925 QualType QT = GetGroupRecordTypeForObjCIvarBitfield(IV);
3926 RewriteObjCFieldDeclType(QT, Result);
3932 Result +=
"\nstruct ";
3934 Result +=
"_IMPL {\n";
3936 if (RCDecl && ObjCSynthesizedStructs.count(RCDecl)) {
3937 Result +=
"\tstruct "; Result += RCDecl->getNameAsString();
3938 Result +=
"_IMPL "; Result += RCDecl->getNameAsString();
3939 Result +=
"_IVARS;\n";
3942 for (
unsigned i = 0, e = IVars.size(); i < e; i++) {
3943 if (IVars[i]->isBitField()) {
3945 Result +=
"\tstruct ";
3946 ObjCIvarBitfieldGroupType(IV, Result); Result +=
" ";
3947 ObjCIvarBitfieldGroupDecl(IV, Result); Result +=
";\n";
3952 RewriteObjCFieldDecl(IVars[i], Result);
3956 endBuf += Lexer::MeasureTokenLength(LocEnd, *
SM, LangOpts);
3957 ReplaceText(LocStart, endBuf-startBuf, Result);
3959 if (!ObjCSynthesizedStructs.insert(CDecl).second)
3960 llvm_unreachable(
"struct already synthesize- RewriteObjCInternalStruct");
3966 std::string &Result) {
3977 unsigned GroupNo = 0;
3978 if (IvarDecl->isBitField()) {
3979 GroupNo = ObjCIvarBitfieldGroupNo(IvarDecl);
3980 if (GroupSymbolOutput.count(std::make_pair(IDecl, GroupNo)))
3984 if (LangOpts.MicrosoftExt)
3985 Result +=
"__declspec(allocate(\".objc_ivar$B\")) ";
3986 Result +=
"extern \"C\" ";
3987 if (LangOpts.MicrosoftExt &&
3988 IvarDecl->getAccessControl() != ObjCIvarDecl::Private &&
3989 IvarDecl->getAccessControl() != ObjCIvarDecl::Package)
3990 Result +=
"__declspec(dllimport) ";
3992 Result +=
"unsigned long ";
3993 if (IvarDecl->isBitField()) {
3994 ObjCIvarBitfieldGroupOffset(IvarDecl, Result);
3995 GroupSymbolOutput.insert(std::make_pair(IDecl, GroupNo));
4010 void RewriteModernObjC::RewriteImplementations() {
4011 int ClsDefCount = ClassImplementation.size();
4012 int CatDefCount = CategoryImplementation.size();
4015 for (
int i = 0; i < ClsDefCount; i++) {
4020 "Legacy implicit interface rewriting not supported in moder abi");
4021 RewriteImplementationDecl(OIMP);
4024 for (
int i = 0; i < CatDefCount; i++) {
4029 "Legacy implicit interface rewriting not supported in moder abi");
4030 RewriteImplementationDecl(CIMP);
4034 void RewriteModernObjC::RewriteByRefString(std::string &ResultStr,
4035 const std::string &Name,
4037 assert(BlockByRefDeclNo.count(VD) &&
4038 "RewriteByRefString: ByRef decl missing");
4040 ResultStr +=
"struct ";
4041 ResultStr +=
"__Block_byref_" + Name +
4042 "_" + utostr(BlockByRefDeclNo[VD]) ;
4046 if (
VarDecl *Var = dyn_cast<VarDecl>(VD))
4047 return (Var->isFunctionOrMethodVarDecl() && !Var->hasLocalStorage());
4051 std::string RewriteModernObjC::SynthesizeBlockFunc(
BlockExpr *CE,
int i,
4056 std::string StructRef =
"struct " + Tag;
4059 ConvertSourceLocationToLineDirective(BlockLoc, S);
4062 funcName.str() +
"_block_func_" + utostr(i);
4066 if (isa<FunctionNoProtoType>(AFT)) {
4069 S +=
"(" + StructRef +
" *__cself)";
4071 S +=
"(" + StructRef +
" *__cself)";
4074 assert(FT &&
"SynthesizeBlockFunc: No function proto");
4077 S += StructRef +
" *__cself, ";
4078 std::string ParamStr;
4082 ParamStr = (*AI)->getNameAsString();
4084 (void)convertBlockPointerToFunctionPointer(QT);
4099 E = BlockByRefDecls.end(); I !=
E; ++
I) {
4101 std::string Name = (*I)->getNameAsString();
4102 std::string TypeString;
4103 RewriteByRefString(TypeString, Name, (*I));
4105 Name = TypeString +
Name;
4106 S += Name +
" = __cself->" + (*I)->getNameAsString() +
"; // bound by ref\n";
4110 E = BlockByCopyDecls.end(); I !=
E; ++
I) {
4122 if (isTopLevelBlockPointerType((*I)->getType())) {
4123 RewriteBlockPointerTypeVariable(S, (*I));
4125 RewriteBlockPointerType(S, (*I)->getType());
4127 S +=
"__cself->" + (*I)->getNameAsString() +
"; // bound by copy\n";
4130 std::string Name = (*I)->getNameAsString();
4135 S += Name +
" = __cself->" +
4136 (*I)->getNameAsString() +
"; // bound by copy\n";
4139 std::string RewrittenStr = RewrittenBlockExprs[CE];
4140 const char *cstr = RewrittenStr.c_str();
4141 while (*cstr++ !=
'{') ;
4147 std::string RewriteModernObjC::SynthesizeBlockHelperFuncs(
BlockExpr *CE,
int i,
4150 std::string StructRef =
"struct " + Tag;
4151 std::string S =
"static void __";
4154 S +=
"_block_copy_" + utostr(i);
4155 S +=
"(" + StructRef;
4156 S +=
"*dst, " + StructRef;
4158 for (
ValueDecl *VD : ImportedBlockDecls) {
4159 S +=
"_Block_object_assign((void*)&dst->";
4161 S +=
", (void*)src->";
4163 if (BlockByRefDeclsPtrSet.count(VD))
4172 S +=
"\nstatic void __";
4174 S +=
"_block_dispose_" + utostr(i);
4175 S +=
"(" + StructRef;
4177 for (
ValueDecl *VD : ImportedBlockDecls) {
4178 S +=
"_Block_object_dispose((void*)src->";
4180 if (BlockByRefDeclsPtrSet.count(VD))
4191 std::string RewriteModernObjC::SynthesizeBlockImpl(
BlockExpr *CE, std::string Tag,
4193 std::string S =
"\nstruct " + Tag;
4196 S +=
" {\n struct __block_impl impl;\n";
4197 S +=
" struct " + Desc;
4200 Constructor +=
"(void *fp, ";
4201 Constructor +=
"struct " + Desc;
4202 Constructor +=
" *desc";
4204 if (BlockDeclRefs.size()) {
4207 E = BlockByCopyDecls.end(); I !=
E; ++
I) {
4209 std::string FieldName = (*I)->getNameAsString();
4210 std::string ArgName =
"_" + FieldName;
4221 if (isTopLevelBlockPointerType((*I)->getType())) {
4222 S +=
"struct __block_impl *";
4223 Constructor +=
", void *" + ArgName;
4230 Constructor +=
", " + ArgName;
4232 S += FieldName +
";\n";
4236 E = BlockByRefDecls.end(); I !=
E; ++
I) {
4238 std::string FieldName = (*I)->getNameAsString();
4239 std::string ArgName =
"_" + FieldName;
4241 std::string TypeString;
4242 RewriteByRefString(TypeString, FieldName, (*I));
4244 FieldName = TypeString + FieldName;
4245 ArgName = TypeString + ArgName;
4246 Constructor +=
", " + ArgName;
4248 S += FieldName +
"; // by ref\n";
4251 Constructor +=
", int flags=0)";
4253 bool firsTime =
true;
4255 E = BlockByCopyDecls.end(); I !=
E; ++
I) {
4256 std::string Name = (*I)->getNameAsString();
4258 Constructor +=
" : ";
4262 Constructor +=
", ";
4263 if (isTopLevelBlockPointerType((*I)->getType()))
4264 Constructor += Name +
"((struct __block_impl *)_" + Name +
")";
4266 Constructor += Name +
"(_" + Name +
")";
4270 E = BlockByRefDecls.end(); I !=
E; ++
I) {
4271 std::string Name = (*I)->getNameAsString();
4273 Constructor +=
" : ";
4277 Constructor +=
", ";
4278 Constructor += Name +
"(_" + Name +
"->__forwarding)";
4281 Constructor +=
" {\n";
4283 Constructor +=
" impl.isa = &_NSConcreteGlobalBlock;\n";
4285 Constructor +=
" impl.isa = &_NSConcreteStackBlock;\n";
4286 Constructor +=
" impl.Flags = flags;\n impl.FuncPtr = fp;\n";
4288 Constructor +=
" Desc = desc;\n";
4291 Constructor +=
", int flags=0) {\n";
4293 Constructor +=
" impl.isa = &_NSConcreteGlobalBlock;\n";
4295 Constructor +=
" impl.isa = &_NSConcreteStackBlock;\n";
4296 Constructor +=
" impl.Flags = flags;\n impl.FuncPtr = fp;\n";
4297 Constructor +=
" Desc = desc;\n";
4300 Constructor +=
"}\n";
4306 std::string RewriteModernObjC::SynthesizeBlockDescriptor(std::string DescTag,
4307 std::string ImplTag,
int i,
4310 std::string S =
"\nstatic struct " + DescTag;
4312 S +=
" {\n size_t reserved;\n";
4313 S +=
" size_t Block_size;\n";
4315 S +=
" void (*copy)(struct ";
4316 S += ImplTag; S +=
"*, struct ";
4317 S += ImplTag; S +=
"*);\n";
4319 S +=
" void (*dispose)(struct ";
4320 S += ImplTag; S +=
"*);\n";
4324 S += DescTag +
"_DATA = { 0, sizeof(struct ";
4327 S +=
", __" + FunName.str() +
"_block_copy_" + utostr(i);
4328 S +=
", __" + FunName.str() +
"_block_dispose_" + utostr(i);
4334 void RewriteModernObjC::SynthesizeBlockLiterals(
SourceLocation FunLocStart,
4335 StringRef FunName) {
4336 bool RewriteSC = (GlobalVarDecl &&
4338 GlobalVarDecl->getStorageClass() ==
SC_Static &&
4339 GlobalVarDecl->getType().getCVRQualifiers());
4341 std::string SC(
" void __");
4342 SC += GlobalVarDecl->getNameAsString();
4344 InsertText(FunLocStart, SC);
4348 for (
unsigned i = 0, count=0; i < Blocks.size(); i++) {
4349 CollectBlockDeclRefInfo(Blocks[i]);
4352 for (
int j = 0; j < InnerDeclRefsCount[i]; j++) {
4355 BlockDeclRefs.push_back(Exp);
4356 if (!VD->
hasAttr<BlocksAttr>()) {
4357 if (!BlockByCopyDeclsPtrSet.count(VD)) {
4358 BlockByCopyDeclsPtrSet.insert(VD);
4359 BlockByCopyDecls.push_back(VD);
4364 if (!BlockByRefDeclsPtrSet.count(VD)) {
4365 BlockByRefDeclsPtrSet.insert(VD);
4366 BlockByRefDecls.push_back(VD);
4373 ImportedBlockDecls.insert(VD);
4376 std::string ImplTag =
"__" + FunName.str() +
"_block_impl_" + utostr(i);
4377 std::string DescTag =
"__" + FunName.str() +
"_block_desc_" + utostr(i);
4379 std::string CI = SynthesizeBlockImpl(Blocks[i], ImplTag, DescTag);
4381 InsertText(FunLocStart, CI);
4383 std::string CF = SynthesizeBlockFunc(Blocks[i], i, FunName, ImplTag);
4385 InsertText(FunLocStart, CF);
4387 if (ImportedBlockDecls.size()) {
4388 std::string HF = SynthesizeBlockHelperFuncs(Blocks[i], i, FunName, ImplTag);
4389 InsertText(FunLocStart, HF);
4391 std::string BD = SynthesizeBlockDescriptor(DescTag, ImplTag, i, FunName,
4392 ImportedBlockDecls.size() > 0);
4393 InsertText(FunLocStart, BD);
4395 BlockDeclRefs.clear();
4396 BlockByRefDecls.clear();
4397 BlockByRefDeclsPtrSet.clear();
4398 BlockByCopyDecls.clear();
4399 BlockByCopyDeclsPtrSet.clear();
4400 ImportedBlockDecls.clear();
4406 if (GlobalVarDecl->getStorageClass() ==
SC_Static)
4408 if (GlobalVarDecl->getType().isConstQualified())
4410 if (GlobalVarDecl->getType().isVolatileQualified())
4412 if (GlobalVarDecl->getType().isRestrictQualified())
4414 InsertText(FunLocStart, SC);
4416 if (GlobalConstructionExp) {
4420 std::string Tag =
"__";
4422 Tag +=
"_block_impl_";
4423 Tag += utostr(Blocks.size()-1);
4424 std::string globalBuf =
"static ";
4425 globalBuf += Tag; globalBuf +=
" ";
4428 llvm::raw_string_ostream constructorExprBuf(SStr);
4429 GlobalConstructionExp->printPretty(constructorExprBuf,
nullptr,
4431 globalBuf += constructorExprBuf.str();
4433 InsertText(FunLocStart, globalBuf);
4434 GlobalConstructionExp =
nullptr;
4438 InnerDeclRefsCount.clear();
4439 InnerDeclRefs.clear();
4440 RewrittenBlockExprs.clear();
4443 void RewriteModernObjC::InsertBlockLiteralsWithinFunction(
FunctionDecl *FD) {
4447 StringRef FuncName = FD->
getName();
4449 SynthesizeBlockLiterals(FunLocStart, FuncName);
4458 std::string::size_type loc = 0;
4459 while ((loc = Name.find(
':', loc)) != std::string::npos)
4460 Name.replace(loc, 1,
"_");
4463 void RewriteModernObjC::InsertBlockLiteralsWithinMethod(
ObjCMethodDecl *MD) {
4467 std::string FuncName;
4469 SynthesizeBlockLiterals(FunLocStart, FuncName);
4472 void RewriteModernObjC::GetBlockDeclRefExprs(
Stmt *S) {
4475 if (
BlockExpr *CBE = dyn_cast<BlockExpr>(SubStmt))
4476 GetBlockDeclRefExprs(CBE->getBody());
4478 GetBlockDeclRefExprs(SubStmt);
4485 BlockDeclRefs.push_back(DRE);
4488 void RewriteModernObjC::GetInnerBlockDeclRefExprs(
Stmt *S,
4490 llvm::SmallPtrSetImpl<const DeclContext *> &InnerContexts) {
4493 if (
BlockExpr *CBE = dyn_cast<BlockExpr>(SubStmt)) {
4494 InnerContexts.insert(cast<DeclContext>(CBE->getBlockDecl()));
4495 GetInnerBlockDeclRefExprs(CBE->getBody(),
4500 GetInnerBlockDeclRefExprs(SubStmt, InnerBlockDeclRefs, InnerContexts);
4503 if (
DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(S)) {
4507 InnerBlockDeclRefs.push_back(DRE);
4509 if (Var->isFunctionOrMethodVarDecl())
4510 ImportedLocalExternalDecls.insert(Var);
4518 bool RewriteModernObjC::convertObjCTypeToCStyleType(
QualType &T) {
4520 convertBlockPointerToFunctionPointer(T);
4526 T = convertFunctionTypeOfBlocks(FT);
4532 convertToUnqualifiedObjCType(T);
4546 bool modified = convertObjCTypeToCStyleType(Res);
4552 if (convertObjCTypeToCStyleType(t))
4554 ArgTypes.push_back(t);
4559 FuncType = getSimpleFunctionType(Res, ArgTypes);
4564 Stmt *RewriteModernObjC::SynthesizeBlockCall(
CallExpr *Exp,
const Expr *BlockExp) {
4568 if (
const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(BlockExp)) {
4570 }
else if (
const MemberExpr *MExpr = dyn_cast<MemberExpr>(BlockExp)) {
4573 else if (
const ParenExpr *PRE = dyn_cast<ParenExpr>(BlockExp)) {
4574 return SynthesizeBlockCall(Exp, PRE->getSubExpr());
4576 else if (
const ImplicitCastExpr *IEXPR = dyn_cast<ImplicitCastExpr>(BlockExp))
4579 dyn_cast<ConditionalOperator>(BlockExp)) {
4580 Expr *LHSExp = CEXPR->getLHS();
4581 Stmt *LHSStmt = SynthesizeBlockCall(Exp, LHSExp);
4582 Expr *RHSExp = CEXPR->getRHS();
4583 Stmt *RHSStmt = SynthesizeBlockCall(Exp, RHSExp);
4584 Expr *CONDExp = CEXPR->getCond();
4591 }
else if (
const ObjCIvarRefExpr *IRE = dyn_cast<ObjCIvarRefExpr>(BlockExp)) {
4594 = dyn_cast<PseudoObjectExpr>(BlockExp)) {
4597 assert(
false &&
"RewriteBlockClass: Bad type");
4599 assert(CPT &&
"RewriteBlockClass: Bad type");
4601 assert(FT &&
"RewriteBlockClass: Bad type");
4614 ArgTypes.push_back(PtrBlock);
4619 if (!convertBlockPointerToFunctionPointer(t))
4620 convertToUnqualifiedObjCType(t);
4621 ArgTypes.push_back(t);
4625 QualType PtrToFuncCastType = getSimpleFunctionType(Exp->
getType(), ArgTypes);
4631 const_cast<Expr*>(BlockExp));
4647 CastExpr *FunkCast = NoTypeInfoCStyleCastExpr(
Context, PtrToFuncCastType,
4653 BlkExprs.push_back(BlkCast);
4657 BlkExprs.push_back(*I);
4678 Stmt *RewriteModernObjC::RewriteBlockDeclRefExpr(
DeclRefExpr *DeclRefExp) {
4695 StringRef Name = VD->
getName();
4709 ReplaceStmt(DeclRefExp, PE);
4716 Stmt *RewriteModernObjC::RewriteLocalVariableExternalStorage(
DeclRefExpr *DRE) {
4718 if (
VarDecl *Var = dyn_cast<VarDecl>(VD))
4719 if (!ImportedLocalExternalDecls.count(Var))
4727 ReplaceStmt(DRE, PE);
4739 if (!Rewriter::isRewritable(LocStart) || !Rewriter::isRewritable(LocEnd))
4745 const Type* TypePtr = QT->
getAs<Type>();
4746 if (isa<TypeOfExprType>(TypePtr)) {
4747 const TypeOfExprType *TypeOfExprTypePtr = cast<TypeOfExprType>(TypePtr);
4749 std::string TypeAsString =
"(";
4750 RewriteBlockPointerType(TypeAsString, QT);
4751 TypeAsString +=
")";
4752 ReplaceText(LocStart, endBuf-startBuf+1, TypeAsString);
4756 const char *argPtr = startBuf;
4758 while (*argPtr++ && (argPtr < endBuf)) {
4763 ReplaceText(LocStart, 1,
"*");
4769 void RewriteModernObjC::RewriteImplicitCastObjCExpr(
CastExpr *IC) {
4771 if (CastKind != CK_BlockPointerToObjCPointerCast &&
4772 CastKind != CK_AnyPointerToBlockPointerCast)
4776 (void)convertBlockPointerToFunctionPointer(QT);
4778 std::string Str =
"(";
4784 void RewriteModernObjC::RewriteBlockPointerFunctionArgs(
FunctionDecl *FD) {
4786 unsigned parenCount = 0;
4790 const char *startArgList = strchr(startBuf,
'(');
4792 assert((*startArgList ==
'(') &&
"Rewriter fuzzy parser confused");
4797 assert((DeclLoc.
isValid()) &&
"Invalid DeclLoc");
4799 const char *argPtr = startArgList;
4801 while (*argPtr++ && parenCount) {
4806 ReplaceText(DeclLoc, 1,
"*");
4818 bool RewriteModernObjC::PointerTypeTakesAnyBlockArguments(
QualType QT) {
4825 assert(BPT &&
"BlockPointerTypeTakeAnyBlockArguments(): not a block pointer type");
4830 if (isTopLevelBlockPointerType(I))
4836 bool RewriteModernObjC::PointerTypeTakesAnyObjCQualifiedType(
QualType QT) {
4843 assert(BPT &&
"BlockPointerTypeTakeAnyBlockArguments(): not a block pointer type");
4848 if (I->isObjCQualifiedIdType())
4850 if (I->isObjCObjectPointerType() &&
4851 I->getPointeeType()->isObjCQualifiedInterfaceType())
4859 void RewriteModernObjC::GetExtentOfArgList(
const char *Name,
const char *&LParen,
4860 const char *&RParen) {
4861 const char *argPtr = strchr(Name,
'(');
4862 assert((*argPtr ==
'(') &&
"Rewriter fuzzy parser confused");
4866 unsigned parenCount = 1;
4868 while (*argPtr && parenCount) {
4870 case '(': parenCount++;
break;
4871 case ')': parenCount--;
break;
4874 if (parenCount) argPtr++;
4876 assert((*argPtr ==
')') &&
"Rewriter fuzzy parser confused");
4880 void RewriteModernObjC::RewriteBlockPointerDecl(
NamedDecl *ND) {
4882 RewriteBlockPointerFunctionArgs(FD);
4888 if (
VarDecl *VD = dyn_cast<VarDecl>(ND))
4891 DeclT = TDD->getUnderlyingType();
4892 else if (
FieldDecl *FD = dyn_cast<FieldDecl>(ND))
4895 llvm_unreachable(
"RewriteBlockPointerDecl(): Decl type not yet handled");
4898 const char *endBuf = startBuf;
4900 while (*startBuf !=
'^' && *startBuf !=
';' && startBuf != MainFileStart)
4904 unsigned OrigLength=0;
4907 if (*startBuf ==
'^') {
4913 while (*startBuf !=
')') {
4921 if (PointerTypeTakesAnyBlockArguments(DeclT) ||
4922 PointerTypeTakesAnyObjCQualifiedType(DeclT)) {
4927 const char *argListBegin, *argListEnd;
4928 GetExtentOfArgList(startBuf, argListBegin, argListEnd);
4929 while (argListBegin < argListEnd) {
4930 if (*argListBegin ==
'^')
4932 else if (*argListBegin ==
'<') {
4934 buf += *argListBegin++;
4936 while (*argListBegin !=
'>') {
4937 buf += *argListBegin++;
4940 buf += *argListBegin;
4944 buf += *argListBegin;
4951 ReplaceText(Start, OrigLength, buf);
4974 std::string RewriteModernObjC::SynthesizeByrefCopyDestroyHelper(
VarDecl *VD,
4977 if (CopyDestroyCache.count(flag))
4979 CopyDestroyCache.insert(flag);
4980 S =
"static void __Block_byref_id_object_copy_";
4982 S +=
"(void *dst, void *src) {\n";
4988 unsigned VoidPtrSize =
4992 S +=
" _Block_object_assign((char*)dst + ";
4993 S += utostr(offset);
4994 S +=
", *(void * *) ((char*)src + ";
4995 S += utostr(offset);
5000 S +=
"static void __Block_byref_id_object_dispose_";
5002 S +=
"(void *src) {\n";
5003 S +=
" _Block_object_dispose(*(void * *) ((char*)src + ";
5004 S += utostr(offset);
5029 void RewriteModernObjC::RewriteByRefVar(
VarDecl *ND,
bool firstDecl,
5043 std::string ByrefType;
5044 RewriteByRefString(ByrefType, Name, ND,
true);
5045 ByrefType +=
" {\n";
5046 ByrefType +=
" void *__isa;\n";
5047 RewriteByRefString(ByrefType, Name, ND);
5048 ByrefType +=
" *__forwarding;\n";
5049 ByrefType +=
" int __flags;\n";
5050 ByrefType +=
" int __size;\n";
5055 if (HasCopyAndDispose) {
5056 ByrefType +=
" void (*__Block_byref_id_object_copy)(void*, void*);\n";
5057 ByrefType +=
" void (*__Block_byref_id_object_dispose)(void*);\n";
5061 (void)convertBlockPointerToFunctionPointer(T);
5064 ByrefType +=
" " + Name +
";\n";
5065 ByrefType +=
"};\n";
5071 assert(CurMethodDef &&
"RewriteByRefVar - CurMethodDef is null");
5072 FunLocStart = CurMethodDef->getLocStart();
5074 InsertText(FunLocStart, ByrefType);
5080 if (HasCopyAndDispose) {
5088 std::string HF = SynthesizeByrefCopyDestroyHelper(ND, flag);
5096 bool hasInit = (ND->
getInit() !=
nullptr);
5107 if (HasCopyAndDispose)
5111 RewriteByRefString(ByrefType, Name, ND);
5112 std::string ForwardingCastType(
"(");
5113 ForwardingCastType += ByrefType +
" *)";
5114 ByrefType +=
" " + Name +
" = {(void*)";
5115 ByrefType += utostr(isa);
5116 ByrefType +=
"," + ForwardingCastType +
"&" + Name +
", ";
5117 ByrefType += utostr(flags);
5119 ByrefType +=
"sizeof(";
5120 RewriteByRefString(ByrefType, Name, ND);
5122 if (HasCopyAndDispose) {
5123 ByrefType +=
", __Block_byref_id_object_copy_";
5124 ByrefType += utostr(flag);
5125 ByrefType +=
", __Block_byref_id_object_dispose_";
5126 ByrefType += utostr(flag);
5135 const char *commaBuf = startDeclBuf;
5136 while (*commaBuf !=
',')
5138 assert((*commaBuf ==
',') &&
"RewriteByRefVar: can't find ','");
5140 startBuf = commaBuf;
5144 ByrefType +=
"};\n";
5145 unsigned nameSize = Name.size();
5150 ReplaceText(DeclLoc, endBuf-startBuf+nameSize, ByrefType);
5157 startLoc = ECE->getLParenLoc();
5162 ReplaceText(DeclLoc, endBuf-startBuf, ByrefType);
5164 const char separator = lastDecl ?
';' :
',';
5166 const char *separatorBuf = strchr(startInitializerBuf, separator);
5167 assert((*separatorBuf == separator) &&
5168 "RewriteByRefVar: can't find ';' or ','");
5172 InsertText(separatorLoc, lastDecl ?
"}" :
"};\n");
5176 void RewriteModernObjC::CollectBlockDeclRefInfo(
BlockExpr *Exp) {
5178 GetBlockDeclRefExprs(Exp->
getBody());
5179 if (BlockDeclRefs.size()) {
5181 for (
unsigned i = 0; i < BlockDeclRefs.size(); i++)
5182 if (!BlockDeclRefs[i]->getDecl()->hasAttr<BlocksAttr>()) {
5183 if (!BlockByCopyDeclsPtrSet.count(BlockDeclRefs[i]->getDecl())) {
5184 BlockByCopyDeclsPtrSet.insert(BlockDeclRefs[i]->getDecl());
5185 BlockByCopyDecls.push_back(BlockDeclRefs[i]->getDecl());
5189 for (
unsigned i = 0; i < BlockDeclRefs.size(); i++)
5190 if (BlockDeclRefs[i]->getDecl()->hasAttr<BlocksAttr>()) {
5191 if (!BlockByRefDeclsPtrSet.count(BlockDeclRefs[i]->getDecl())) {
5192 BlockByRefDeclsPtrSet.insert(BlockDeclRefs[i]->getDecl());
5193 BlockByRefDecls.push_back(BlockDeclRefs[i]->getDecl());
5197 for (
unsigned i = 0; i < BlockDeclRefs.size(); i++)
5198 if (BlockDeclRefs[i]->getDecl()->hasAttr<BlocksAttr>() ||
5199 BlockDeclRefs[i]->getType()->isObjCObjectPointerType() ||
5200 BlockDeclRefs[i]->getType()->isBlockPointerType())
5201 ImportedBlockDecls.insert(BlockDeclRefs[i]->getDecl());
5205 FunctionDecl *RewriteModernObjC::SynthBlockInitFunctionDecl(StringRef name) {
5217 Blocks.push_back(Exp);
5219 CollectBlockDeclRefInfo(Exp);
5222 int countOfInnerDecls = 0;
5223 if (!InnerBlockDeclRefs.empty()) {
5224 for (
unsigned i = 0; i < InnerBlockDeclRefs.size(); i++) {
5227 if (!VD->
hasAttr<BlocksAttr>() && !BlockByCopyDeclsPtrSet.count(VD)) {
5231 InnerDeclRefs.push_back(Exp); countOfInnerDecls++;
5232 BlockDeclRefs.push_back(Exp);
5233 BlockByCopyDeclsPtrSet.insert(VD);
5234 BlockByCopyDecls.push_back(VD);
5236 if (VD->
hasAttr<BlocksAttr>() && !BlockByRefDeclsPtrSet.count(VD)) {
5237 InnerDeclRefs.push_back(Exp); countOfInnerDecls++;
5238 BlockDeclRefs.push_back(Exp);
5239 BlockByRefDeclsPtrSet.insert(VD);
5240 BlockByRefDecls.push_back(VD);
5244 for (
unsigned i = 0; i < InnerBlockDeclRefs.size(); i++)
5245 if (InnerBlockDeclRefs[i]->getDecl()->hasAttr<BlocksAttr>() ||
5246 InnerBlockDeclRefs[i]->getType()->isObjCObjectPointerType() ||
5247 InnerBlockDeclRefs[i]->getType()->isBlockPointerType())
5248 ImportedBlockDecls.insert(InnerBlockDeclRefs[i]->getDecl());
5250 InnerDeclRefsCount.push_back(countOfInnerDecls);
5252 std::string FuncName;
5256 else if (CurMethodDef)
5258 else if (GlobalVarDecl)
5259 FuncName = std::string(GlobalVarDecl->getNameAsString());
5261 bool GlobalBlockExpr =
5264 if (GlobalBlockExpr && !GlobalVarDecl) {
5265 Diags.Report(block->
getLocation(), GlobalBlockRewriteFailedDiag);
5266 GlobalBlockExpr =
false;
5269 std::string BlockNumber = utostr(Blocks.size()-1);
5271 std::string Func =
"__" + FuncName +
"_block_func_" + BlockNumber;
5274 QualType BFT = convertFunctionTypeOfBlocks(Exp->getFunctionType());
5283 if (GlobalBlockExpr)
5287 Tag += FuncName +
"_block_impl_" + BlockNumber;
5289 FD = SynthBlockInitFunctionDecl(Tag);
5296 FD = SynthBlockInitFunctionDecl(Func);
5301 InitExprs.push_back(castExpr);
5304 std::string DescData =
"__" + FuncName +
"_block_desc_" + BlockNumber +
"_DATA";
5318 InitExprs.push_back(DescRefExpr);
5321 if (BlockDeclRefs.size()) {
5325 E = BlockByCopyDecls.end(); I !=
E; ++
I) {
5326 if (isObjCType((*I)->getType())) {
5328 FD = SynthBlockInitFunctionDecl((*I)->getName());
5337 }
else if (isTopLevelBlockPointerType((*I)->getType())) {
5338 FD = SynthBlockInitFunctionDecl((*I)->getName());
5344 FD = SynthBlockInitFunctionDecl((*I)->getName());
5355 InitExprs.push_back(Exp);
5359 E = BlockByRefDecls.end(); I !=
E; ++
I) {
5362 std::string RecName;
5363 RewriteByRefString(RecName, Name, ND,
true);
5365 +
sizeof(
"struct"));
5369 assert(RD &&
"SynthBlockInitExpr(): Can't find RecordDecl");
5372 FD = SynthBlockInitFunctionDecl((*I)->getName());
5375 bool isNestedCapturedVar =
false;
5377 for (
const auto &CI : block->
captures()) {
5378 const VarDecl *variable = CI.getVariable();
5379 if (variable == ND && CI.isNested()) {
5380 assert (CI.isByRef() &&
5381 "SynthBlockInitExpr - captured block variable is not byref");
5382 isNestedCapturedVar =
true;
5388 if (!isNestedCapturedVar)
5392 Exp = NoTypeInfoCStyleCastExpr(
Context, castT, CK_BitCast, Exp);
5393 InitExprs.push_back(Exp);
5396 if (ImportedBlockDecls.size()) {
5403 InitExprs.push_back(FlagExp);
5408 if (GlobalBlockExpr) {
5409 assert (!GlobalConstructionExp &&
5410 "SynthBlockInitExpr - GlobalConstructionExp must be null");
5411 GlobalConstructionExp = NewRep;
5418 NewRep = NoTypeInfoCStyleCastExpr(
Context, FType, CK_BitCast,
5424 BlockDeclRefs.clear();
5425 BlockByRefDecls.clear();
5426 BlockByRefDeclsPtrSet.clear();
5427 BlockByCopyDecls.clear();
5428 BlockByCopyDeclsPtrSet.clear();
5429 ImportedBlockDecls.clear();
5433 bool RewriteModernObjC::IsDeclStmtInForeachHeader(
DeclStmt *DS) {
5435 dyn_cast<ObjCForCollectionStmt>(Stmts.back()))
5436 return CS->getElement() == DS;
5444 Stmt *RewriteModernObjC::RewriteFunctionBodyOrGlobalInitializer(
Stmt *S) {
5445 if (isa<SwitchStmt>(S) || isa<WhileStmt>(S) ||
5446 isa<DoStmt>(S) || isa<ForStmt>(S))
5448 else if (isa<ObjCForCollectionStmt>(S)) {
5450 ObjCBcLabelNo.push_back(++BcLabelCount);
5457 return RewritePropertyOrImplicitSetter(PseudoOp);
5459 return RewritePropertyOrImplicitGetter(PseudoOp);
5461 }
else if (
ObjCIvarRefExpr *IvarRefExpr = dyn_cast<ObjCIvarRefExpr>(S)) {
5462 return RewriteObjCIvarRefExpr(IvarRefExpr);
5464 else if (isa<OpaqueValueExpr>(S))
5465 S = cast<OpaqueValueExpr>(
S)->getSourceExpr();
5472 Stmt *newStmt = RewriteFunctionBodyOrGlobalInitializer(childStmt);
5474 childStmt = newStmt;
5478 if (
BlockExpr *BE = dyn_cast<BlockExpr>(S)) {
5480 llvm::SmallPtrSet<const DeclContext *, 8> InnerContexts;
5481 InnerContexts.insert(BE->getBlockDecl());
5482 ImportedLocalExternalDecls.clear();
5483 GetInnerBlockDeclRefExprs(BE->getBody(),
5484 InnerBlockDeclRefs, InnerContexts);
5486 Stmt *SaveCurrentBody = CurrentBody;
5487 CurrentBody = BE->getBody();
5488 PropParentMap =
nullptr;
5494 bool saveDisableReplaceStmt = DisableReplaceStmt;
5495 DisableReplaceStmt =
false;
5496 RewriteFunctionBodyOrGlobalInitializer(BE->getBody());
5497 DisableReplaceStmt = saveDisableReplaceStmt;
5498 CurrentBody = SaveCurrentBody;
5499 PropParentMap =
nullptr;
5500 ImportedLocalExternalDecls.clear();
5502 std::string Str = Rewrite.getRewrittenText(BE->getSourceRange());
5503 RewrittenBlockExprs[BE] = Str;
5505 Stmt *blockTranscribed = SynthBlockInitExpr(BE, InnerBlockDeclRefs);
5508 ReplaceStmt(S, blockTranscribed);
5509 return blockTranscribed;
5513 return RewriteAtEncode(AtEncode);
5516 return RewriteAtSelector(AtSelector);
5519 return RewriteObjCStringLiteral(AtString);
5522 return RewriteObjCBoolLiteralExpr(BoolLitExpr);
5525 return RewriteObjCBoxedExpr(BoxedExpr);
5528 return RewriteObjCArrayLiteralExpr(ArrayLitExpr);
5531 dyn_cast<ObjCDictionaryLiteral>(S))
5532 return RewriteObjCDictionaryLiteralExpr(DictionaryLitExpr);
5543 std::string messString;
5544 messString +=
"// ";
5545 messString.append(startBuf, endBuf-startBuf+1);
5554 return RewriteMessageExpr(MessExpr);
5558 dyn_cast<ObjCAutoreleasePoolStmt>(S)) {
5559 return RewriteObjCAutoreleasePoolStmt(StmtAutoRelease);
5563 return RewriteObjCTryStmt(StmtTry);
5566 return RewriteObjCSynchronizedStmt(StmtTry);
5569 return RewriteObjCThrowStmt(StmtThrow);
5572 return RewriteObjCProtocolExpr(ProtocolExp);
5575 dyn_cast<ObjCForCollectionStmt>(S))
5576 return RewriteObjCForCollectionStmt(StmtForCollection,
5579 dyn_cast<BreakStmt>(S))
5580 return RewriteBreakStmt(StmtBreakStmt);
5582 dyn_cast<ContinueStmt>(S))
5583 return RewriteContinueStmt(StmtContinueStmt);
5587 if (
DeclStmt *DS = dyn_cast<DeclStmt>(S)) {
5597 if (Stmts.empty() || !IsDeclStmtInForeachHeader(DS))
5598 RewriteObjCQualifiedInterfaceTypes(*DS->
decl_begin());
5604 if (
ValueDecl *ND = dyn_cast<ValueDecl>(SD)) {
5605 if (isTopLevelBlockPointerType(ND->
getType()))
5606 RewriteBlockPointerDecl(ND);
5608 CheckFunctionPointerDecl(ND->
getType(), ND);
5609 if (
VarDecl *VD = dyn_cast<VarDecl>(SD)) {
5610 if (VD->
hasAttr<BlocksAttr>()) {
5611 static unsigned uniqueByrefDeclCount = 0;
5612 assert(!BlockByRefDeclNo.count(ND) &&
5613 "RewriteFunctionBodyOrGlobalInitializer: Duplicate byref decl");
5614 BlockByRefDeclNo[ND] = uniqueByrefDeclCount++;
5615 RewriteByRefVar(VD, (DI == DS->
decl_begin()), ((DI+1) == DE));
5618 RewriteTypeOfDecl(VD);
5622 if (isTopLevelBlockPointerType(TD->getUnderlyingType()))
5623 RewriteBlockPointerDecl(TD);
5624 else if (TD->getUnderlyingType()->isFunctionPointerType())
5625 CheckFunctionPointerDecl(TD->getUnderlyingType(), TD);
5631 RewriteObjCQualifiedInterfaceTypes(CE);
5633 if (isa<SwitchStmt>(S) || isa<WhileStmt>(
S) ||
5634 isa<DoStmt>(S) || isa<ForStmt>(
S)) {
5635 assert(!Stmts.empty() &&
"Statement stack is empty");
5636 assert ((isa<SwitchStmt>(Stmts.back()) || isa<WhileStmt>(Stmts.back()) ||
5637 isa<DoStmt>(Stmts.back()) || isa<ForStmt>(Stmts.back()))
5638 &&
"Statement stack mismatch");
5642 if (
DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(S)) {
5644 if (VD->
hasAttr<BlocksAttr>())
5645 return RewriteBlockDeclRefExpr(DRE);
5647 return RewriteLocalVariableExternalStorage(DRE);
5650 if (
CallExpr *CE = dyn_cast<CallExpr>(S)) {
5653 ReplaceStmt(S, BlockCall);
5658 RewriteCastExpr(CE);
5661 RewriteImplicitCastObjCExpr(ICE);
5671 llvm::raw_string_ostream Buf(SStr);
5673 const std::string &Str = Buf.str();
5675 printf(
"CAST = %s\n", &Str[0]);
5685 void RewriteModernObjC::RewriteRecordBody(
RecordDecl *RD) {
5686 for (
auto *FD : RD->
fields()) {
5687 if (isTopLevelBlockPointerType(FD->
getType()))
5688 RewriteBlockPointerDecl(FD);
5691 RewriteObjCQualifiedInterfaceTypes(FD);
5697 void RewriteModernObjC::HandleDeclInMainFile(
Decl *D) {
5699 case Decl::Function: {
5707 RewriteBlocksInFunctionProtoType(FD->
getType(), FD);
5714 CurFunctionDef = FD;
5717 cast_or_null<CompoundStmt>(RewriteFunctionBodyOrGlobalInitializer(Body));
5719 CurrentBody =
nullptr;
5720 if (PropParentMap) {
5721 delete PropParentMap;
5722 PropParentMap =
nullptr;
5726 InsertBlockLiteralsWithinFunction(FD);
5727 RewriteLineDirective(D);
5728 CurFunctionDef =
nullptr;
5732 case Decl::ObjCMethod: {
5738 cast_or_null<CompoundStmt>(RewriteFunctionBodyOrGlobalInitializer(Body));
5740 CurrentBody =
nullptr;
5741 if (PropParentMap) {
5742 delete PropParentMap;
5743 PropParentMap =
nullptr;
5745 InsertBlockLiteralsWithinMethod(MD);
5746 RewriteLineDirective(D);
5747 CurMethodDef =
nullptr;
5751 case Decl::ObjCImplementation: {
5753 ClassImplementation.push_back(CI);
5756 case Decl::ObjCCategoryImpl: {
5758 CategoryImplementation.push_back(CI);
5762 VarDecl *VD = cast<VarDecl>(D);
5763 RewriteObjCQualifiedInterfaceTypes(VD);
5764 if (isTopLevelBlockPointerType(VD->
getType()))
5765 RewriteBlockPointerDecl(VD);
5767 CheckFunctionPointerDecl(VD->
getType(), VD);
5770 RewriteCastExpr(CE);
5776 RewriteRecordBody(RD);
5781 RewriteFunctionBodyOrGlobalInitializer(VD->
getInit());
5782 CurrentBody =
nullptr;
5783 if (PropParentMap) {
5784 delete PropParentMap;
5785 PropParentMap =
nullptr;
5788 GlobalVarDecl =
nullptr;
5792 RewriteCastExpr(CE);
5797 case Decl::TypeAlias:
5798 case Decl::Typedef: {
5800 if (isTopLevelBlockPointerType(TD->getUnderlyingType()))
5801 RewriteBlockPointerDecl(TD);
5802 else if (TD->getUnderlyingType()->isFunctionPointerType())
5803 CheckFunctionPointerDecl(TD->getUnderlyingType(), TD);
5805 RewriteObjCQualifiedInterfaceTypes(TD);
5809 case Decl::CXXRecord:
5810 case Decl::Record: {
5813 RewriteRecordBody(RD);
5827 std::string &Result) {
5830 Result +=
"static ";
5831 Result +=
"struct _protocol_t *";
5832 Result +=
"_OBJC_PROTOCOL_REFERENCE_$_";
5839 void RewriteModernObjC::HandleTranslationUnit(
ASTContext &
C) {
5840 if (Diags.hasErrorOccurred())
5845 for (
unsigned i = 0, e = FunctionDefinitionsSeen.size(); i < e; i++) {
5850 HandleTopLevelSingleDecl(FDecl);
5856 RewriteObjCProtocolMetaData(ProtDecl, Preamble);
5862 if (ClassImplementation.size() || CategoryImplementation.size())
5863 RewriteImplementations();
5865 for (
unsigned i = 0, e = ObjCInterfacesSeen.size(); i < e; i++) {
5871 RewriteInterfaceDecl(CDecl);
5877 Rewrite.getRewriteBufferFor(MainFileID)) {
5879 *OutFile << std::string(RewriteBuf->begin(), RewriteBuf->end());
5881 llvm::errs() <<
"No changes\n";
5884 if (ClassImplementation.size() || CategoryImplementation.size() ||
5885 ProtocolExprDecls.size()) {
5887 std::string ResultStr;
5888 RewriteMetaDataIntoBuffer(ResultStr);
5890 *OutFile << ResultStr;
5894 std::string ResultStr;
5895 WriteImageInfo(ResultStr);
5896 *OutFile << ResultStr;
5901 void RewriteModernObjC::Initialize(
ASTContext &context) {
5902 InitializeCommon(context);
5904 Preamble +=
"#ifndef __OBJC2__\n";
5905 Preamble +=
"#define __OBJC2__\n";
5906 Preamble +=
"#endif\n";
5911 Preamble =
"#pragma once\n";
5912 Preamble +=
"struct objc_selector; struct objc_class;\n";
5913 Preamble +=
"struct __rw_objc_super { \n\tstruct objc_object *object; ";
5914 Preamble +=
"\n\tstruct objc_object *superClass; ";
5916 Preamble +=
"\n\t__rw_objc_super(struct objc_object *o, struct objc_object *s) ";
5917 Preamble +=
": object(o), superClass(s) {} ";
5918 Preamble +=
"\n};\n";
5920 if (LangOpts.MicrosoftExt) {
5923 Preamble +=
"\n#pragma section(\".objc_classlist$B\", long, read, write)\n";
5924 Preamble +=
"#pragma section(\".objc_catlist$B\", long, read, write)\n";
5925 Preamble +=
"#pragma section(\".objc_imageinfo$B\", long, read, write)\n";
5926 Preamble +=
"#pragma section(\".objc_nlclslist$B\", long, read, write)\n";
5927 Preamble +=
"#pragma section(\".objc_nlcatlist$B\", long, read, write)\n";
5929 Preamble +=
"#pragma section(\".cat_cls_meth$B\", long, read, write)\n";
5930 Preamble +=
"#pragma section(\".inst_meth$B\", long, read, write)\n";
5931 Preamble +=
"#pragma section(\".cls_meth$B\", long, read, write)\n";
5932 Preamble +=
"#pragma section(\".objc_ivar$B\", long, read, write)\n";
5936 Preamble +=
"#pragma section(\".objc_selrefs$B\", long, read, write)\n";
5937 Preamble +=
"#pragma section(\".objc_classrefs$B\", long, read, write)\n";
5938 Preamble +=
"#pragma section(\".objc_superrefs$B\", long, read, write)\n";
5941 Preamble +=
"#ifndef _REWRITER_typedef_Protocol\n";
5942 Preamble +=
"typedef struct objc_object Protocol;\n";
5943 Preamble +=
"#define _REWRITER_typedef_Protocol\n";
5944 Preamble +=
"#endif\n";
5945 if (LangOpts.MicrosoftExt) {
5946 Preamble +=
"#define __OBJC_RW_DLLIMPORT extern \"C\" __declspec(dllimport)\n";
5947 Preamble +=
"#define __OBJC_RW_STATICIMPORT extern \"C\"\n";
5950 Preamble +=
"#define __OBJC_RW_DLLIMPORT extern\n";
5952 Preamble +=
"__OBJC_RW_DLLIMPORT void objc_msgSend(void);\n";
5953 Preamble +=
"__OBJC_RW_DLLIMPORT void objc_msgSendSuper(void);\n";
5954 Preamble +=
"__OBJC_RW_DLLIMPORT void objc_msgSend_stret(void);\n";
5955 Preamble +=
"__OBJC_RW_DLLIMPORT void objc_msgSendSuper_stret(void);\n";
5956 Preamble +=
"__OBJC_RW_DLLIMPORT void objc_msgSend_fpret(void);\n";
5958 Preamble +=
"__OBJC_RW_DLLIMPORT struct objc_class *objc_getClass";
5959 Preamble +=
"(const char *);\n";
5960 Preamble +=
"__OBJC_RW_DLLIMPORT struct objc_class *class_getSuperclass";
5961 Preamble +=
"(struct objc_class *);\n";
5962 Preamble +=
"__OBJC_RW_DLLIMPORT struct objc_class *objc_getMetaClass";
5963 Preamble +=
"(const char *);\n";
5964 Preamble +=
"__OBJC_RW_DLLIMPORT void objc_exception_throw( struct objc_object *);\n";
5966 Preamble +=
"__OBJC_RW_DLLIMPORT int objc_sync_enter( struct objc_object *);\n";
5967 Preamble +=
"__OBJC_RW_DLLIMPORT int objc_sync_exit( struct objc_object *);\n";
5968 Preamble +=
"__OBJC_RW_DLLIMPORT Protocol *objc_getProtocol(const char *);\n";
5969 Preamble +=
"#ifdef _WIN64\n";
5970 Preamble +=
"typedef unsigned long long _WIN_NSUInteger;\n";
5971 Preamble +=
"#else\n";
5972 Preamble +=
"typedef unsigned int _WIN_NSUInteger;\n";
5973 Preamble +=
"#endif\n";
5974 Preamble +=
"#ifndef __FASTENUMERATIONSTATE\n";
5975 Preamble +=
"struct __objcFastEnumerationState {\n\t";
5976 Preamble +=
"unsigned long state;\n\t";
5977 Preamble +=
"void **itemsPtr;\n\t";
5978 Preamble +=
"unsigned long *mutationsPtr;\n\t";
5979 Preamble +=
"unsigned long extra[5];\n};\n";
5980 Preamble +=
"__OBJC_RW_DLLIMPORT void objc_enumerationMutation(struct objc_object *);\n";
5981 Preamble +=
"#define __FASTENUMERATIONSTATE\n";
5982 Preamble +=
"#endif\n";
5983 Preamble +=
"#ifndef __NSCONSTANTSTRINGIMPL\n";
5984 Preamble +=
"struct __NSConstantStringImpl {\n";
5985 Preamble +=
" int *isa;\n";
5986 Preamble +=
" int flags;\n";
5987 Preamble +=
" char *str;\n";
5988 Preamble +=
"#if _WIN64\n";
5989 Preamble +=
" long long length;\n";
5990 Preamble +=
"#else\n";
5991 Preamble +=
" long length;\n";
5992 Preamble +=
"#endif\n";
5994 Preamble +=
"#ifdef CF_EXPORT_CONSTANT_STRING\n";
5995 Preamble +=
"extern \"C\" __declspec(dllexport) int __CFConstantStringClassReference[];\n";
5996 Preamble +=
"#else\n";
5997 Preamble +=
"__OBJC_RW_DLLIMPORT int __CFConstantStringClassReference[];\n";
5998 Preamble +=
"#endif\n";
5999 Preamble +=
"#define __NSCONSTANTSTRINGIMPL\n";
6000 Preamble +=
"#endif\n";
6002 Preamble +=
"#ifndef BLOCK_IMPL\n";
6003 Preamble +=
"#define BLOCK_IMPL\n";
6004 Preamble +=
"struct __block_impl {\n";
6005 Preamble +=
" void *isa;\n";
6006 Preamble +=
" int Flags;\n";
6007 Preamble +=
" int Reserved;\n";
6008 Preamble +=
" void *FuncPtr;\n";
6010 Preamble +=
"// Runtime copy/destroy helper functions (from Block_private.h)\n";
6011 Preamble +=
"#ifdef __OBJC_EXPORT_BLOCKS\n";
6012 Preamble +=
"extern \"C\" __declspec(dllexport) "
6013 "void _Block_object_assign(void *, const void *, const int);\n";
6014 Preamble +=
"extern \"C\" __declspec(dllexport) void _Block_object_dispose(const void *, const int);\n";
6015 Preamble +=
"extern \"C\" __declspec(dllexport) void *_NSConcreteGlobalBlock[32];\n";
6016 Preamble +=
"extern \"C\" __declspec(dllexport) void *_NSConcreteStackBlock[32];\n";
6017 Preamble +=
"#else\n";
6018 Preamble +=
"__OBJC_RW_DLLIMPORT void _Block_object_assign(void *, const void *, const int);\n";
6019 Preamble +=
"__OBJC_RW_DLLIMPORT void _Block_object_dispose(const void *, const int);\n";
6020 Preamble +=
"__OBJC_RW_DLLIMPORT void *_NSConcreteGlobalBlock[32];\n";
6021 Preamble +=
"__OBJC_RW_DLLIMPORT void *_NSConcreteStackBlock[32];\n";
6022 Preamble +=
"#endif\n";
6023 Preamble +=
"#endif\n";
6024 if (LangOpts.MicrosoftExt) {
6025 Preamble +=
"#undef __OBJC_RW_DLLIMPORT\n";
6026 Preamble +=
"#undef __OBJC_RW_STATICIMPORT\n";
6027 Preamble +=
"#ifndef KEEP_ATTRIBUTES\n";
6028 Preamble +=
"#define __attribute__(X)\n";
6029 Preamble +=
"#endif\n";
6030 Preamble +=
"#ifndef __weak\n";
6031 Preamble +=
"#define __weak\n";
6032 Preamble +=
"#endif\n";
6033 Preamble +=
"#ifndef __block\n";
6034 Preamble +=
"#define __block\n";
6035 Preamble +=
"#endif\n";
6038 Preamble +=
"#define __block\n";
6039 Preamble +=
"#define __weak\n";
6043 Preamble +=
"\n#include <stdarg.h>\n";
6044 Preamble +=
"struct __NSContainer_literal {\n";
6045 Preamble +=
" void * *arr;\n";
6046 Preamble +=
" __NSContainer_literal (unsigned int count, ...) {\n";
6047 Preamble +=
"\tva_list marker;\n";
6048 Preamble +=
"\tva_start(marker, count);\n";
6049 Preamble +=
"\tarr = new void *[count];\n";
6050 Preamble +=
"\tfor (unsigned i = 0; i < count; i++)\n";
6051 Preamble +=
"\t arr[i] = va_arg(marker, void *);\n";
6052 Preamble +=
"\tva_end( marker );\n";
6053 Preamble +=
" };\n";
6054 Preamble +=
" ~__NSContainer_literal() {\n";
6055 Preamble +=
"\tdelete[] arr;\n";
6060 Preamble +=
"extern \"C\" __declspec(dllimport) void * objc_autoreleasePoolPush(void);\n";
6061 Preamble +=
"extern \"C\" __declspec(dllimport) void objc_autoreleasePoolPop(void *);\n\n";
6062 Preamble +=
"struct __AtAutoreleasePool {\n";
6063 Preamble +=
" __AtAutoreleasePool() {atautoreleasepoolobj = objc_autoreleasePoolPush();}\n";
6064 Preamble +=
" ~__AtAutoreleasePool() {objc_autoreleasePoolPop(atautoreleasepoolobj);}\n";
6065 Preamble +=
" void * atautoreleasepoolobj;\n";
6070 Preamble +=
"\n#define __OFFSETOFIVAR__(TYPE, MEMBER) ((long long) &((TYPE *)0)->MEMBER)\n";
6075 void RewriteModernObjC::RewriteIvarOffsetComputation(
ObjCIvarDecl *ivar,
6076 std::string &Result) {
6077 Result +=
"__OFFSETOFIVAR__(struct ";
6079 if (LangOpts.MicrosoftExt)
6083 ObjCIvarBitfieldGroupDecl(ivar, Result);
6192 static bool meta_data_declared =
false;
6193 if (meta_data_declared)
6196 Result +=
"\nstruct _prop_t {\n";
6197 Result +=
"\tconst char *name;\n";
6198 Result +=
"\tconst char *attributes;\n";
6201 Result +=
"\nstruct _protocol_t;\n";
6203 Result +=
"\nstruct _objc_method {\n";
6204 Result +=
"\tstruct objc_selector * _cmd;\n";
6205 Result +=
"\tconst char *method_type;\n";
6206 Result +=
"\tvoid *_imp;\n";
6209 Result +=
"\nstruct _protocol_t {\n";
6210 Result +=
"\tvoid * isa; // NULL\n";
6211 Result +=
"\tconst char *protocol_name;\n";
6212 Result +=
"\tconst struct _protocol_list_t * protocol_list; // super protocols\n";
6213 Result +=
"\tconst struct method_list_t *instance_methods;\n";
6214 Result +=
"\tconst struct method_list_t *class_methods;\n";
6215 Result +=
"\tconst struct method_list_t *optionalInstanceMethods;\n";
6216 Result +=
"\tconst struct method_list_t *optionalClassMethods;\n";
6217 Result +=
"\tconst struct _prop_list_t * properties;\n";
6218 Result +=
"\tconst unsigned int size; // sizeof(struct _protocol_t)\n";
6219 Result +=
"\tconst unsigned int flags; // = 0\n";
6220 Result +=
"\tconst char ** extendedMethodTypes;\n";
6223 Result +=
"\nstruct _ivar_t {\n";
6224 Result +=
"\tunsigned long int *offset; // pointer to ivar offset location\n";
6225 Result +=
"\tconst char *name;\n";
6226 Result +=
"\tconst char *type;\n";
6227 Result +=
"\tunsigned int alignment;\n";
6228 Result +=
"\tunsigned int size;\n";
6231 Result +=
"\nstruct _class_ro_t {\n";
6232 Result +=
"\tunsigned int flags;\n";
6233 Result +=
"\tunsigned int instanceStart;\n";
6234 Result +=
"\tunsigned int instanceSize;\n";
6236 if (Triple.getArch() == llvm::Triple::x86_64)
6237 Result +=
"\tunsigned int reserved;\n";
6238 Result +=
"\tconst unsigned char *ivarLayout;\n";
6239 Result +=
"\tconst char *name;\n";
6240 Result +=
"\tconst struct _method_list_t *baseMethods;\n";
6241 Result +=
"\tconst struct _objc_protocol_list *baseProtocols;\n";
6242 Result +=
"\tconst struct _ivar_list_t *ivars;\n";
6243 Result +=
"\tconst unsigned char *weakIvarLayout;\n";
6244 Result +=
"\tconst struct _prop_list_t *properties;\n";
6247 Result +=
"\nstruct _class_t {\n";
6248 Result +=
"\tstruct _class_t *isa;\n";
6249 Result +=
"\tstruct _class_t *superclass;\n";
6250 Result +=
"\tvoid *cache;\n";
6251 Result +=
"\tvoid *vtable;\n";
6252 Result +=
"\tstruct _class_ro_t *ro;\n";
6255 Result +=
"\nstruct _category_t {\n";
6256 Result +=
"\tconst char *name;\n";
6257 Result +=
"\tstruct _class_t *cls;\n";
6258 Result +=
"\tconst struct _method_list_t *instance_methods;\n";
6259 Result +=
"\tconst struct _method_list_t *class_methods;\n";
6260 Result +=
"\tconst struct _protocol_list_t *protocols;\n";
6261 Result +=
"\tconst struct _prop_list_t *properties;\n";
6264 Result +=
"extern \"C\" __declspec(dllimport) struct objc_cache _objc_empty_cache;\n";
6265 Result +=
"#pragma warning(disable:4273)\n";
6266 meta_data_declared =
true;
6270 long super_protocol_count) {
6271 Result +=
"struct /*_protocol_list_t*/"; Result +=
" {\n";
6272 Result +=
"\tlong protocol_count; // Note, this is 32/64 bit\n";
6273 Result +=
"\tstruct _protocol_t *super_protocols[";
6274 Result += utostr(super_protocol_count); Result +=
"];\n";
6279 unsigned int method_count) {
6280 Result +=
"struct /*_method_list_t*/"; Result +=
" {\n";
6281 Result +=
"\tunsigned int entsize; // sizeof(struct _objc_method)\n";
6282 Result +=
"\tunsigned int method_count;\n";
6283 Result +=
"\tstruct _objc_method method_list[";
6284 Result += utostr(method_count); Result +=
"];\n";
6289 unsigned int property_count) {
6290 Result +=
"struct /*_prop_list_t*/"; Result +=
" {\n";
6291 Result +=
"\tunsigned int entsize; // sizeof(struct _prop_t)\n";
6292 Result +=
"\tunsigned int count_of_properties;\n";
6293 Result +=
"\tstruct _prop_t prop_list[";
6294 Result += utostr(property_count); Result +=
"];\n";
6299 unsigned int ivar_count) {
6300 Result +=
"struct /*_ivar_list_t*/"; Result +=
" {\n";
6301 Result +=
"\tunsigned int entsize; // sizeof(struct _prop_t)\n";
6302 Result +=
"\tunsigned int count;\n";
6303 Result +=
"\tstruct _ivar_t ivar_list[";
6304 Result += utostr(ivar_count); Result +=
"];\n";
6311 StringRef ProtocolName) {
6312 if (SuperProtocols.size() > 0) {
6313 Result +=
"\nstatic ";
6315 Result +=
" "; Result += VarName;
6316 Result += ProtocolName;
6317 Result +=
" __attribute__ ((used, section (\"__DATA,__objc_const\"))) = {\n";
6318 Result +=
"\t"; Result += utostr(SuperProtocols.size()); Result +=
",\n";
6319 for (
unsigned i = 0, e = SuperProtocols.size(); i < e; i++) {
6321 Result +=
"\t&"; Result +=
"_OBJC_PROTOCOL_";
6335 StringRef TopLevelDeclName,
6337 if (Methods.size() > 0) {
6338 Result +=
"\nstatic ";
6340 Result +=
" "; Result += VarName;
6341 Result += TopLevelDeclName;
6342 Result +=
" __attribute__ ((used, section (\"__DATA,__objc_const\"))) = {\n";
6343 Result +=
"\t"; Result +=
"sizeof(_objc_method)"; Result +=
",\n";
6344 Result +=
"\t"; Result += utostr(Methods.size()); Result +=
",\n";
6345 for (
unsigned i = 0, e = Methods.size(); i < e; i++) {
6348 Result +=
"\t{{(struct objc_selector *)\"";
6350 Result +=
"\t{(struct objc_selector *)\"";
6351 Result += (MD)->getSelector().getAsString(); Result +=
"\"";
6354 Result +=
"\""; Result += MethodTypeString; Result +=
"\"";
6359 Result +=
"(void *)";
6360 Result += RewriteObj.MethodInternalNames[MD];
6374 const Decl *Container,
6376 StringRef ProtocolName) {
6377 if (Properties.size() > 0) {
6378 Result +=
"\nstatic ";
6380 Result +=
" "; Result += VarName;
6381 Result += ProtocolName;
6382 Result +=
" __attribute__ ((used, section (\"__DATA,__objc_const\"))) = {\n";
6383 Result +=
"\t"; Result +=
"sizeof(_prop_t)"; Result +=
",\n";
6384 Result +=
"\t"; Result += utostr(Properties.size()); Result +=
",\n";
6385 for (
unsigned i = 0, e = Properties.size(); i < e; i++) {
6391 Result += PropDecl->
getName(); Result +=
"\",";
6392 std::string PropertyTypeString =
6394 std::string QuotePropertyTypeString;
6395 RewriteObj.QuoteDoublequotes(PropertyTypeString, QuotePropertyTypeString);
6396 Result +=
"\""; Result += QuotePropertyTypeString; Result +=
"\"";
6422 const std::string &InstanceStart,
6423 const std::string &InstanceSize,
6429 StringRef ClassName) {
6430 Result +=
"\nstatic struct _class_ro_t ";
6431 Result += VarName; Result += ClassName;
6432 Result +=
" __attribute__ ((used, section (\"__DATA,__objc_const\"))) = {\n";
6434 Result += llvm::utostr(flags); Result +=
", ";
6435 Result += InstanceStart; Result +=
", ";
6436 Result += InstanceSize; Result +=
", \n";
6439 if (Triple.getArch() == llvm::Triple::x86_64)
6441 Result +=
"(unsigned int)0, \n\t";
6443 Result +=
"0, \n\t";
6444 Result +=
"\""; Result += ClassName; Result +=
"\",\n\t";
6445 bool metaclass = ((flags &
CLS_META) != 0);
6446 if (baseMethods.size() > 0) {
6447 Result +=
"(const struct _method_list_t *)&";
6449 Result +=
"_OBJC_$_CLASS_METHODS_";
6451 Result +=
"_OBJC_$_INSTANCE_METHODS_";
6452 Result += ClassName;
6456 Result +=
"0, \n\t";
6458 if (!metaclass && baseProtocols.size() > 0) {
6459 Result +=
"(const struct _objc_protocol_list *)&";
6460 Result +=
"_OBJC_CLASS_PROTOCOLS_$_"; Result += ClassName;
6464 Result +=
"0, \n\t";
6466 if (!metaclass && ivars.size() > 0) {
6467 Result +=
"(const struct _ivar_list_t *)&";
6468 Result +=
"_OBJC_$_INSTANCE_VARIABLES_"; Result += ClassName;
6472 Result +=
"0, \n\t";
6475 Result +=
"0, \n\t";
6476 if (!metaclass && Properties.size() > 0) {
6477 Result +=
"(const struct _prop_list_t *)&";
6478 Result +=
"_OBJC_$_PROP_LIST_"; Result += ClassName;
6501 if (metaclass && rootClass) {
6504 Result +=
"extern \"C\" ";
6506 Result +=
"__declspec(dllexport) ";
6508 Result +=
"__declspec(dllimport) ";
6510 Result +=
"struct _class_t OBJC_CLASS_$_";
6518 Result +=
"extern \"C\" ";
6520 Result +=
"__declspec(dllexport) ";
6522 Result +=
"__declspec(dllimport) ";
6524 Result +=
"struct _class_t ";
6529 if (metaclass && RootClass != SuperClass) {
6530 Result +=
"extern \"C\" ";
6532 Result +=
"__declspec(dllexport) ";
6534 Result +=
"__declspec(dllimport) ";
6536 Result +=
"struct _class_t ";
6543 Result +=
"\nextern \"C\" __declspec(dllexport) struct _class_t ";
6545 Result +=
" __attribute__ ((used, section (\"__DATA,__objc_data\"))) = {\n";
6549 Result +=
"0, // &"; Result += VarName;
6552 Result +=
"0, // &"; Result += VarName;
6557 Result +=
"0, // &"; Result += VarName;
6565 Result +=
"0, // &OBJC_METACLASS_$_";
6569 Result +=
"0, // &"; Result += VarName;
6576 Result +=
"0, // (void *)&_objc_empty_cache,\n\t";
6577 Result +=
"0, // unused, was (void *)&_objc_empty_vtable,\n\t";
6579 Result +=
"&_OBJC_METACLASS_RO_$_";
6581 Result +=
"&_OBJC_CLASS_RO_$_";
6583 Result +=
",\n};\n";
6593 Result +=
"static void OBJC_CLASS_SETUP_$_";
6595 Result +=
"(void ) {\n";
6597 Result +=
".isa = "; Result +=
"&OBJC_METACLASS_$_";
6601 Result +=
".superclass = ";
6603 Result +=
"&OBJC_CLASS_$_";
6605 Result +=
"&OBJC_METACLASS_$_";
6610 Result +=
".cache = "; Result +=
"&_objc_empty_cache"; Result +=
";\n";
6613 Result +=
".isa = "; Result +=
"&OBJC_METACLASS_$_";
6618 Result +=
".superclass = "; Result +=
"&OBJC_CLASS_$_";
6623 Result +=
".cache = "; Result +=
"&_objc_empty_cache"; Result +=
";\n";
6628 std::string &Result,
6635 StringRef CatName = CatDecl->
getName();
6636 StringRef ClassName = ClassDecl->
getName();
6640 Result +=
"extern \"C\" ";
6642 Result +=
"__declspec(dllexport) ";
6644 Result +=
"__declspec(dllimport) ";
6646 Result +=
"struct _class_t ";
6647 Result +=
"OBJC_CLASS_$_"; Result += ClassName;
6650 Result +=
"\nstatic struct _category_t ";
6651 Result +=
"_OBJC_$_CATEGORY_";
6652 Result += ClassName; Result +=
"_$_"; Result += CatName;
6653 Result +=
" __attribute__ ((used, section (\"__DATA,__objc_const\"))) = \n";
6655 Result +=
"\t\""; Result += ClassName; Result +=
"\",\n";
6656 Result +=
"\t0, // &"; Result +=
"OBJC_CLASS_$_"; Result += ClassName;
6658 if (InstanceMethods.size() > 0) {
6659 Result +=
"\t(const struct _method_list_t *)&";
6660 Result +=
"_OBJC_$_CATEGORY_INSTANCE_METHODS_";
6661 Result += ClassName; Result +=
"_$_"; Result += CatName;
6667 if (ClassMethods.size() > 0) {
6668 Result +=
"\t(const struct _method_list_t *)&";
6669 Result +=
"_OBJC_$_CATEGORY_CLASS_METHODS_";
6670 Result += ClassName; Result +=
"_$_"; Result += CatName;
6676 if (RefedProtocols.size() > 0) {
6677 Result +=
"\t(const struct _protocol_list_t *)&";
6678 Result +=
"_OBJC_CATEGORY_PROTOCOLS_$_";
6679 Result += ClassName; Result +=
"_$_"; Result += CatName;
6685 if (ClassProperties.size() > 0) {
6686 Result +=
"\t(const struct _prop_list_t *)&"; Result +=
"_OBJC_$_PROP_LIST_";
6687 Result += ClassName; Result +=
"_$_"; Result += CatName;
6696 Result +=
"static void OBJC_CATEGORY_SETUP_$_";
6700 Result +=
"(void ) {\n";
6701 Result +=
"\t_OBJC_$_CATEGORY_";
6705 Result +=
".cls = "; Result +=
"&OBJC_CLASS_$_"; Result += ClassName;
6713 StringRef ProtocolName) {
6714 if (Methods.size() == 0)
6717 Result +=
"\nstatic const char *";
6718 Result += VarName; Result += ProtocolName;
6719 Result +=
" [] __attribute__ ((used, section (\"__DATA,__objc_const\"))) = \n";
6721 for (
unsigned i = 0, e = Methods.size(); i < e; i++) {
6723 std::string MethodTypeString =
6725 std::string QuoteMethodTypeString;
6726 RewriteObj.QuoteDoublequotes(MethodTypeString, QuoteMethodTypeString);
6727 Result +=
"\t\""; Result += QuoteMethodTypeString; Result +=
"\"";
6738 std::string &Result,
6753 for (
unsigned i =0, e = Ivars.size(); i < e; i++) {
6756 Result +=
"__declspec(allocate(\".objc_ivar$B\")) ";
6761 Result +=
"extern \"C\" unsigned long int ";
6763 Result +=
"extern \"C\" __declspec(dllexport) unsigned long int ";
6764 if (Ivars[i]->isBitField())
6765 RewriteObj.ObjCIvarBitfieldGroupOffset(IvarDecl, Result);
6768 Result +=
" __attribute__ ((used, section (\"__DATA,__objc_ivar\")))";
6770 RewriteObj.RewriteIvarOffsetComputation(IvarDecl, Result);
6772 if (Ivars[i]->isBitField()) {
6784 if (OriginalIvars.size() > 0) {
6790 for (
unsigned i = 0, e = OriginalIvars.size(); i < e; i++) {
6791 if (OriginalIvars[i]->isBitField()) {
6792 Ivars.push_back(OriginalIvars[i]);
6797 Ivars.push_back(OriginalIvars[i]);
6800 Result +=
"\nstatic ";
6802 Result +=
" "; Result += VarName;
6804 Result +=
" __attribute__ ((used, section (\"__DATA,__objc_const\"))) = {\n";
6805 Result +=
"\t"; Result +=
"sizeof(_ivar_t)"; Result +=
",\n";
6806 Result +=
"\t"; Result += utostr(Ivars.size()); Result +=
",\n";
6807 for (
unsigned i =0, e = Ivars.size(); i < e; i++) {
6813 Result +=
"(unsigned long int *)&";
6814 if (Ivars[i]->isBitField())
6815 RewriteObj.ObjCIvarBitfieldGroupOffset(IvarDecl, Result);
6821 if (Ivars[i]->isBitField())
6822 RewriteObj.ObjCIvarBitfieldGroupDecl(Ivars[i], Result);
6824 Result += IvarDecl->
getName();
6829 IVQT = RewriteObj.GetGroupRecordTypeForObjCIvarBitfield(IvarDecl);
6831 std::string IvarTypeString, QuoteIvarTypeString;
6834 RewriteObj.QuoteDoublequotes(IvarTypeString, QuoteIvarTypeString);
6835 Result +=
"\""; Result += QuoteIvarTypeString; Result +=
"\", ";
6840 Align = llvm::Log2_32(Align);
6841 Result += llvm::utostr(Align); Result +=
", ";
6854 void RewriteModernObjC::RewriteObjCProtocolMetaData(
ObjCProtocolDecl *PDecl,
6855 std::string &Result) {
6867 RewriteObjCProtocolMetaData(I, Result);
6870 std::vector<ObjCMethodDecl *> InstanceMethods, ClassMethods;
6871 std::vector<ObjCMethodDecl *> OptInstanceMethods, OptClassMethods;
6874 OptInstanceMethods.push_back(MD);
6876 InstanceMethods.push_back(MD);
6882 OptClassMethods.push_back(MD);
6884 ClassMethods.push_back(MD);
6887 std::vector<ObjCMethodDecl *> AllMethods;
6888 for (
unsigned i = 0, e = InstanceMethods.size(); i < e; i++)
6889 AllMethods.push_back(InstanceMethods[i]);
6890 for (
unsigned i = 0, e = ClassMethods.size(); i < e; i++)
6891 AllMethods.push_back(ClassMethods[i]);
6892 for (
unsigned i = 0, e = OptInstanceMethods.size(); i < e; i++)
6893 AllMethods.push_back(OptInstanceMethods[i]);
6894 for (
unsigned i = 0, e = OptClassMethods.size(); i < e; i++)
6895 AllMethods.push_back(OptClassMethods[i]);
6899 "_OBJC_PROTOCOL_METHOD_TYPES_",
6904 "_OBJC_PROTOCOL_REFS_",
6908 "_OBJC_PROTOCOL_INSTANCE_METHODS_",
6912 "_OBJC_PROTOCOL_CLASS_METHODS_",
6916 "_OBJC_PROTOCOL_OPT_INSTANCE_METHODS_",
6920 "_OBJC_PROTOCOL_OPT_CLASS_METHODS_",
6928 "_OBJC_PROTOCOL_PROPERTIES_",
6933 if (LangOpts.MicrosoftExt)
6934 Result +=
"static ";
6935 Result +=
"struct _protocol_t _OBJC_PROTOCOL_";
6937 Result +=
" __attribute__ ((used)) = {\n";
6939 Result +=
"\t\""; Result += PDecl->
getNameAsString(); Result +=
"\",\n";
6940 if (SuperProtocols.size() > 0) {
6941 Result +=
"\t(const struct _protocol_list_t *)&"; Result +=
"_OBJC_PROTOCOL_REFS_";
6946 if (InstanceMethods.size() > 0) {
6947 Result +=
"\t(const struct method_list_t *)&_OBJC_PROTOCOL_INSTANCE_METHODS_";
6953 if (ClassMethods.size() > 0) {
6954 Result +=
"\t(const struct method_list_t *)&_OBJC_PROTOCOL_CLASS_METHODS_";
6960 if (OptInstanceMethods.size() > 0) {
6961 Result +=
"\t(const struct method_list_t *)&_OBJC_PROTOCOL_OPT_INSTANCE_METHODS_";
6967 if (OptClassMethods.size() > 0) {
6968 Result +=
"\t(const struct method_list_t *)&_OBJC_PROTOCOL_OPT_CLASS_METHODS_";
6974 if (ProtocolProperties.size() > 0) {
6975 Result +=
"\t(const struct _prop_list_t *)&_OBJC_PROTOCOL_PROPERTIES_";
6981 Result +=
"\t"; Result +=
"sizeof(_protocol_t)"; Result +=
",\n";
6984 if (AllMethods.size() > 0) {
6985 Result +=
"\t(const char **)&"; Result +=
"_OBJC_PROTOCOL_METHOD_TYPES_";
6990 Result +=
"\t0\n};\n";
6992 if (LangOpts.MicrosoftExt)
6993 Result +=
"static ";
6994 Result +=
"struct _protocol_t *";
6995 Result +=
"_OBJC_LABEL_PROTOCOL_$_"; Result += PDecl->
getNameAsString();
7001 llvm_unreachable(
"protocol already synthesized");
7009 if (OID->
hasAttr<ObjCExceptionAttr>())
7017 std::string &Result) {
7023 "Legacy implicit interface rewriting not supported in moder abi");
7031 if (!IVD->getDeclName())
7033 IVars.push_back(IVD);
7037 "_OBJC_$_INSTANCE_VARIABLES_",
7046 if (Prop->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic)
7048 if (!Prop->getPropertyIvarDecl())
7055 InstanceMethods.push_back(Getter);
7060 InstanceMethods.push_back(Setter);
7064 "_OBJC_$_INSTANCE_METHODS_",
7070 "_OBJC_$_CLASS_METHODS_",
7075 std::vector<ObjCProtocolDecl *> RefedProtocols;
7078 E = Protocols.
end();
7080 RefedProtocols.push_back(*I);
7083 RewriteObjCProtocolMetaData(*I, Result);
7088 "_OBJC_CLASS_PROTOCOLS_$_",
7096 "_OBJC_$_PROP_LIST_",
7101 std::string InstanceSize;
7102 std::string InstanceStart;
7111 InstanceSize =
"sizeof(struct _class_t)";
7112 InstanceStart = InstanceSize;
7114 InstanceStart, InstanceSize,
7119 "_OBJC_METACLASS_RO_$_",
7134 InstanceSize.clear();
7135 InstanceStart.clear();
7136 if (!ObjCSynthesizedStructs.count(CDecl)) {
7138 InstanceStart =
"0";
7141 InstanceSize =
"sizeof(struct ";
7143 InstanceSize +=
"_IMPL)";
7147 RewriteIvarOffsetComputation(IVD, InstanceStart);
7150 InstanceStart = InstanceSize;
7153 InstanceStart, InstanceSize,
7158 "_OBJC_CLASS_RO_$_",
7162 "OBJC_METACLASS_$_",
7169 if (ImplementationIsNonLazy(IDecl))
7170 DefinedNonLazyClasses.push_back(CDecl);
7173 void RewriteModernObjC::RewriteClassSetupInitHook(std::string &Result) {
7174 int ClsDefCount = ClassImplementation.size();
7177 Result +=
"#pragma section(\".objc_inithooks$B\", long, read, write)\n";
7178 Result +=
"__declspec(allocate(\".objc_inithooks$B\")) ";
7179 Result +=
"static void *OBJC_CLASS_SETUP[] = {\n";
7180 for (
int i = 0; i < ClsDefCount; i++) {
7183 Result +=
"\t(void *)&OBJC_CLASS_SETUP_$_";
7184 Result += CDecl->
getName(); Result +=
",\n";
7189 void RewriteModernObjC::RewriteMetaDataIntoBuffer(std::string &Result) {
7190 int ClsDefCount = ClassImplementation.size();
7191 int CatDefCount = CategoryImplementation.size();
7194 for (
int i = 0; i < ClsDefCount; i++)
7195 RewriteObjCClassMetaData(ClassImplementation[i], Result);
7197 RewriteClassSetupInitHook(Result);
7200 for (
int i = 0; i < CatDefCount; i++)
7201 RewriteObjCCategoryImplDecl(CategoryImplementation[i], Result);
7203 RewriteCategorySetupInitHook(Result);
7205 if (ClsDefCount > 0) {
7206 if (LangOpts.MicrosoftExt)
7207 Result +=
"__declspec(allocate(\".objc_classlist$B\")) ";
7208 Result +=
"static struct _class_t *L_OBJC_LABEL_CLASS_$ [";
7209 Result += llvm::utostr(ClsDefCount); Result +=
"]";
7211 " __attribute__((used, section (\"__DATA, __objc_classlist,"
7212 "regular,no_dead_strip\")))= {\n";
7213 for (
int i = 0; i < ClsDefCount; i++) {
7214 Result +=
"\t&OBJC_CLASS_$_";
7215 Result += ClassImplementation[i]->getNameAsString();
7220 if (!DefinedNonLazyClasses.empty()) {
7221 if (LangOpts.MicrosoftExt)
7222 Result +=
"__declspec(allocate(\".objc_nlclslist$B\")) \n";
7223 Result +=
"static struct _class_t *_OBJC_LABEL_NONLAZY_CLASS_$[] = {\n\t";
7224 for (
unsigned i = 0, e = DefinedNonLazyClasses.size(); i < e; i++) {
7225 Result +=
"\t&OBJC_CLASS_$_"; Result += DefinedNonLazyClasses[i]->getNameAsString();
7232 if (CatDefCount > 0) {
7233 if (LangOpts.MicrosoftExt)
7234 Result +=
"__declspec(allocate(\".objc_catlist$B\")) ";
7235 Result +=
"static struct _category_t *L_OBJC_LABEL_CATEGORY_$ [";
7236 Result += llvm::utostr(CatDefCount); Result +=
"]";
7238 " __attribute__((used, section (\"__DATA, __objc_catlist,"
7239 "regular,no_dead_strip\")))= {\n";
7240 for (
int i = 0; i < CatDefCount; i++) {
7241 Result +=
"\t&_OBJC_$_CATEGORY_";
7243 CategoryImplementation[i]->getClassInterface()->getNameAsString();
7245 Result += CategoryImplementation[i]->getNameAsString();
7251 if (!DefinedNonLazyCategories.empty()) {
7252 if (LangOpts.MicrosoftExt)
7253 Result +=
"__declspec(allocate(\".objc_nlcatlist$B\")) \n";
7254 Result +=
"static struct _category_t *_OBJC_LABEL_NONLAZY_CATEGORY_$[] = {\n\t";
7255 for (
unsigned i = 0, e = DefinedNonLazyCategories.size(); i < e; i++) {
7256 Result +=
"\t&_OBJC_$_CATEGORY_";
7258 DefinedNonLazyCategories[i]->getClassInterface()->getNameAsString();
7260 Result += DefinedNonLazyCategories[i]->getNameAsString();
7267 void RewriteModernObjC::WriteImageInfo(std::string &Result) {
7268 if (LangOpts.MicrosoftExt)
7269 Result +=
"__declspec(allocate(\".objc_imageinfo$B\")) \n";
7271 Result +=
"static struct IMAGE_INFO { unsigned version; unsigned flag; } ";
7273 Result +=
"_OBJC_IMAGE_INFO = { 0, 2 };\n";
7279 std::string &Result) {
7287 FullCategoryName +=
"_$_";
7296 if (Prop->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic)
7298 if (!Prop->getPropertyIvarDecl())
7304 InstanceMethods.push_back(Getter);
7308 InstanceMethods.push_back(Setter);
7312 "_OBJC_$_CATEGORY_INSTANCE_METHODS_",
7313 FullCategoryName,
true);
7318 "_OBJC_$_CATEGORY_CLASS_METHODS_",
7319 FullCategoryName,
true);
7327 RewriteObjCProtocolMetaData(I, Result);
7331 "_OBJC_CATEGORY_PROTOCOLS_$_",
7339 "_OBJC_$_PROP_LIST_",
7351 if (ImplementationIsNonLazy(IDecl))
7352 DefinedNonLazyCategories.push_back(CDecl);
7355 void RewriteModernObjC::RewriteCategorySetupInitHook(std::string &Result) {
7356 int CatDefCount = CategoryImplementation.size();
7359 Result +=
"#pragma section(\".objc_inithooks$B\", long, read, write)\n";
7360 Result +=
"__declspec(allocate(\".objc_inithooks$B\")) ";
7361 Result +=
"static void *OBJC_CATEGORY_SETUP[] = {\n";
7362 for (
int i = 0; i < CatDefCount; i++) {
7366 Result +=
"\t(void *)&OBJC_CATEGORY_SETUP_$_";
7367 Result += ClassDecl->
getName();
7377 template<
typename MethodIterator>
7378 void RewriteModernObjC::RewriteObjCMethodsMetaData(MethodIterator MethodBegin,
7379 MethodIterator MethodEnd,
7380 bool IsInstanceMethod,
7382 StringRef ClassName,
7383 std::string &Result) {
7384 if (MethodBegin == MethodEnd)
return;
7386 if (!objc_impl_method) {
7393 Result +=
"\nstruct _objc_method {\n";
7394 Result +=
"\tSEL _cmd;\n";
7395 Result +=
"\tchar *method_types;\n";
7396 Result +=
"\tvoid *_imp;\n";
7399 objc_impl_method =
true;
7410 unsigned NumMethods =
std::distance(MethodBegin, MethodEnd);
7412 if (LangOpts.MicrosoftExt) {
7413 if (IsInstanceMethod)
7414 Result +=
"__declspec(allocate(\".inst_meth$B\")) ";
7416 Result +=
"__declspec(allocate(\".cls_meth$B\")) ";
7418 Result +=
"static struct {\n";
7419 Result +=
"\tstruct _objc_method_list *next_method;\n";
7420 Result +=
"\tint method_count;\n";
7421 Result +=
"\tstruct _objc_method method_list[";
7422 Result += utostr(NumMethods);
7423 Result +=
"];\n} _OBJC_";
7425 Result += IsInstanceMethod ?
"INSTANCE" :
"CLASS";
7426 Result +=
"_METHODS_";
7427 Result += ClassName;
7428 Result +=
" __attribute__ ((used, section (\"__OBJC, __";
7429 Result += IsInstanceMethod ?
"inst" :
"cls";
7430 Result +=
"_meth\")))= ";
7431 Result +=
"{\n\t0, " + utostr(NumMethods) +
"\n";
7433 Result +=
"\t,{{(SEL)\"";
7434 Result += (*MethodBegin)->getSelector().getAsString().c_str();
7435 std::string MethodTypeString;
7438 Result += MethodTypeString;
7439 Result +=
"\", (void *)";
7440 Result += MethodInternalNames[*MethodBegin];
7442 for (++MethodBegin; MethodBegin != MethodEnd; ++MethodBegin) {
7443 Result +=
"\t ,{(SEL)\"";
7444 Result += (*MethodBegin)->getSelector().getAsString().c_str();
7445 std::string MethodTypeString;
7448 Result += MethodTypeString;
7449 Result +=
"\", (void *)";
7450 Result += MethodInternalNames[*MethodBegin];
7453 Result +=
"\t }\n};\n";
7462 DisableReplaceStmtScope
S(*
this);
7463 BaseExpr = cast<Expr>(RewriteFunctionBodyOrGlobalInitializer(BaseExpr));
7469 Expr *Replacement = IV;
7474 assert(iFaceDecl &&
"RewriteObjCIvarRefExpr - iFaceDecl is null");
7479 assert(clsDeclared &&
"RewriteObjCIvarRefExpr(): Can't find class");
7482 std::string IvarOffsetName;
7484 ObjCIvarBitfieldGroupOffset(D, IvarOffsetName);
7488 ReferencedIvars[clsDeclared].insert(D);
7512 IvarT = GetGroupRecordTypeForObjCIvarBitfield(D);
7514 if (!isa<TypedefType>(IvarT) && IvarT->
isRecordType()) {
7524 std::string RecName = CDecl->
getName();
7530 unsigned UnsignedIntSize =
7533 llvm::APInt(UnsignedIntSize, 0),
7535 Zero = NoTypeInfoCStyleCastExpr(
Context, PtrStructIMPL, CK_BitCast, Zero);
7550 convertObjCTypeToCStyleType(IvarT);
7553 castExpr = NoTypeInfoCStyleCastExpr(
Context,
7560 VK_LValue, OK_Ordinary,
7583 ReplaceStmtWithRange(IV, Replacement, OldRange);
7587 #endif // CLANG_ENABLE_OBJC_REWRITER
void printPretty(raw_ostream &OS, PrinterHelper *Helper, const PrintingPolicy &Policy, unsigned Indentation=0) const
static bool scanForProtocolRefs(const char *startBuf, const char *endBuf, const char *&startRef, const char *&endRef)
SourceLocation getEnd() const
const Expr * getBase() const
ObjCInterfaceDecl * getDecl() const
Get the declaration of this interface.
CastKind getCastKind() const
FunctionDecl - An instance of this class is created to represent a function declaration or definition...
StringRef getName() const
getName - Get the name of identifier for this declaration as a StringRef.
protocol_range protocols() const
Expr * getSyntacticForm()
Return the syntactic form of this expression, i.e.
static void Write__prop_list_t_TypeDecl(std::string &Result, unsigned int property_count)
Smart pointer class that efficiently represents Objective-C method names.
SourceLocation getLocStart() const LLVM_READONLY
PointerType - C99 6.7.5.1 - Pointer Declarators.
const ObjCAtFinallyStmt * getFinallyStmt() const
Retrieve the @finally statement, if any.
A (possibly-)qualified type.
ArrayRef< Capture > captures() const
ImplementationControl getImplementationControl() const
QualType getCallResultType(const ASTContext &Context) const
Determine the type of an expression that calls a function of this type.
ObjCInterfaceDecl * getClassInterface()
ObjCInterfaceDecl * getClassInterface()
bool isBitField() const
Determines whether this field is a bitfield.
ASTConsumer - This is an abstract interface that should be implemented by clients that read ASTs...
QualType getClassReceiver() const
Returns the type of a class message send, or NULL if the message is not a class message.
IdentifierInfo * getIdentifier() const
getIdentifier - Get the identifier that names this declaration, if there is one.
static void scanToNextArgument(const char *&argRef)
CanQual< T > getUnqualifiedType() const
Retrieve the unqualified form of this type.
Stmt - This represents one statement.
FunctionType - C99 6.7.5.3 - Function Declarators.
bool isMain() const
Determines whether this function is "main", which is the entry point into an executable program...
bool isThisDeclarationADefinition() const
Determine whether this particular declaration of this class is actually also a definition.
Defines the SourceManager interface.
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
static void Write_class_t(ASTContext *Context, std::string &Result, StringRef VarName, const ObjCInterfaceDecl *CDecl, bool metaclass)
SourceLocation getForLoc() const
bool isRecordType() const
Decl - This represents one declaration (or definition), e.g.
SourceLocation getLocEnd() const LLVM_READONLY
const char * getCharacterData(SourceLocation SL, bool *Invalid=nullptr) const
Return a pointer to the start of the specified location in the appropriate spelling MemoryBuffer...
param_iterator param_end()
llvm::MemoryBuffer * getBuffer(FileID FID, SourceLocation Loc, bool *Invalid=nullptr) const
Return the buffer for the specified FileID.
bool isEnumeralType() const
ParenExpr - This represents a parethesized expression, e.g.
void getSelectorLocs(SmallVectorImpl< SourceLocation > &SelLocs) const
std::string getAsString() const
FullSourceLoc getFullLoc(SourceLocation Loc) const
IdentifierInfo * getAsIdentifierInfo() const
getAsIdentifierInfo - Retrieve the IdentifierInfo * stored in this declaration name, or NULL if this declaration name isn't a simple identifier.
The base class of the type hierarchy.
SourceLocation getLocStart() const LLVM_READONLY
bool isObjCQualifiedClassType() const
Represents Objective-C's @throw statement.
SourceLocation getLocStart() const LLVM_READONLY
Represents an array type, per C99 6.7.5.2 - Array Declarators.
const Expr * getInit() const
Represents a call to a C++ constructor.
virtual void completeDefinition()
completeDefinition - Notes that the definition of this type is now complete.
bool isBooleanType() const
A container of type source information.
Floating point control options.
bool isBlockPointerType() const
static StringLiteral * Create(const ASTContext &C, StringRef Str, StringKind Kind, bool Pascal, QualType Ty, const SourceLocation *Loc, unsigned NumStrs)
This is the "fully general" constructor that allows representation of strings formed from multiple co...
protocol_range protocols() const
SourceLocation getLocStart() const LLVM_READONLY
SourceLocation getLocEnd() const LLVM_READONLY
Represents a C++ constructor within a class.
float __ovld __cnfn distance(float p0, float p1)
Returns the distance between p0 and p1.
static void Write_prop_list_t_initializer(RewriteModernObjC &RewriteObj, ASTContext *Context, std::string &Result, ArrayRef< ObjCPropertyDecl * > Properties, const Decl *Container, StringRef VarName, StringRef ProtocolName)
ObjCDictionaryElement getKeyValueElement(unsigned Index) const
VarDecl - An instance of this class is created to represent a variable declaration or definition...
Objects with "hidden" visibility are not seen by the dynamic linker.
CompoundLiteralExpr - [C99 6.5.2.5].
SourceLocation getIvarRBraceLoc() const
static SourceLocation getFunctionSourceLocation(RewriteModernObjC &R, FunctionDecl *FD)
getFunctionSourceLocation - returns start location of a function definition.
Extra information about a function prototype.
SourceLocation getLocStart() const LLVM_READONLY
QualType getObjCClassType() const
Represents the Objective-C Class type.
const FunctionProtoType * getFunctionType() const
getFunctionType - Return the underlying function type for this block.
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
ObjCMethodDecl - Represents an instance or class method declaration.
RewriteBuffer - As code is rewritten, SourceBuffer's from the original input with modifications get a...
Expr * IgnoreImplicit() LLVM_READONLY
IgnoreImplicit - Skip past any implicit AST nodes which might surround this expression.
static void Write_RethrowObject(std::string &buf)
Visibility getVisibility() const
Determines the visibility of this entity.
Describes how types, statements, expressions, and declarations should be printed. ...
void getAsStringInternal(std::string &Str, const PrintingPolicy &Policy) const
SourceLocation getLocation() const
QualType getFunctionNoProtoType(QualType ResultTy, const FunctionType::ExtInfo &Info) const
Return a K&R style C function type like 'int()'.
SourceLocation getLocStart() const LLVM_READONLY
QualType withConst() const
Retrieves a version of this type with const applied.
unsigned getNumParams() const
Kind getPropertyImplementation() const
static void Write__ivar_list_t_TypeDecl(std::string &Result, unsigned int ivar_count)
RecordDecl - Represents a struct/union/class.
bool isExternC() const
Determines whether this function is a function with external, C linkage.
ObjCProtocolDecl * getCanonicalDecl() override
Retrieves the canonical declaration of this Objective-C protocol.
One of these records is kept for each identifier that is lexed.
ObjCProtocolDecl * getProtocol() const
An element in an Objective-C dictionary literal.
const ObjCInterfaceDecl * getContainingInterface() const
Return the class interface that this ivar is logically contained in; this is either the interface whe...
Represents a class type in Objective C.
StringRef getBufferData(FileID FID, bool *Invalid=nullptr) const
Return a StringRef to the source buffer data for the specified FileID.
static void Write_method_list_t_TypeDecl(std::string &Result, unsigned int method_count)
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
unsigned getNumSemanticExprs() const
std::string getNameAsString() const
Get the name of the class associated with this interface.
FieldDecl - An instance of this class is created by Sema::ActOnField to represent a member of a struc...
bool isCompleteDefinition() const
isCompleteDefinition - Return true if this decl has its body fully specified.
std::unique_ptr< ASTConsumer > CreateModernObjCRewriter(const std::string &InFile, std::unique_ptr< raw_ostream > OS, DiagnosticsEngine &Diags, const LangOptions &LOpts, bool SilenceRewriteMacroWarning, bool LineInfo)
StringLiteral * getString()
const Stmt * getBody() const
ObjCMethodDecl * getClassMethod(Selector Sel, bool AllowHidden=false) const
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
ObjCArrayLiteral - used for objective-c array containers; as in: @["Hello", NSApp, [NSNumber numberWithInt:42]];.
QualType getTypeDeclType(const TypeDecl *Decl, const TypeDecl *PrevDecl=nullptr) const
Return the unique reference to the type for the specified type declaration.
An r-value expression (a pr-value in the C++11 taxonomy) produces a temporary value.
SourceLocation getSuperLoc() const
Retrieve the location of the 'super' keyword for a class or instance message to 'super', otherwise an invalid source location.
const VarDecl * getCatchParamDecl() const
Represents Objective-C's @catch statement.
const CompoundStmt * getSynchBody() const
Describes an C or C++ initializer list.
param_type_range param_types() const
ObjCMethodDecl * getBoxingMethod() const
const Stmt * getFinallyBody() const
const TargetInfo & getTargetInfo() const
SourceLocation getLocWithOffset(int Offset) const
Return a source location with the specified offset from this SourceLocation.
ObjCContainerDecl - Represents a container for method declarations.
const LangOptions & getLangOpts() const
bool isImplicit() const
isImplicit - Indicates whether the declaration was implicitly generated by the implementation.
CharUnits - This is an opaque type for sizes expressed in character units.
QualType getReturnType() const
QualType getSuperType() const
Retrieve the type referred to by 'super'.
field_range fields() const
Concrete class used by the front-end to report problems and issues.
const ArrayType * getAsArrayType(QualType T) const
Type Query functions.
Represents a typeof (or typeof) expression (a GCC extension).
TypeDecl - Represents a declaration of a type.
A builtin binary operation expression such as "x + y" or "x <= y".
Selector getSelector() const
Selector getSetterName() const
bool isOverloadedOperator() const
isOverloadedOperator - Whether this function declaration represents an C++ overloaded operator...
Defines the Diagnostic-related interfaces.
std::string getNameAsString() const
getNameAsString - Get a human-readable name for the declaration, even if it is one of the special kin...
ObjCStringLiteral, used for Objective-C string literals i.e.
ObjCProtocolDecl * getDefinition()
Retrieve the definition of this protocol, if any.
bool isVariadic() const
Whether this function is variadic.
const Stmt * getCatchBody() const
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
CompoundStmt * getCompoundBody()
Represents an Objective-C protocol declaration.
const ObjCAtCatchStmt * getCatchStmt(unsigned I) const
Retrieve a @catch statement.
Expr * Key
The key for the dictionary element.
SourceLocation getLocStart() const LLVM_READONLY
SourceLocation getLocEnd() const LLVM_READONLY
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
unsigned getLine() const
Return the presumed line number of this location.
An ordinary object is located at an address in memory.
Represents an ObjC class declaration.
SourceLocation getLocEnd() const LLVM_READONLY
propimpl_range property_impls() const
Represents a linkage specification.
detail::InMemoryDirectory::const_iterator I
PropertyAttributeKind getPropertyAttributes() const
static void WriteInternalIvarName(const ObjCInterfaceDecl *IDecl, ObjCIvarDecl *IvarDecl, std::string &Result)
Iterator for iterating over Stmt * arrays that contain only Expr *.
SourceLocation getAtLoc() const
static void Write_protocol_list_t_TypeDecl(std::string &Result, long super_protocol_count)
SourceRange getAtEndRange() const
ObjCPropertyImplDecl - Represents implementation declaration of a property in a class or category imp...
bool isThisDeclarationADefinition() const
Determine whether this particular declaration is also the definition.
ConditionalOperator - The ?: ternary operator.
static bool hasObjCExceptionAttribute(ASTContext &Context, const ObjCInterfaceDecl *OID)
hasObjCExceptionAttribute - Return true if this class or any super class has the objc_exception attri...
SourceLocation getLocStart() const LLVM_READONLY
SourceLocation getLocEnd() const LLVM_READONLY
CompoundStmt - This represents a group of statements like { stmt stmt }.
QualType getParamType(unsigned i) const
Represents a prototype with parameter type info, e.g.
SourceLocation getLocEnd() const LLVM_READONLY
CastKind
CastKind - The kind of operation required for a conversion.
static void Write_IvarOffsetVar(RewriteModernObjC &RewriteObj, ASTContext *Context, std::string &Result, ArrayRef< ObjCIvarDecl * > Ivars, ObjCInterfaceDecl *CDecl)
SourceLocation getLocEnd() const LLVM_READONLY
void getObjCEncodingForType(QualType T, std::string &S, const FieldDecl *Field=nullptr, QualType *NotEncodedT=nullptr) const
Emit the Objective-CC type encoding for the given type T into S.
static void RewriteOneForwardClassDecl(ObjCInterfaceDecl *ForwardDecl, std::string &typedefString)
SourceLocation getTypeSpecStartLoc() const
static bool IsHeaderFile(const std::string &Filename)
StorageClass getStorageClass() const
Returns the storage class as written in the source.
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee...
bool isFunctionPointerType() const
QualType getObjCInterfaceType(const ObjCInterfaceDecl *Decl, ObjCInterfaceDecl *PrevDecl=nullptr) const
getObjCInterfaceType - Return the unique reference to the type for the specified ObjC interface decl...
bool isRealFloatingType() const
Floating point categories.
static void Write_method_list_t_initializer(RewriteModernObjC &RewriteObj, ASTContext *Context, std::string &Result, ArrayRef< ObjCMethodDecl * > Methods, StringRef VarName, StringRef TopLevelDeclName, bool MethodImpl)
const ObjCMethodDecl * getMethodDecl() const
SourceLocation getLocStart() const LLVM_READONLY
BlockDecl - This represents a block literal declaration, which is like an unnamed FunctionDecl...
QualType getPointeeType() const
ValueDecl - Represent the declaration of a variable (in which case it is an lvalue) a function (in wh...
Expr - This represents one expression.
StringRef getName() const
Return the actual identifier string.
bool isBeforeInTranslationUnit(SourceLocation LHS, SourceLocation RHS) const
Determines the order of 2 source locations in the translation unit.
ObjCIvarDecl * getPropertyIvarDecl() const
Expr * getBitWidth() const
SourceLocation getRParenLoc() const
BlockExpr - Adaptor class for mixing a BlockDecl with expressions.
TranslationUnitDecl * getTranslationUnitDecl() const
bool isObjCGCWeak() const
true when Type is objc's weak.
Expr * getUnderlyingExpr() const
ObjCDictionaryLiteral - AST node to represent objective-c dictionary literals; as in:"name" : NSUserN...
DeclContext * getDeclContext()
Represents Objective-C's @synchronized statement.
ObjCSelectorExpr used for @selector in Objective-C.
unsigned getExpansionLineNumber(SourceLocation Loc, bool *Invalid=nullptr) const
static bool mustSynthesizeSetterGetterMethod(ObjCImplementationDecl *IMP, ObjCPropertyDecl *PD, bool getter)
mustSynthesizeSetterGetterMethod - returns true if setter or getter has not been found in the class i...
bool isWrittenInMainFile(SourceLocation Loc) const
Returns true if the spelling location for the given location is in the main file buffer.
Selector getSelector() const
unsigned getNumElements() const
getNumElements - Return number of elements of objective-c array literal.
Defines the clang::IdentifierInfo, clang::IdentifierTable, and clang::Selector interfaces.
ObjCIvarDecl * lookupInstanceVariable(IdentifierInfo *IVarName, ObjCInterfaceDecl *&ClassDeclared)
static void Write__class_ro_t_initializer(ASTContext *Context, std::string &Result, unsigned int flags, const std::string &InstanceStart, const std::string &InstanceSize, ArrayRef< ObjCMethodDecl * >baseMethods, ArrayRef< ObjCProtocolDecl * >baseProtocols, ArrayRef< ObjCIvarDecl * >ivars, ArrayRef< ObjCPropertyDecl * >Properties, StringRef VarName, StringRef ClassName)
Expr * getElement(unsigned Index)
getExpr - Return the Expr at the specified index.
bool isInstanceMethod() const
bool isa(CodeGen::Address addr)
QualType getObjCIdType() const
Represents the Objective-CC id type.
An expression that sends a message to the given Objective-C object or class.
Represents an unpacked "presumed" location which can be presented to the user.
#define SKIP_BITFIELDS(IX, ENDIX, VEC)
UnaryOperator - This represents the unary-expression's (except sizeof and alignof), the postinc/postdec operators from postfix-expression, and various extensions.
DeclarationName getDeclName() const
getDeclName - Get the actual, stored name of the declaration, which may be a special name...
static void BuildUniqueMethodName(std::string &Name, ObjCMethodDecl *MD)
The result type of a method or function.
CStyleCastExpr - An explicit cast in C (C99 6.5.4) or a C-style cast in C++ (C++ [expr.cast]), which uses the syntax (Type)expr.
RecordDecl * getDefinition() const
getDefinition - Returns the RecordDecl that actually defines this struct/union/class.
Expr * getArg(unsigned Arg)
getArg - Return the specified argument.
const clang::PrintingPolicy & getPrintingPolicy() const
SourceLocation getAtLoc() const
SourceLocation getRightLoc() const
static std::string getIvarAccessString(ObjCIvarDecl *OID)
ObjCCategoryDecl * getCategoryDecl() const
param_iterator param_begin()
ArrayRef< ParmVarDecl * > parameters() const
Stmt * getBody(const FunctionDecl *&Definition) const
getBody - Retrieve the body (definition) of the function.
SourceLocation getLocStart() const LLVM_READONLY
unsigned getTypeAlign(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in bits.
SelectorTable & Selectors
PseudoObjectExpr - An expression which accesses a pseudo-object l-value.
SourceLocation getLocStart() const LLVM_READONLY
const char * getFilename() const
Return the presumed filename of this location.
Encodes a location in the source.
enumerator_range enumerators() const
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of enums...
SourceLocation getLocStart() const LLVM_READONLY
unsigned getBitWidthValue(const ASTContext &Ctx) const
static LLVM_READONLY bool isAlphanumeric(unsigned char c)
Return true if this character is an ASCII letter or digit: [a-zA-Z0-9].
Interfaces are the core concept in Objective-C for object oriented design.
bool isValid() const
Return true if this is a valid SourceLocation object.
TagDecl - Represents the declaration of a struct/union/class/enum.
static OMPLinearClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, OpenMPLinearClauseKind Modifier, SourceLocation ModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL, ArrayRef< Expr * > PL, ArrayRef< Expr * > IL, Expr *Step, Expr *CalcStep, Stmt *PreInit, Expr *PostUpdate)
Creates clause with a list of variables VL and a linear step Step.
TypeSourceInfo * getTrivialTypeSourceInfo(QualType T, SourceLocation Loc=SourceLocation()) const
Allocate a TypeSourceInfo where all locations have been initialized to a given location, which defaults to the empty location.
bool refersToEnclosingVariableOrCapture() const
Does this DeclRefExpr refer to an enclosing local or a captured variable?
DeclStmt - Adaptor class for mixing declarations with statements and expressions. ...
static void Write__extendedMethodTypes_initializer(RewriteModernObjC &RewriteObj, ASTContext *Context, std::string &Result, ArrayRef< ObjCMethodDecl * > Methods, StringRef VarName, StringRef ProtocolName)
QualType withConst() const
TypeSourceInfo * getClassReceiverTypeInfo() const
Returns a type-source information of a class message send, or NULL if the message is not a class mess...
SourceLocation getLocStart() const LLVM_READONLY
bool isIntegralType(const ASTContext &Ctx) const
Determine whether this type is an integral type.
ObjCCategoryDecl - Represents a category declaration.
const ObjCInterfaceDecl * getClassInterface() const
decl_iterator decl_begin()
ObjCProtocolExpr used for protocol expression in Objective-C.
std::string getAsString() const
Derive the full selector name (e.g.
Represents one property declaration in an Objective-C interface.
ImplicitCastExpr - Allows us to explicitly represent implicit type conversions, which have no direct ...
QualType getReturnType() const
SourceLocation getBegin() const
const T * castAs() const
Member-template castAs<specific type>.
FileID getMainFileID() const
Returns the FileID of the main source file.
bool isFileContext() const
std::string getObjCEncodingForPropertyDecl(const ObjCPropertyDecl *PD, const Decl *Container) const
getObjCEncodingForPropertyDecl - Return the encoded type for this method declaration.
SourceLocation getAtSynchronizedLoc() const
ObjCBoxedExpr - used for generalized expression boxing.
const BlockDecl * getBlockDecl() const
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
QualType getObjCInstanceType()
Retrieve the Objective-C "instancetype" type, if already known; otherwise, returns a NULL type;...
QualType getPointeeType() const
Expr * Value
The value of the dictionary element.
QualType getObjCSelType() const
Retrieve the type that corresponds to the predefined Objective-C 'SEL' type.
decl_iterator - Iterates through the declarations stored within this context.
Expr * getInstanceReceiver()
Returns the object expression (receiver) for an instance message, or null for a message that is not a...
ObjCIvarDecl * getNextIvar()
Base class for declarations which introduce a typedef-name.
Expr * getResultExpr()
Return the result-bearing expression, or null if there is none.
An opaque identifier used by SourceManager which refers to a source file (MemoryBuffer) along with it...
instmeth_range instance_methods() const
ObjCCategoryDecl * FindCategoryDeclaration(IdentifierInfo *CategoryId) const
FindCategoryDeclaration - Finds category declaration in the list of categories for this class and ret...
SourceLocation getLParenLoc() const
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
unsigned getByteLength() const
static void Write__ivar_list_t_initializer(RewriteModernObjC &RewriteObj, ASTContext *Context, std::string &Result, ArrayRef< ObjCIvarDecl * > OriginalIvars, StringRef VarName, ObjCInterfaceDecl *CDecl)
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
SourceLocation getLocStart() const LLVM_READONLY
ObjCMethodDecl * getInstanceMethod(Selector Sel, bool AllowHidden=false) const
QualType IgnoreParens() const
Returns the specified type after dropping any outer-level parentheses.
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
Selector getGetterName() const
U cast(CodeGen::Address addr)
int printf(__constant const char *st,...)
bool isThisDeclarationADefinition() const
Returns whether this specific declaration of the function is also a definition that does not contain ...
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
EnumDecl - Represents an enum.
Selector getSelector() const
ObjCMethodDecl * getArrayWithObjectsMethod() const
detail::InMemoryDirectory::const_iterator E
static void Write_category_t(RewriteModernObjC &RewriteObj, ASTContext *Context, std::string &Result, ObjCCategoryDecl *CatDecl, ObjCInterfaceDecl *ClassDecl, ArrayRef< ObjCMethodDecl * > InstanceMethods, ArrayRef< ObjCMethodDecl * > ClassMethods, ArrayRef< ObjCProtocolDecl * > RefedProtocols, ArrayRef< ObjCPropertyDecl * > ClassProperties)
SourceLocation getEndOfDefinitionLoc() const
CanQualType getCanonicalType(QualType T) const
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
ObjCMethodDecl * getDictWithObjectsMethod() const
Expr * IgnoreParenImpCasts() LLVM_READONLY
IgnoreParenImpCasts - Ignore parentheses and implicit casts.
Represents a pointer to an Objective C object.
CanQualType ObjCBuiltinBoolTy
SourceLocation getRParenLoc() const
ObjCImplementationDecl - Represents a class definition - this is where method definitions are specifi...
ObjCMethodDecl * getGetterMethodDecl() const
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
SourceLocation getLeftLoc() const
(Obsolete) ARC-specific: this class has a .release_ivars method
const T * getAs() const
Member-template getAs<specific type>'.
static void Write_protocol_list_initializer(ASTContext *Context, std::string &Result, ArrayRef< ObjCProtocolDecl * > SuperProtocols, StringRef VarName, StringRef ProtocolName)
const Stmt * getSubStmt() const
Represents Objective-C's collection statement.
CanQualType UnsignedLongTy
ObjCMethodDecl * getSetterMethodDecl() const
ObjCEncodeExpr, used for @encode in Objective-C.
QualType getFunctionType(QualType ResultTy, ArrayRef< QualType > Args, const FunctionProtoType::ExtProtoInfo &EPI) const
Return a normal function type with a typed argument list.
Selector getSelector(unsigned NumArgs, IdentifierInfo **IIV)
Can create any sort of selector.
SourceLocation getAtTryLoc() const
Retrieve the location of the @ in the @try.
static CStyleCastExpr * Create(const ASTContext &Context, QualType T, ExprValueKind VK, CastKind K, Expr *Op, const CXXCastPath *BasePath, TypeSourceInfo *WrittenTy, SourceLocation L, SourceLocation R)
instprop_range instance_properties() const
bool isObjCQualifiedIdType() const
MutableArrayRef< ParmVarDecl * >::iterator param_iterator
DeclContext * getRedeclContext()
getRedeclContext - Retrieve the context in which an entity conflicts with other entities of the same ...
ObjCInterfaceDecl * getCanonicalDecl() override
Retrieves the canonical declaration of this Objective-C class.
Represents Objective-C's @finally statement.
uint64_t getCharWidth() const
Return the size of the character type, in bits.
const ObjCProtocolList & getReferencedProtocols() const
ObjCImplementationDecl * getImplementation() const
void addDecl(Decl *D)
Add the declaration D into this context.
unsigned getNumArgs() const
Return the number of actual arguments in this message, not counting the receiver. ...
QualType getTagDeclType(const TagDecl *Decl) const
Return the unique reference to the type for the specified TagDecl (struct/union/class/enum) decl...
unsigned getNumCatchStmts() const
Retrieve the number of @catch statements in this try-catch-finally block.
SourceLocation getRParenLoc() const
ObjCIvarRefExpr - A reference to an ObjC instance variable.
SourceManager & getSourceManager()
bool isDefaultConstructor() const
Whether this constructor is a default constructor (C++ [class.ctor]p5), which can be used to default-...
X
Add a minimal nested name specifier fixit hint to allow lookup of a tag name from an outer enclosing ...
ObjCPropertyDecl * getPropertyDecl() const
AccessControl getAccessControl() const
classmeth_range class_methods() const
const internal::VariadicDynCastAllOfMatcher< Stmt, CastExpr > castExpr
Matches any cast nodes of Clang's AST.
Rewriter - This is the main interface to the rewrite buffers.
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
bool isImplicitInterfaceDecl() const
isImplicitInterfaceDecl - check that this is an implicitly declared ObjCInterfaceDecl node...
std::string getObjCEncodingForMethodDecl(const ObjCMethodDecl *Decl, bool Extended=false) const
Emit the encoded type for the method declaration Decl into S.
ContinueStmt - This represents a continue.
bool isReadOnly() const
isReadOnly - Return true iff the property has a setter.
bool isObjCObjectPointerType() const
QualType getEncodedType() const
ObjCIvarDecl - Represents an ObjC instance variable.
bool isImplicit() const
Indicates whether the message send was implicitly generated by the implementation.
SourceLocation getLocEnd() const LLVM_READONLY
static bool HasLocalVariableExternalStorage(ValueDecl *VD)
Represents Objective-C's @try ... @catch ... @finally statement.
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
const Expr * getThrowExpr() const
SourceLocation getLocation() const
StringLiteral - This represents a string literal expression, e.g.
Defines the clang::TargetInfo interface.
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
ObjCInterfaceDecl * getSuperClass() const
static void Write_ProtocolExprReferencedMetadata(ASTContext *Context, ObjCProtocolDecl *PDecl, std::string &Result)
Write_ProtocolExprReferencedMetadata - This routine writer out the protocol reference symbols in the ...
ObjCBoolLiteralExpr - Objective-C Boolean Literal.
SourceLocation getIvarRBraceLoc() const
const Stmt * getTryBody() const
Retrieve the @try body.
TranslationUnitDecl - The top declaration context.
const internal::VariadicDynCastAllOfMatcher< Decl, FieldDecl > fieldDecl
Matches field declarations.
A reference to a declared variable, function, enum, etc.
ExprValueKind getValueKind() const
getValueKind - The value kind that this expression produces.
QualType getDecltypeType(Expr *e, QualType UnderlyingType) const
C++11 decltype.
QualType getConstantArrayType(QualType EltTy, const llvm::APInt &ArySize, ArrayType::ArraySizeModifier ASM, unsigned IndexTypeQuals) const
Return the unique reference to the type for a constant array of the specified element type...
QualType getElementType() const
BreakStmt - This represents a break.
Expr * getSemanticExpr(unsigned index)
SourceLocation getLocForStartOfFile(FileID FID) const
Return the source location corresponding to the first byte of the specified file. ...
An l-value expression is a reference to an object with independent storage.
class was compiled with -fobjc-arr
A trivial tuple used to represent a source range.
SourceLocation getLocation() const
NamedDecl - This represents a decl with a name.
ObjCIvarDecl * all_declared_ivar_begin()
all_declared_ivar_begin - return first ivar declared in this class, its extensions and its implementa...
SourceLocation getLocStart() const LLVM_READONLY
SourceLocation getExpansionLoc(SourceLocation Loc) const
Given a SourceLocation object Loc, return the expansion location referenced by the ID...
SourceLocation getLocStart() const LLVM_READONLY
SourceLocation getLocEnd() const LLVM_READONLY
bool isConstQualified() const
Determine whether this type is const-qualified.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
const ObjCObjectPointerType * getAsObjCInterfacePointerType() const
SourceLocation getLocStart() const LLVM_READONLY
ReceiverKind getReceiverKind() const
Determine the kind of receiver that this message is being sent to.
Represents Objective-C's @autoreleasepool Statement.
ObjCCategoryImplDecl - An object of this class encapsulates a category @implementation declaration...
Represents the canonical version of C arrays with a specified constant size.
This class handles loading and caching of source files into memory.
QualType getBaseElementType(const ArrayType *VAT) const
Return the innermost element type of an array type.
unsigned getNumElements() const
getNumElements - Return number of elements of objective-c dictionary literal.
bool isObjCQualifiedInterfaceType() const
bool BlockRequiresCopying(QualType Ty, const VarDecl *D)
Returns true iff we need copy/dispose helpers for the given type.
static void WriteModernMetadataDeclarations(ASTContext *Context, std::string &Result)
WriteModernMetadataDeclarations - Writes out metadata declarations for modern ABI.
CanQualType UnsignedIntTy
bool isPointerType() const
PresumedLoc getPresumedLoc(SourceLocation Loc, bool UseLineDirectives=true) const
Returns the "presumed" location of a SourceLocation specifies.