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 #if 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;
193 if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(*I)) {
194 if (!
Class->isThisDeclarationADefinition()) {
195 RewriteForwardClassDecl(D);
199 ObjCInterfacesSeen.push_back(Class);
205 if (!Proto->isThisDeclarationADefinition()) {
206 RewriteForwardProtocolDecl(D);
216 if (FDecl->isThisDeclarationADefinition() &&
218 !FDecl->isTopLevelDeclInObjCContainer()) {
219 FunctionDefinitionsSeen.push_back(FDecl);
223 HandleTopLevelSingleDecl(*I);
228 void HandleTopLevelDeclInObjCContainer(
DeclGroupRef D)
override {
231 if (isTopLevelBlockPointerType(TD->getUnderlyingType()))
232 RewriteBlockPointerDecl(TD);
233 else if (TD->getUnderlyingType()->isFunctionPointerType())
234 CheckFunctionPointerDecl(TD->getUnderlyingType(), TD);
236 RewriteObjCQualifiedInterfaceTypes(TD);
241 void HandleTopLevelSingleDecl(
Decl *D);
242 void HandleDeclInMainFile(
Decl *D);
243 RewriteModernObjC(std::string inFile, std::unique_ptr<raw_ostream> OS,
245 bool silenceMacroWarn,
bool LineInfo);
247 ~RewriteModernObjC()
override {}
249 void HandleTranslationUnit(
ASTContext &
C)
override;
251 void ReplaceStmt(
Stmt *Old,
Stmt *New) {
256 assert(Old !=
nullptr && New !=
nullptr &&
"Expected non-null Stmt's");
258 Stmt *ReplacingStmt = ReplacedNodes[Old];
262 if (DisableReplaceStmt)
274 llvm::raw_string_ostream S(SStr);
276 const std::string &Str = S.str();
280 ReplacedNodes[Old] = New;
283 if (SilenceRewriteMacroWarning)
290 bool InsertAfter =
true) {
292 if (!Rewrite.
InsertText(Loc, Str, InsertAfter) ||
293 SilenceRewriteMacroWarning)
302 if (!Rewrite.
ReplaceText(Start, OrigLength, Str) ||
303 SilenceRewriteMacroWarning)
311 void RewriteInclude();
312 void RewriteLineDirective(
const Decl *D);
314 std::string &LineString);
317 void RewriteForwardClassEpilogue(ObjCInterfaceDecl *ClassDecl,
318 const std::string &typedefString);
319 void RewriteImplementations();
323 void RewriteInterfaceDecl(ObjCInterfaceDecl *Dcl);
324 void RewriteImplementationDecl(
Decl *Dcl);
325 void RewriteObjCMethodDecl(
const ObjCInterfaceDecl *IDecl,
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);
395 void RewriteObjCInternalStruct(ObjCInterfaceDecl *CDecl,
400 bool &IsNamedDefinition);
406 void RewriteIvarOffsetSymbols(ObjCInterfaceDecl *CDecl,
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");
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) {
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();
748 if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>((*DI))) {
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 + ";
905 ReferencedIvars[
const_cast<ObjCInterfaceDecl *
>(ClassDecl)].insert(D);
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");
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);
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);
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;
1074 if (ObjCInterfaceDecl *ForwardDecl = dyn_cast<ObjCInterfaceDecl>(*I)) {
1075 if (I == D.
begin()) {
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++) {
1096 ObjCInterfaceDecl *ForwardDecl = cast<ObjCInterfaceDecl>(D[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,
1231 void RewriteModernObjC::RewriteObjCMethodDecl(
const ObjCInterfaceDecl *IDecl,
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(),
"// ");
1378 void RewriteModernObjC::RewriteInterfaceDecl(ObjCInterfaceDecl *ClassDecl) {
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);
1495 ReplaceStmtWithRange(PseudoOp, Replacement, OldRange);
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);
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 +=
" \"";
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;
1967 ObjCInterfaceDecl *IDecl = Ptr->getObjectType()->getInterface();
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)) {
2199 Loc = VD->getLocation();
2200 Type = VD->getType();
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) {
2279 if (!isa<TypeOfExprType>(TypePtr))
2281 while (isa<TypeOfExprType>(TypePtr)) {
2282 const TypeOfExprType *TypeOfExprTypePtr = cast<TypeOfExprType>(TypePtr);
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() {
2447 ArgTys.push_back(Context->
VoidTy);
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() {
2480 &Context->
Idents.
get(
"objc_msgSendSuper_stret");
2482 ArgTys.push_back(Context->
VoidTy);
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() {
2529 &Context->
Idents.
get(
"class_getSuperclass");
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();
2718 getSimpleFunctionType(Context->
VoidTy, IntQT,
true);
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 =
2736 new (Context)
CallExpr(*Context, NSArrayDRE, InitExprs,
2750 NoTypeInfoCStyleCastExpr(Context,
2761 ObjCInterfaceDecl *Class =
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();
2841 getSimpleFunctionType(Context->
VoidTy, IntQT,
true);
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 =
2867 new (Context)
CallExpr(*Context, NSDictDRE, ValueExprs,
2876 MemberExpr *DictLiteralValueME =
new (Context)
2881 NoTypeInfoCStyleCastExpr(Context,
2884 DictLiteralValueME);
2886 Expr *NSKeyCallExpr =
2887 new (Context)
CallExpr(*Context, NSDictDRE, KeyExprs,
2895 NoTypeInfoCStyleCastExpr(Context,
2906 ObjCInterfaceDecl *Class =
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) {
2985 &Context->
Idents.
get(
"__rw_objc_super"));
2994 for (
unsigned i = 0; i < 2; ++i) {
2998 FieldTypes[i],
nullptr,
3009 QualType RewriteModernObjC::getConstantStringStructType() {
3010 if (!ConstantStringDecl) {
3013 &Context->
Idents.
get(
"__NSConstantStringImpl"));
3019 FieldTypes[1] = Context->
IntTy;
3023 FieldTypes[3] = Context->
LongTy;
3026 for (
unsigned i = 0; i < 4; ++i) {
3031 FieldTypes[i],
nullptr,
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 +=
" \"";
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");
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;
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();
3286 SuperRep =
new (Context)
CallExpr(*Context, DRE, InitExprs,
3299 SuperRep = NoTypeInfoCStyleCastExpr(Context,
3301 CK_BitCast, SuperRep);
3318 MsgExprs.push_back(SuperRep);
3324 ObjCInterfaceDecl *Class
3327 ClsExprs.push_back(getStringLiteral(clsName->
getName()));
3328 CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl, ClsExprs,
3330 CastExpr *ArgExpr = NoTypeInfoCStyleCastExpr(Context,
3333 MsgExprs.push_back(ArgExpr);
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();
3381 SuperRep =
new (Context)
CallExpr(*Context, DRE, InitExprs,
3393 SuperRep = NoTypeInfoCStyleCastExpr(Context,
3395 CK_BitCast, SuperRep);
3407 MsgExprs.push_back(SuperRep);
3416 recExpr = CE->getSubExpr();
3419 ? CK_BlockPointerToObjCPointerCast
3420 : CK_CPointerToObjCPointerCast;
3422 recExpr = NoTypeInfoCStyleCastExpr(Context, Context->
getObjCIdType(),
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;
3481 userExpr = NoTypeInfoCStyleCastExpr(Context, Context->
getObjCIdType(),
3485 MsgExprs.push_back(userExpr);
3497 if (MsgSendFlavor == MsgSendSuperFunctionDecl)
3498 ArgTypes.push_back(Context->
getPointerType(getSuperStructType()));
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)) {
3620 RD = RD->getDefinition();
3621 if (!RD || !RD->getDeclName().getAsIdentifierInfo())
3623 IsNamedDefinition =
true;
3624 TagLocation = RD->getLocation();
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,
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()) \ 3888 void RewriteModernObjC::RewriteObjCInternalStruct(ObjCInterfaceDecl *CDecl,
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))) {
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);
3957 ReplaceText(LocStart, endBuf-startBuf, Result);
3959 if (!ObjCSynthesizedStructs.insert(CDecl).second)
3960 llvm_unreachable(
"struct already synthesize- RewriteObjCInternalStruct");
3965 void RewriteModernObjC::RewriteIvarOffsetSymbols(ObjCInterfaceDecl *CDecl,
3966 std::string &Result) {
3976 const ObjCInterfaceDecl *IDecl = IvarDecl->getContainingInterface();
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 &&
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;
4194 std::string Constructor =
" " + 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 &&
4341 std::string SC(
" void __");
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();
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);
4482 if (DRE->refersToEnclosingVariableOrCapture() ||
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)) {
4504 if (DRE->refersToEnclosingVariableOrCapture() ||
4506 if (!InnerContexts.count(DRE->getDecl()->getDeclContext()))
4507 InnerBlockDeclRefs.push_back(DRE);
4508 if (
VarDecl *Var = cast<VarDecl>(DRE->getDecl()))
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);
4629 CastExpr *BlkCast = NoTypeInfoCStyleCastExpr(Context, PtrBlock,
4631 const_cast<Expr*>(BlockExp));
4647 CastExpr *FunkCast = NoTypeInfoCStyleCastExpr(Context, PtrToFuncCastType,
4653 BlkExprs.push_back(BlkCast);
4656 E = Exp->
arg_end(); I != E; ++I) {
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);
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 =
4991 unsigned offset = (VoidPtrSize*4 + IntSize + IntSize)/Context->
getCharWidth();
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");
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)
5261 bool GlobalBlockExpr =
5264 if (GlobalBlockExpr && !GlobalVarDecl) {
5266 GlobalBlockExpr =
false;
5269 std::string BlockNumber = utostr(Blocks.size()-1);
5271 std::string Func =
"__" + FuncName +
"_block_func_" + BlockNumber;
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());
5338 }
else if (isTopLevelBlockPointerType((*I)->getType())) {
5339 FD = SynthBlockInitFunctionDecl((*I)->getName());
5342 Exp = NoTypeInfoCStyleCastExpr(Context, Context->
VoidPtrTy,
5345 FD = SynthBlockInitFunctionDecl((*I)->getName());
5357 InitExprs.push_back(Exp);
5361 E = BlockByRefDecls.end(); I != E; ++I) {
5364 std::string RecName;
5365 RewriteByRefString(RecName, Name, ND,
true);
5367 +
sizeof(
"struct"));
5371 assert(RD &&
"SynthBlockInitExpr(): Can't find RecordDecl");
5374 FD = SynthBlockInitFunctionDecl((*I)->getName());
5377 bool isNestedCapturedVar =
false;
5379 for (
const auto &CI : block->
captures()) {
5380 const VarDecl *variable = CI.getVariable();
5381 if (variable == ND && CI.isNested()) {
5382 assert (CI.isByRef() &&
5383 "SynthBlockInitExpr - captured block variable is not byref");
5384 isNestedCapturedVar =
true;
5390 if (!isNestedCapturedVar)
5395 Exp = NoTypeInfoCStyleCastExpr(Context, castT, CK_BitCast, Exp);
5396 InitExprs.push_back(Exp);
5399 if (ImportedBlockDecls.size()) {
5406 InitExprs.push_back(FlagExp);
5408 NewRep =
new (Context)
CallExpr(*Context, DRE, InitExprs,
5411 if (GlobalBlockExpr) {
5412 assert (!GlobalConstructionExp &&
5413 "SynthBlockInitExpr - GlobalConstructionExp must be null");
5414 GlobalConstructionExp = NewRep;
5421 NewRep = NoTypeInfoCStyleCastExpr(Context, FType, CK_BitCast,
5427 BlockDeclRefs.clear();
5428 BlockByRefDecls.clear();
5429 BlockByRefDeclsPtrSet.clear();
5430 BlockByCopyDecls.clear();
5431 BlockByCopyDeclsPtrSet.clear();
5432 ImportedBlockDecls.clear();
5436 bool RewriteModernObjC::IsDeclStmtInForeachHeader(
DeclStmt *DS) {
5438 dyn_cast<ObjCForCollectionStmt>(Stmts.back()))
5439 return CS->getElement() == DS;
5447 Stmt *RewriteModernObjC::RewriteFunctionBodyOrGlobalInitializer(
Stmt *S) {
5448 if (isa<SwitchStmt>(S) || isa<WhileStmt>(S) ||
5449 isa<DoStmt>(S) || isa<ForStmt>(S))
5451 else if (isa<ObjCForCollectionStmt>(S)) {
5453 ObjCBcLabelNo.push_back(++BcLabelCount);
5460 return RewritePropertyOrImplicitSetter(PseudoOp);
5462 return RewritePropertyOrImplicitGetter(PseudoOp);
5464 }
else if (
ObjCIvarRefExpr *IvarRefExpr = dyn_cast<ObjCIvarRefExpr>(S)) {
5465 return RewriteObjCIvarRefExpr(IvarRefExpr);
5467 else if (isa<OpaqueValueExpr>(S))
5468 S = cast<OpaqueValueExpr>(S)->getSourceExpr();
5475 Stmt *newStmt = RewriteFunctionBodyOrGlobalInitializer(childStmt);
5477 childStmt = newStmt;
5481 if (
BlockExpr *BE = dyn_cast<BlockExpr>(S)) {
5483 llvm::SmallPtrSet<const DeclContext *, 8> InnerContexts;
5484 InnerContexts.insert(BE->getBlockDecl());
5485 ImportedLocalExternalDecls.clear();
5486 GetInnerBlockDeclRefExprs(BE->getBody(),
5487 InnerBlockDeclRefs, InnerContexts);
5489 Stmt *SaveCurrentBody = CurrentBody;
5490 CurrentBody = BE->getBody();
5491 PropParentMap =
nullptr;
5497 bool saveDisableReplaceStmt = DisableReplaceStmt;
5498 DisableReplaceStmt =
false;
5499 RewriteFunctionBodyOrGlobalInitializer(BE->getBody());
5500 DisableReplaceStmt = saveDisableReplaceStmt;
5501 CurrentBody = SaveCurrentBody;
5502 PropParentMap =
nullptr;
5503 ImportedLocalExternalDecls.clear();
5506 RewrittenBlockExprs[BE] = Str;
5508 Stmt *blockTranscribed = SynthBlockInitExpr(BE, InnerBlockDeclRefs);
5511 ReplaceStmt(S, blockTranscribed);
5512 return blockTranscribed;
5516 return RewriteAtEncode(AtEncode);
5519 return RewriteAtSelector(AtSelector);
5522 return RewriteObjCStringLiteral(AtString);
5525 return RewriteObjCBoolLiteralExpr(BoolLitExpr);
5528 return RewriteObjCBoxedExpr(BoxedExpr);
5531 return RewriteObjCArrayLiteralExpr(ArrayLitExpr);
5534 dyn_cast<ObjCDictionaryLiteral>(S))
5535 return RewriteObjCDictionaryLiteralExpr(DictionaryLitExpr);
5546 std::string messString;
5547 messString +=
"// ";
5548 messString.append(startBuf, endBuf-startBuf+1);
5557 return RewriteMessageExpr(MessExpr);
5561 dyn_cast<ObjCAutoreleasePoolStmt>(S)) {
5562 return RewriteObjCAutoreleasePoolStmt(StmtAutoRelease);
5566 return RewriteObjCTryStmt(StmtTry);
5569 return RewriteObjCSynchronizedStmt(StmtTry);
5572 return RewriteObjCThrowStmt(StmtThrow);
5575 return RewriteObjCProtocolExpr(ProtocolExp);
5578 dyn_cast<ObjCForCollectionStmt>(S))
5579 return RewriteObjCForCollectionStmt(StmtForCollection,
5582 dyn_cast<BreakStmt>(S))
5583 return RewriteBreakStmt(StmtBreakStmt);
5585 dyn_cast<ContinueStmt>(S))
5586 return RewriteContinueStmt(StmtContinueStmt);
5590 if (
DeclStmt *DS = dyn_cast<DeclStmt>(S)) {
5600 if (Stmts.empty() || !IsDeclStmtInForeachHeader(DS))
5601 RewriteObjCQualifiedInterfaceTypes(*DS->
decl_begin());
5607 if (
ValueDecl *ND = dyn_cast<ValueDecl>(SD)) {
5608 if (isTopLevelBlockPointerType(ND->
getType()))
5609 RewriteBlockPointerDecl(ND);
5611 CheckFunctionPointerDecl(ND->
getType(), ND);
5612 if (
VarDecl *VD = dyn_cast<VarDecl>(SD)) {
5613 if (VD->
hasAttr<BlocksAttr>()) {
5614 static unsigned uniqueByrefDeclCount = 0;
5615 assert(!BlockByRefDeclNo.count(ND) &&
5616 "RewriteFunctionBodyOrGlobalInitializer: Duplicate byref decl");
5617 BlockByRefDeclNo[ND] = uniqueByrefDeclCount++;
5618 RewriteByRefVar(VD, (DI == DS->
decl_begin()), ((DI+1) == DE));
5621 RewriteTypeOfDecl(VD);
5625 if (isTopLevelBlockPointerType(TD->getUnderlyingType()))
5626 RewriteBlockPointerDecl(TD);
5627 else if (TD->getUnderlyingType()->isFunctionPointerType())
5628 CheckFunctionPointerDecl(TD->getUnderlyingType(), TD);
5634 RewriteObjCQualifiedInterfaceTypes(CE);
5636 if (isa<SwitchStmt>(S) || isa<WhileStmt>(S) ||
5637 isa<DoStmt>(S) || isa<ForStmt>(S)) {
5638 assert(!Stmts.empty() &&
"Statement stack is empty");
5639 assert ((isa<SwitchStmt>(Stmts.back()) || isa<WhileStmt>(Stmts.back()) ||
5640 isa<DoStmt>(Stmts.back()) || isa<ForStmt>(Stmts.back()))
5641 &&
"Statement stack mismatch");
5645 if (
DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(S)) {
5647 if (VD->
hasAttr<BlocksAttr>())
5648 return RewriteBlockDeclRefExpr(DRE);
5650 return RewriteLocalVariableExternalStorage(DRE);
5653 if (
CallExpr *CE = dyn_cast<CallExpr>(S)) {
5656 ReplaceStmt(S, BlockCall);
5661 RewriteCastExpr(CE);
5664 RewriteImplicitCastObjCExpr(ICE);
5674 llvm::raw_string_ostream Buf(SStr);
5676 const std::string &Str = Buf.str();
5678 printf(
"CAST = %s\n", &Str[0]);
5679 InsertText(ICE->getSubExpr()->getLocStart(), Str);
5688 void RewriteModernObjC::RewriteRecordBody(
RecordDecl *RD) {
5689 for (
auto *FD : RD->
fields()) {
5690 if (isTopLevelBlockPointerType(FD->
getType()))
5691 RewriteBlockPointerDecl(FD);
5694 RewriteObjCQualifiedInterfaceTypes(FD);
5700 void RewriteModernObjC::HandleDeclInMainFile(
Decl *D) {
5710 RewriteBlocksInFunctionProtoType(FD->
getType(), FD);
5717 CurFunctionDef = FD;
5720 cast_or_null<CompoundStmt>(RewriteFunctionBodyOrGlobalInitializer(Body));
5722 CurrentBody =
nullptr;
5723 if (PropParentMap) {
5724 delete PropParentMap;
5725 PropParentMap =
nullptr;
5729 InsertBlockLiteralsWithinFunction(FD);
5730 RewriteLineDirective(D);
5731 CurFunctionDef =
nullptr;
5735 case Decl::ObjCMethod: {
5741 cast_or_null<CompoundStmt>(RewriteFunctionBodyOrGlobalInitializer(Body));
5743 CurrentBody =
nullptr;
5744 if (PropParentMap) {
5745 delete PropParentMap;
5746 PropParentMap =
nullptr;
5748 InsertBlockLiteralsWithinMethod(MD);
5749 RewriteLineDirective(D);
5750 CurMethodDef =
nullptr;
5754 case Decl::ObjCImplementation: {
5756 ClassImplementation.push_back(CI);
5759 case Decl::ObjCCategoryImpl: {
5761 CategoryImplementation.push_back(CI);
5765 VarDecl *VD = cast<VarDecl>(D);
5766 RewriteObjCQualifiedInterfaceTypes(VD);
5767 if (isTopLevelBlockPointerType(VD->
getType()))
5768 RewriteBlockPointerDecl(VD);
5770 CheckFunctionPointerDecl(VD->
getType(), VD);
5773 RewriteCastExpr(CE);
5779 RewriteRecordBody(RD);
5784 RewriteFunctionBodyOrGlobalInitializer(VD->
getInit());
5785 CurrentBody =
nullptr;
5786 if (PropParentMap) {
5787 delete PropParentMap;
5788 PropParentMap =
nullptr;
5791 GlobalVarDecl =
nullptr;
5795 RewriteCastExpr(CE);
5800 case Decl::TypeAlias:
5801 case Decl::Typedef: {
5803 if (isTopLevelBlockPointerType(TD->getUnderlyingType()))
5804 RewriteBlockPointerDecl(TD);
5805 else if (TD->getUnderlyingType()->isFunctionPointerType())
5806 CheckFunctionPointerDecl(TD->getUnderlyingType(), TD);
5808 RewriteObjCQualifiedInterfaceTypes(TD);
5812 case Decl::CXXRecord:
5813 case Decl::Record: {
5816 RewriteRecordBody(RD);
5830 std::string &Result) {
5833 Result +=
"static ";
5834 Result +=
"struct _protocol_t *";
5835 Result +=
"_OBJC_PROTOCOL_REFERENCE_$_";
5842 void RewriteModernObjC::HandleTranslationUnit(
ASTContext &
C) {
5848 for (
unsigned i = 0, e = FunctionDefinitionsSeen.size(); i < e; i++) {
5853 HandleTopLevelSingleDecl(FDecl);
5859 RewriteObjCProtocolMetaData(ProtDecl, Preamble);
5865 if (ClassImplementation.size() || CategoryImplementation.size())
5866 RewriteImplementations();
5868 for (
unsigned i = 0, e = ObjCInterfacesSeen.size(); i < e; i++) {
5869 ObjCInterfaceDecl *CDecl = ObjCInterfacesSeen[i];
5874 RewriteInterfaceDecl(CDecl);
5882 *OutFile << std::string(RewriteBuf->begin(), RewriteBuf->end());
5884 llvm::errs() <<
"No changes\n";
5887 if (ClassImplementation.size() || CategoryImplementation.size() ||
5888 ProtocolExprDecls.size()) {
5890 std::string ResultStr;
5891 RewriteMetaDataIntoBuffer(ResultStr);
5893 *OutFile << ResultStr;
5897 std::string ResultStr;
5898 WriteImageInfo(ResultStr);
5899 *OutFile << ResultStr;
5904 void RewriteModernObjC::Initialize(
ASTContext &context) {
5905 InitializeCommon(context);
5907 Preamble +=
"#ifndef __OBJC2__\n";
5908 Preamble +=
"#define __OBJC2__\n";
5909 Preamble +=
"#endif\n";
5914 Preamble =
"#pragma once\n";
5915 Preamble +=
"struct objc_selector; struct objc_class;\n";
5916 Preamble +=
"struct __rw_objc_super { \n\tstruct objc_object *object; ";
5917 Preamble +=
"\n\tstruct objc_object *superClass; ";
5919 Preamble +=
"\n\t__rw_objc_super(struct objc_object *o, struct objc_object *s) ";
5920 Preamble +=
": object(o), superClass(s) {} ";
5921 Preamble +=
"\n};\n";
5923 if (LangOpts.MicrosoftExt) {
5926 Preamble +=
"\n#pragma section(\".objc_classlist$B\", long, read, write)\n";
5927 Preamble +=
"#pragma section(\".objc_catlist$B\", long, read, write)\n";
5928 Preamble +=
"#pragma section(\".objc_imageinfo$B\", long, read, write)\n";
5929 Preamble +=
"#pragma section(\".objc_nlclslist$B\", long, read, write)\n";
5930 Preamble +=
"#pragma section(\".objc_nlcatlist$B\", long, read, write)\n";
5932 Preamble +=
"#pragma section(\".cat_cls_meth$B\", long, read, write)\n";
5933 Preamble +=
"#pragma section(\".inst_meth$B\", long, read, write)\n";
5934 Preamble +=
"#pragma section(\".cls_meth$B\", long, read, write)\n";
5935 Preamble +=
"#pragma section(\".objc_ivar$B\", long, read, write)\n";
5939 Preamble +=
"#pragma section(\".objc_selrefs$B\", long, read, write)\n";
5940 Preamble +=
"#pragma section(\".objc_classrefs$B\", long, read, write)\n";
5941 Preamble +=
"#pragma section(\".objc_superrefs$B\", long, read, write)\n";
5944 Preamble +=
"#ifndef _REWRITER_typedef_Protocol\n";
5945 Preamble +=
"typedef struct objc_object Protocol;\n";
5946 Preamble +=
"#define _REWRITER_typedef_Protocol\n";
5947 Preamble +=
"#endif\n";
5948 if (LangOpts.MicrosoftExt) {
5949 Preamble +=
"#define __OBJC_RW_DLLIMPORT extern \"C\" __declspec(dllimport)\n";
5950 Preamble +=
"#define __OBJC_RW_STATICIMPORT extern \"C\"\n";
5953 Preamble +=
"#define __OBJC_RW_DLLIMPORT extern\n";
5955 Preamble +=
"__OBJC_RW_DLLIMPORT void objc_msgSend(void);\n";
5956 Preamble +=
"__OBJC_RW_DLLIMPORT void objc_msgSendSuper(void);\n";
5957 Preamble +=
"__OBJC_RW_DLLIMPORT void objc_msgSend_stret(void);\n";
5958 Preamble +=
"__OBJC_RW_DLLIMPORT void objc_msgSendSuper_stret(void);\n";
5959 Preamble +=
"__OBJC_RW_DLLIMPORT void objc_msgSend_fpret(void);\n";
5961 Preamble +=
"__OBJC_RW_DLLIMPORT struct objc_class *objc_getClass";
5962 Preamble +=
"(const char *);\n";
5963 Preamble +=
"__OBJC_RW_DLLIMPORT struct objc_class *class_getSuperclass";
5964 Preamble +=
"(struct objc_class *);\n";
5965 Preamble +=
"__OBJC_RW_DLLIMPORT struct objc_class *objc_getMetaClass";
5966 Preamble +=
"(const char *);\n";
5967 Preamble +=
"__OBJC_RW_DLLIMPORT void objc_exception_throw( struct objc_object *);\n";
5969 Preamble +=
"__OBJC_RW_DLLIMPORT int objc_sync_enter( struct objc_object *);\n";
5970 Preamble +=
"__OBJC_RW_DLLIMPORT int objc_sync_exit( struct objc_object *);\n";
5971 Preamble +=
"__OBJC_RW_DLLIMPORT Protocol *objc_getProtocol(const char *);\n";
5972 Preamble +=
"#ifdef _WIN64\n";
5973 Preamble +=
"typedef unsigned long long _WIN_NSUInteger;\n";
5974 Preamble +=
"#else\n";
5975 Preamble +=
"typedef unsigned int _WIN_NSUInteger;\n";
5976 Preamble +=
"#endif\n";
5977 Preamble +=
"#ifndef __FASTENUMERATIONSTATE\n";
5978 Preamble +=
"struct __objcFastEnumerationState {\n\t";
5979 Preamble +=
"unsigned long state;\n\t";
5980 Preamble +=
"void **itemsPtr;\n\t";
5981 Preamble +=
"unsigned long *mutationsPtr;\n\t";
5982 Preamble +=
"unsigned long extra[5];\n};\n";
5983 Preamble +=
"__OBJC_RW_DLLIMPORT void objc_enumerationMutation(struct objc_object *);\n";
5984 Preamble +=
"#define __FASTENUMERATIONSTATE\n";
5985 Preamble +=
"#endif\n";
5986 Preamble +=
"#ifndef __NSCONSTANTSTRINGIMPL\n";
5987 Preamble +=
"struct __NSConstantStringImpl {\n";
5988 Preamble +=
" int *isa;\n";
5989 Preamble +=
" int flags;\n";
5990 Preamble +=
" char *str;\n";
5991 Preamble +=
"#if _WIN64\n";
5992 Preamble +=
" long long length;\n";
5993 Preamble +=
"#else\n";
5994 Preamble +=
" long length;\n";
5995 Preamble +=
"#endif\n";
5997 Preamble +=
"#ifdef CF_EXPORT_CONSTANT_STRING\n";
5998 Preamble +=
"extern \"C\" __declspec(dllexport) int __CFConstantStringClassReference[];\n";
5999 Preamble +=
"#else\n";
6000 Preamble +=
"__OBJC_RW_DLLIMPORT int __CFConstantStringClassReference[];\n";
6001 Preamble +=
"#endif\n";
6002 Preamble +=
"#define __NSCONSTANTSTRINGIMPL\n";
6003 Preamble +=
"#endif\n";
6005 Preamble +=
"#ifndef BLOCK_IMPL\n";
6006 Preamble +=
"#define BLOCK_IMPL\n";
6007 Preamble +=
"struct __block_impl {\n";
6008 Preamble +=
" void *isa;\n";
6009 Preamble +=
" int Flags;\n";
6010 Preamble +=
" int Reserved;\n";
6011 Preamble +=
" void *FuncPtr;\n";
6013 Preamble +=
"// Runtime copy/destroy helper functions (from Block_private.h)\n";
6014 Preamble +=
"#ifdef __OBJC_EXPORT_BLOCKS\n";
6015 Preamble +=
"extern \"C\" __declspec(dllexport) " 6016 "void _Block_object_assign(void *, const void *, const int);\n";
6017 Preamble +=
"extern \"C\" __declspec(dllexport) void _Block_object_dispose(const void *, const int);\n";
6018 Preamble +=
"extern \"C\" __declspec(dllexport) void *_NSConcreteGlobalBlock[32];\n";
6019 Preamble +=
"extern \"C\" __declspec(dllexport) void *_NSConcreteStackBlock[32];\n";
6020 Preamble +=
"#else\n";
6021 Preamble +=
"__OBJC_RW_DLLIMPORT void _Block_object_assign(void *, const void *, const int);\n";
6022 Preamble +=
"__OBJC_RW_DLLIMPORT void _Block_object_dispose(const void *, const int);\n";
6023 Preamble +=
"__OBJC_RW_DLLIMPORT void *_NSConcreteGlobalBlock[32];\n";
6024 Preamble +=
"__OBJC_RW_DLLIMPORT void *_NSConcreteStackBlock[32];\n";
6025 Preamble +=
"#endif\n";
6026 Preamble +=
"#endif\n";
6027 if (LangOpts.MicrosoftExt) {
6028 Preamble +=
"#undef __OBJC_RW_DLLIMPORT\n";
6029 Preamble +=
"#undef __OBJC_RW_STATICIMPORT\n";
6030 Preamble +=
"#ifndef KEEP_ATTRIBUTES\n";
6031 Preamble +=
"#define __attribute__(X)\n";
6032 Preamble +=
"#endif\n";
6033 Preamble +=
"#ifndef __weak\n";
6034 Preamble +=
"#define __weak\n";
6035 Preamble +=
"#endif\n";
6036 Preamble +=
"#ifndef __block\n";
6037 Preamble +=
"#define __block\n";
6038 Preamble +=
"#endif\n";
6041 Preamble +=
"#define __block\n";
6042 Preamble +=
"#define __weak\n";
6046 Preamble +=
"\n#include <stdarg.h>\n";
6047 Preamble +=
"struct __NSContainer_literal {\n";
6048 Preamble +=
" void * *arr;\n";
6049 Preamble +=
" __NSContainer_literal (unsigned int count, ...) {\n";
6050 Preamble +=
"\tva_list marker;\n";
6051 Preamble +=
"\tva_start(marker, count);\n";
6052 Preamble +=
"\tarr = new void *[count];\n";
6053 Preamble +=
"\tfor (unsigned i = 0; i < count; i++)\n";
6054 Preamble +=
"\t arr[i] = va_arg(marker, void *);\n";
6055 Preamble +=
"\tva_end( marker );\n";
6056 Preamble +=
" };\n";
6057 Preamble +=
" ~__NSContainer_literal() {\n";
6058 Preamble +=
"\tdelete[] arr;\n";
6063 Preamble +=
"extern \"C\" __declspec(dllimport) void * objc_autoreleasePoolPush(void);\n";
6064 Preamble +=
"extern \"C\" __declspec(dllimport) void objc_autoreleasePoolPop(void *);\n\n";
6065 Preamble +=
"struct __AtAutoreleasePool {\n";
6066 Preamble +=
" __AtAutoreleasePool() {atautoreleasepoolobj = objc_autoreleasePoolPush();}\n";
6067 Preamble +=
" ~__AtAutoreleasePool() {objc_autoreleasePoolPop(atautoreleasepoolobj);}\n";
6068 Preamble +=
" void * atautoreleasepoolobj;\n";
6073 Preamble +=
"\n#define __OFFSETOFIVAR__(TYPE, MEMBER) ((long long) &((TYPE *)0)->MEMBER)\n";
6078 void RewriteModernObjC::RewriteIvarOffsetComputation(
ObjCIvarDecl *ivar,
6079 std::string &Result) {
6080 Result +=
"__OFFSETOFIVAR__(struct ";
6082 if (LangOpts.MicrosoftExt)
6086 ObjCIvarBitfieldGroupDecl(ivar, Result);
6195 static bool meta_data_declared =
false;
6196 if (meta_data_declared)
6199 Result +=
"\nstruct _prop_t {\n";
6200 Result +=
"\tconst char *name;\n";
6201 Result +=
"\tconst char *attributes;\n";
6204 Result +=
"\nstruct _protocol_t;\n";
6206 Result +=
"\nstruct _objc_method {\n";
6207 Result +=
"\tstruct objc_selector * _cmd;\n";
6208 Result +=
"\tconst char *method_type;\n";
6209 Result +=
"\tvoid *_imp;\n";
6212 Result +=
"\nstruct _protocol_t {\n";
6213 Result +=
"\tvoid * isa; // NULL\n";
6214 Result +=
"\tconst char *protocol_name;\n";
6215 Result +=
"\tconst struct _protocol_list_t * protocol_list; // super protocols\n";
6216 Result +=
"\tconst struct method_list_t *instance_methods;\n";
6217 Result +=
"\tconst struct method_list_t *class_methods;\n";
6218 Result +=
"\tconst struct method_list_t *optionalInstanceMethods;\n";
6219 Result +=
"\tconst struct method_list_t *optionalClassMethods;\n";
6220 Result +=
"\tconst struct _prop_list_t * properties;\n";
6221 Result +=
"\tconst unsigned int size; // sizeof(struct _protocol_t)\n";
6222 Result +=
"\tconst unsigned int flags; // = 0\n";
6223 Result +=
"\tconst char ** extendedMethodTypes;\n";
6226 Result +=
"\nstruct _ivar_t {\n";
6227 Result +=
"\tunsigned long int *offset; // pointer to ivar offset location\n";
6228 Result +=
"\tconst char *name;\n";
6229 Result +=
"\tconst char *type;\n";
6230 Result +=
"\tunsigned int alignment;\n";
6231 Result +=
"\tunsigned int size;\n";
6234 Result +=
"\nstruct _class_ro_t {\n";
6235 Result +=
"\tunsigned int flags;\n";
6236 Result +=
"\tunsigned int instanceStart;\n";
6237 Result +=
"\tunsigned int instanceSize;\n";
6239 if (Triple.getArch() == llvm::Triple::x86_64)
6240 Result +=
"\tunsigned int reserved;\n";
6241 Result +=
"\tconst unsigned char *ivarLayout;\n";
6242 Result +=
"\tconst char *name;\n";
6243 Result +=
"\tconst struct _method_list_t *baseMethods;\n";
6244 Result +=
"\tconst struct _objc_protocol_list *baseProtocols;\n";
6245 Result +=
"\tconst struct _ivar_list_t *ivars;\n";
6246 Result +=
"\tconst unsigned char *weakIvarLayout;\n";
6247 Result +=
"\tconst struct _prop_list_t *properties;\n";
6250 Result +=
"\nstruct _class_t {\n";
6251 Result +=
"\tstruct _class_t *isa;\n";
6252 Result +=
"\tstruct _class_t *superclass;\n";
6253 Result +=
"\tvoid *cache;\n";
6254 Result +=
"\tvoid *vtable;\n";
6255 Result +=
"\tstruct _class_ro_t *ro;\n";
6258 Result +=
"\nstruct _category_t {\n";
6259 Result +=
"\tconst char *name;\n";
6260 Result +=
"\tstruct _class_t *cls;\n";
6261 Result +=
"\tconst struct _method_list_t *instance_methods;\n";
6262 Result +=
"\tconst struct _method_list_t *class_methods;\n";
6263 Result +=
"\tconst struct _protocol_list_t *protocols;\n";
6264 Result +=
"\tconst struct _prop_list_t *properties;\n";
6267 Result +=
"extern \"C\" __declspec(dllimport) struct objc_cache _objc_empty_cache;\n";
6268 Result +=
"#pragma warning(disable:4273)\n";
6269 meta_data_declared =
true;
6273 long super_protocol_count) {
6274 Result +=
"struct /*_protocol_list_t*/"; Result +=
" {\n";
6275 Result +=
"\tlong protocol_count; // Note, this is 32/64 bit\n";
6276 Result +=
"\tstruct _protocol_t *super_protocols[";
6277 Result += utostr(super_protocol_count); Result +=
"];\n";
6282 unsigned int method_count) {
6283 Result +=
"struct /*_method_list_t*/"; Result +=
" {\n";
6284 Result +=
"\tunsigned int entsize; // sizeof(struct _objc_method)\n";
6285 Result +=
"\tunsigned int method_count;\n";
6286 Result +=
"\tstruct _objc_method method_list[";
6287 Result += utostr(method_count); Result +=
"];\n";
6292 unsigned int property_count) {
6293 Result +=
"struct /*_prop_list_t*/"; Result +=
" {\n";
6294 Result +=
"\tunsigned int entsize; // sizeof(struct _prop_t)\n";
6295 Result +=
"\tunsigned int count_of_properties;\n";
6296 Result +=
"\tstruct _prop_t prop_list[";
6297 Result += utostr(property_count); Result +=
"];\n";
6302 unsigned int ivar_count) {
6303 Result +=
"struct /*_ivar_list_t*/"; Result +=
" {\n";
6304 Result +=
"\tunsigned int entsize; // sizeof(struct _prop_t)\n";
6305 Result +=
"\tunsigned int count;\n";
6306 Result +=
"\tstruct _ivar_t ivar_list[";
6307 Result += utostr(ivar_count); Result +=
"];\n";
6314 StringRef ProtocolName) {
6315 if (SuperProtocols.size() > 0) {
6316 Result +=
"\nstatic ";
6318 Result +=
" "; Result += VarName;
6319 Result += ProtocolName;
6320 Result +=
" __attribute__ ((used, section (\"__DATA,__objc_const\"))) = {\n";
6321 Result +=
"\t"; Result += utostr(SuperProtocols.size()); Result +=
",\n";
6322 for (
unsigned i = 0, e = SuperProtocols.size(); i < e; i++) {
6324 Result +=
"\t&"; Result +=
"_OBJC_PROTOCOL_";
6338 StringRef TopLevelDeclName,
6340 if (Methods.size() > 0) {
6341 Result +=
"\nstatic ";
6343 Result +=
" "; Result += VarName;
6344 Result += TopLevelDeclName;
6345 Result +=
" __attribute__ ((used, section (\"__DATA,__objc_const\"))) = {\n";
6346 Result +=
"\t"; Result +=
"sizeof(_objc_method)"; Result +=
",\n";
6347 Result +=
"\t"; Result += utostr(Methods.size()); Result +=
",\n";
6348 for (
unsigned i = 0, e = Methods.size(); i < e; i++) {
6351 Result +=
"\t{{(struct objc_selector *)\"";
6353 Result +=
"\t{(struct objc_selector *)\"";
6354 Result += (MD)->getSelector().getAsString(); Result +=
"\"";
6357 Result +=
"\""; Result += MethodTypeString; Result +=
"\"";
6362 Result +=
"(void *)";
6363 Result += RewriteObj.MethodInternalNames[MD];
6377 const Decl *Container,
6379 StringRef ProtocolName) {
6380 if (Properties.size() > 0) {
6381 Result +=
"\nstatic ";
6383 Result +=
" "; Result += VarName;
6384 Result += ProtocolName;
6385 Result +=
" __attribute__ ((used, section (\"__DATA,__objc_const\"))) = {\n";
6386 Result +=
"\t"; Result +=
"sizeof(_prop_t)"; Result +=
",\n";
6387 Result +=
"\t"; Result += utostr(Properties.size()); Result +=
",\n";
6388 for (
unsigned i = 0, e = Properties.size(); i < e; i++) {
6394 Result += PropDecl->
getName(); Result +=
"\",";
6395 std::string PropertyTypeString =
6397 std::string QuotePropertyTypeString;
6398 RewriteObj.QuoteDoublequotes(PropertyTypeString, QuotePropertyTypeString);
6399 Result +=
"\""; Result += QuotePropertyTypeString; Result +=
"\"";
6425 const std::string &InstanceStart,
6426 const std::string &InstanceSize,
6432 StringRef ClassName) {
6433 Result +=
"\nstatic struct _class_ro_t ";
6434 Result += VarName; Result += ClassName;
6435 Result +=
" __attribute__ ((used, section (\"__DATA,__objc_const\"))) = {\n";
6437 Result += llvm::utostr(flags); Result +=
", ";
6438 Result += InstanceStart; Result +=
", ";
6439 Result += InstanceSize; Result +=
", \n";
6442 if (Triple.getArch() == llvm::Triple::x86_64)
6444 Result +=
"(unsigned int)0, \n\t";
6446 Result +=
"0, \n\t";
6447 Result +=
"\""; Result += ClassName; Result +=
"\",\n\t";
6448 bool metaclass = ((flags &
CLS_META) != 0);
6449 if (baseMethods.size() > 0) {
6450 Result +=
"(const struct _method_list_t *)&";
6452 Result +=
"_OBJC_$_CLASS_METHODS_";
6454 Result +=
"_OBJC_$_INSTANCE_METHODS_";
6455 Result += ClassName;
6459 Result +=
"0, \n\t";
6461 if (!metaclass && baseProtocols.size() > 0) {
6462 Result +=
"(const struct _objc_protocol_list *)&";
6463 Result +=
"_OBJC_CLASS_PROTOCOLS_$_"; Result += ClassName;
6467 Result +=
"0, \n\t";
6469 if (!metaclass && ivars.size() > 0) {
6470 Result +=
"(const struct _ivar_list_t *)&";
6471 Result +=
"_OBJC_$_INSTANCE_VARIABLES_"; Result += ClassName;
6475 Result +=
"0, \n\t";
6478 Result +=
"0, \n\t";
6479 if (!metaclass && Properties.size() > 0) {
6480 Result +=
"(const struct _prop_list_t *)&";
6481 Result +=
"_OBJC_$_PROP_LIST_"; Result += ClassName;
6492 const ObjCInterfaceDecl *CDecl,
bool metaclass) {
6494 const ObjCInterfaceDecl *RootClass = CDecl;
6504 if (metaclass && rootClass) {
6507 Result +=
"extern \"C\" ";
6509 Result +=
"__declspec(dllexport) ";
6511 Result +=
"__declspec(dllimport) ";
6513 Result +=
"struct _class_t OBJC_CLASS_$_";
6521 Result +=
"extern \"C\" ";
6523 Result +=
"__declspec(dllexport) ";
6525 Result +=
"__declspec(dllimport) ";
6527 Result +=
"struct _class_t ";
6532 if (metaclass && RootClass != SuperClass) {
6533 Result +=
"extern \"C\" ";
6535 Result +=
"__declspec(dllexport) ";
6537 Result +=
"__declspec(dllimport) ";
6539 Result +=
"struct _class_t ";
6546 Result +=
"\nextern \"C\" __declspec(dllexport) struct _class_t ";
6548 Result +=
" __attribute__ ((used, section (\"__DATA,__objc_data\"))) = {\n";
6552 Result +=
"0, // &"; Result += VarName;
6555 Result +=
"0, // &"; Result += VarName;
6560 Result +=
"0, // &"; Result += VarName;
6568 Result +=
"0, // &OBJC_METACLASS_$_";
6572 Result +=
"0, // &"; Result += VarName;
6579 Result +=
"0, // (void *)&_objc_empty_cache,\n\t";
6580 Result +=
"0, // unused, was (void *)&_objc_empty_vtable,\n\t";
6582 Result +=
"&_OBJC_METACLASS_RO_$_";
6584 Result +=
"&_OBJC_CLASS_RO_$_";
6586 Result +=
",\n};\n";
6593 const ObjCInterfaceDecl *SuperClass =
6596 Result +=
"static void OBJC_CLASS_SETUP_$_";
6598 Result +=
"(void ) {\n";
6600 Result +=
".isa = "; Result +=
"&OBJC_METACLASS_$_";
6604 Result +=
".superclass = ";
6606 Result +=
"&OBJC_CLASS_$_";
6608 Result +=
"&OBJC_METACLASS_$_";
6613 Result +=
".cache = "; Result +=
"&_objc_empty_cache"; Result +=
";\n";
6616 Result +=
".isa = "; Result +=
"&OBJC_METACLASS_$_";
6621 Result +=
".superclass = "; Result +=
"&OBJC_CLASS_$_";
6626 Result +=
".cache = "; Result +=
"&_objc_empty_cache"; Result +=
";\n";
6631 std::string &Result,
6633 ObjCInterfaceDecl *ClassDecl,
6638 StringRef CatName = CatDecl->
getName();
6639 StringRef ClassName = ClassDecl->
getName();
6643 Result +=
"extern \"C\" ";
6645 Result +=
"__declspec(dllexport) ";
6647 Result +=
"__declspec(dllimport) ";
6649 Result +=
"struct _class_t ";
6650 Result +=
"OBJC_CLASS_$_"; Result += ClassName;
6653 Result +=
"\nstatic struct _category_t ";
6654 Result +=
"_OBJC_$_CATEGORY_";
6655 Result += ClassName; Result +=
"_$_"; Result += CatName;
6656 Result +=
" __attribute__ ((used, section (\"__DATA,__objc_const\"))) = \n";
6658 Result +=
"\t\""; Result += ClassName; Result +=
"\",\n";
6659 Result +=
"\t0, // &"; Result +=
"OBJC_CLASS_$_"; Result += ClassName;
6661 if (InstanceMethods.size() > 0) {
6662 Result +=
"\t(const struct _method_list_t *)&";
6663 Result +=
"_OBJC_$_CATEGORY_INSTANCE_METHODS_";
6664 Result += ClassName; Result +=
"_$_"; Result += CatName;
6670 if (ClassMethods.size() > 0) {
6671 Result +=
"\t(const struct _method_list_t *)&";
6672 Result +=
"_OBJC_$_CATEGORY_CLASS_METHODS_";
6673 Result += ClassName; Result +=
"_$_"; Result += CatName;
6679 if (RefedProtocols.size() > 0) {
6680 Result +=
"\t(const struct _protocol_list_t *)&";
6681 Result +=
"_OBJC_CATEGORY_PROTOCOLS_$_";
6682 Result += ClassName; Result +=
"_$_"; Result += CatName;
6688 if (ClassProperties.size() > 0) {
6689 Result +=
"\t(const struct _prop_list_t *)&"; Result +=
"_OBJC_$_PROP_LIST_";
6690 Result += ClassName; Result +=
"_$_"; Result += CatName;
6699 Result +=
"static void OBJC_CATEGORY_SETUP_$_";
6703 Result +=
"(void ) {\n";
6704 Result +=
"\t_OBJC_$_CATEGORY_";
6708 Result +=
".cls = "; Result +=
"&OBJC_CLASS_$_"; Result += ClassName;
6716 StringRef ProtocolName) {
6717 if (Methods.size() == 0)
6720 Result +=
"\nstatic const char *";
6721 Result += VarName; Result += ProtocolName;
6722 Result +=
" [] __attribute__ ((used, section (\"__DATA,__objc_const\"))) = \n";
6724 for (
unsigned i = 0, e = Methods.size(); i < e; i++) {
6726 std::string MethodTypeString =
6728 std::string QuoteMethodTypeString;
6729 RewriteObj.QuoteDoublequotes(MethodTypeString, QuoteMethodTypeString);
6730 Result +=
"\t\""; Result += QuoteMethodTypeString; Result +=
"\"";
6741 std::string &Result,
6743 ObjCInterfaceDecl *CDecl) {
6756 for (
unsigned i =0, e = Ivars.size(); i < e; i++) {
6759 Result +=
"__declspec(allocate(\".objc_ivar$B\")) ";
6764 Result +=
"extern \"C\" unsigned long int ";
6766 Result +=
"extern \"C\" __declspec(dllexport) unsigned long int ";
6767 if (Ivars[i]->isBitField())
6768 RewriteObj.ObjCIvarBitfieldGroupOffset(IvarDecl, Result);
6771 Result +=
" __attribute__ ((used, section (\"__DATA,__objc_ivar\")))";
6773 RewriteObj.RewriteIvarOffsetComputation(IvarDecl, Result);
6775 if (Ivars[i]->isBitField()) {
6786 ObjCInterfaceDecl *CDecl) {
6787 if (OriginalIvars.size() > 0) {
6793 for (
unsigned i = 0, e = OriginalIvars.size(); i < e; i++) {
6794 if (OriginalIvars[i]->isBitField()) {
6795 Ivars.push_back(OriginalIvars[i]);
6800 Ivars.push_back(OriginalIvars[i]);
6803 Result +=
"\nstatic ";
6805 Result +=
" "; Result += VarName;
6807 Result +=
" __attribute__ ((used, section (\"__DATA,__objc_const\"))) = {\n";
6808 Result +=
"\t"; Result +=
"sizeof(_ivar_t)"; Result +=
",\n";
6809 Result +=
"\t"; Result += utostr(Ivars.size()); Result +=
",\n";
6810 for (
unsigned i =0, e = Ivars.size(); i < e; i++) {
6816 Result +=
"(unsigned long int *)&";
6817 if (Ivars[i]->isBitField())
6818 RewriteObj.ObjCIvarBitfieldGroupOffset(IvarDecl, Result);
6824 if (Ivars[i]->isBitField())
6825 RewriteObj.ObjCIvarBitfieldGroupDecl(Ivars[i], Result);
6827 Result += IvarDecl->
getName();
6832 IVQT = RewriteObj.GetGroupRecordTypeForObjCIvarBitfield(IvarDecl);
6834 std::string IvarTypeString, QuoteIvarTypeString;
6837 RewriteObj.QuoteDoublequotes(IvarTypeString, QuoteIvarTypeString);
6838 Result +=
"\""; Result += QuoteIvarTypeString; Result +=
"\", ";
6843 Align = llvm::Log2_32(Align);
6844 Result += llvm::utostr(Align); Result +=
", ";
6857 void RewriteModernObjC::RewriteObjCProtocolMetaData(
ObjCProtocolDecl *PDecl,
6858 std::string &Result) {
6870 RewriteObjCProtocolMetaData(I, Result);
6873 std::vector<ObjCMethodDecl *> InstanceMethods, ClassMethods;
6874 std::vector<ObjCMethodDecl *> OptInstanceMethods, OptClassMethods;
6877 OptInstanceMethods.push_back(MD);
6879 InstanceMethods.push_back(MD);
6885 OptClassMethods.push_back(MD);
6887 ClassMethods.push_back(MD);
6890 std::vector<ObjCMethodDecl *> AllMethods;
6891 for (
unsigned i = 0, e = InstanceMethods.size(); i < e; i++)
6892 AllMethods.push_back(InstanceMethods[i]);
6893 for (
unsigned i = 0, e = ClassMethods.size(); i < e; i++)
6894 AllMethods.push_back(ClassMethods[i]);
6895 for (
unsigned i = 0, e = OptInstanceMethods.size(); i < e; i++)
6896 AllMethods.push_back(OptInstanceMethods[i]);
6897 for (
unsigned i = 0, e = OptClassMethods.size(); i < e; i++)
6898 AllMethods.push_back(OptClassMethods[i]);
6902 "_OBJC_PROTOCOL_METHOD_TYPES_",
6907 "_OBJC_PROTOCOL_REFS_",
6911 "_OBJC_PROTOCOL_INSTANCE_METHODS_",
6915 "_OBJC_PROTOCOL_CLASS_METHODS_",
6919 "_OBJC_PROTOCOL_OPT_INSTANCE_METHODS_",
6923 "_OBJC_PROTOCOL_OPT_CLASS_METHODS_",
6931 "_OBJC_PROTOCOL_PROPERTIES_",
6936 if (LangOpts.MicrosoftExt)
6937 Result +=
"static ";
6938 Result +=
"struct _protocol_t _OBJC_PROTOCOL_";
6940 Result +=
" __attribute__ ((used)) = {\n";
6942 Result +=
"\t\""; Result += PDecl->
getNameAsString(); Result +=
"\",\n";
6943 if (SuperProtocols.size() > 0) {
6944 Result +=
"\t(const struct _protocol_list_t *)&"; Result +=
"_OBJC_PROTOCOL_REFS_";
6949 if (InstanceMethods.size() > 0) {
6950 Result +=
"\t(const struct method_list_t *)&_OBJC_PROTOCOL_INSTANCE_METHODS_";
6956 if (ClassMethods.size() > 0) {
6957 Result +=
"\t(const struct method_list_t *)&_OBJC_PROTOCOL_CLASS_METHODS_";
6963 if (OptInstanceMethods.size() > 0) {
6964 Result +=
"\t(const struct method_list_t *)&_OBJC_PROTOCOL_OPT_INSTANCE_METHODS_";
6970 if (OptClassMethods.size() > 0) {
6971 Result +=
"\t(const struct method_list_t *)&_OBJC_PROTOCOL_OPT_CLASS_METHODS_";
6977 if (ProtocolProperties.size() > 0) {
6978 Result +=
"\t(const struct _prop_list_t *)&_OBJC_PROTOCOL_PROPERTIES_";
6984 Result +=
"\t"; Result +=
"sizeof(_protocol_t)"; Result +=
",\n";
6987 if (AllMethods.size() > 0) {
6988 Result +=
"\t(const char **)&"; Result +=
"_OBJC_PROTOCOL_METHOD_TYPES_";
6993 Result +=
"\t0\n};\n";
6995 if (LangOpts.MicrosoftExt)
6996 Result +=
"static ";
6997 Result +=
"struct _protocol_t *";
6998 Result +=
"_OBJC_LABEL_PROTOCOL_$_"; Result += PDecl->
getNameAsString();
7004 llvm_unreachable(
"protocol already synthesized");
7011 const ObjCInterfaceDecl *OID) {
7012 if (OID->
hasAttr<ObjCExceptionAttr>())
7020 std::string &Result) {
7026 "Legacy implicit interface rewriting not supported in moder abi");
7034 if (!IVD->getDeclName())
7036 IVars.push_back(IVD);
7040 "_OBJC_$_INSTANCE_VARIABLES_",
7051 if (!Prop->getPropertyIvarDecl())
7058 InstanceMethods.push_back(Getter);
7063 InstanceMethods.push_back(Setter);
7067 "_OBJC_$_INSTANCE_METHODS_",
7073 "_OBJC_$_CLASS_METHODS_",
7078 std::vector<ObjCProtocolDecl *> RefedProtocols;
7081 E = Protocols.
end();
7083 RefedProtocols.push_back(*I);
7086 RewriteObjCProtocolMetaData(*I, Result);
7091 "_OBJC_CLASS_PROTOCOLS_$_",
7099 "_OBJC_$_PROP_LIST_",
7104 std::string InstanceSize;
7105 std::string InstanceStart;
7114 InstanceSize =
"sizeof(struct _class_t)";
7115 InstanceStart = InstanceSize;
7117 InstanceStart, InstanceSize,
7122 "_OBJC_METACLASS_RO_$_",
7137 InstanceSize.clear();
7138 InstanceStart.clear();
7139 if (!ObjCSynthesizedStructs.count(CDecl)) {
7141 InstanceStart =
"0";
7144 InstanceSize =
"sizeof(struct ";
7146 InstanceSize +=
"_IMPL)";
7150 RewriteIvarOffsetComputation(IVD, InstanceStart);
7153 InstanceStart = InstanceSize;
7156 InstanceStart, InstanceSize,
7161 "_OBJC_CLASS_RO_$_",
7165 "OBJC_METACLASS_$_",
7172 if (ImplementationIsNonLazy(IDecl))
7173 DefinedNonLazyClasses.push_back(CDecl);
7176 void RewriteModernObjC::RewriteClassSetupInitHook(std::string &Result) {
7177 int ClsDefCount = ClassImplementation.size();
7180 Result +=
"#pragma section(\".objc_inithooks$B\", long, read, write)\n";
7181 Result +=
"__declspec(allocate(\".objc_inithooks$B\")) ";
7182 Result +=
"static void *OBJC_CLASS_SETUP[] = {\n";
7183 for (
int i = 0; i < ClsDefCount; i++) {
7186 Result +=
"\t(void *)&OBJC_CLASS_SETUP_$_";
7187 Result += CDecl->
getName(); Result +=
",\n";
7192 void RewriteModernObjC::RewriteMetaDataIntoBuffer(std::string &Result) {
7193 int ClsDefCount = ClassImplementation.size();
7194 int CatDefCount = CategoryImplementation.size();
7197 for (
int i = 0; i < ClsDefCount; i++)
7198 RewriteObjCClassMetaData(ClassImplementation[i], Result);
7200 RewriteClassSetupInitHook(Result);
7203 for (
int i = 0; i < CatDefCount; i++)
7204 RewriteObjCCategoryImplDecl(CategoryImplementation[i], Result);
7206 RewriteCategorySetupInitHook(Result);
7208 if (ClsDefCount > 0) {
7209 if (LangOpts.MicrosoftExt)
7210 Result +=
"__declspec(allocate(\".objc_classlist$B\")) ";
7211 Result +=
"static struct _class_t *L_OBJC_LABEL_CLASS_$ [";
7212 Result += llvm::utostr(ClsDefCount); Result +=
"]";
7214 " __attribute__((used, section (\"__DATA, __objc_classlist," 7215 "regular,no_dead_strip\")))= {\n";
7216 for (
int i = 0; i < ClsDefCount; i++) {
7217 Result +=
"\t&OBJC_CLASS_$_";
7218 Result += ClassImplementation[i]->getNameAsString();
7223 if (!DefinedNonLazyClasses.empty()) {
7224 if (LangOpts.MicrosoftExt)
7225 Result +=
"__declspec(allocate(\".objc_nlclslist$B\")) \n";
7226 Result +=
"static struct _class_t *_OBJC_LABEL_NONLAZY_CLASS_$[] = {\n\t";
7227 for (
unsigned i = 0, e = DefinedNonLazyClasses.size(); i < e; i++) {
7228 Result +=
"\t&OBJC_CLASS_$_"; Result += DefinedNonLazyClasses[i]->getNameAsString();
7235 if (CatDefCount > 0) {
7236 if (LangOpts.MicrosoftExt)
7237 Result +=
"__declspec(allocate(\".objc_catlist$B\")) ";
7238 Result +=
"static struct _category_t *L_OBJC_LABEL_CATEGORY_$ [";
7239 Result += llvm::utostr(CatDefCount); Result +=
"]";
7241 " __attribute__((used, section (\"__DATA, __objc_catlist," 7242 "regular,no_dead_strip\")))= {\n";
7243 for (
int i = 0; i < CatDefCount; i++) {
7244 Result +=
"\t&_OBJC_$_CATEGORY_";
7246 CategoryImplementation[i]->getClassInterface()->getNameAsString();
7248 Result += CategoryImplementation[i]->getNameAsString();
7254 if (!DefinedNonLazyCategories.empty()) {
7255 if (LangOpts.MicrosoftExt)
7256 Result +=
"__declspec(allocate(\".objc_nlcatlist$B\")) \n";
7257 Result +=
"static struct _category_t *_OBJC_LABEL_NONLAZY_CATEGORY_$[] = {\n\t";
7258 for (
unsigned i = 0, e = DefinedNonLazyCategories.size(); i < e; i++) {
7259 Result +=
"\t&_OBJC_$_CATEGORY_";
7261 DefinedNonLazyCategories[i]->getClassInterface()->getNameAsString();
7263 Result += DefinedNonLazyCategories[i]->getNameAsString();
7270 void RewriteModernObjC::WriteImageInfo(std::string &Result) {
7271 if (LangOpts.MicrosoftExt)
7272 Result +=
"__declspec(allocate(\".objc_imageinfo$B\")) \n";
7274 Result +=
"static struct IMAGE_INFO { unsigned version; unsigned flag; } ";
7276 Result +=
"_OBJC_IMAGE_INFO = { 0, 2 };\n";
7282 std::string &Result) {
7290 FullCategoryName +=
"_$_";
7301 if (!Prop->getPropertyIvarDecl())
7307 InstanceMethods.push_back(Getter);
7311 InstanceMethods.push_back(Setter);
7315 "_OBJC_$_CATEGORY_INSTANCE_METHODS_",
7316 FullCategoryName,
true);
7321 "_OBJC_$_CATEGORY_CLASS_METHODS_",
7322 FullCategoryName,
true);
7330 RewriteObjCProtocolMetaData(I, Result);
7334 "_OBJC_CATEGORY_PROTOCOLS_$_",
7342 "_OBJC_$_PROP_LIST_",
7354 if (ImplementationIsNonLazy(IDecl))
7355 DefinedNonLazyCategories.push_back(CDecl);
7358 void RewriteModernObjC::RewriteCategorySetupInitHook(std::string &Result) {
7359 int CatDefCount = CategoryImplementation.size();
7362 Result +=
"#pragma section(\".objc_inithooks$B\", long, read, write)\n";
7363 Result +=
"__declspec(allocate(\".objc_inithooks$B\")) ";
7364 Result +=
"static void *OBJC_CATEGORY_SETUP[] = {\n";
7365 for (
int i = 0; i < CatDefCount; i++) {
7369 Result +=
"\t(void *)&OBJC_CATEGORY_SETUP_$_";
7370 Result += ClassDecl->
getName();
7380 template<
typename MethodIterator>
7381 void RewriteModernObjC::RewriteObjCMethodsMetaData(MethodIterator MethodBegin,
7382 MethodIterator MethodEnd,
7383 bool IsInstanceMethod,
7385 StringRef ClassName,
7386 std::string &Result) {
7387 if (MethodBegin == MethodEnd)
return;
7389 if (!objc_impl_method) {
7396 Result +=
"\nstruct _objc_method {\n";
7397 Result +=
"\tSEL _cmd;\n";
7398 Result +=
"\tchar *method_types;\n";
7399 Result +=
"\tvoid *_imp;\n";
7402 objc_impl_method =
true;
7413 unsigned NumMethods =
std::distance(MethodBegin, MethodEnd);
7415 if (LangOpts.MicrosoftExt) {
7416 if (IsInstanceMethod)
7417 Result +=
"__declspec(allocate(\".inst_meth$B\")) ";
7419 Result +=
"__declspec(allocate(\".cls_meth$B\")) ";
7421 Result +=
"static struct {\n";
7422 Result +=
"\tstruct _objc_method_list *next_method;\n";
7423 Result +=
"\tint method_count;\n";
7424 Result +=
"\tstruct _objc_method method_list[";
7425 Result += utostr(NumMethods);
7426 Result +=
"];\n} _OBJC_";
7428 Result += IsInstanceMethod ?
"INSTANCE" :
"CLASS";
7429 Result +=
"_METHODS_";
7430 Result += ClassName;
7431 Result +=
" __attribute__ ((used, section (\"__OBJC, __";
7432 Result += IsInstanceMethod ?
"inst" :
"cls";
7433 Result +=
"_meth\")))= ";
7434 Result +=
"{\n\t0, " + utostr(NumMethods) +
"\n";
7436 Result +=
"\t,{{(SEL)\"";
7437 Result += (*MethodBegin)->getSelector().getAsString().c_str();
7438 std::string MethodTypeString;
7441 Result += MethodTypeString;
7442 Result +=
"\", (void *)";
7443 Result += MethodInternalNames[*MethodBegin];
7445 for (++MethodBegin; MethodBegin != MethodEnd; ++MethodBegin) {
7446 Result +=
"\t ,{(SEL)\"";
7447 Result += (*MethodBegin)->getSelector().getAsString().c_str();
7448 std::string MethodTypeString;
7451 Result += MethodTypeString;
7452 Result +=
"\", (void *)";
7453 Result += MethodInternalNames[*MethodBegin];
7456 Result +=
"\t }\n};\n";
7465 DisableReplaceStmtScope S(*
this);
7466 BaseExpr = cast<Expr>(RewriteFunctionBodyOrGlobalInitializer(BaseExpr));
7477 assert(iFaceDecl &&
"RewriteObjCIvarRefExpr - iFaceDecl is null");
7479 ObjCInterfaceDecl *clsDeclared =
nullptr;
7482 assert(clsDeclared &&
"RewriteObjCIvarRefExpr(): Can't find class");
7485 std::string IvarOffsetName;
7487 ObjCIvarBitfieldGroupOffset(D, IvarOffsetName);
7491 ReferencedIvars[clsDeclared].insert(D);
7515 IvarT = GetGroupRecordTypeForObjCIvarBitfield(D);
7517 if (!isa<TypedefType>(IvarT) && IvarT->
isRecordType()) {
7527 std::string RecName = CDecl->
getName();
7533 unsigned UnsignedIntSize =
7536 llvm::APInt(UnsignedIntSize, 0),
7538 Zero = NoTypeInfoCStyleCastExpr(Context, PtrStructIMPL, CK_BitCast, Zero);
7553 convertObjCTypeToCStyleType(IvarT);
7556 castExpr = NoTypeInfoCStyleCastExpr(Context,
7586 ReplaceStmtWithRange(IV, Replacement, OldRange);
7590 #endif // CLANG_ENABLE_OBJC_REWRITER unsigned getNumSemanticExprs() const
QualType getDecltypeType(Expr *e, QualType UnderlyingType) const
C++11 decltype.
SourceLocation getLocForStartOfFile(FileID FID) const
Return the source location corresponding to the first byte of the specified file. ...
The receiver is the instance of the superclass object.
const BlockDecl * getBlockDecl() const
static bool scanForProtocolRefs(const char *startBuf, const char *endBuf, const char *&startRef, const char *&endRef)
QualType withConst() const
Retrieves a version of this type with const applied.
Represents a function declaration or definition.
The receiver is an object instance.
Expr * getSyntacticForm()
Return the syntactic form of this expression, i.e.
ObjCDictionaryElement getKeyValueElement(unsigned Index) const
static void Write__prop_list_t_TypeDecl(std::string &Result, unsigned int property_count)
bool hasErrorOccurred() const
SourceLocation getLocWithOffset(int Offset) const
Return a source location with the specified offset from this SourceLocation.
const FunctionProtoType * getFunctionType() const
getFunctionType - Return the underlying function type for this block.
Smart pointer class that efficiently represents Objective-C method names.
QualType getObjCIdType() const
Represents the Objective-CC id type.
SourceLocation getLocStart() const LLVM_READONLY
PointerType - C99 6.7.5.1 - Pointer Declarators.
QualType getPointeeType() const
A (possibly-)qualified type.
bool isBlockPointerType() const
bool isOverloadedOperator() const
Whether this function declaration represents an C++ overloaded operator, e.g., "operator+".
ObjCInterfaceDecl * getClassInterface()
Selector getSelector() const
ObjCInterfaceDecl * getClassInterface()
ASTConsumer - This is an abstract interface that should be implemented by clients that read ASTs...
bool isExternC() const
Determines whether this function is a function with external, C linkage.
bool isThisDeclarationADefinition() const
Determine whether this particular declaration of this class is actually also a definition.
ObjCIvarDecl * getPropertyIvarDecl() const
static void scanToNextArgument(const char *&argRef)
SourceLocation getRParenLoc() const
ObjCProtocolDecl * getProtocol() const
Stmt - This represents one statement.
const ObjCAtFinallyStmt * getFinallyStmt() const
Retrieve the @finally statement, if any.
Expr * getBitWidth() const
FunctionType - C99 6.7.5.3 - Function Declarators.
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee...
bool isMain() const
Determines whether this function is "main", which is the entry point into an executable program...
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
bool isRealFloatingType() const
Floating point categories.
StorageClass getStorageClass() const
Returns the storage class as written in the source.
Defines the SourceManager interface.
static void Write_class_t(ASTContext *Context, std::string &Result, StringRef VarName, const ObjCInterfaceDecl *CDecl, bool metaclass)
bool isRecordType() const
Decl - This represents one declaration (or definition), e.g.
SourceLocation getLocEnd() const LLVM_READONLY
param_iterator param_end()
bool isBeforeInTranslationUnit(SourceLocation LHS, SourceLocation RHS) const
Determines the order of 2 source locations in the translation unit.
ParenExpr - This represents a parethesized expression, e.g.
const char * getCharacterData(SourceLocation SL, bool *Invalid=nullptr) const
Return a pointer to the start of the specified location in the appropriate spelling MemoryBuffer...
The base class of the type hierarchy.
SourceLocation getLocStart() const LLVM_READONLY
Represents Objective-C's @throw statement.
SourceLocation getLocStart() const LLVM_READONLY
CanQual< T > getUnqualifiedType() const
Retrieve the unqualified form of this type.
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
Represents an array type, per C99 6.7.5.2 - Array Declarators.
Represents a call to a C++ constructor.
const ObjCObjectPointerType * getAsObjCInterfacePointerType() const
bool isRestrictQualified() const
Determine whether this type is restrict-qualified.
virtual void completeDefinition()
Note that the definition of this type is now complete.
QualType withConst() const
SourceLocation getLParenLoc() const
const TargetInfo & getTargetInfo() const
A container of type source information.
Floating point control options.
constexpr XRayInstrMask Function
static StringLiteral * Create(const ASTContext &C, StringRef Str, StringKind Kind, bool Pascal, QualType Ty, const SourceLocation *Loc, unsigned NumStrs)
This is the "fully general" constructor that allows representation of strings formed from multiple co...
SourceLocation getLocStart() const LLVM_READONLY
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.
MutableArrayRef< ParmVarDecl * >::iterator param_iterator
QualType getElementType() const
bool isCompleteDefinition() const
Return true if this decl has its body fully specified.
StringRef getBufferData(FileID FID, bool *Invalid=nullptr) const
Return a StringRef to the source buffer data for the specified FileID.
unsigned getTypeAlign(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in bits.
bool isDefaultConstructor() const
Whether this constructor is a default constructor (C++ [class.ctor]p5), which can be used to default-...
enumerator_range enumerators() const
Represents a variable declaration or definition.
Objects with "hidden" visibility are not seen by the dynamic linker.
CompoundLiteralExpr - [C99 6.5.2.5].
unsigned getNumParams() const
bool isEnumeralType() const
const T * getAs() const
Member-template getAs<specific type>'.
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
ObjCMethodDecl - Represents an instance or class method declaration.
SourceLocation getLeftLoc() const
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)
QualType getObjCClassType() const
Represents the Objective-C Class type.
Describes how types, statements, expressions, and declarations should be printed. ...
classmeth_range class_methods() const
std::string getRewrittenText(SourceRange Range) const
getRewrittenText - Return the rewritten form of the text in the specified range.
protocol_range protocols() const
SourceLocation getLocStart() const LLVM_READONLY
const Stmt * getSubStmt() const
static void Write_protocol_list_initializer(ASTContext *Context, std::string &Result, ArrayRef< ObjCProtocolDecl *> SuperProtocols, StringRef VarName, StringRef ProtocolName)
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
static void Write__ivar_list_t_TypeDecl(std::string &Result, unsigned int ivar_count)
Represents a struct/union/class.
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
ObjCProtocolDecl * getCanonicalDecl() override
Retrieves the canonical declaration of this Objective-C protocol.
instprop_range instance_properties() const
One of these records is kept for each identifier that is lexed.
An element in an Objective-C dictionary literal.
QualType IgnoreParens() const
Returns the specified type after dropping any outer-level parentheses.
Represents a class type in Objective C.
static RecordDecl * Create(const ASTContext &C, TagKind TK, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, IdentifierInfo *Id, RecordDecl *PrevDecl=nullptr)
QualType getPointeeType() const
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 ...
ObjCMethodDecl * getClassMethod(Selector Sel, bool AllowHidden=false) const
RecordDecl * getDefinition() const
Returns the RecordDecl that actually defines this struct/union/class.
field_range fields() const
Represents a member of a struct/union/class.
std::unique_ptr< ASTConsumer > CreateModernObjCRewriter(const std::string &InFile, std::unique_ptr< raw_ostream > OS, DiagnosticsEngine &Diags, const LangOptions &LOpts, bool SilenceRewriteMacroWarning, bool LineInfo)
static ObjCMessageExpr * Create(const ASTContext &Context, QualType T, ExprValueKind VK, SourceLocation LBracLoc, SourceLocation SuperLoc, bool IsInstanceSuper, QualType SuperType, Selector Sel, ArrayRef< SourceLocation > SelLocs, ObjCMethodDecl *Method, ArrayRef< Expr *> Args, SourceLocation RBracLoc, bool isImplicit)
Create a message send to super.
instmeth_range instance_methods() const
StringLiteral * getString()
std::string getNameAsString() const
Get the name of the class associated with this interface.
SourceLocation getRParenLoc() const
ObjCMethodDecl * getSetterMethodDecl() const
bool ReplaceText(SourceLocation Start, unsigned OrigLength, StringRef NewStr)
ReplaceText - This method replaces a range of characters in the input buffer with a new string...
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]];.
bool isObjCQualifiedClassType() const
An r-value expression (a pr-value in the C++11 taxonomy) produces a temporary value.
Selector getSelector() const
Represents Objective-C's @catch statement.
Describes an C or C++ initializer list.
SourceLocation getIvarRBraceLoc() const
bool isBitField() const
Determines whether this field is a bitfield.
Stmt * getBody(const FunctionDecl *&Definition) const
Retrieve the body (definition) of the function.
ObjCContainerDecl - Represents a container for method declarations.
const Expr * getThrowExpr() const
CharUnits - This is an opaque type for sizes expressed in character units.
SourceLocation getLocEnd() const LLVM_READONLY
ExprValueKind getValueKind() const
getValueKind - The value kind that this expression produces.
SourceLocation getExpansionLoc(SourceLocation Loc) const
Given a SourceLocation object Loc, return the expansion location referenced by the ID...
PropertyAttributeKind getPropertyAttributes() const
Concrete class used by the front-end to report problems and issues.
Represents a typeof (or typeof) expression (a GCC extension).
const clang::PrintingPolicy & getPrintingPolicy() const
Represents a declaration of a type.
A builtin binary operation expression such as "x + y" or "x <= y".
bool isVolatileQualified() const
Determine whether this type is volatile-qualified.
bool isReadOnly() const
isReadOnly - Return true iff the property has a setter.
Defines the Diagnostic-related interfaces.
ObjCStringLiteral, used for Objective-C string literals i.e.
ObjCProtocolDecl * getDefinition()
Retrieve the definition of this protocol, if any.
void printPretty(raw_ostream &OS, PrinterHelper *Helper, const PrintingPolicy &Policy, unsigned Indentation=0, const ASTContext *Context=nullptr) const
void getAsStringInternal(std::string &Str, const PrintingPolicy &Policy) const
unsigned getBitWidthValue(const ASTContext &Ctx) const
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
CompoundStmt * getCompoundBody()
Represents an Objective-C protocol declaration.
Expr * Key
The key for the dictionary element.
const internal::VariadicDynCastAllOfMatcher< Stmt, CastExpr > castExpr
Matches any cast nodes of Clang's AST.
ObjCMethodDecl * getArrayWithObjectsMethod() const
static VarDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, StorageClass S)
SourceLocation getLocStart() const LLVM_READONLY
SourceLocation getLocEnd() const LLVM_READONLY
static IntegerLiteral * Create(const ASTContext &C, const llvm::APInt &V, QualType type, SourceLocation l)
Returns a new integer literal with value 'V' and type 'type'.
An ordinary object is located at an address in memory.
Represents an ObjC class declaration.
Represents a linkage specification.
QualType getReturnType() const
SourceLocation getTypeSpecStartLoc() const
const Stmt * getBody() const
SourceLocation getLocation() const
static FunctionDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation NLoc, DeclarationName N, QualType T, TypeSourceInfo *TInfo, StorageClass SC, bool isInlineSpecified=false, bool hasWrittenPrototype=true, bool isConstexprSpecified=false)
static void WriteInternalIvarName(const ObjCInterfaceDecl *IDecl, ObjCIvarDecl *IvarDecl, std::string &Result)
Iterator for iterating over Stmt * arrays that contain only Expr *.
std::string getObjCEncodingForMethodDecl(const ObjCMethodDecl *Decl, bool Extended=false) const
Emit the encoded type for the method declaration Decl into S.
ObjCMethodDecl * getDictWithObjectsMethod() const
static void Write_prop_list_t_initializer(RewriteModernObjC &RewriteObj, ASTContext *Context, std::string &Result, ArrayRef< ObjCPropertyDecl *> Properties, const Decl *Container, StringRef VarName, StringRef ProtocolName)
static void Write_protocol_list_t_TypeDecl(std::string &Result, long super_protocol_count)
const ObjCAtCatchStmt * getCatchStmt(unsigned I) const
Retrieve a @catch statement.
ObjCPropertyImplDecl - Represents implementation declaration of a property in a class or category imp...
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 }.
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 ImplicitCastExpr * Create(const ASTContext &Context, QualType T, CastKind Kind, Expr *Operand, const CXXCastPath *BasePath, ExprValueKind Cat)
static void RewriteOneForwardClassDecl(ObjCInterfaceDecl *ForwardDecl, std::string &typedefString)
SourceLocation getLocation() const
static bool IsHeaderFile(const std::string &Filename)
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
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.
ObjCMethodDecl * getBoxingMethod() const
SourceLocation getLocStart() const LLVM_READONLY
Pepresents a block literal declaration, which is like an unnamed FunctionDecl.
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Expr - This represents one expression.
bool isVariadic() const
Whether this function is variadic.
Selector getSetterName() const
static unsigned MeasureTokenLength(SourceLocation Loc, const SourceManager &SM, const LangOptions &LangOpts)
MeasureTokenLength - Relex the token at the specified location and return its length in bytes in the ...
const T * castAs() const
Member-template castAs<specific type>.
std::string getObjCEncodingForPropertyDecl(const ObjCPropertyDecl *PD, const Decl *Container) const
getObjCEncodingForPropertyDecl - Return the encoded type for this method declaration.
unsigned getLine() const
Return the presumed line number of this location.
BlockExpr - Adaptor class for mixing a BlockDecl with expressions.
bool isThisDeclarationADefinition() const
Returns whether this specific declaration of the function is also a definition that does not contain ...
bool isThisDeclarationADefinition() const
Determine whether this particular declaration is also the definition.
bool isImplicit() const
isImplicit - Indicates whether the declaration was implicitly generated by the implementation.
QualType getTagDeclType(const TagDecl *Decl) const
Return the unique reference to the type for the specified TagDecl (struct/union/class/enum) decl...
bool isFileContext() const
ObjCDictionaryLiteral - AST node to represent objective-c dictionary literals; as in:"name" : NSUserN...
const CompoundStmt * getSynchBody() const
DeclContext * getDeclContext()
bool isWrittenInMainFile(SourceLocation Loc) const
Returns true if the spelling location for the given location is in the main file buffer.
Represents Objective-C's @synchronized statement.
ObjCInterfaceDecl * getSuperClass() const
ObjCSelectorExpr used for @selector in Objective-C.
const internal::VariadicDynCastAllOfMatcher< Decl, FieldDecl > fieldDecl
Matches field declarations.
static bool mustSynthesizeSetterGetterMethod(ObjCImplementationDecl *IMP, ObjCPropertyDecl *PD, bool getter)
mustSynthesizeSetterGetterMethod - returns true if setter or getter has not been found in the class i...
StorageClass getStorageClass() const
Returns the storage class as written in the source.
LLVM_READONLY bool isAlphanumeric(unsigned char c)
Return true if this character is an ASCII letter or digit: [a-zA-Z0-9].
SourceLocation getAtTryLoc() const
Retrieve the location of the @ in the @try.
bool refersToEnclosingVariableOrCapture() const
Does this DeclRefExpr refer to an enclosing local or a captured variable?
IdentifierInfo * getAsIdentifierInfo() const
getAsIdentifierInfo - Retrieve the IdentifierInfo * stored in this declaration name, or NULL if this declaration name isn't a simple identifier.
Defines the clang::IdentifierInfo, clang::IdentifierTable, and clang::Selector interfaces.
ObjCIvarDecl * lookupInstanceVariable(IdentifierInfo *IVarName, ObjCInterfaceDecl *&ClassDeclared)
Expr * getElement(unsigned Index)
getElement - Return the Element at the specified index.
propimpl_range property_impls() const
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...
const Stmt * getTryBody() const
Retrieve the @try body.
QualType getEncodedType() const
bool isa(CodeGen::Address addr)
An expression that sends a message to the given Objective-C object or class.
SourceLocation getAtLoc() const
Represents an unpacked "presumed" location which can be presented to the user.
QualType getObjCInterfaceType(const ObjCInterfaceDecl *Decl, ObjCInterfaceDecl *PrevDecl=nullptr) const
getObjCInterfaceType - Return the unique reference to the type for the specified ObjC interface decl...
SourceLocation getEnd() const
#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.
bool isInstanceMethod() const
QualType getFunctionType(QualType ResultTy, ArrayRef< QualType > Args, const FunctionProtoType::ExtProtoInfo &EPI) const
Return a normal function type with a typed argument list.
ReceiverKind getReceiverKind() const
Determine the kind of receiver that this message is being sent to.
static void BuildUniqueMethodName(std::string &Name, ObjCMethodDecl *MD)
int getRangeSize(SourceRange Range, RewriteOptions opts=RewriteOptions()) const
getRangeSize - Return the size in bytes of the specified range if they are in the same file...
Selector getSelector() const
QualType getTypeDeclType(const TypeDecl *Decl, const TypeDecl *PrevDecl=nullptr) const
Return the unique reference to the type for the specified type declaration.
The result type of a method or function.
unsigned getExpansionLineNumber(SourceLocation Loc, bool *Invalid=nullptr) const
SourceLocation getForLoc() const
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.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
ImplicitParamDecl * getSelfDecl() const
Expr * getArg(unsigned Arg)
getArg - Return the specified argument.
Expr * getUnderlyingExpr() const
unsigned getCVRQualifiers() const
Retrieve the set of CVR (const-volatile-restrict) qualifiers applied to this type.
static std::string getIvarAccessString(ObjCIvarDecl *OID)
bool isConstQualified() const
Determine whether this type is const-qualified.
param_iterator param_begin()
const char * getFilename() const
Return the presumed filename of this location.
SourceLocation getLocStart() const LLVM_READONLY
unsigned getNumArgs() const
Return the number of actual arguments in this message, not counting the receiver. ...
std::string getAsString() const
Derive the full selector name (e.g.
SelectorTable & Selectors
llvm::MemoryBuffer * getBuffer(FileID FID, SourceLocation Loc, bool *Invalid=nullptr) const
Return the buffer for the specified FileID.
void setSourceMgr(SourceManager &SM, const LangOptions &LO)
PseudoObjectExpr - An expression which accesses a pseudo-object l-value.
param_type_range param_types() const
SourceLocation getLocStart() const LLVM_READONLY
Encodes a location in the source.
ObjCInterfaceDecl * getDecl() const
Get the declaration of this interface.
QualType getReturnType() 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...
const Stmt * getCatchBody() const
SourceLocation getLocStart() const LLVM_READONLY
Interfaces are the core concept in Objective-C for object oriented design.
CastKind getCastKind() const
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)
std::string getNameAsString() const
Get a human-readable name for the declaration, even if it is one of the special kinds of names (C++ c...
unsigned getNumElements() const
getNumElements - Return number of elements of objective-c dictionary literal.
Represents the declaration of a struct/union/class/enum.
static void Write_method_list_t_initializer(RewriteModernObjC &RewriteObj, ASTContext *Context, std::string &Result, ArrayRef< ObjCMethodDecl *> Methods, StringRef VarName, StringRef TopLevelDeclName, bool MethodImpl)
SourceLocation getLocStart() const LLVM_READONLY
ObjCCategoryDecl * getCategoryDecl() const
DeclStmt - Adaptor class for mixing declarations with statements and expressions. ...
QualType getObjCSelType() const
Retrieve the type that corresponds to the predefined Objective-C 'SEL' type.
const RewriteBuffer * getRewriteBufferFor(FileID FID) const
getRewriteBufferFor - Return the rewrite buffer for the specified FileID.
QualType getBaseElementType(const ArrayType *VAT) const
Return the innermost element type of an array type.
bool isIntegralType(const ASTContext &Ctx) const
Determine whether this type is an integral type.
bool InsertText(SourceLocation Loc, StringRef Str, bool InsertAfter=true, bool indentNewLines=false)
InsertText - Insert the specified string at the specified location in the original buffer...
SourceLocation getLocStart() const LLVM_READONLY
SourceLocation getSuperLoc() const
Retrieve the location of the 'super' keyword for a class or instance message to 'super', otherwise an invalid source location.
const ArrayType * getAsArrayType(QualType T) const
Type Query functions.
ObjCCategoryDecl - Represents a category declaration.
decl_iterator decl_begin()
ObjCProtocolExpr used for protocol expression in Objective-C.
bool isObjCObjectPointerType() const
Represents one property declaration in an Objective-C interface.
ImplicitCastExpr - Allows us to explicitly represent implicit type conversions, which have no direct ...
bool isImplicit() const
Indicates whether the message send was implicitly generated by the implementation.
SourceLocation getLocEnd() const LLVM_READONLY
unsigned getCustomDiagID(Level L, const char(&FormatString)[N])
Return an ID for a diagnostic with the specified format string and level.
bool isImplicitInterfaceDecl() const
isImplicitInterfaceDecl - check that this is an implicitly declared ObjCInterfaceDecl node...
const ObjCMethodDecl * getMethodDecl() const
ObjCBoxedExpr - used for generalized expression boxing.
static void Write__extendedMethodTypes_initializer(RewriteModernObjC &RewriteObj, ASTContext *Context, std::string &Result, ArrayRef< ObjCMethodDecl *> Methods, StringRef VarName, StringRef ProtocolName)
ObjCImplementationDecl * getImplementation() const
protocol_range protocols() 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;...
Expr * Value
The value of the dictionary element.
StringRef getName() const
Return the actual identifier string.
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()
bool isObjCGCWeak() const
true when Type is objc's weak.
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...
const ObjCInterfaceDecl * getClassInterface() const
Dataflow Directional Tag Classes.
bool isObjCQualifiedInterfaceType() const
bool isValid() const
Return true if this is a valid SourceLocation object.
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)
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
ArrayRef< Capture > captures() const
Kind getPropertyImplementation() const
SourceLocation getLocStart() const LLVM_READONLY
const Stmt * getFinallyBody() const
SourceLocation getAtLoc() const
QualType getSuperType() const
Retrieve the type referred to by 'super'.
const ObjCProtocolList & getReferencedProtocols() const
const Expr * getInit() const
FileID getMainFileID() const
Returns the FileID of the main source file.
static std::string getAsString(SplitQualType split, const PrintingPolicy &Policy)
bool isBooleanType() const
QualType getFunctionNoProtoType(QualType ResultTy, const FunctionType::ExtInfo &Info) const
Return a K&R style C function type like 'int()'.
U cast(CodeGen::Address addr)
int printf(__constant const char *st,...)
PresumedLoc getPresumedLoc(SourceLocation Loc, bool UseLineDirectives=true) const
Returns the "presumed" location of a SourceLocation specifies.
const ObjCInterfaceDecl * getContainingInterface() const
Return the class interface that this ivar is logically contained in; this is either the interface whe...
QualType getCallResultType(const ASTContext &Context) const
Determine the type of an expression that calls a function of this type.
Expr * IgnoreParenImpCasts() LLVM_READONLY
IgnoreParenImpCasts - Ignore parentheses and implicit casts.
QualType getClassReceiver() const
Returns the type of a class message send, or NULL if the message is not a class message.
Represents a pointer to an Objective C object.
unsigned getByteLength() const
CanQualType ObjCBuiltinBoolTy
ObjCImplementationDecl - Represents a class definition - this is where method definitions are specifi...
SourceLocation getRParenLoc() const
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
(Obsolete) ARC-specific: this class has a .release_ivars method
unsigned getNumElements() const
getNumElements - Return number of elements of objective-c array literal.
Represents Objective-C's collection statement.
CanQualType UnsignedLongTy
ObjCEncodeExpr, used for @encode in Objective-C.
Selector getSelector(unsigned NumArgs, IdentifierInfo **IIV)
Can create any sort of selector.
static CStyleCastExpr * Create(const ASTContext &Context, QualType T, ExprValueKind VK, CastKind K, Expr *Op, const CXXCastPath *BasePath, TypeSourceInfo *WrittenTy, SourceLocation L, SourceLocation R)
uint64_t getCharWidth() const
Return the size of the character type, in bits.
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.
bool isObjCQualifiedIdType() const
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.
void addDecl(Decl *D)
Add the declaration D into this context.
const Expr * getBase() const
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
ObjCIvarRefExpr - A reference to an ObjC instance variable.
SourceManager & getSourceManager()
ImplementationControl getImplementationControl() const
CanQualType getCanonicalType(QualType T) const
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
SourceRange getAtEndRange() const
X
Add a minimal nested name specifier fixit hint to allow lookup of a tag name from an outer enclosing ...
Rewriter - This is the main interface to the rewrite buffers.
QualType getParamType(unsigned i) const
TranslationUnitDecl * getTranslationUnitDecl() const
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
ContinueStmt - This represents a continue.
ObjCIvarDecl - Represents an ObjC instance variable.
static bool isRewritable(SourceLocation Loc)
isRewritable - Return true if this location is a raw file location, which is rewritable.
static TypedefDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, IdentifierInfo *Id, TypeSourceInfo *TInfo)
SourceLocation getLocEnd() const LLVM_READONLY
SourceLocation getAtSynchronizedLoc() const
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
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...
unsigned getNumCatchStmts() const
Retrieve the number of @catch statements in this try-catch-finally block.
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]).
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
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.
The top declaration context.
A reference to a declared variable, function, enum, etc.
ObjCPropertyDecl * getPropertyDecl() const
Visibility getVisibility() const
Determines the visibility of this entity.
bool isPointerType() const
BreakStmt - This represents a break.
Expr * getSemanticExpr(unsigned index)
const VarDecl * getCatchParamDecl() const
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
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.
ObjCMethodDecl * getGetterMethodDecl() const
This represents a decl that may have 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 getLocStart() const LLVM_READONLY
ObjCMethodDecl * getInstanceMethod(Selector Sel, bool AllowHidden=false) const
AccessControl getAccessControl() const
SourceLocation getLocEnd() const LLVM_READONLY
SourceLocation getIvarRBraceLoc() const
Selector getGetterName() const
SourceLocation getEndOfDefinitionLoc() const
SourceLocation getRightLoc() const
bool isFunctionPointerType() const
static FieldDecl * Create(const ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, Expr *BW, bool Mutable, InClassInitStyle InitStyle)
The receiver is a superclass.
static void Write__ivar_list_t_initializer(RewriteModernObjC &RewriteObj, ASTContext *Context, std::string &Result, ArrayRef< ObjCIvarDecl *> OriginalIvars, StringRef VarName, ObjCInterfaceDecl *CDecl)
void getSelectorLocs(SmallVectorImpl< SourceLocation > &SelLocs) const
SourceLocation getBegin() const
const LangOptions & getLangOpts() const
Represents Objective-C's @autoreleasepool Statement.
FullSourceLoc getFullLoc(SourceLocation Loc) const
ObjCCategoryImplDecl - An object of this class encapsulates a category @implementation declaration...
static void Write_IvarOffsetVar(RewriteModernObjC &RewriteObj, ASTContext *Context, std::string &Result, ArrayRef< ObjCIvarDecl *> Ivars, ObjCInterfaceDecl *CDecl)
Represents the canonical version of C arrays with a specified constant size.
This class handles loading and caching of source files into memory.
bool BlockRequiresCopying(QualType Ty, const VarDecl *D)
Returns true iff we need copy/dispose helpers for the given type.
SourceLocation getLocation() const
static void WriteModernMetadataDeclarations(ASTContext *Context, std::string &Result)
WriteModernMetadataDeclarations - Writes out metadata declarations for modern ABI.
ArrayRef< ParmVarDecl * > parameters() const
static std::string Stringify(StringRef Str, bool Charify=false)
Stringify - Convert the specified string into a C string by i) escaping '\' and " characters and ii) ...
CanQualType UnsignedIntTy
TypeSourceInfo * getClassReceiverTypeInfo() const
Returns a type-source information of a class message send, or nullptr if the message is not a class m...
ObjCCategoryDecl * FindCategoryDeclaration(IdentifierInfo *CategoryId) const
FindCategoryDeclaration - Finds category declaration in the list of categories for this class and ret...