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());
5337 }
else if (isTopLevelBlockPointerType((*I)->getType())) {
5338 FD = SynthBlockInitFunctionDecl((*I)->getName());
5341 Exp = NoTypeInfoCStyleCastExpr(Context, Context->
VoidPtrTy,
5344 FD = SynthBlockInitFunctionDecl((*I)->getName());
5355 InitExprs.push_back(Exp);
5359 E = BlockByRefDecls.end(); I != E; ++I) {
5362 std::string RecName;
5363 RewriteByRefString(RecName, Name, ND,
true);
5365 +
sizeof(
"struct"));
5369 assert(RD &&
"SynthBlockInitExpr(): Can't find RecordDecl");
5372 FD = SynthBlockInitFunctionDecl((*I)->getName());
5375 bool isNestedCapturedVar =
false;
5377 for (
const auto &CI : block->
captures()) {
5378 const VarDecl *variable = CI.getVariable();
5379 if (variable == ND && CI.isNested()) {
5380 assert (CI.isByRef() &&
5381 "SynthBlockInitExpr - captured block variable is not byref");
5382 isNestedCapturedVar =
true;
5388 if (!isNestedCapturedVar)
5392 Exp = NoTypeInfoCStyleCastExpr(Context, castT, CK_BitCast, Exp);
5393 InitExprs.push_back(Exp);
5396 if (ImportedBlockDecls.size()) {
5403 InitExprs.push_back(FlagExp);
5405 NewRep =
new (Context)
CallExpr(*Context, DRE, InitExprs,
5408 if (GlobalBlockExpr) {
5409 assert (!GlobalConstructionExp &&
5410 "SynthBlockInitExpr - GlobalConstructionExp must be null");
5411 GlobalConstructionExp = NewRep;
5418 NewRep = NoTypeInfoCStyleCastExpr(Context, FType, CK_BitCast,
5424 BlockDeclRefs.clear();
5425 BlockByRefDecls.clear();
5426 BlockByRefDeclsPtrSet.clear();
5427 BlockByCopyDecls.clear();
5428 BlockByCopyDeclsPtrSet.clear();
5429 ImportedBlockDecls.clear();
5433 bool RewriteModernObjC::IsDeclStmtInForeachHeader(
DeclStmt *DS) {
5435 dyn_cast<ObjCForCollectionStmt>(Stmts.back()))
5436 return CS->getElement() == DS;
5444 Stmt *RewriteModernObjC::RewriteFunctionBodyOrGlobalInitializer(
Stmt *S) {
5445 if (isa<SwitchStmt>(S) || isa<WhileStmt>(S) ||
5446 isa<DoStmt>(S) || isa<ForStmt>(S))
5448 else if (isa<ObjCForCollectionStmt>(S)) {
5450 ObjCBcLabelNo.push_back(++BcLabelCount);
5457 return RewritePropertyOrImplicitSetter(PseudoOp);
5459 return RewritePropertyOrImplicitGetter(PseudoOp);
5461 }
else if (
ObjCIvarRefExpr *IvarRefExpr = dyn_cast<ObjCIvarRefExpr>(S)) {
5462 return RewriteObjCIvarRefExpr(IvarRefExpr);
5464 else if (isa<OpaqueValueExpr>(S))
5465 S = cast<OpaqueValueExpr>(S)->getSourceExpr();
5472 Stmt *newStmt = RewriteFunctionBodyOrGlobalInitializer(childStmt);
5474 childStmt = newStmt;
5478 if (
BlockExpr *BE = dyn_cast<BlockExpr>(S)) {
5480 llvm::SmallPtrSet<const DeclContext *, 8> InnerContexts;
5481 InnerContexts.insert(BE->getBlockDecl());
5482 ImportedLocalExternalDecls.clear();
5483 GetInnerBlockDeclRefExprs(BE->getBody(),
5484 InnerBlockDeclRefs, InnerContexts);
5486 Stmt *SaveCurrentBody = CurrentBody;
5487 CurrentBody = BE->getBody();
5488 PropParentMap =
nullptr;
5494 bool saveDisableReplaceStmt = DisableReplaceStmt;
5495 DisableReplaceStmt =
false;
5496 RewriteFunctionBodyOrGlobalInitializer(BE->getBody());
5497 DisableReplaceStmt = saveDisableReplaceStmt;
5498 CurrentBody = SaveCurrentBody;
5499 PropParentMap =
nullptr;
5500 ImportedLocalExternalDecls.clear();
5503 RewrittenBlockExprs[BE] = Str;
5505 Stmt *blockTranscribed = SynthBlockInitExpr(BE, InnerBlockDeclRefs);
5508 ReplaceStmt(S, blockTranscribed);
5509 return blockTranscribed;
5513 return RewriteAtEncode(AtEncode);
5516 return RewriteAtSelector(AtSelector);
5519 return RewriteObjCStringLiteral(AtString);
5522 return RewriteObjCBoolLiteralExpr(BoolLitExpr);
5525 return RewriteObjCBoxedExpr(BoxedExpr);
5528 return RewriteObjCArrayLiteralExpr(ArrayLitExpr);
5531 dyn_cast<ObjCDictionaryLiteral>(S))
5532 return RewriteObjCDictionaryLiteralExpr(DictionaryLitExpr);
5543 std::string messString;
5544 messString +=
"// ";
5545 messString.append(startBuf, endBuf-startBuf+1);
5554 return RewriteMessageExpr(MessExpr);
5558 dyn_cast<ObjCAutoreleasePoolStmt>(S)) {
5559 return RewriteObjCAutoreleasePoolStmt(StmtAutoRelease);
5563 return RewriteObjCTryStmt(StmtTry);
5566 return RewriteObjCSynchronizedStmt(StmtTry);
5569 return RewriteObjCThrowStmt(StmtThrow);
5572 return RewriteObjCProtocolExpr(ProtocolExp);
5575 dyn_cast<ObjCForCollectionStmt>(S))
5576 return RewriteObjCForCollectionStmt(StmtForCollection,
5579 dyn_cast<BreakStmt>(S))
5580 return RewriteBreakStmt(StmtBreakStmt);
5582 dyn_cast<ContinueStmt>(S))
5583 return RewriteContinueStmt(StmtContinueStmt);
5587 if (
DeclStmt *DS = dyn_cast<DeclStmt>(S)) {
5597 if (Stmts.empty() || !IsDeclStmtInForeachHeader(DS))
5598 RewriteObjCQualifiedInterfaceTypes(*DS->
decl_begin());
5604 if (
ValueDecl *ND = dyn_cast<ValueDecl>(SD)) {
5605 if (isTopLevelBlockPointerType(ND->
getType()))
5606 RewriteBlockPointerDecl(ND);
5608 CheckFunctionPointerDecl(ND->
getType(), ND);
5609 if (
VarDecl *VD = dyn_cast<VarDecl>(SD)) {
5610 if (VD->
hasAttr<BlocksAttr>()) {
5611 static unsigned uniqueByrefDeclCount = 0;
5612 assert(!BlockByRefDeclNo.count(ND) &&
5613 "RewriteFunctionBodyOrGlobalInitializer: Duplicate byref decl");
5614 BlockByRefDeclNo[ND] = uniqueByrefDeclCount++;
5615 RewriteByRefVar(VD, (DI == DS->
decl_begin()), ((DI+1) == DE));
5618 RewriteTypeOfDecl(VD);
5622 if (isTopLevelBlockPointerType(TD->getUnderlyingType()))
5623 RewriteBlockPointerDecl(TD);
5624 else if (TD->getUnderlyingType()->isFunctionPointerType())
5625 CheckFunctionPointerDecl(TD->getUnderlyingType(), TD);
5631 RewriteObjCQualifiedInterfaceTypes(CE);
5633 if (isa<SwitchStmt>(S) || isa<WhileStmt>(S) ||
5634 isa<DoStmt>(S) || isa<ForStmt>(S)) {
5635 assert(!Stmts.empty() &&
"Statement stack is empty");
5636 assert ((isa<SwitchStmt>(Stmts.back()) || isa<WhileStmt>(Stmts.back()) ||
5637 isa<DoStmt>(Stmts.back()) || isa<ForStmt>(Stmts.back()))
5638 &&
"Statement stack mismatch");
5642 if (
DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(S)) {
5644 if (VD->
hasAttr<BlocksAttr>())
5645 return RewriteBlockDeclRefExpr(DRE);
5647 return RewriteLocalVariableExternalStorage(DRE);
5650 if (
CallExpr *CE = dyn_cast<CallExpr>(S)) {
5653 ReplaceStmt(S, BlockCall);
5658 RewriteCastExpr(CE);
5661 RewriteImplicitCastObjCExpr(ICE);
5671 llvm::raw_string_ostream Buf(SStr);
5673 const std::string &Str = Buf.str();
5675 printf(
"CAST = %s\n", &Str[0]);
5676 InsertText(ICE->getSubExpr()->getLocStart(), Str);
5685 void RewriteModernObjC::RewriteRecordBody(
RecordDecl *RD) {
5686 for (
auto *FD : RD->
fields()) {
5687 if (isTopLevelBlockPointerType(FD->
getType()))
5688 RewriteBlockPointerDecl(FD);
5691 RewriteObjCQualifiedInterfaceTypes(FD);
5697 void RewriteModernObjC::HandleDeclInMainFile(
Decl *D) {
5699 case Decl::Function: {
5707 RewriteBlocksInFunctionProtoType(FD->
getType(), FD);
5714 CurFunctionDef = FD;
5717 cast_or_null<CompoundStmt>(RewriteFunctionBodyOrGlobalInitializer(Body));
5719 CurrentBody =
nullptr;
5720 if (PropParentMap) {
5721 delete PropParentMap;
5722 PropParentMap =
nullptr;
5726 InsertBlockLiteralsWithinFunction(FD);
5727 RewriteLineDirective(D);
5728 CurFunctionDef =
nullptr;
5732 case Decl::ObjCMethod: {
5738 cast_or_null<CompoundStmt>(RewriteFunctionBodyOrGlobalInitializer(Body));
5740 CurrentBody =
nullptr;
5741 if (PropParentMap) {
5742 delete PropParentMap;
5743 PropParentMap =
nullptr;
5745 InsertBlockLiteralsWithinMethod(MD);
5746 RewriteLineDirective(D);
5747 CurMethodDef =
nullptr;
5751 case Decl::ObjCImplementation: {
5753 ClassImplementation.push_back(CI);
5756 case Decl::ObjCCategoryImpl: {
5758 CategoryImplementation.push_back(CI);
5762 VarDecl *VD = cast<VarDecl>(D);
5763 RewriteObjCQualifiedInterfaceTypes(VD);
5764 if (isTopLevelBlockPointerType(VD->
getType()))
5765 RewriteBlockPointerDecl(VD);
5767 CheckFunctionPointerDecl(VD->
getType(), VD);
5770 RewriteCastExpr(CE);
5776 RewriteRecordBody(RD);
5781 RewriteFunctionBodyOrGlobalInitializer(VD->
getInit());
5782 CurrentBody =
nullptr;
5783 if (PropParentMap) {
5784 delete PropParentMap;
5785 PropParentMap =
nullptr;
5788 GlobalVarDecl =
nullptr;
5792 RewriteCastExpr(CE);
5797 case Decl::TypeAlias:
5798 case Decl::Typedef: {
5800 if (isTopLevelBlockPointerType(TD->getUnderlyingType()))
5801 RewriteBlockPointerDecl(TD);
5802 else if (TD->getUnderlyingType()->isFunctionPointerType())
5803 CheckFunctionPointerDecl(TD->getUnderlyingType(), TD);
5805 RewriteObjCQualifiedInterfaceTypes(TD);
5809 case Decl::CXXRecord:
5810 case Decl::Record: {
5813 RewriteRecordBody(RD);
5827 std::string &Result) {
5830 Result +=
"static ";
5831 Result +=
"struct _protocol_t *";
5832 Result +=
"_OBJC_PROTOCOL_REFERENCE_$_";
5839 void RewriteModernObjC::HandleTranslationUnit(
ASTContext &
C) {
5845 for (
unsigned i = 0, e = FunctionDefinitionsSeen.size(); i < e; i++) {
5850 HandleTopLevelSingleDecl(FDecl);
5856 RewriteObjCProtocolMetaData(ProtDecl, Preamble);
5862 if (ClassImplementation.size() || CategoryImplementation.size())
5863 RewriteImplementations();
5865 for (
unsigned i = 0, e = ObjCInterfacesSeen.size(); i < e; i++) {
5866 ObjCInterfaceDecl *CDecl = ObjCInterfacesSeen[i];
5871 RewriteInterfaceDecl(CDecl);
5879 *OutFile << std::string(RewriteBuf->begin(), RewriteBuf->end());
5881 llvm::errs() <<
"No changes\n";
5884 if (ClassImplementation.size() || CategoryImplementation.size() ||
5885 ProtocolExprDecls.size()) {
5887 std::string ResultStr;
5888 RewriteMetaDataIntoBuffer(ResultStr);
5890 *OutFile << ResultStr;
5894 std::string ResultStr;
5895 WriteImageInfo(ResultStr);
5896 *OutFile << ResultStr;
5901 void RewriteModernObjC::Initialize(
ASTContext &context) {
5902 InitializeCommon(context);
5904 Preamble +=
"#ifndef __OBJC2__\n";
5905 Preamble +=
"#define __OBJC2__\n";
5906 Preamble +=
"#endif\n";
5911 Preamble =
"#pragma once\n";
5912 Preamble +=
"struct objc_selector; struct objc_class;\n";
5913 Preamble +=
"struct __rw_objc_super { \n\tstruct objc_object *object; ";
5914 Preamble +=
"\n\tstruct objc_object *superClass; ";
5916 Preamble +=
"\n\t__rw_objc_super(struct objc_object *o, struct objc_object *s) ";
5917 Preamble +=
": object(o), superClass(s) {} ";
5918 Preamble +=
"\n};\n";
5920 if (LangOpts.MicrosoftExt) {
5923 Preamble +=
"\n#pragma section(\".objc_classlist$B\", long, read, write)\n";
5924 Preamble +=
"#pragma section(\".objc_catlist$B\", long, read, write)\n";
5925 Preamble +=
"#pragma section(\".objc_imageinfo$B\", long, read, write)\n";
5926 Preamble +=
"#pragma section(\".objc_nlclslist$B\", long, read, write)\n";
5927 Preamble +=
"#pragma section(\".objc_nlcatlist$B\", long, read, write)\n";
5929 Preamble +=
"#pragma section(\".cat_cls_meth$B\", long, read, write)\n";
5930 Preamble +=
"#pragma section(\".inst_meth$B\", long, read, write)\n";
5931 Preamble +=
"#pragma section(\".cls_meth$B\", long, read, write)\n";
5932 Preamble +=
"#pragma section(\".objc_ivar$B\", long, read, write)\n";
5936 Preamble +=
"#pragma section(\".objc_selrefs$B\", long, read, write)\n";
5937 Preamble +=
"#pragma section(\".objc_classrefs$B\", long, read, write)\n";
5938 Preamble +=
"#pragma section(\".objc_superrefs$B\", long, read, write)\n";
5941 Preamble +=
"#ifndef _REWRITER_typedef_Protocol\n";
5942 Preamble +=
"typedef struct objc_object Protocol;\n";
5943 Preamble +=
"#define _REWRITER_typedef_Protocol\n";
5944 Preamble +=
"#endif\n";
5945 if (LangOpts.MicrosoftExt) {
5946 Preamble +=
"#define __OBJC_RW_DLLIMPORT extern \"C\" __declspec(dllimport)\n";
5947 Preamble +=
"#define __OBJC_RW_STATICIMPORT extern \"C\"\n";
5950 Preamble +=
"#define __OBJC_RW_DLLIMPORT extern\n";
5952 Preamble +=
"__OBJC_RW_DLLIMPORT void objc_msgSend(void);\n";
5953 Preamble +=
"__OBJC_RW_DLLIMPORT void objc_msgSendSuper(void);\n";
5954 Preamble +=
"__OBJC_RW_DLLIMPORT void objc_msgSend_stret(void);\n";
5955 Preamble +=
"__OBJC_RW_DLLIMPORT void objc_msgSendSuper_stret(void);\n";
5956 Preamble +=
"__OBJC_RW_DLLIMPORT void objc_msgSend_fpret(void);\n";
5958 Preamble +=
"__OBJC_RW_DLLIMPORT struct objc_class *objc_getClass";
5959 Preamble +=
"(const char *);\n";
5960 Preamble +=
"__OBJC_RW_DLLIMPORT struct objc_class *class_getSuperclass";
5961 Preamble +=
"(struct objc_class *);\n";
5962 Preamble +=
"__OBJC_RW_DLLIMPORT struct objc_class *objc_getMetaClass";
5963 Preamble +=
"(const char *);\n";
5964 Preamble +=
"__OBJC_RW_DLLIMPORT void objc_exception_throw( struct objc_object *);\n";
5966 Preamble +=
"__OBJC_RW_DLLIMPORT int objc_sync_enter( struct objc_object *);\n";
5967 Preamble +=
"__OBJC_RW_DLLIMPORT int objc_sync_exit( struct objc_object *);\n";
5968 Preamble +=
"__OBJC_RW_DLLIMPORT Protocol *objc_getProtocol(const char *);\n";
5969 Preamble +=
"#ifdef _WIN64\n";
5970 Preamble +=
"typedef unsigned long long _WIN_NSUInteger;\n";
5971 Preamble +=
"#else\n";
5972 Preamble +=
"typedef unsigned int _WIN_NSUInteger;\n";
5973 Preamble +=
"#endif\n";
5974 Preamble +=
"#ifndef __FASTENUMERATIONSTATE\n";
5975 Preamble +=
"struct __objcFastEnumerationState {\n\t";
5976 Preamble +=
"unsigned long state;\n\t";
5977 Preamble +=
"void **itemsPtr;\n\t";
5978 Preamble +=
"unsigned long *mutationsPtr;\n\t";
5979 Preamble +=
"unsigned long extra[5];\n};\n";
5980 Preamble +=
"__OBJC_RW_DLLIMPORT void objc_enumerationMutation(struct objc_object *);\n";
5981 Preamble +=
"#define __FASTENUMERATIONSTATE\n";
5982 Preamble +=
"#endif\n";
5983 Preamble +=
"#ifndef __NSCONSTANTSTRINGIMPL\n";
5984 Preamble +=
"struct __NSConstantStringImpl {\n";
5985 Preamble +=
" int *isa;\n";
5986 Preamble +=
" int flags;\n";
5987 Preamble +=
" char *str;\n";
5988 Preamble +=
"#if _WIN64\n";
5989 Preamble +=
" long long length;\n";
5990 Preamble +=
"#else\n";
5991 Preamble +=
" long length;\n";
5992 Preamble +=
"#endif\n";
5994 Preamble +=
"#ifdef CF_EXPORT_CONSTANT_STRING\n";
5995 Preamble +=
"extern \"C\" __declspec(dllexport) int __CFConstantStringClassReference[];\n";
5996 Preamble +=
"#else\n";
5997 Preamble +=
"__OBJC_RW_DLLIMPORT int __CFConstantStringClassReference[];\n";
5998 Preamble +=
"#endif\n";
5999 Preamble +=
"#define __NSCONSTANTSTRINGIMPL\n";
6000 Preamble +=
"#endif\n";
6002 Preamble +=
"#ifndef BLOCK_IMPL\n";
6003 Preamble +=
"#define BLOCK_IMPL\n";
6004 Preamble +=
"struct __block_impl {\n";
6005 Preamble +=
" void *isa;\n";
6006 Preamble +=
" int Flags;\n";
6007 Preamble +=
" int Reserved;\n";
6008 Preamble +=
" void *FuncPtr;\n";
6010 Preamble +=
"// Runtime copy/destroy helper functions (from Block_private.h)\n";
6011 Preamble +=
"#ifdef __OBJC_EXPORT_BLOCKS\n";
6012 Preamble +=
"extern \"C\" __declspec(dllexport) " 6013 "void _Block_object_assign(void *, const void *, const int);\n";
6014 Preamble +=
"extern \"C\" __declspec(dllexport) void _Block_object_dispose(const void *, const int);\n";
6015 Preamble +=
"extern \"C\" __declspec(dllexport) void *_NSConcreteGlobalBlock[32];\n";
6016 Preamble +=
"extern \"C\" __declspec(dllexport) void *_NSConcreteStackBlock[32];\n";
6017 Preamble +=
"#else\n";
6018 Preamble +=
"__OBJC_RW_DLLIMPORT void _Block_object_assign(void *, const void *, const int);\n";
6019 Preamble +=
"__OBJC_RW_DLLIMPORT void _Block_object_dispose(const void *, const int);\n";
6020 Preamble +=
"__OBJC_RW_DLLIMPORT void *_NSConcreteGlobalBlock[32];\n";
6021 Preamble +=
"__OBJC_RW_DLLIMPORT void *_NSConcreteStackBlock[32];\n";
6022 Preamble +=
"#endif\n";
6023 Preamble +=
"#endif\n";
6024 if (LangOpts.MicrosoftExt) {
6025 Preamble +=
"#undef __OBJC_RW_DLLIMPORT\n";
6026 Preamble +=
"#undef __OBJC_RW_STATICIMPORT\n";
6027 Preamble +=
"#ifndef KEEP_ATTRIBUTES\n";
6028 Preamble +=
"#define __attribute__(X)\n";
6029 Preamble +=
"#endif\n";
6030 Preamble +=
"#ifndef __weak\n";
6031 Preamble +=
"#define __weak\n";
6032 Preamble +=
"#endif\n";
6033 Preamble +=
"#ifndef __block\n";
6034 Preamble +=
"#define __block\n";
6035 Preamble +=
"#endif\n";
6038 Preamble +=
"#define __block\n";
6039 Preamble +=
"#define __weak\n";
6043 Preamble +=
"\n#include <stdarg.h>\n";
6044 Preamble +=
"struct __NSContainer_literal {\n";
6045 Preamble +=
" void * *arr;\n";
6046 Preamble +=
" __NSContainer_literal (unsigned int count, ...) {\n";
6047 Preamble +=
"\tva_list marker;\n";
6048 Preamble +=
"\tva_start(marker, count);\n";
6049 Preamble +=
"\tarr = new void *[count];\n";
6050 Preamble +=
"\tfor (unsigned i = 0; i < count; i++)\n";
6051 Preamble +=
"\t arr[i] = va_arg(marker, void *);\n";
6052 Preamble +=
"\tva_end( marker );\n";
6053 Preamble +=
" };\n";
6054 Preamble +=
" ~__NSContainer_literal() {\n";
6055 Preamble +=
"\tdelete[] arr;\n";
6060 Preamble +=
"extern \"C\" __declspec(dllimport) void * objc_autoreleasePoolPush(void);\n";
6061 Preamble +=
"extern \"C\" __declspec(dllimport) void objc_autoreleasePoolPop(void *);\n\n";
6062 Preamble +=
"struct __AtAutoreleasePool {\n";
6063 Preamble +=
" __AtAutoreleasePool() {atautoreleasepoolobj = objc_autoreleasePoolPush();}\n";
6064 Preamble +=
" ~__AtAutoreleasePool() {objc_autoreleasePoolPop(atautoreleasepoolobj);}\n";
6065 Preamble +=
" void * atautoreleasepoolobj;\n";
6070 Preamble +=
"\n#define __OFFSETOFIVAR__(TYPE, MEMBER) ((long long) &((TYPE *)0)->MEMBER)\n";
6075 void RewriteModernObjC::RewriteIvarOffsetComputation(
ObjCIvarDecl *ivar,
6076 std::string &Result) {
6077 Result +=
"__OFFSETOFIVAR__(struct ";
6079 if (LangOpts.MicrosoftExt)
6083 ObjCIvarBitfieldGroupDecl(ivar, Result);
6192 static bool meta_data_declared =
false;
6193 if (meta_data_declared)
6196 Result +=
"\nstruct _prop_t {\n";
6197 Result +=
"\tconst char *name;\n";
6198 Result +=
"\tconst char *attributes;\n";
6201 Result +=
"\nstruct _protocol_t;\n";
6203 Result +=
"\nstruct _objc_method {\n";
6204 Result +=
"\tstruct objc_selector * _cmd;\n";
6205 Result +=
"\tconst char *method_type;\n";
6206 Result +=
"\tvoid *_imp;\n";
6209 Result +=
"\nstruct _protocol_t {\n";
6210 Result +=
"\tvoid * isa; // NULL\n";
6211 Result +=
"\tconst char *protocol_name;\n";
6212 Result +=
"\tconst struct _protocol_list_t * protocol_list; // super protocols\n";
6213 Result +=
"\tconst struct method_list_t *instance_methods;\n";
6214 Result +=
"\tconst struct method_list_t *class_methods;\n";
6215 Result +=
"\tconst struct method_list_t *optionalInstanceMethods;\n";
6216 Result +=
"\tconst struct method_list_t *optionalClassMethods;\n";
6217 Result +=
"\tconst struct _prop_list_t * properties;\n";
6218 Result +=
"\tconst unsigned int size; // sizeof(struct _protocol_t)\n";
6219 Result +=
"\tconst unsigned int flags; // = 0\n";
6220 Result +=
"\tconst char ** extendedMethodTypes;\n";
6223 Result +=
"\nstruct _ivar_t {\n";
6224 Result +=
"\tunsigned long int *offset; // pointer to ivar offset location\n";
6225 Result +=
"\tconst char *name;\n";
6226 Result +=
"\tconst char *type;\n";
6227 Result +=
"\tunsigned int alignment;\n";
6228 Result +=
"\tunsigned int size;\n";
6231 Result +=
"\nstruct _class_ro_t {\n";
6232 Result +=
"\tunsigned int flags;\n";
6233 Result +=
"\tunsigned int instanceStart;\n";
6234 Result +=
"\tunsigned int instanceSize;\n";
6236 if (Triple.getArch() == llvm::Triple::x86_64)
6237 Result +=
"\tunsigned int reserved;\n";
6238 Result +=
"\tconst unsigned char *ivarLayout;\n";
6239 Result +=
"\tconst char *name;\n";
6240 Result +=
"\tconst struct _method_list_t *baseMethods;\n";
6241 Result +=
"\tconst struct _objc_protocol_list *baseProtocols;\n";
6242 Result +=
"\tconst struct _ivar_list_t *ivars;\n";
6243 Result +=
"\tconst unsigned char *weakIvarLayout;\n";
6244 Result +=
"\tconst struct _prop_list_t *properties;\n";
6247 Result +=
"\nstruct _class_t {\n";
6248 Result +=
"\tstruct _class_t *isa;\n";
6249 Result +=
"\tstruct _class_t *superclass;\n";
6250 Result +=
"\tvoid *cache;\n";
6251 Result +=
"\tvoid *vtable;\n";
6252 Result +=
"\tstruct _class_ro_t *ro;\n";
6255 Result +=
"\nstruct _category_t {\n";
6256 Result +=
"\tconst char *name;\n";
6257 Result +=
"\tstruct _class_t *cls;\n";
6258 Result +=
"\tconst struct _method_list_t *instance_methods;\n";
6259 Result +=
"\tconst struct _method_list_t *class_methods;\n";
6260 Result +=
"\tconst struct _protocol_list_t *protocols;\n";
6261 Result +=
"\tconst struct _prop_list_t *properties;\n";
6264 Result +=
"extern \"C\" __declspec(dllimport) struct objc_cache _objc_empty_cache;\n";
6265 Result +=
"#pragma warning(disable:4273)\n";
6266 meta_data_declared =
true;
6270 long super_protocol_count) {
6271 Result +=
"struct /*_protocol_list_t*/"; Result +=
" {\n";
6272 Result +=
"\tlong protocol_count; // Note, this is 32/64 bit\n";
6273 Result +=
"\tstruct _protocol_t *super_protocols[";
6274 Result += utostr(super_protocol_count); Result +=
"];\n";
6279 unsigned int method_count) {
6280 Result +=
"struct /*_method_list_t*/"; Result +=
" {\n";
6281 Result +=
"\tunsigned int entsize; // sizeof(struct _objc_method)\n";
6282 Result +=
"\tunsigned int method_count;\n";
6283 Result +=
"\tstruct _objc_method method_list[";
6284 Result += utostr(method_count); Result +=
"];\n";
6289 unsigned int property_count) {
6290 Result +=
"struct /*_prop_list_t*/"; Result +=
" {\n";
6291 Result +=
"\tunsigned int entsize; // sizeof(struct _prop_t)\n";
6292 Result +=
"\tunsigned int count_of_properties;\n";
6293 Result +=
"\tstruct _prop_t prop_list[";
6294 Result += utostr(property_count); Result +=
"];\n";
6299 unsigned int ivar_count) {
6300 Result +=
"struct /*_ivar_list_t*/"; Result +=
" {\n";
6301 Result +=
"\tunsigned int entsize; // sizeof(struct _prop_t)\n";
6302 Result +=
"\tunsigned int count;\n";
6303 Result +=
"\tstruct _ivar_t ivar_list[";
6304 Result += utostr(ivar_count); Result +=
"];\n";
6311 StringRef ProtocolName) {
6312 if (SuperProtocols.size() > 0) {
6313 Result +=
"\nstatic ";
6315 Result +=
" "; Result += VarName;
6316 Result += ProtocolName;
6317 Result +=
" __attribute__ ((used, section (\"__DATA,__objc_const\"))) = {\n";
6318 Result +=
"\t"; Result += utostr(SuperProtocols.size()); Result +=
",\n";
6319 for (
unsigned i = 0, e = SuperProtocols.size(); i < e; i++) {
6321 Result +=
"\t&"; Result +=
"_OBJC_PROTOCOL_";
6335 StringRef TopLevelDeclName,
6337 if (Methods.size() > 0) {
6338 Result +=
"\nstatic ";
6340 Result +=
" "; Result += VarName;
6341 Result += TopLevelDeclName;
6342 Result +=
" __attribute__ ((used, section (\"__DATA,__objc_const\"))) = {\n";
6343 Result +=
"\t"; Result +=
"sizeof(_objc_method)"; Result +=
",\n";
6344 Result +=
"\t"; Result += utostr(Methods.size()); Result +=
",\n";
6345 for (
unsigned i = 0, e = Methods.size(); i < e; i++) {
6348 Result +=
"\t{{(struct objc_selector *)\"";
6350 Result +=
"\t{(struct objc_selector *)\"";
6351 Result += (MD)->getSelector().getAsString(); Result +=
"\"";
6354 Result +=
"\""; Result += MethodTypeString; Result +=
"\"";
6359 Result +=
"(void *)";
6360 Result += RewriteObj.MethodInternalNames[MD];
6374 const Decl *Container,
6376 StringRef ProtocolName) {
6377 if (Properties.size() > 0) {
6378 Result +=
"\nstatic ";
6380 Result +=
" "; Result += VarName;
6381 Result += ProtocolName;
6382 Result +=
" __attribute__ ((used, section (\"__DATA,__objc_const\"))) = {\n";
6383 Result +=
"\t"; Result +=
"sizeof(_prop_t)"; Result +=
",\n";
6384 Result +=
"\t"; Result += utostr(Properties.size()); Result +=
",\n";
6385 for (
unsigned i = 0, e = Properties.size(); i < e; i++) {
6391 Result += PropDecl->
getName(); Result +=
"\",";
6392 std::string PropertyTypeString =
6394 std::string QuotePropertyTypeString;
6395 RewriteObj.QuoteDoublequotes(PropertyTypeString, QuotePropertyTypeString);
6396 Result +=
"\""; Result += QuotePropertyTypeString; Result +=
"\"";
6422 const std::string &InstanceStart,
6423 const std::string &InstanceSize,
6429 StringRef ClassName) {
6430 Result +=
"\nstatic struct _class_ro_t ";
6431 Result += VarName; Result += ClassName;
6432 Result +=
" __attribute__ ((used, section (\"__DATA,__objc_const\"))) = {\n";
6434 Result += llvm::utostr(flags); Result +=
", ";
6435 Result += InstanceStart; Result +=
", ";
6436 Result += InstanceSize; Result +=
", \n";
6439 if (Triple.getArch() == llvm::Triple::x86_64)
6441 Result +=
"(unsigned int)0, \n\t";
6443 Result +=
"0, \n\t";
6444 Result +=
"\""; Result += ClassName; Result +=
"\",\n\t";
6445 bool metaclass = ((flags &
CLS_META) != 0);
6446 if (baseMethods.size() > 0) {
6447 Result +=
"(const struct _method_list_t *)&";
6449 Result +=
"_OBJC_$_CLASS_METHODS_";
6451 Result +=
"_OBJC_$_INSTANCE_METHODS_";
6452 Result += ClassName;
6456 Result +=
"0, \n\t";
6458 if (!metaclass && baseProtocols.size() > 0) {
6459 Result +=
"(const struct _objc_protocol_list *)&";
6460 Result +=
"_OBJC_CLASS_PROTOCOLS_$_"; Result += ClassName;
6464 Result +=
"0, \n\t";
6466 if (!metaclass && ivars.size() > 0) {
6467 Result +=
"(const struct _ivar_list_t *)&";
6468 Result +=
"_OBJC_$_INSTANCE_VARIABLES_"; Result += ClassName;
6472 Result +=
"0, \n\t";
6475 Result +=
"0, \n\t";
6476 if (!metaclass && Properties.size() > 0) {
6477 Result +=
"(const struct _prop_list_t *)&";
6478 Result +=
"_OBJC_$_PROP_LIST_"; Result += ClassName;
6489 const ObjCInterfaceDecl *CDecl,
bool metaclass) {
6491 const ObjCInterfaceDecl *RootClass = CDecl;
6501 if (metaclass && rootClass) {
6504 Result +=
"extern \"C\" ";
6506 Result +=
"__declspec(dllexport) ";
6508 Result +=
"__declspec(dllimport) ";
6510 Result +=
"struct _class_t OBJC_CLASS_$_";
6518 Result +=
"extern \"C\" ";
6520 Result +=
"__declspec(dllexport) ";
6522 Result +=
"__declspec(dllimport) ";
6524 Result +=
"struct _class_t ";
6529 if (metaclass && RootClass != SuperClass) {
6530 Result +=
"extern \"C\" ";
6532 Result +=
"__declspec(dllexport) ";
6534 Result +=
"__declspec(dllimport) ";
6536 Result +=
"struct _class_t ";
6543 Result +=
"\nextern \"C\" __declspec(dllexport) struct _class_t ";
6545 Result +=
" __attribute__ ((used, section (\"__DATA,__objc_data\"))) = {\n";
6549 Result +=
"0, // &"; Result += VarName;
6552 Result +=
"0, // &"; Result += VarName;
6557 Result +=
"0, // &"; Result += VarName;
6565 Result +=
"0, // &OBJC_METACLASS_$_";
6569 Result +=
"0, // &"; Result += VarName;
6576 Result +=
"0, // (void *)&_objc_empty_cache,\n\t";
6577 Result +=
"0, // unused, was (void *)&_objc_empty_vtable,\n\t";
6579 Result +=
"&_OBJC_METACLASS_RO_$_";
6581 Result +=
"&_OBJC_CLASS_RO_$_";
6583 Result +=
",\n};\n";
6590 const ObjCInterfaceDecl *SuperClass =
6593 Result +=
"static void OBJC_CLASS_SETUP_$_";
6595 Result +=
"(void ) {\n";
6597 Result +=
".isa = "; Result +=
"&OBJC_METACLASS_$_";
6601 Result +=
".superclass = ";
6603 Result +=
"&OBJC_CLASS_$_";
6605 Result +=
"&OBJC_METACLASS_$_";
6610 Result +=
".cache = "; Result +=
"&_objc_empty_cache"; Result +=
";\n";
6613 Result +=
".isa = "; Result +=
"&OBJC_METACLASS_$_";
6618 Result +=
".superclass = "; Result +=
"&OBJC_CLASS_$_";
6623 Result +=
".cache = "; Result +=
"&_objc_empty_cache"; Result +=
";\n";
6628 std::string &Result,
6630 ObjCInterfaceDecl *ClassDecl,
6635 StringRef CatName = CatDecl->
getName();
6636 StringRef ClassName = ClassDecl->
getName();
6640 Result +=
"extern \"C\" ";
6642 Result +=
"__declspec(dllexport) ";
6644 Result +=
"__declspec(dllimport) ";
6646 Result +=
"struct _class_t ";
6647 Result +=
"OBJC_CLASS_$_"; Result += ClassName;
6650 Result +=
"\nstatic struct _category_t ";
6651 Result +=
"_OBJC_$_CATEGORY_";
6652 Result += ClassName; Result +=
"_$_"; Result += CatName;
6653 Result +=
" __attribute__ ((used, section (\"__DATA,__objc_const\"))) = \n";
6655 Result +=
"\t\""; Result += ClassName; Result +=
"\",\n";
6656 Result +=
"\t0, // &"; Result +=
"OBJC_CLASS_$_"; Result += ClassName;
6658 if (InstanceMethods.size() > 0) {
6659 Result +=
"\t(const struct _method_list_t *)&";
6660 Result +=
"_OBJC_$_CATEGORY_INSTANCE_METHODS_";
6661 Result += ClassName; Result +=
"_$_"; Result += CatName;
6667 if (ClassMethods.size() > 0) {
6668 Result +=
"\t(const struct _method_list_t *)&";
6669 Result +=
"_OBJC_$_CATEGORY_CLASS_METHODS_";
6670 Result += ClassName; Result +=
"_$_"; Result += CatName;
6676 if (RefedProtocols.size() > 0) {
6677 Result +=
"\t(const struct _protocol_list_t *)&";
6678 Result +=
"_OBJC_CATEGORY_PROTOCOLS_$_";
6679 Result += ClassName; Result +=
"_$_"; Result += CatName;
6685 if (ClassProperties.size() > 0) {
6686 Result +=
"\t(const struct _prop_list_t *)&"; Result +=
"_OBJC_$_PROP_LIST_";
6687 Result += ClassName; Result +=
"_$_"; Result += CatName;
6696 Result +=
"static void OBJC_CATEGORY_SETUP_$_";
6700 Result +=
"(void ) {\n";
6701 Result +=
"\t_OBJC_$_CATEGORY_";
6705 Result +=
".cls = "; Result +=
"&OBJC_CLASS_$_"; Result += ClassName;
6713 StringRef ProtocolName) {
6714 if (Methods.size() == 0)
6717 Result +=
"\nstatic const char *";
6718 Result += VarName; Result += ProtocolName;
6719 Result +=
" [] __attribute__ ((used, section (\"__DATA,__objc_const\"))) = \n";
6721 for (
unsigned i = 0, e = Methods.size(); i < e; i++) {
6723 std::string MethodTypeString =
6725 std::string QuoteMethodTypeString;
6726 RewriteObj.QuoteDoublequotes(MethodTypeString, QuoteMethodTypeString);
6727 Result +=
"\t\""; Result += QuoteMethodTypeString; Result +=
"\"";
6738 std::string &Result,
6740 ObjCInterfaceDecl *CDecl) {
6753 for (
unsigned i =0, e = Ivars.size(); i < e; i++) {
6756 Result +=
"__declspec(allocate(\".objc_ivar$B\")) ";
6761 Result +=
"extern \"C\" unsigned long int ";
6763 Result +=
"extern \"C\" __declspec(dllexport) unsigned long int ";
6764 if (Ivars[i]->isBitField())
6765 RewriteObj.ObjCIvarBitfieldGroupOffset(IvarDecl, Result);
6768 Result +=
" __attribute__ ((used, section (\"__DATA,__objc_ivar\")))";
6770 RewriteObj.RewriteIvarOffsetComputation(IvarDecl, Result);
6772 if (Ivars[i]->isBitField()) {
6783 ObjCInterfaceDecl *CDecl) {
6784 if (OriginalIvars.size() > 0) {
6790 for (
unsigned i = 0, e = OriginalIvars.size(); i < e; i++) {
6791 if (OriginalIvars[i]->isBitField()) {
6792 Ivars.push_back(OriginalIvars[i]);
6797 Ivars.push_back(OriginalIvars[i]);
6800 Result +=
"\nstatic ";
6802 Result +=
" "; Result += VarName;
6804 Result +=
" __attribute__ ((used, section (\"__DATA,__objc_const\"))) = {\n";
6805 Result +=
"\t"; Result +=
"sizeof(_ivar_t)"; Result +=
",\n";
6806 Result +=
"\t"; Result += utostr(Ivars.size()); Result +=
",\n";
6807 for (
unsigned i =0, e = Ivars.size(); i < e; i++) {
6813 Result +=
"(unsigned long int *)&";
6814 if (Ivars[i]->isBitField())
6815 RewriteObj.ObjCIvarBitfieldGroupOffset(IvarDecl, Result);
6821 if (Ivars[i]->isBitField())
6822 RewriteObj.ObjCIvarBitfieldGroupDecl(Ivars[i], Result);
6824 Result += IvarDecl->
getName();
6829 IVQT = RewriteObj.GetGroupRecordTypeForObjCIvarBitfield(IvarDecl);
6831 std::string IvarTypeString, QuoteIvarTypeString;
6834 RewriteObj.QuoteDoublequotes(IvarTypeString, QuoteIvarTypeString);
6835 Result +=
"\""; Result += QuoteIvarTypeString; Result +=
"\", ";
6840 Align = llvm::Log2_32(Align);
6841 Result += llvm::utostr(Align); Result +=
", ";
6854 void RewriteModernObjC::RewriteObjCProtocolMetaData(
ObjCProtocolDecl *PDecl,
6855 std::string &Result) {
6867 RewriteObjCProtocolMetaData(I, Result);
6870 std::vector<ObjCMethodDecl *> InstanceMethods, ClassMethods;
6871 std::vector<ObjCMethodDecl *> OptInstanceMethods, OptClassMethods;
6874 OptInstanceMethods.push_back(MD);
6876 InstanceMethods.push_back(MD);
6882 OptClassMethods.push_back(MD);
6884 ClassMethods.push_back(MD);
6887 std::vector<ObjCMethodDecl *> AllMethods;
6888 for (
unsigned i = 0, e = InstanceMethods.size(); i < e; i++)
6889 AllMethods.push_back(InstanceMethods[i]);
6890 for (
unsigned i = 0, e = ClassMethods.size(); i < e; i++)
6891 AllMethods.push_back(ClassMethods[i]);
6892 for (
unsigned i = 0, e = OptInstanceMethods.size(); i < e; i++)
6893 AllMethods.push_back(OptInstanceMethods[i]);
6894 for (
unsigned i = 0, e = OptClassMethods.size(); i < e; i++)
6895 AllMethods.push_back(OptClassMethods[i]);
6899 "_OBJC_PROTOCOL_METHOD_TYPES_",
6904 "_OBJC_PROTOCOL_REFS_",
6908 "_OBJC_PROTOCOL_INSTANCE_METHODS_",
6912 "_OBJC_PROTOCOL_CLASS_METHODS_",
6916 "_OBJC_PROTOCOL_OPT_INSTANCE_METHODS_",
6920 "_OBJC_PROTOCOL_OPT_CLASS_METHODS_",
6928 "_OBJC_PROTOCOL_PROPERTIES_",
6933 if (LangOpts.MicrosoftExt)
6934 Result +=
"static ";
6935 Result +=
"struct _protocol_t _OBJC_PROTOCOL_";
6937 Result +=
" __attribute__ ((used)) = {\n";
6939 Result +=
"\t\""; Result += PDecl->
getNameAsString(); Result +=
"\",\n";
6940 if (SuperProtocols.size() > 0) {
6941 Result +=
"\t(const struct _protocol_list_t *)&"; Result +=
"_OBJC_PROTOCOL_REFS_";
6946 if (InstanceMethods.size() > 0) {
6947 Result +=
"\t(const struct method_list_t *)&_OBJC_PROTOCOL_INSTANCE_METHODS_";
6953 if (ClassMethods.size() > 0) {
6954 Result +=
"\t(const struct method_list_t *)&_OBJC_PROTOCOL_CLASS_METHODS_";
6960 if (OptInstanceMethods.size() > 0) {
6961 Result +=
"\t(const struct method_list_t *)&_OBJC_PROTOCOL_OPT_INSTANCE_METHODS_";
6967 if (OptClassMethods.size() > 0) {
6968 Result +=
"\t(const struct method_list_t *)&_OBJC_PROTOCOL_OPT_CLASS_METHODS_";
6974 if (ProtocolProperties.size() > 0) {
6975 Result +=
"\t(const struct _prop_list_t *)&_OBJC_PROTOCOL_PROPERTIES_";
6981 Result +=
"\t"; Result +=
"sizeof(_protocol_t)"; Result +=
",\n";
6984 if (AllMethods.size() > 0) {
6985 Result +=
"\t(const char **)&"; Result +=
"_OBJC_PROTOCOL_METHOD_TYPES_";
6990 Result +=
"\t0\n};\n";
6992 if (LangOpts.MicrosoftExt)
6993 Result +=
"static ";
6994 Result +=
"struct _protocol_t *";
6995 Result +=
"_OBJC_LABEL_PROTOCOL_$_"; Result += PDecl->
getNameAsString();
7001 llvm_unreachable(
"protocol already synthesized");
7008 const ObjCInterfaceDecl *OID) {
7009 if (OID->
hasAttr<ObjCExceptionAttr>())
7017 std::string &Result) {
7023 "Legacy implicit interface rewriting not supported in moder abi");
7031 if (!IVD->getDeclName())
7033 IVars.push_back(IVD);
7037 "_OBJC_$_INSTANCE_VARIABLES_",
7048 if (!Prop->getPropertyIvarDecl())
7055 InstanceMethods.push_back(Getter);
7060 InstanceMethods.push_back(Setter);
7064 "_OBJC_$_INSTANCE_METHODS_",
7070 "_OBJC_$_CLASS_METHODS_",
7075 std::vector<ObjCProtocolDecl *> RefedProtocols;
7078 E = Protocols.
end();
7080 RefedProtocols.push_back(*I);
7083 RewriteObjCProtocolMetaData(*I, Result);
7088 "_OBJC_CLASS_PROTOCOLS_$_",
7096 "_OBJC_$_PROP_LIST_",
7101 std::string InstanceSize;
7102 std::string InstanceStart;
7111 InstanceSize =
"sizeof(struct _class_t)";
7112 InstanceStart = InstanceSize;
7114 InstanceStart, InstanceSize,
7119 "_OBJC_METACLASS_RO_$_",
7134 InstanceSize.clear();
7135 InstanceStart.clear();
7136 if (!ObjCSynthesizedStructs.count(CDecl)) {
7138 InstanceStart =
"0";
7141 InstanceSize =
"sizeof(struct ";
7143 InstanceSize +=
"_IMPL)";
7147 RewriteIvarOffsetComputation(IVD, InstanceStart);
7150 InstanceStart = InstanceSize;
7153 InstanceStart, InstanceSize,
7158 "_OBJC_CLASS_RO_$_",
7162 "OBJC_METACLASS_$_",
7169 if (ImplementationIsNonLazy(IDecl))
7170 DefinedNonLazyClasses.push_back(CDecl);
7173 void RewriteModernObjC::RewriteClassSetupInitHook(std::string &Result) {
7174 int ClsDefCount = ClassImplementation.size();
7177 Result +=
"#pragma section(\".objc_inithooks$B\", long, read, write)\n";
7178 Result +=
"__declspec(allocate(\".objc_inithooks$B\")) ";
7179 Result +=
"static void *OBJC_CLASS_SETUP[] = {\n";
7180 for (
int i = 0; i < ClsDefCount; i++) {
7183 Result +=
"\t(void *)&OBJC_CLASS_SETUP_$_";
7184 Result += CDecl->
getName(); Result +=
",\n";
7189 void RewriteModernObjC::RewriteMetaDataIntoBuffer(std::string &Result) {
7190 int ClsDefCount = ClassImplementation.size();
7191 int CatDefCount = CategoryImplementation.size();
7194 for (
int i = 0; i < ClsDefCount; i++)
7195 RewriteObjCClassMetaData(ClassImplementation[i], Result);
7197 RewriteClassSetupInitHook(Result);
7200 for (
int i = 0; i < CatDefCount; i++)
7201 RewriteObjCCategoryImplDecl(CategoryImplementation[i], Result);
7203 RewriteCategorySetupInitHook(Result);
7205 if (ClsDefCount > 0) {
7206 if (LangOpts.MicrosoftExt)
7207 Result +=
"__declspec(allocate(\".objc_classlist$B\")) ";
7208 Result +=
"static struct _class_t *L_OBJC_LABEL_CLASS_$ [";
7209 Result += llvm::utostr(ClsDefCount); Result +=
"]";
7211 " __attribute__((used, section (\"__DATA, __objc_classlist," 7212 "regular,no_dead_strip\")))= {\n";
7213 for (
int i = 0; i < ClsDefCount; i++) {
7214 Result +=
"\t&OBJC_CLASS_$_";
7215 Result += ClassImplementation[i]->getNameAsString();
7220 if (!DefinedNonLazyClasses.empty()) {
7221 if (LangOpts.MicrosoftExt)
7222 Result +=
"__declspec(allocate(\".objc_nlclslist$B\")) \n";
7223 Result +=
"static struct _class_t *_OBJC_LABEL_NONLAZY_CLASS_$[] = {\n\t";
7224 for (
unsigned i = 0, e = DefinedNonLazyClasses.size(); i < e; i++) {
7225 Result +=
"\t&OBJC_CLASS_$_"; Result += DefinedNonLazyClasses[i]->getNameAsString();
7232 if (CatDefCount > 0) {
7233 if (LangOpts.MicrosoftExt)
7234 Result +=
"__declspec(allocate(\".objc_catlist$B\")) ";
7235 Result +=
"static struct _category_t *L_OBJC_LABEL_CATEGORY_$ [";
7236 Result += llvm::utostr(CatDefCount); Result +=
"]";
7238 " __attribute__((used, section (\"__DATA, __objc_catlist," 7239 "regular,no_dead_strip\")))= {\n";
7240 for (
int i = 0; i < CatDefCount; i++) {
7241 Result +=
"\t&_OBJC_$_CATEGORY_";
7243 CategoryImplementation[i]->getClassInterface()->getNameAsString();
7245 Result += CategoryImplementation[i]->getNameAsString();
7251 if (!DefinedNonLazyCategories.empty()) {
7252 if (LangOpts.MicrosoftExt)
7253 Result +=
"__declspec(allocate(\".objc_nlcatlist$B\")) \n";
7254 Result +=
"static struct _category_t *_OBJC_LABEL_NONLAZY_CATEGORY_$[] = {\n\t";
7255 for (
unsigned i = 0, e = DefinedNonLazyCategories.size(); i < e; i++) {
7256 Result +=
"\t&_OBJC_$_CATEGORY_";
7258 DefinedNonLazyCategories[i]->getClassInterface()->getNameAsString();
7260 Result += DefinedNonLazyCategories[i]->getNameAsString();
7267 void RewriteModernObjC::WriteImageInfo(std::string &Result) {
7268 if (LangOpts.MicrosoftExt)
7269 Result +=
"__declspec(allocate(\".objc_imageinfo$B\")) \n";
7271 Result +=
"static struct IMAGE_INFO { unsigned version; unsigned flag; } ";
7273 Result +=
"_OBJC_IMAGE_INFO = { 0, 2 };\n";
7279 std::string &Result) {
7287 FullCategoryName +=
"_$_";
7298 if (!Prop->getPropertyIvarDecl())
7304 InstanceMethods.push_back(Getter);
7308 InstanceMethods.push_back(Setter);
7312 "_OBJC_$_CATEGORY_INSTANCE_METHODS_",
7313 FullCategoryName,
true);
7318 "_OBJC_$_CATEGORY_CLASS_METHODS_",
7319 FullCategoryName,
true);
7327 RewriteObjCProtocolMetaData(I, Result);
7331 "_OBJC_CATEGORY_PROTOCOLS_$_",
7339 "_OBJC_$_PROP_LIST_",
7351 if (ImplementationIsNonLazy(IDecl))
7352 DefinedNonLazyCategories.push_back(CDecl);
7355 void RewriteModernObjC::RewriteCategorySetupInitHook(std::string &Result) {
7356 int CatDefCount = CategoryImplementation.size();
7359 Result +=
"#pragma section(\".objc_inithooks$B\", long, read, write)\n";
7360 Result +=
"__declspec(allocate(\".objc_inithooks$B\")) ";
7361 Result +=
"static void *OBJC_CATEGORY_SETUP[] = {\n";
7362 for (
int i = 0; i < CatDefCount; i++) {
7366 Result +=
"\t(void *)&OBJC_CATEGORY_SETUP_$_";
7367 Result += ClassDecl->
getName();
7377 template<
typename MethodIterator>
7378 void RewriteModernObjC::RewriteObjCMethodsMetaData(MethodIterator MethodBegin,
7379 MethodIterator MethodEnd,
7380 bool IsInstanceMethod,
7382 StringRef ClassName,
7383 std::string &Result) {
7384 if (MethodBegin == MethodEnd)
return;
7386 if (!objc_impl_method) {
7393 Result +=
"\nstruct _objc_method {\n";
7394 Result +=
"\tSEL _cmd;\n";
7395 Result +=
"\tchar *method_types;\n";
7396 Result +=
"\tvoid *_imp;\n";
7399 objc_impl_method =
true;
7410 unsigned NumMethods =
std::distance(MethodBegin, MethodEnd);
7412 if (LangOpts.MicrosoftExt) {
7413 if (IsInstanceMethod)
7414 Result +=
"__declspec(allocate(\".inst_meth$B\")) ";
7416 Result +=
"__declspec(allocate(\".cls_meth$B\")) ";
7418 Result +=
"static struct {\n";
7419 Result +=
"\tstruct _objc_method_list *next_method;\n";
7420 Result +=
"\tint method_count;\n";
7421 Result +=
"\tstruct _objc_method method_list[";
7422 Result += utostr(NumMethods);
7423 Result +=
"];\n} _OBJC_";
7425 Result += IsInstanceMethod ?
"INSTANCE" :
"CLASS";
7426 Result +=
"_METHODS_";
7427 Result += ClassName;
7428 Result +=
" __attribute__ ((used, section (\"__OBJC, __";
7429 Result += IsInstanceMethod ?
"inst" :
"cls";
7430 Result +=
"_meth\")))= ";
7431 Result +=
"{\n\t0, " + utostr(NumMethods) +
"\n";
7433 Result +=
"\t,{{(SEL)\"";
7434 Result += (*MethodBegin)->getSelector().getAsString().c_str();
7435 std::string MethodTypeString;
7438 Result += MethodTypeString;
7439 Result +=
"\", (void *)";
7440 Result += MethodInternalNames[*MethodBegin];
7442 for (++MethodBegin; MethodBegin != MethodEnd; ++MethodBegin) {
7443 Result +=
"\t ,{(SEL)\"";
7444 Result += (*MethodBegin)->getSelector().getAsString().c_str();
7445 std::string MethodTypeString;
7448 Result += MethodTypeString;
7449 Result +=
"\", (void *)";
7450 Result += MethodInternalNames[*MethodBegin];
7453 Result +=
"\t }\n};\n";
7462 DisableReplaceStmtScope S(*
this);
7463 BaseExpr = cast<Expr>(RewriteFunctionBodyOrGlobalInitializer(BaseExpr));
7474 assert(iFaceDecl &&
"RewriteObjCIvarRefExpr - iFaceDecl is null");
7476 ObjCInterfaceDecl *clsDeclared =
nullptr;
7479 assert(clsDeclared &&
"RewriteObjCIvarRefExpr(): Can't find class");
7482 std::string IvarOffsetName;
7484 ObjCIvarBitfieldGroupOffset(D, IvarOffsetName);
7488 ReferencedIvars[clsDeclared].insert(D);
7512 IvarT = GetGroupRecordTypeForObjCIvarBitfield(D);
7514 if (!isa<TypedefType>(IvarT) && IvarT->
isRecordType()) {
7524 std::string RecName = CDecl->
getName();
7530 unsigned UnsignedIntSize =
7533 llvm::APInt(UnsignedIntSize, 0),
7535 Zero = NoTypeInfoCStyleCastExpr(Context, PtrStructIMPL, CK_BitCast, Zero);
7550 convertObjCTypeToCStyleType(IvarT);
7553 castExpr = NoTypeInfoCStyleCastExpr(Context,
7583 ReplaceStmtWithRange(IV, Replacement, OldRange);
7587 #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.
An instance of this class is created to represent 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
isOverloadedOperator - Whether this function declaration represents an C++ overloaded 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()
completeDefinition - Notes 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.
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
isCompleteDefinition - 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
VarDecl - An instance of this class is created to represent a variable declaration or definition...
Objects with "hidden" visibility are not seen by the dynamic linker.
CompoundLiteralExpr - [C99 6.5.2.5].
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
getIdentifier - 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)
RecordDecl - Represents a struct/union/class.
DeclarationName getDeclName() const
getDeclName - 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
getDefinition - Returns the RecordDecl that actually defines this struct/union/class.
field_range fields() const
FieldDecl - An instance of this class is created by Sema::ActOnField to represent a member of a struc...
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.
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
TypeDecl - 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.
SourceLocation getLocEnd() const LLVM_READONLY
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)
SourceLocation getLocEnd() const LLVM_READONLY
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
BlockDecl - This represents a block literal declaration, which is like an unnamed FunctionDecl...
ValueDecl - Represent the declaration of a variable (in which case it is an lvalue) a function (in wh...
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 FunctionProtoType * T
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
getNameAsString - Get a human-readable name for the declaration, even if it is one of the special kin...
unsigned getNumElements() const
getNumElements - Return number of elements of objective-c dictionary literal.
TagDecl - 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)
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.
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,...)
EnumDecl - Represents an enum.
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
getName - 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.
TranslationUnitDecl - 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
NamedDecl - This represents a decl with a name.
ObjCIvarDecl * all_declared_ivar_begin()
all_declared_ivar_begin - return first ivar declared in this class, its extensions and its implementa...
SourceLocation getLocStart() const LLVM_READONLY
SourceLocation 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 getLocStart() const LLVM_READONLY
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...