23 #include "clang/Config/config.h" 26 #include "llvm/ADT/DenseSet.h" 27 #include "llvm/ADT/SmallPtrSet.h" 28 #include "llvm/ADT/StringExtras.h" 29 #include "llvm/Support/MemoryBuffer.h" 30 #include "llvm/Support/raw_ostream.h" 33 #if CLANG_ENABLE_OBJC_REWRITER 35 using namespace clang;
56 BLOCK_NEEDS_FREE = (1 << 24),
59 BLOCK_IS_GC = (1 << 27),
61 BLOCK_HAS_DESCRIPTOR = (1 << 29)
71 const char *MainFileStart, *MainFileEnd;
74 std::string InFileName;
75 std::unique_ptr<raw_ostream> OutFile;
80 Expr *GlobalConstructionExp;
81 unsigned RewriteFailedDiag;
82 unsigned GlobalBlockRewriteFailedDiag;
84 unsigned NumObjCStringLiterals;
85 VarDecl *ConstantStringClassReference;
91 unsigned TryFinallyContainsReturnDiag;
113 llvm::SmallPtrSet<ObjCInterfaceDecl*, 8> ObjCSynthesizedStructs;
114 llvm::SmallPtrSet<ObjCProtocolDecl*, 8> ObjCSynthesizedProtocols;
115 llvm::SmallPtrSet<ObjCInterfaceDecl*, 8> ObjCWrittenInterfaces;
116 llvm::SmallPtrSet<TagDecl*, 32> GlobalDefinedTags;
127 llvm::SmallPtrSet<ObjCProtocolDecl *, 32> ProtocolExprDecls;
140 llvm::SmallPtrSet<ValueDecl *, 8> BlockByCopyDeclsPtrSet;
142 llvm::SmallPtrSet<ValueDecl *, 8> BlockByRefDeclsPtrSet;
143 llvm::DenseMap<ValueDecl *, unsigned> BlockByRefDeclNo;
144 llvm::SmallPtrSet<ValueDecl *, 8> ImportedBlockDecls;
145 llvm::SmallPtrSet<VarDecl *, 8> ImportedLocalExternalDecls;
147 llvm::DenseMap<BlockExpr *, std::string> RewrittenBlockExprs;
153 llvm::DenseMap<const ObjCIvarDecl* , unsigned> IvarGroupNumber;
156 llvm::DenseMap<std::pair<const ObjCInterfaceDecl*, unsigned>,
QualType> GroupRecordType;
162 llvm::DenseMap<Stmt *, Stmt *> ReplacedNodes;
166 bool SilenceRewriteMacroWarning;
167 bool GenerateLineInfo;
168 bool objc_impl_method;
170 bool DisableReplaceStmt;
171 class DisableReplaceStmtScope {
172 RewriteModernObjC &R;
176 DisableReplaceStmtScope(RewriteModernObjC &R)
177 : R(R), SavedValue(R.DisableReplaceStmt) {
178 R.DisableReplaceStmt =
true;
180 ~DisableReplaceStmtScope() {
181 R.DisableReplaceStmt = SavedValue;
187 llvm::DenseMap<ObjCMethodDecl*, std::string> MethodInternalNames;
192 if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(*I)) {
193 if (!
Class->isThisDeclarationADefinition()) {
194 RewriteForwardClassDecl(D);
198 ObjCInterfacesSeen.push_back(Class);
204 if (!Proto->isThisDeclarationADefinition()) {
205 RewriteForwardProtocolDecl(D);
215 if (FDecl->isThisDeclarationADefinition() &&
217 !FDecl->isTopLevelDeclInObjCContainer()) {
218 FunctionDefinitionsSeen.push_back(FDecl);
222 HandleTopLevelSingleDecl(*I);
227 void HandleTopLevelDeclInObjCContainer(
DeclGroupRef D)
override {
230 if (isTopLevelBlockPointerType(TD->getUnderlyingType()))
231 RewriteBlockPointerDecl(TD);
232 else if (TD->getUnderlyingType()->isFunctionPointerType())
233 CheckFunctionPointerDecl(TD->getUnderlyingType(), TD);
235 RewriteObjCQualifiedInterfaceTypes(TD);
240 void HandleTopLevelSingleDecl(
Decl *D);
241 void HandleDeclInMainFile(
Decl *D);
242 RewriteModernObjC(std::string inFile, std::unique_ptr<raw_ostream> OS,
244 bool silenceMacroWarn,
bool LineInfo);
246 ~RewriteModernObjC()
override {}
248 void HandleTranslationUnit(
ASTContext &
C)
override;
250 void ReplaceStmt(
Stmt *Old,
Stmt *New) {
255 assert(Old !=
nullptr && New !=
nullptr &&
"Expected non-null Stmt's");
257 Stmt *ReplacingStmt = ReplacedNodes[Old];
261 if (DisableReplaceStmt)
273 llvm::raw_string_ostream S(SStr);
275 const std::string &Str = S.str();
279 ReplacedNodes[Old] = New;
282 if (SilenceRewriteMacroWarning)
289 bool InsertAfter =
true) {
291 if (!Rewrite.
InsertText(Loc, Str, InsertAfter) ||
292 SilenceRewriteMacroWarning)
301 if (!Rewrite.
ReplaceText(Start, OrigLength, Str) ||
302 SilenceRewriteMacroWarning)
310 void RewriteInclude();
311 void RewriteLineDirective(
const Decl *D);
313 std::string &LineString);
316 void RewriteForwardClassEpilogue(ObjCInterfaceDecl *ClassDecl,
317 const std::string &typedefString);
318 void RewriteImplementations();
322 void RewriteInterfaceDecl(ObjCInterfaceDecl *Dcl);
323 void RewriteImplementationDecl(
Decl *Dcl);
324 void RewriteObjCMethodDecl(
const ObjCInterfaceDecl *IDecl,
326 void RewriteTypeIntoString(
QualType T, std::string &ResultStr,
328 void RewriteByRefString(std::string &ResultStr,
const std::string &Name,
337 void RewriteBlockPointerType(std::string& Str,
QualType Type);
338 void RewriteBlockPointerTypeVariable(std::string& Str,
ValueDecl *VD);
340 void RewriteObjCQualifiedInterfaceTypes(
Decl *Dcl);
341 void RewriteTypeOfDecl(
VarDecl *VD);
342 void RewriteObjCQualifiedInterfaceTypes(
Expr *E);
347 Stmt *RewriteFunctionBodyOrGlobalInitializer(
Stmt *S);
368 void RewriteImplicitCastObjCExpr(
CastExpr *IE);
380 QualType SynthesizeBitfieldGroupStructType(
388 void RewriteBlockPointerDecl(
NamedDecl *VD);
389 void RewriteByRefVar(
VarDecl *VD,
bool firstDecl,
bool lastDecl);
394 void RewriteObjCInternalStruct(ObjCInterfaceDecl *CDecl,
399 bool &IsNamedDefinition);
405 void RewriteIvarOffsetSymbols(ObjCInterfaceDecl *CDecl,
408 void Initialize(
ASTContext &context)
override;
427 void SynthCountByEnumWithState(std::string &buf);
428 void SynthMsgSendFunctionDecl();
429 void SynthMsgSendSuperFunctionDecl();
430 void SynthMsgSendStretFunctionDecl();
431 void SynthMsgSendFpretFunctionDecl();
432 void SynthMsgSendSuperStretFunctionDecl();
433 void SynthGetClassFunctionDecl();
434 void SynthGetMetaClassFunctionDecl();
435 void SynthGetSuperClassFunctionDecl();
436 void SynthSelGetUidFunctionDecl();
437 void SynthSuperConstructorFunctionDecl();
440 template<
typename MethodIterator>
441 void RewriteObjCMethodsMetaData(MethodIterator MethodBegin,
442 MethodIterator MethodEnd,
443 bool IsInstanceMethod,
451 void RewriteClassSetupInitHook(std::string &
Result);
453 void RewriteMetaDataIntoBuffer(std::string &
Result);
454 void WriteImageInfo(std::string &
Result);
457 void RewriteCategorySetupInitHook(std::string &
Result);
465 std::string SynthesizeByrefCopyDestroyHelper(
VarDecl *VD,
int flag);
466 std::string SynthesizeBlockHelperFuncs(
BlockExpr *CE,
int i,
467 StringRef funcName, std::string Tag);
468 std::string SynthesizeBlockFunc(
BlockExpr *CE,
int i,
469 StringRef funcName, std::string Tag);
470 std::string SynthesizeBlockImpl(
BlockExpr *CE,
471 std::string Tag, std::string Desc);
472 std::string SynthesizeBlockDescriptor(std::string DescTag,
474 int i, StringRef funcName,
485 void WarnAboutReturnGotoStmts(
Stmt *S);
487 void InsertBlockLiteralsWithinFunction(
FunctionDecl *FD);
490 bool IsDeclStmtInForeachHeader(
DeclStmt *DS);
491 void CollectBlockDeclRefInfo(
BlockExpr *Exp);
492 void GetBlockDeclRefExprs(
Stmt *S);
493 void GetInnerBlockDeclRefExprs(
Stmt *S,
495 llvm::SmallPtrSetImpl<const DeclContext *> &InnerContexts);
499 bool isTopLevelBlockPointerType(
QualType T) {
500 return isa<BlockPointerType>(T);
506 bool convertBlockPointerToFunctionPointer(
QualType &T) {
507 if (isTopLevelBlockPointerType(T)) {
515 bool convertObjCTypeToCStyleType(
QualType &T);
517 bool needToScanForQualifiers(
QualType T);
519 QualType getConstantStringStructType();
522 void convertToUnqualifiedObjCType(
QualType &T) {
553 if (isa<ObjCInterfaceType>(PT->getPointeeType()) ||
554 PT->getPointeeType()->isObjCQualifiedIdType())
560 bool PointerTypeTakesAnyBlockArguments(
QualType QT);
561 bool PointerTypeTakesAnyObjCQualifiedType(
QualType QT);
562 void GetExtentOfArgList(
const char *Name,
const char *&LParen,
563 const char *&RParen);
565 void QuoteDoublequotes(std::string &From, std::string &To) {
566 for (
unsigned i = 0; i < From.length(); i++) {
576 bool variadic =
false) {
592 bool ImplementationIsNonLazy(
const ObjCImplDecl *OD)
const {
608 void RewriteModernObjC::RewriteBlocksInFunctionProtoType(
QualType funcType,
611 = dyn_cast<FunctionProtoType>(funcType.
IgnoreParens())) {
612 for (
const auto &I : fproto->param_types())
613 if (isTopLevelBlockPointerType(I)) {
615 RewriteBlockPointerDecl(D);
621 void RewriteModernObjC::CheckFunctionPointerDecl(
QualType funcType,
NamedDecl *ND) {
623 if (PT && PointerTypeTakesAnyBlockArguments(funcType))
628 std::string::size_type DotPos = Filename.rfind(
'.');
630 if (DotPos == std::string::npos) {
635 std::string Ext = std::string(Filename.begin()+DotPos+1, Filename.end());
638 return Ext ==
"h" || Ext ==
"hh" || Ext ==
"H";
641 RewriteModernObjC::RewriteModernObjC(std::string inFile,
642 std::unique_ptr<raw_ostream> OS,
645 bool silenceMacroWarn,
bool LineInfo)
646 : Diags(D), LangOpts(LOpts), InFileName(inFile), OutFile(std::move(OS)),
647 SilenceRewriteMacroWarning(silenceMacroWarn), GenerateLineInfo(LineInfo) {
650 "rewriting sub-expression within a macro (may not be correct)");
654 "rewriting block literal declared in global scope is not implemented");
658 "rewriter doesn't support user-specified control flow semantics " 659 "for @try/@finally (code may not execute properly)");
663 const std::string &InFile, std::unique_ptr<raw_ostream> OS,
665 bool SilenceRewriteMacroWarning,
bool LineInfo) {
666 return std::make_unique<RewriteModernObjC>(InFile, std::move(OS), Diags,
667 LOpts, SilenceRewriteMacroWarning,
671 void RewriteModernObjC::InitializeCommon(
ASTContext &context) {
675 MsgSendFunctionDecl =
nullptr;
676 MsgSendSuperFunctionDecl =
nullptr;
677 MsgSendStretFunctionDecl =
nullptr;
678 MsgSendSuperStretFunctionDecl =
nullptr;
679 MsgSendFpretFunctionDecl =
nullptr;
680 GetClassFunctionDecl =
nullptr;
681 GetMetaClassFunctionDecl =
nullptr;
682 GetSuperClassFunctionDecl =
nullptr;
683 SelGetUidFunctionDecl =
nullptr;
684 CFStringFunctionDecl =
nullptr;
685 ConstantStringClassReference =
nullptr;
686 NSStringRecord =
nullptr;
687 CurMethodDef =
nullptr;
688 CurFunctionDef =
nullptr;
689 GlobalVarDecl =
nullptr;
690 GlobalConstructionExp =
nullptr;
691 SuperStructDecl =
nullptr;
692 ProtocolTypeDecl =
nullptr;
693 ConstantStringDecl =
nullptr;
695 SuperConstructorFunctionDecl =
nullptr;
696 NumObjCStringLiterals = 0;
697 PropParentMap =
nullptr;
698 CurrentBody =
nullptr;
699 DisableReplaceStmt =
false;
700 objc_impl_method =
false;
704 const llvm::MemoryBuffer *MainBuf = SM->
getBuffer(MainFileID);
705 MainFileStart = MainBuf->getBufferStart();
706 MainFileEnd = MainBuf->getBufferEnd();
715 void RewriteModernObjC::HandleTopLevelSingleDecl(
Decl *D) {
730 RewriteFunctionDecl(FD);
731 }
else if (
VarDecl *FVD = dyn_cast<VarDecl>(D)) {
733 if (FVD->getName() ==
"_NSConstantStringClassReference") {
734 ConstantStringClassReference = FVD;
738 RewriteCategoryDecl(CD);
740 if (PD->isThisDeclarationADefinition())
741 RewriteProtocolDecl(PD);
745 DIEnd = LSD->decls_end();
747 if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>((*DI))) {
748 if (!IFace->isThisDeclarationADefinition()) {
752 if (isa<ObjCInterfaceDecl>(*DI) &&
753 !cast<ObjCInterfaceDecl>(*DI)->isThisDeclarationADefinition() &&
754 StartLoc == (*DI)->getBeginLoc())
760 }
while (DI != DIEnd);
761 RewriteForwardClassDecl(DG);
766 ObjCInterfacesSeen.push_back(IFace);
773 if (!Proto->isThisDeclarationADefinition()) {
777 if (isa<ObjCProtocolDecl>(*DI) &&
778 !cast<ObjCProtocolDecl>(*DI)->isThisDeclarationADefinition() &&
779 StartLoc == (*DI)->getBeginLoc())
785 }
while (DI != DIEnd);
786 RewriteForwardProtocolDecl(DG);
791 HandleTopLevelSingleDecl(*DI);
797 return HandleDeclInMainFile(D);
804 void RewriteModernObjC::RewriteInclude() {
807 const char *MainBufStart = MainBuf.begin();
808 const char *MainBufEnd = MainBuf.end();
809 size_t ImportLen = strlen(
"import");
812 for (
const char *BufPtr = MainBufStart; BufPtr < MainBufEnd; ++BufPtr) {
813 if (*BufPtr ==
'#') {
814 if (++BufPtr == MainBufEnd)
816 while (*BufPtr ==
' ' || *BufPtr ==
'\t')
817 if (++BufPtr == MainBufEnd)
819 if (!strncmp(BufPtr,
"import", ImportLen)) {
823 ReplaceText(ImportLoc, ImportLen,
"include");
832 Result +=
"OBJC_IVAR_$_";
843 std::string IvarOffsetName;
845 ObjCIvarBitfieldGroupOffset(D, IvarOffsetName);
849 std::string S =
"(*(";
852 IvarT = GetGroupRecordTypeForObjCIvarBitfield(D);
854 if (!isa<TypedefType>(IvarT) && IvarT->
isRecordType()) {
862 CDecl = CatDecl->getClassInterface();
863 std::string RecName = CDecl->
getName();
869 unsigned UnsignedIntSize =
874 Zero = NoTypeInfoCStyleCastExpr(Context, PtrStructIMPL, CK_BitCast, Zero);
888 convertObjCTypeToCStyleType(IvarT);
895 S +=
"((char *)self + ";
902 ReferencedIvars[
const_cast<ObjCInterfaceDecl *
>(ClassDecl)].insert(D);
919 static bool objcGetPropertyDefined =
false;
920 static bool objcSetPropertyDefined =
false;
925 InsertText(startLoc,
"// ");
927 assert((*startBuf ==
'@') &&
"bogus @synthesize location");
928 const char *semiBuf = strchr(startBuf,
';');
929 assert((*semiBuf ==
';') &&
"@synthesize: can't find ';'");
940 assert(IMD && OID &&
"Synthesized ivars must be attached to @implementation");
948 if (GenGetProperty && !objcGetPropertyDefined) {
949 objcGetPropertyDefined =
true;
951 Getr =
"\nextern \"C\" __declspec(dllimport) " 952 "id objc_getProperty(id, SEL, long, bool);\n";
959 if (GenGetProperty) {
972 for (
unsigned i = 0, e = FT->getNumParams(); i != e; ++i) {
974 std::string ParamStr =
978 if (FT->isVariadic()) {
979 if (FT->getNumParams())
988 Getr +=
"return (_TYPE)";
989 Getr +=
"objc_getProperty(self, _cmd, ";
990 RewriteIvarOffsetComputation(OID, Getr);
996 InsertText(startGetterSetterLoc, Getr);
1007 if (GenSetProperty && !objcSetPropertyDefined) {
1008 objcSetPropertyDefined =
true;
1010 Setr =
"\nextern \"C\" __declspec(dllimport) " 1011 "void objc_setProperty (id, SEL, long, id, bool, bool);\n";
1019 if (GenSetProperty) {
1020 Setr +=
"objc_setProperty (self, _cmd, ";
1021 RewriteIvarOffsetComputation(OID, Setr);
1039 InsertText(startGetterSetterLoc, Setr);
1043 std::string &typedefString) {
1044 typedefString +=
"\n#ifndef _REWRITER_typedef_";
1046 typedefString +=
"\n";
1047 typedefString +=
"#define _REWRITER_typedef_";
1049 typedefString +=
"\n";
1050 typedefString +=
"typedef struct objc_object ";
1053 typedefString +=
";\ntypedef struct {} _objc_exc_";
1055 typedefString +=
";\n#endif\n";
1058 void RewriteModernObjC::RewriteForwardClassEpilogue(ObjCInterfaceDecl *ClassDecl,
1059 const std::string &typedefString) {
1062 const char *semiPtr = strchr(startBuf,
';');
1064 ReplaceText(startLoc, semiPtr-startBuf+1, typedefString);
1067 void RewriteModernObjC::RewriteForwardClassDecl(
DeclGroupRef D) {
1068 std::string typedefString;
1070 if (ObjCInterfaceDecl *ForwardDecl = dyn_cast<ObjCInterfaceDecl>(*I)) {
1071 if (I == D.
begin()) {
1075 typedefString +=
"// @class ";
1076 typedefString += ForwardDecl->getNameAsString();
1077 typedefString +=
";";
1082 HandleTopLevelSingleDecl(*I);
1085 RewriteForwardClassEpilogue(cast<ObjCInterfaceDecl>(*I), typedefString);
1088 void RewriteModernObjC::RewriteForwardClassDecl(
1090 std::string typedefString;
1091 for (
unsigned i = 0; i < D.size(); i++) {
1092 ObjCInterfaceDecl *ForwardDecl = cast<ObjCInterfaceDecl>(D[i]);
1094 typedefString +=
"// @class ";
1096 typedefString +=
";";
1100 RewriteForwardClassEpilogue(cast<ObjCInterfaceDecl>(D[0]), typedefString);
1103 void RewriteModernObjC::RewriteMethodDeclaration(
ObjCMethodDecl *Method) {
1113 InsertText(LocStart,
"#if 0\n");
1114 ReplaceText(LocEnd, 1,
";\n#endif\n");
1116 InsertText(LocStart,
"// ");
1123 ReplaceText(Loc, 0,
"// ");
1132 ReplaceText(LocStart, 1,
"/** ");
1136 ReplaceText(LocStart, 0,
"// ");
1143 RewriteMethodDeclaration(I);
1145 RewriteMethodDeclaration(I);
1149 strlen(
"@end"),
"/* @end */\n");
1157 ReplaceText(LocStart, 0,
"// ");
1160 RewriteMethodDeclaration(I);
1162 RewriteMethodDeclaration(I);
1168 ReplaceText(LocEnd, strlen(
"@end"),
"/* @end */\n");
1173 for (
const char *p = startBuf; p < endBuf; p++) {
1174 if (*p ==
'@' && !strncmp(p+1,
"optional", strlen(
"optional"))) {
1176 ReplaceText(OptionalLoc, strlen(
"@optional"),
"/* @optional */");
1179 else if (*p ==
'@' && !strncmp(p+1,
"required", strlen(
"required"))) {
1181 ReplaceText(OptionalLoc, strlen(
"@required"),
"/* @required */");
1187 void RewriteModernObjC::RewriteForwardProtocolDecl(
DeclGroupRef D) {
1190 llvm_unreachable(
"Invalid SourceLocation");
1192 ReplaceText(LocStart, 0,
"// ");
1199 llvm_unreachable(
"Invalid SourceLocation");
1201 ReplaceText(LocStart, 0,
"// ");
1204 void RewriteModernObjC::RewriteTypeIntoString(
QualType T, std::string &ResultStr,
1227 void RewriteModernObjC::RewriteObjCMethodDecl(
const ObjCInterfaceDecl *IDecl,
1229 std::string &ResultStr) {
1232 ResultStr +=
"\nstatic ";
1233 RewriteTypeIntoString(OMD->
getReturnType(), ResultStr, FPRetType);
1237 std::string NameStr;
1255 int len = selString.size();
1256 for (
int i = 0; i < len; i++)
1257 if (selString[i] ==
':')
1259 NameStr += selString;
1262 MethodInternalNames[OMD] = NameStr;
1263 ResultStr += NameStr;
1272 if (!LangOpts.MicrosoftExt) {
1273 if (ObjCSynthesizedStructs.count(const_cast<ObjCInterfaceDecl*>(IDecl)))
1274 ResultStr +=
"struct ";
1284 ResultStr +=
" self, ";
1286 ResultStr +=
" _cmd";
1289 for (
const auto *PDecl : OMD->
parameters()) {
1291 if (PDecl->getType()->isObjCQualifiedIdType()) {
1298 (void)convertBlockPointerToFunctionPointer(QT);
1304 ResultStr +=
", ...";
1313 for (
unsigned i = 0, e = FT->getNumParams(); i != e; ++i) {
1314 if (i) ResultStr +=
", ";
1315 std::string ParamStr =
1317 ResultStr += ParamStr;
1319 if (FT->isVariadic()) {
1320 if (FT->getNumParams())
1331 void RewriteModernObjC::RewriteImplementationDecl(
Decl *OID) {
1334 assert((IMD || CID) &&
"Unknown implementation type");
1346 InsertText(CID->getBeginLoc(),
"// ");
1348 for (
auto *OMD : IMD ? IMD->
instance_methods() : CID->instance_methods()) {
1351 std::string ResultStr;
1358 ReplaceText(LocStart, endBuf-startBuf, ResultStr);
1361 for (
auto *OMD : IMD ? IMD->
class_methods() : CID->class_methods()) {
1364 std::string ResultStr;
1371 ReplaceText(LocStart, endBuf-startBuf, ResultStr);
1373 for (
auto *I : IMD ? IMD->
property_impls() : CID->property_impls())
1374 RewritePropertyImplDecl(I, IMD, CID);
1376 InsertText(IMD ? IMD->
getEndLoc() : CID->getEndLoc(),
"// ");
1379 void RewriteModernObjC::RewriteInterfaceDecl(ObjCInterfaceDecl *ClassDecl) {
1381 if (ObjCSynthesizedStructs.count(ClassDecl))
1385 while (SuperClass) {
1386 RewriteInterfaceDecl(SuperClass);
1389 std::string ResultStr;
1393 RewriteIvarOffsetSymbols(ClassDecl, ResultStr);
1395 RewriteObjCInternalStruct(ClassDecl, ResultStr);
1402 RewriteMethodDeclaration(I);
1404 RewriteMethodDeclaration(I);
1426 DisableReplaceStmtScope S(*
this);
1432 Base = cast<OpaqueValueExpr>(Base)->getSourceExpr();
1433 Base = cast<Expr>(RewriteFunctionBodyOrGlobalInitializer(Base));
1437 for (
unsigned i = 0; i < numArgs; i++) {
1439 if (isa<OpaqueValueExpr>(Arg))
1440 Arg = cast<OpaqueValueExpr>(Arg)->getSourceExpr();
1441 Arg = cast<Expr>(RewriteFunctionBodyOrGlobalInitializer(Arg));
1442 Args.push_back(Arg);
1495 Stmt *Replacement = SynthMessageExpr(NewMsg);
1496 ReplaceStmtWithRange(PseudoOp, Replacement, OldRange);
1513 DisableReplaceStmtScope S(*
this);
1517 Base = cast<OpaqueValueExpr>(Base)->getSourceExpr();
1518 Base = cast<Expr>(RewriteFunctionBodyOrGlobalInitializer(Base));
1521 for (
unsigned i = 0; i < numArgs; i++) {
1523 if (isa<OpaqueValueExpr>(Arg))
1524 Arg = cast<OpaqueValueExpr>(Arg)->getSourceExpr();
1525 Arg = cast<Expr>(RewriteFunctionBodyOrGlobalInitializer(Arg));
1526 Args.push_back(Arg);
1578 Stmt *Replacement = SynthMessageExpr(NewMsg);
1579 ReplaceStmtWithRange(PseudoOp, Replacement, OldRange);
1592 void RewriteModernObjC::SynthCountByEnumWithState(std::string &buf) {
1593 buf +=
"((_WIN_NSUInteger (*) (id, SEL, struct __objcFastEnumerationState *, " 1594 "id *, _WIN_NSUInteger))(void *)objc_msgSend)";
1596 buf +=
"((id)l_collection,\n\t\t";
1597 buf +=
"sel_registerName(\"countByEnumeratingWithState:objects:count:\"),";
1599 buf +=
"&enumState, " 1600 "(id *)__rw_items, (_WIN_NSUInteger)16)";
1607 if (Stmts.empty() || !isa<ObjCForCollectionStmt>(Stmts.back()))
1613 buf =
"goto __break_label_";
1614 buf += utostr(ObjCBcLabelNo.back());
1615 ReplaceText(startLoc, strlen(
"break"), buf);
1620 void RewriteModernObjC::ConvertSourceLocationToLineDirective(
1622 std::string &LineString) {
1623 if (Loc.
isFileID() && GenerateLineInfo) {
1624 LineString +=
"\n#line ";
1626 LineString += utostr(PLoc.
getLine());
1627 LineString +=
" \"";
1629 LineString +=
"\"\n";
1637 if (Stmts.empty() || !isa<ObjCForCollectionStmt>(Stmts.back()))
1643 buf =
"goto __continue_label_";
1644 buf += utostr(ObjCBcLabelNo.back());
1645 ReplaceText(startLoc, strlen(
"continue"), buf);
1684 assert(!Stmts.empty() &&
"ObjCForCollectionStmt - Statement stack empty");
1685 assert(isa<ObjCForCollectionStmt>(Stmts.back()) &&
1686 "ObjCForCollectionStmt Statement stack mismatch");
1687 assert(!ObjCBcLabelNo.empty() &&
1688 "ObjCForCollectionStmt - Label No stack empty");
1692 StringRef elementName;
1693 std::string elementTypeAsString;
1697 ConvertSourceLocationToLineDirective(ForEachLoc, buf);
1701 NamedDecl* D = cast<NamedDecl>(DS->getSingleDecl());
1702 QualType ElementType = cast<ValueDecl>(D)->getType();
1703 if (ElementType->isObjCQualifiedIdType() ||
1704 ElementType->isObjCQualifiedInterfaceType())
1706 elementTypeAsString =
"id";
1709 buf += elementTypeAsString;
1722 elementTypeAsString =
"id";
1728 buf +=
"struct __objcFastEnumerationState enumState = { 0 };\n\t";
1730 buf +=
"id __rw_items[16];\n\t";
1732 buf +=
"id l_collection = (id)";
1734 const char *startCollectionBuf = startBuf;
1735 startCollectionBuf += 3;
1736 startCollectionBuf = strchr(startCollectionBuf,
'(');
1737 startCollectionBuf++;
1739 while (*startCollectionBuf !=
' ' ||
1740 *(startCollectionBuf+1) !=
'i' || *(startCollectionBuf+2) !=
'n' ||
1741 (*(startCollectionBuf+3) !=
' ' &&
1742 *(startCollectionBuf+3) !=
'[' && *(startCollectionBuf+3) !=
'('))
1743 startCollectionBuf++;
1744 startCollectionBuf += 3;
1747 ReplaceText(startLoc, startCollectionBuf - startBuf, buf);
1765 buf +=
"_WIN_NSUInteger limit =\n\t\t";
1766 SynthCountByEnumWithState(buf);
1776 buf +=
"if (limit) {\n\t";
1777 buf +=
"unsigned long startMutations = *enumState.mutationsPtr;\n\t";
1778 buf +=
"do {\n\t\t";
1779 buf +=
"unsigned long counter = 0;\n\t\t";
1780 buf +=
"do {\n\t\t\t";
1781 buf +=
"if (startMutations != *enumState.mutationsPtr)\n\t\t\t\t";
1782 buf +=
"objc_enumerationMutation(l_collection);\n\t\t\t";
1785 buf += elementTypeAsString;
1786 buf +=
")enumState.itemsPtr[counter++];";
1788 ReplaceText(lparenLoc, 1, buf);
1802 buf +=
"__continue_label_";
1803 buf += utostr(ObjCBcLabelNo.back());
1806 buf +=
"} while (counter < limit);\n\t";
1807 buf +=
"} while ((limit = ";
1808 SynthCountByEnumWithState(buf);
1812 buf += elementTypeAsString;
1814 buf +=
"__break_label_";
1815 buf += utostr(ObjCBcLabelNo.back());
1818 buf +=
"else\n\t\t";
1821 buf += elementTypeAsString;
1827 if (isa<CompoundStmt>(S->
getBody())) {
1829 InsertText(endBodyLoc, buf);
1839 const char *semiBuf = strchr(stmtBuf,
';');
1840 assert(semiBuf &&
"Can't find ';'");
1842 InsertText(endBodyLoc, buf);
1845 ObjCBcLabelNo.pop_back();
1850 buf +=
"{ struct _FIN { _FIN(id reth) : rethrow(reth) {}\n";
1851 buf +=
"\t~_FIN() { if (rethrow) objc_exception_throw(rethrow); }\n";
1852 buf +=
"\tid rethrow;\n";
1853 buf +=
"\t} _fin_force_rethow(_rethrow);";
1867 assert((*startBuf ==
'@') &&
"bogus @synchronized location");
1871 ConvertSourceLocationToLineDirective(SynchLoc, buf);
1872 buf +=
"{ id _rethrow = 0; id _sync_obj = (id)";
1874 const char *lparenBuf = startBuf;
1875 while (*lparenBuf !=
'(') lparenBuf++;
1876 ReplaceText(startLoc, lparenBuf-startBuf+1, buf);
1878 buf =
"; objc_sync_enter(_sync_obj);\n";
1879 buf +=
"try {\n\tstruct _SYNC_EXIT { _SYNC_EXIT(id arg) : sync_exit(arg) {}";
1880 buf +=
"\n\t~_SYNC_EXIT() {objc_sync_exit(sync_exit);}";
1881 buf +=
"\n\tid sync_exit;";
1882 buf +=
"\n\t} _sync_exit(_sync_obj);\n";
1889 while (*RParenExprLocBuf !=
')') RParenExprLocBuf--;
1894 assert (*LBraceLocBuf ==
'{');
1895 ReplaceText(RParenExprLoc, (LBraceLocBuf - SM->
getCharacterData(RParenExprLoc) + 1), buf);
1899 "bogus @synchronized block");
1901 buf =
"} catch (id e) {_rethrow = e;}\n";
1906 ReplaceText(startRBraceLoc, 1, buf);
1911 void RewriteModernObjC::WarnAboutReturnGotoStmts(
Stmt *S)
1916 WarnAboutReturnGotoStmts(SubStmt);
1918 if (isa<ReturnStmt>(S) || isa<GotoStmt>(S)) {
1920 TryFinallyContainsReturnDiag);
1926 ReplaceText(startLoc, strlen(
"@autoreleasepool"),
"/* @autoreleasepool */");
1928 "{ __AtAutoreleasePool __autoreleasepool; ");
1938 ConvertSourceLocationToLineDirective(TryLocation, buf);
1942 buf +=
"{ id volatile _rethrow = 0;\n";
1944 buf +=
"{ id volatile _rethrow = 0;\ntry {\n";
1951 assert((*startBuf ==
'@') &&
"bogus @try location");
1953 ReplaceText(startLoc, 1, buf);
1956 ReplaceText(startLoc, 1,
"");
1963 bool AtRemoved =
false;
1968 ObjCInterfaceDecl *IDecl = Ptr->getObjectType()->getInterface();
1974 assert((*startBuf ==
'@') &&
"bogus @catch location");
1982 ReplaceText(startLoc, rParenBuf-startBuf+1, Result);
1993 ReplaceText(lBraceLoc, 1, Result);
2000 ReplaceText(startLoc, 1,
"");
2008 ConvertSourceLocationToLineDirective(FinallyLoc, buf);
2009 buf +=
"catch (id e) {_rethrow = e;}\n";
2013 ConvertSourceLocationToLineDirective(FinallyLoc, buf);
2014 buf +=
"catch (id e) {_rethrow = e;}\n";
2018 ReplaceText(startFinalLoc, 8, buf);
2023 ReplaceText(startFinalBodyLoc, 1, buf);
2026 ReplaceText(endFinalBodyLoc, 1,
"}\n}");
2042 assert((*startBuf ==
'@') &&
"bogus @throw location");
2047 buf =
"objc_exception_throw(";
2052 const char *wBuf = strchr(startBuf,
'w');
2053 assert((*wBuf ==
'w') &&
"@throw: can't find 'w'");
2054 ReplaceText(startLoc, wBuf-startBuf+1, buf);
2058 const char *semiBuf = strchr(endBuf,
';');
2059 assert((*semiBuf ==
';') &&
"@throw: can't find ';'");
2062 ReplaceText(semiLoc, 1,
");");
2068 std::string StrEncoding;
2070 Expr *Replacement = getStringLiteral(StrEncoding);
2071 ReplaceStmt(Exp, Replacement);
2079 if (!SelGetUidFunctionDecl)
2080 SynthSelGetUidFunctionDecl();
2081 assert(SelGetUidFunctionDecl &&
"Can't find sel_registerName() decl");
2085 CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl,
2087 ReplaceStmt(Exp, SelExp);
2093 RewriteModernObjC::SynthesizeCallToFunctionDecl(
FunctionDecl *FD,
2112 *Context, ICE, Args, FT->getCallResultType(*Context),
VK_RValue, EndLoc);
2117 const char *&startRef,
const char *&endRef) {
2118 while (startBuf < endBuf) {
2119 if (*startBuf ==
'<')
2120 startRef = startBuf;
2121 if (*startBuf ==
'>') {
2122 if (startRef && *startRef ==
'<') {
2135 while (*argRef !=
')' && (*argRef !=
',' || angle > 0)) {
2138 else if (*argRef ==
'>')
2142 assert(angle == 0 &&
"scanToNextArgument - bad protocol type syntax");
2145 bool RewriteModernObjC::needToScanForQualifiers(
QualType T) {
2158 return needToScanForQualifiers(ElemTy);
2163 void RewriteModernObjC::RewriteObjCQualifiedInterfaceTypes(
Expr *E) {
2165 if (needToScanForQualifiers(Type)) {
2169 Loc = ECE->getLParenLoc();
2170 EndLoc = ECE->getRParenLoc();
2181 const char *startRef =
nullptr, *endRef =
nullptr;
2187 InsertText(LessLoc,
"/*");
2188 InsertText(GreaterLoc,
"*/");
2193 void RewriteModernObjC::RewriteObjCQualifiedInterfaceTypes(
Decl *Dcl) {
2197 if (
VarDecl *VD = dyn_cast<VarDecl>(Dcl)) {
2198 Loc = VD->getLocation();
2199 Type = VD->getType();
2201 else if (
FunctionDecl *FD = dyn_cast<FunctionDecl>(Dcl)) {
2206 assert(funcType &&
"missing function type");
2212 else if (
FieldDecl *FD = dyn_cast<FieldDecl>(Dcl)) {
2217 Loc = TD->getLocation();
2218 Type = TD->getUnderlyingType();
2223 if (needToScanForQualifiers(Type)) {
2227 const char *startBuf = endBuf;
2228 while (*startBuf !=
';' && *startBuf !=
'<' && startBuf != MainFileStart)
2230 const char *startRef =
nullptr, *endRef =
nullptr;
2236 InsertText(LessLoc,
"/*");
2237 InsertText(GreaterLoc,
"*/");
2244 const char *startFuncBuf = startBuf;
2249 const char *endBuf = startBuf;
2252 const char *startRef =
nullptr, *endRef =
nullptr;
2260 InsertText(LessLoc,
"/*");
2261 InsertText(GreaterLoc,
"*/");
2263 startBuf = ++endBuf;
2268 while (*startBuf && *startBuf !=
')' && *startBuf !=
',')
2275 void RewriteModernObjC::RewriteTypeOfDecl(
VarDecl *ND) {
2278 if (!isa<TypeOfExprType>(TypePtr))
2280 while (isa<TypeOfExprType>(TypePtr)) {
2281 const TypeOfExprType *TypeOfExprTypePtr = cast<TypeOfExprType>(TypePtr);
2292 TypeAsString +=
" " + Name +
" = ";
2296 startLoc = ECE->getLParenLoc();
2301 ReplaceText(DeclLoc, endBuf-startBuf-1, TypeAsString);
2307 ReplaceText(DeclLoc, endBuf-startBuf-1, TypeAsString);
2312 void RewriteModernObjC::SynthSelGetUidFunctionDecl() {
2321 SelGetUidIdent, getFuncType,
2325 void RewriteModernObjC::RewriteFunctionDecl(
FunctionDecl *FD) {
2328 FD->
getName() ==
"sel_registerName") {
2329 SelGetUidFunctionDecl = FD;
2332 RewriteObjCQualifiedInterfaceTypes(FD);
2335 void RewriteModernObjC::RewriteBlockPointerType(std::string& Str,
QualType Type) {
2337 const char *argPtr = TypeString.c_str();
2338 if (!strchr(argPtr,
'^')) {
2343 Str += (*argPtr ==
'^' ?
'*' : *argPtr);
2349 void RewriteModernObjC::RewriteBlockPointerTypeVariable(std::string& Str,
2353 const char *argPtr = TypeString.c_str();
2378 void RewriteModernObjC::RewriteBlockLiteralFunctionDecl(
FunctionDecl *FD) {
2384 QualType Type = proto->getReturnType();
2389 unsigned numArgs = proto->getNumParams();
2390 for (
unsigned i = 0; i < numArgs; i++) {
2391 QualType ArgType = proto->getParamType(i);
2392 RewriteBlockPointerType(FdStr, ArgType);
2397 FdStr += (numArgs > 0) ?
", ...);\n" :
"...);\n";
2401 InsertText(FunLocStart, FdStr);
2405 void RewriteModernObjC::SynthSuperConstructorFunctionDecl() {
2406 if (SuperConstructorFunctionDecl)
2411 assert(!argT.
isNull() &&
"Can't find 'id' type");
2412 ArgTys.push_back(argT);
2413 ArgTys.push_back(argT);
2419 msgSendIdent, msgSendType,
2424 void RewriteModernObjC::SynthMsgSendFunctionDecl() {
2428 assert(!argT.
isNull() &&
"Can't find 'id' type");
2429 ArgTys.push_back(argT);
2431 assert(!argT.
isNull() &&
"Can't find 'SEL' type");
2432 ArgTys.push_back(argT);
2438 msgSendIdent, msgSendType,
nullptr,
2443 void RewriteModernObjC::SynthMsgSendSuperFunctionDecl() {
2446 ArgTys.push_back(Context->
VoidTy);
2452 msgSendIdent, msgSendType,
2457 void RewriteModernObjC::SynthMsgSendStretFunctionDecl() {
2461 assert(!argT.
isNull() &&
"Can't find 'id' type");
2462 ArgTys.push_back(argT);
2464 assert(!argT.
isNull() &&
"Can't find 'SEL' type");
2465 ArgTys.push_back(argT);
2471 msgSendIdent, msgSendType,
2477 void RewriteModernObjC::SynthMsgSendSuperStretFunctionDecl() {
2479 &Context->
Idents.
get(
"objc_msgSendSuper_stret");
2481 ArgTys.push_back(Context->
VoidTy);
2488 msgSendType,
nullptr,
2493 void RewriteModernObjC::SynthMsgSendFpretFunctionDecl() {
2497 assert(!argT.
isNull() &&
"Can't find 'id' type");
2498 ArgTys.push_back(argT);
2500 assert(!argT.
isNull() &&
"Can't find 'SEL' type");
2501 ArgTys.push_back(argT);
2507 msgSendIdent, msgSendType,
2512 void RewriteModernObjC::SynthGetClassFunctionDecl() {
2521 getClassIdent, getClassType,
2526 void RewriteModernObjC::SynthGetSuperClassFunctionDecl() {
2528 &Context->
Idents.
get(
"class_getSuperclass");
2537 getClassType,
nullptr,
2542 void RewriteModernObjC::SynthGetMetaClassFunctionDecl() {
2551 getClassIdent, getClassType,
2556 assert (Exp !=
nullptr &&
"Expected non-null ObjCStringLiteral");
2557 QualType strType = getConstantStringStructType();
2559 std::string S =
"__NSConstantStringImpl_";
2561 std::string tmpName = InFileName;
2563 for (i=0; i < tmpName.length(); i++) {
2564 char c = tmpName.at(i);
2571 S += utostr(NumObjCStringLiterals++);
2573 Preamble +=
"static __NSConstantStringImpl " + S;
2574 Preamble +=
" __attribute__ ((section (\"__DATA, __cfstring\"))) = {__CFConstantStringClassReference,";
2575 Preamble +=
"0x000007c8,";
2577 std::string prettyBufS;
2578 llvm::raw_string_ostream prettyBuf(prettyBufS);
2580 Preamble += prettyBuf.str();
2589 Expr *Unop =
new (Context)
2594 CK_CPointerToObjCPointerCast, Unop);
2595 ReplaceStmt(Exp, cast);
2608 CK_BitCast, FlagExp);
2611 ReplaceStmt(Exp, PE);
2617 if (!SelGetUidFunctionDecl)
2618 SynthSelGetUidFunctionDecl();
2620 if (!MsgSendFunctionDecl)
2621 SynthMsgSendFunctionDecl();
2622 if (!GetClassFunctionDecl)
2623 SynthGetClassFunctionDecl();
2638 ClsExprs.push_back(getStringLiteral(clsName->
getName()));
2639 CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl, ClsExprs,
2641 MsgExprs.push_back(Cls);
2648 CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl,
2649 SelExprs, StartLoc, EndLoc);
2650 MsgExprs.push_back(SelExp);
2659 CK = CK_IntegralToBoolean;
2660 subExpr = NoTypeInfoCStyleCastExpr(Context, type, CK, subExpr);
2662 MsgExprs.push_back(subExpr);
2667 for (
const auto PI : BoxingMethod->
parameters())
2668 ArgTypes.push_back(PI->getType());
2683 getSimpleFunctionType(returnType, ArgTypes, BoxingMethod->
isVariadic());
2685 cast = NoTypeInfoCStyleCastExpr(Context, castType, CK_BitCast,
2694 ReplaceStmt(Exp, CE);
2700 if (!SelGetUidFunctionDecl)
2701 SynthSelGetUidFunctionDecl();
2703 if (!MsgSendFunctionDecl)
2704 SynthMsgSendFunctionDecl();
2705 if (!GetClassFunctionDecl)
2706 SynthGetClassFunctionDecl();
2715 getSimpleFunctionType(Context->
VoidTy, IntQT,
true);
2716 std::string NSArrayFName(
"__NSContainer_literal");
2717 FunctionDecl *NSArrayFD = SynthBlockInitFunctionDecl(NSArrayFName);
2723 unsigned UnsignedIntSize =
2728 InitExprs.push_back(count);
2729 for (
unsigned i = 0; i < NumElements; i++)
2731 Expr *NSArrayCallExpr =
2746 NoTypeInfoCStyleCastExpr(Context,
2757 ObjCInterfaceDecl *Class =
2761 ClsExprs.push_back(getStringLiteral(clsName->
getName()));
2762 CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl, ClsExprs,
2764 MsgExprs.push_back(Cls);
2772 CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl,
2773 SelExprs, StartLoc, EndLoc);
2774 MsgExprs.push_back(SelExp);
2777 MsgExprs.push_back(ArrayLiteralObjects);
2783 MsgExprs.push_back(cnt);
2788 for (
const auto *PI : ArrayMethod->
parameters())
2789 ArgTypes.push_back(PI->getType());
2804 getSimpleFunctionType(returnType, ArgTypes, ArrayMethod->
isVariadic());
2806 cast = NoTypeInfoCStyleCastExpr(Context, castType, CK_BitCast,
2815 ReplaceStmt(Exp, CE);
2821 if (!SelGetUidFunctionDecl)
2822 SynthSelGetUidFunctionDecl();
2824 if (!MsgSendFunctionDecl)
2825 SynthMsgSendFunctionDecl();
2826 if (!GetClassFunctionDecl)
2827 SynthGetClassFunctionDecl();
2836 getSimpleFunctionType(Context->
VoidTy, IntQT,
true);
2837 std::string NSDictFName(
"__NSContainer_literal");
2838 FunctionDecl *NSDictFD = SynthBlockInitFunctionDecl(NSDictFName);
2846 unsigned UnsignedIntSize =
2851 KeyExprs.push_back(count);
2852 ValueExprs.push_back(count);
2853 for (
unsigned i = 0; i < NumElements; i++) {
2855 KeyExprs.push_back(Element.
Key);
2856 ValueExprs.push_back(Element.
Value);
2860 Expr *NSValueCallExpr =
2875 NoTypeInfoCStyleCastExpr(Context,
2878 DictLiteralValueME);
2888 NoTypeInfoCStyleCastExpr(Context,
2899 ObjCInterfaceDecl *Class =
2903 ClsExprs.push_back(getStringLiteral(clsName->
getName()));
2904 CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl, ClsExprs,
2906 MsgExprs.push_back(Cls);
2913 CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl,
2914 SelExprs, StartLoc, EndLoc);
2915 MsgExprs.push_back(SelExp);
2918 MsgExprs.push_back(DictValueObjects);
2921 MsgExprs.push_back(DictKeyObjects);
2927 MsgExprs.push_back(cnt);
2932 for (
const auto *PI : DictMethod->
parameters()) {
2936 convertToUnqualifiedObjCType(PointeeTy);
2939 ArgTypes.push_back(T);
2955 getSimpleFunctionType(returnType, ArgTypes, DictMethod->
isVariadic());
2957 cast = NoTypeInfoCStyleCastExpr(Context, castType, CK_BitCast,
2966 ReplaceStmt(Exp, CE);
2973 QualType RewriteModernObjC::getSuperStructType() {
2974 if (!SuperStructDecl) {
2977 &Context->
Idents.
get(
"__rw_objc_super"));
2986 for (
unsigned i = 0; i < 2; ++i) {
2990 FieldTypes[i],
nullptr,
3001 QualType RewriteModernObjC::getConstantStringStructType() {
3002 if (!ConstantStringDecl) {
3005 &Context->
Idents.
get(
"__NSConstantStringImpl"));
3011 FieldTypes[1] = Context->
IntTy;
3015 FieldTypes[3] = Context->
LongTy;
3018 for (
unsigned i = 0; i < 4; ++i) {
3023 FieldTypes[i],
nullptr,
3043 if (!LSD->getRBraceLoc().isValid())
3044 return LSD->getExternLoc();
3047 R.RewriteBlockLiteralFunctionDecl(FD);
3051 void RewriteModernObjC::RewriteLineDirective(
const Decl *D) {
3055 if (Location.
isFileID() && GenerateLineInfo) {
3056 std::string LineString(
"\n#line ");
3058 LineString += utostr(PLoc.
getLine());
3059 LineString +=
" \"";
3061 if (isa<ObjCMethodDecl>(D))
3063 else LineString +=
"\"\n";
3066 if (
const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
3071 if (!LSD->getRBraceLoc().isValid())
3072 Location = LSD->getExternLoc();
3075 InsertText(Location, LineString);
3089 Expr *RewriteModernObjC::SynthMsgSendStretCallExpr(
FunctionDecl *MsgSendStretFlavor,
3095 QualType FuncType = getSimpleFunctionType(
3096 returnType, ArgTypes, Method ? Method->
isVariadic() :
false);
3100 static unsigned stretCount=0;
3101 std::string
name =
"__Stret"; name += utostr(stretCount);
3103 "extern \"C\" void * __cdecl memset(void *_Dst, int _Val, size_t _Size);\n";
3104 str +=
"namespace {\n";
3105 str +=
"struct "; str +=
name;
3108 str +=
"(id receiver, SEL sel";
3109 for (
unsigned i = 2; i < ArgTypes.size(); i++) {
3110 std::string ArgName =
"arg"; ArgName += utostr(i);
3112 str +=
", "; str += ArgName;
3115 for (
unsigned i = ArgTypes.size(); i < MsgExprs.size(); i++) {
3116 std::string ArgName =
"arg"; ArgName += utostr(i);
3117 MsgExprs[i]->getType().getAsStringInternal(ArgName,
3119 str +=
", "; str += ArgName;
3123 str +=
"\t unsigned size = sizeof(";
3126 str +=
"\t if (size == 1 || size == 2 || size == 4 || size == 8)\n";
3129 str +=
")(void *)objc_msgSend)(receiver, sel";
3130 for (
unsigned i = 2; i < ArgTypes.size(); i++) {
3131 str +=
", arg"; str += utostr(i);
3134 for (
unsigned i = ArgTypes.size(); i < MsgExprs.size(); i++) {
3135 str +=
", arg"; str += utostr(i);
3139 str +=
"\t else if (receiver == 0)\n";
3140 str +=
"\t memset((void*)&s, 0, sizeof(s));\n";
3144 str +=
")(void *)objc_msgSend_stret)(receiver, sel";
3145 for (
unsigned i = 2; i < ArgTypes.size(); i++) {
3146 str +=
", arg"; str += utostr(i);
3149 for (
unsigned i = ArgTypes.size(); i < MsgExprs.size(); i++) {
3150 str +=
", arg"; str += utostr(i);
3157 str +=
"};\n};\n\n";
3162 assert(CurMethodDef &&
"SynthMsgSendStretCallExpr - CurMethodDef is null");
3166 InsertText(FunLocStart, str);
3173 ID, FuncType,
nullptr,
SC_Extern,
false,
false);
3182 returnType,
nullptr,
3194 if (!SelGetUidFunctionDecl)
3195 SynthSelGetUidFunctionDecl();
3196 if (!MsgSendFunctionDecl)
3197 SynthMsgSendFunctionDecl();
3198 if (!MsgSendSuperFunctionDecl)
3199 SynthMsgSendSuperFunctionDecl();
3200 if (!MsgSendStretFunctionDecl)
3201 SynthMsgSendStretFunctionDecl();
3202 if (!MsgSendSuperStretFunctionDecl)
3203 SynthMsgSendSuperStretFunctionDecl();
3204 if (!MsgSendFpretFunctionDecl)
3205 SynthMsgSendFpretFunctionDecl();
3206 if (!GetClassFunctionDecl)
3207 SynthGetClassFunctionDecl();
3208 if (!GetSuperClassFunctionDecl)
3209 SynthGetSuperClassFunctionDecl();
3210 if (!GetMetaClassFunctionDecl)
3211 SynthGetMetaClassFunctionDecl();
3218 QualType resultType = mDecl->getReturnType();
3220 MsgSendStretFlavor = MsgSendStretFunctionDecl;
3222 MsgSendFlavor = MsgSendFpretFunctionDecl;
3229 MsgSendFlavor = MsgSendSuperFunctionDecl;
3230 if (MsgSendStretFlavor)
3231 MsgSendStretFlavor = MsgSendSuperStretFunctionDecl;
3232 assert(MsgSendFlavor &&
"MsgSendFlavor is NULL!");
3239 InitExprs.push_back(
3254 CallExpr *Cls = SynthesizeCallToFunctionDecl(GetMetaClassFunctionDecl,
3255 ClsExprs, StartLoc, EndLoc);
3257 ClsExprs.push_back(Cls);
3258 Cls = SynthesizeCallToFunctionDecl(GetSuperClassFunctionDecl, ClsExprs,
3263 InitExprs.push_back(
3264 NoTypeInfoCStyleCastExpr(Context,
3268 QualType superType = getSuperStructType();
3271 if (LangOpts.MicrosoftExt) {
3272 SynthSuperConstructorFunctionDecl();
3275 DeclRefExpr(*Context, SuperConstructorFunctionDecl,
false, superType,
3289 SuperRep = NoTypeInfoCStyleCastExpr(Context,
3291 CK_BitCast, SuperRep);
3308 MsgExprs.push_back(SuperRep);
3314 ObjCInterfaceDecl *Class
3317 ClsExprs.push_back(getStringLiteral(clsName->
getName()));
3318 CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl, ClsExprs,
3320 CastExpr *ArgExpr = NoTypeInfoCStyleCastExpr(Context,
3323 MsgExprs.push_back(ArgExpr);
3328 MsgSendFlavor = MsgSendSuperFunctionDecl;
3329 if (MsgSendStretFlavor)
3330 MsgSendStretFlavor = MsgSendSuperStretFunctionDecl;
3331 assert(MsgSendFlavor &&
"MsgSendFlavor is NULL!");
3335 InitExprs.push_back(
3349 CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl, ClsExprs,
3352 ClsExprs.push_back(Cls);
3353 Cls = SynthesizeCallToFunctionDecl(GetSuperClassFunctionDecl, ClsExprs,
3358 InitExprs.push_back(
3363 QualType superType = getSuperStructType();
3366 if (LangOpts.MicrosoftExt) {
3367 SynthSuperConstructorFunctionDecl();
3370 DeclRefExpr(*Context, SuperConstructorFunctionDecl,
false, superType,
3384 SuperRep = NoTypeInfoCStyleCastExpr(Context,
3386 CK_BitCast, SuperRep);
3398 MsgExprs.push_back(SuperRep);
3407 recExpr = CE->getSubExpr();
3410 ? CK_BlockPointerToObjCPointerCast
3411 : CK_CPointerToObjCPointerCast;
3413 recExpr = NoTypeInfoCStyleCastExpr(Context, Context->
getObjCIdType(),
3415 MsgExprs.push_back(recExpr);
3423 CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl,
3424 SelExprs, StartLoc, EndLoc);
3425 MsgExprs.push_back(SelExp);
3428 for (
unsigned i = 0; i < Exp->
getNumArgs(); i++) {
3434 if (needToScanForQualifiers(type))
3437 (void)convertBlockPointerToFunctionPointer(type);
3442 CK = CK_IntegralToBoolean;
3445 CK = CK_BlockPointerToObjCPointerCast;
3447 CK = CK_CPointerToObjCPointerCast;
3455 userExpr = NoTypeInfoCStyleCastExpr(Context, type, CK, userExpr);
3458 else if (
CStyleCastExpr *CE = dyn_cast<CStyleCastExpr>(userExpr)) {
3459 if (CE->getType()->isObjCQualifiedIdType()) {
3460 while ((CE = dyn_cast<CStyleCastExpr>(userExpr)))
3461 userExpr = CE->getSubExpr();
3464 CK = CK_IntegralToPointer;
3466 CK = CK_BlockPointerToObjCPointerCast;
3468 CK = CK_CPointerToObjCPointerCast;
3472 userExpr = NoTypeInfoCStyleCastExpr(Context, Context->
getObjCIdType(),
3476 MsgExprs.push_back(userExpr);
3488 if (MsgSendFlavor == MsgSendSuperFunctionDecl)
3489 ArgTypes.push_back(Context->
getPointerType(getSuperStructType()));
3500 (void)convertBlockPointerToFunctionPointer(t);
3501 ArgTypes.push_back(t);
3504 convertToUnqualifiedObjCType(returnType);
3505 (void)convertBlockPointerToFunctionPointer(returnType);
3520 cast = NoTypeInfoCStyleCastExpr(Context,
3528 getSimpleFunctionType(returnType, ArgTypes, MD ? MD->isVariadic() :
true);
3530 cast = NoTypeInfoCStyleCastExpr(Context, castType, CK_BitCast,
3539 Stmt *ReplacingStmt = CE;
3540 if (MsgSendStretFlavor) {
3546 Expr *STCE = SynthMsgSendStretCallExpr(MsgSendStretFlavor,
3550 ReplacingStmt = STCE;
3553 return ReplacingStmt;
3557 Stmt *ReplacingStmt =
3561 ReplaceStmt(Exp, ReplacingStmt);
3564 return ReplacingStmt;
3568 QualType RewriteModernObjC::getProtocolType() {
3569 if (!ProtocolTypeDecl) {
3585 std::string Name =
"_OBJC_PROTOCOL_REFERENCE_$_" +
3595 ReplaceStmt(Exp, castExpr);
3605 bool &IsNamedDefinition) {
3609 if (
RecordDecl *RD = dyn_cast<RecordDecl>(Tag)) {
3610 RD = RD->getDefinition();
3611 if (!RD || !RD->getDeclName().getAsIdentifierInfo())
3613 IsNamedDefinition =
true;
3614 TagLocation = RD->getLocation();
3618 if (
EnumDecl *ED = dyn_cast<EnumDecl>(Tag)) {
3619 if (!ED || !ED->getDeclName().getAsIdentifierInfo())
3621 IsNamedDefinition =
true;
3622 TagLocation = ED->getLocation();
3631 bool RewriteModernObjC::RewriteObjCFieldDeclType(
QualType &Type,
3633 if (isa<TypedefType>(Type)) {
3640 return RewriteObjCFieldDeclType(ElemTy, Result);
3646 Result +=
"\n\tstruct ";
3648 Result +=
"\n\tunion ";
3650 assert(
false &&
"class not allowed as an ivar type");
3653 if (GlobalDefinedTags.count(RD)) {
3659 for (
auto *FD : RD->
fields())
3660 RewriteObjCFieldDecl(FD, Result);
3668 Result +=
"\n\tenum ";
3670 if (GlobalDefinedTags.count(ED)) {
3678 Result +=
"\t"; Result += EC->getName(); Result +=
" = ";
3680 Result += Val.toString(10);
3689 convertObjCTypeToCStyleType(Type);
3697 std::string &Result) {
3701 bool EleboratedType = RewriteObjCFieldDeclType(Type, Result);
3702 if (!EleboratedType)
3714 Result += utostr(Dim.getZExtValue());
3726 void RewriteModernObjC::RewriteLocallyDefinedNamedAggregates(
FieldDecl *fieldDecl,
3727 std::string &Result) {
3729 if (isa<TypedefType>(Type))
3745 if (GlobalDefinedTags.count(TD))
3748 bool IsNamedDefinition =
false;
3749 if (IsTagDefinedInsideClass(IDecl, TD, IsNamedDefinition)) {
3750 RewriteObjCFieldDeclType(Type, Result);
3753 if (IsNamedDefinition)
3754 GlobalDefinedTags.insert(TD);
3758 unsigned RewriteModernObjC::ObjCIvarBitfieldGroupNo(
ObjCIvarDecl *IV) {
3760 if (ObjCInterefaceHasBitfieldGroups.count(CDecl)) {
3761 return IvarGroupNumber[IV];
3763 unsigned GroupNo = 0;
3767 IVars.push_back(IVD);
3769 for (
unsigned i = 0, e = IVars.size(); i < e; i++)
3770 if (IVars[i]->isBitField()) {
3771 IvarGroupNumber[IVars[i++]] = ++GroupNo;
3772 while (i < e && IVars[i]->isBitField())
3773 IvarGroupNumber[IVars[i++]] = GroupNo;
3778 ObjCInterefaceHasBitfieldGroups.insert(CDecl);
3779 return IvarGroupNumber[IV];
3782 QualType RewriteModernObjC::SynthesizeBitfieldGroupStructType(
3785 std::string StructTagName;
3786 ObjCIvarBitfieldGroupType(IV, StructTagName);
3791 for (
unsigned i=0, e = IVars.size(); i < e; i++) {
3805 unsigned GroupNo = ObjCIvarBitfieldGroupNo(IV);
3806 std::pair<const ObjCInterfaceDecl*, unsigned> tuple = std::make_pair(CDecl, GroupNo);
3807 if (GroupRecordType.count(tuple))
3808 return GroupRecordType[tuple];
3813 if (IVD->isBitField())
3814 IVars.push_back(const_cast<ObjCIvarDecl *>(IVD));
3816 if (!IVars.empty()) {
3817 unsigned GroupNo = ObjCIvarBitfieldGroupNo(IVars[0]);
3819 GroupRecordType[std::make_pair(CDecl, GroupNo)] =
3820 SynthesizeBitfieldGroupStructType(IVars[0], IVars);
3825 if (!IVars.empty()) {
3827 unsigned GroupNo = ObjCIvarBitfieldGroupNo(IVars[0]);
3828 GroupRecordType[std::make_pair(CDecl, GroupNo)] =
3829 SynthesizeBitfieldGroupStructType(IVars[0], IVars);
3831 QualType RetQT = GroupRecordType[tuple];
3832 assert(!RetQT.
isNull() &&
"GetGroupRecordTypeForObjCIvarBitfield struct type is NULL");
3839 void RewriteModernObjC::ObjCIvarBitfieldGroupDecl(
ObjCIvarDecl *IV,
3840 std::string &Result) {
3843 Result +=
"__GRBF_";
3844 unsigned GroupNo = ObjCIvarBitfieldGroupNo(IV);
3845 Result += utostr(GroupNo);
3851 void RewriteModernObjC::ObjCIvarBitfieldGroupType(
ObjCIvarDecl *IV,
3852 std::string &Result) {
3856 unsigned GroupNo = ObjCIvarBitfieldGroupNo(IV);
3857 Result += utostr(GroupNo);
3863 void RewriteModernObjC::ObjCIvarBitfieldGroupOffset(
ObjCIvarDecl *IV,
3864 std::string &Result) {
3865 Result +=
"OBJC_IVAR_$_";
3866 ObjCIvarBitfieldGroupDecl(IV, Result);
3869 #define SKIP_BITFIELDS(IX, ENDIX, VEC) { \ 3870 while ((IX < ENDIX) && VEC[IX]->isBitField()) \ 3878 void RewriteModernObjC::RewriteObjCInternalStruct(ObjCInterfaceDecl *CDecl,
3879 std::string &Result) {
3880 assert(CDecl &&
"Class missing in SynthesizeObjCInternalStruct");
3881 assert(CDecl->
getName() !=
"" &&
3882 "Name missing in SynthesizeObjCInternalStruct");
3887 IVars.push_back(IVD);
3898 (!RCDecl || !ObjCSynthesizedStructs.count(RCDecl))) {
3900 ReplaceText(LocStart, endBuf-startBuf, Result);
3907 for (
unsigned i = 0, e = IVars.size(); i < e; i++)
3908 RewriteLocallyDefinedNamedAggregates(IVars[i], Result);
3912 for (
unsigned i = 0, e = IVars.size(); i < e; i++)
3913 if (IVars[i]->isBitField()) {
3915 QualType QT = GetGroupRecordTypeForObjCIvarBitfield(IV);
3916 RewriteObjCFieldDeclType(QT, Result);
3922 Result +=
"\nstruct ";
3924 Result +=
"_IMPL {\n";
3926 if (RCDecl && ObjCSynthesizedStructs.count(RCDecl)) {
3927 Result +=
"\tstruct "; Result += RCDecl->getNameAsString();
3928 Result +=
"_IMPL "; Result += RCDecl->getNameAsString();
3929 Result +=
"_IVARS;\n";
3932 for (
unsigned i = 0, e = IVars.size(); i < e; i++) {
3933 if (IVars[i]->isBitField()) {
3935 Result +=
"\tstruct ";
3936 ObjCIvarBitfieldGroupType(IV, Result); Result +=
" ";
3937 ObjCIvarBitfieldGroupDecl(IV, Result); Result +=
";\n";
3942 RewriteObjCFieldDecl(IVars[i], Result);
3947 ReplaceText(LocStart, endBuf-startBuf, Result);
3949 if (!ObjCSynthesizedStructs.insert(CDecl).second)
3950 llvm_unreachable(
"struct already synthesize- RewriteObjCInternalStruct");
3955 void RewriteModernObjC::RewriteIvarOffsetSymbols(ObjCInterfaceDecl *CDecl,
3956 std::string &Result) {
3966 const ObjCInterfaceDecl *IDecl = IvarDecl->getContainingInterface();
3967 unsigned GroupNo = 0;
3968 if (IvarDecl->isBitField()) {
3969 GroupNo = ObjCIvarBitfieldGroupNo(IvarDecl);
3970 if (GroupSymbolOutput.count(std::make_pair(IDecl, GroupNo)))
3974 if (LangOpts.MicrosoftExt)
3975 Result +=
"__declspec(allocate(\".objc_ivar$B\")) ";
3976 Result +=
"extern \"C\" ";
3977 if (LangOpts.MicrosoftExt &&
3980 Result +=
"__declspec(dllimport) ";
3982 Result +=
"unsigned long ";
3983 if (IvarDecl->isBitField()) {
3984 ObjCIvarBitfieldGroupOffset(IvarDecl, Result);
3985 GroupSymbolOutput.insert(std::make_pair(IDecl, GroupNo));
4000 void RewriteModernObjC::RewriteImplementations() {
4001 int ClsDefCount = ClassImplementation.size();
4002 int CatDefCount = CategoryImplementation.size();
4005 for (
int i = 0; i < ClsDefCount; i++) {
4010 "Legacy implicit interface rewriting not supported in moder abi");
4011 RewriteImplementationDecl(OIMP);
4014 for (
int i = 0; i < CatDefCount; i++) {
4019 "Legacy implicit interface rewriting not supported in moder abi");
4020 RewriteImplementationDecl(CIMP);
4024 void RewriteModernObjC::RewriteByRefString(std::string &ResultStr,
4025 const std::string &Name,
4027 assert(BlockByRefDeclNo.count(VD) &&
4028 "RewriteByRefString: ByRef decl missing");
4030 ResultStr +=
"struct ";
4031 ResultStr +=
"__Block_byref_" + Name +
4032 "_" + utostr(BlockByRefDeclNo[VD]) ;
4036 if (
VarDecl *Var = dyn_cast<VarDecl>(VD))
4037 return (Var->isFunctionOrMethodVarDecl() && !Var->hasLocalStorage());
4041 std::string RewriteModernObjC::SynthesizeBlockFunc(
BlockExpr *CE,
int i,
4046 std::string StructRef =
"struct " + Tag;
4049 ConvertSourceLocationToLineDirective(BlockLoc, S);
4052 funcName.str() +
"_block_func_" + utostr(i);
4056 if (isa<FunctionNoProtoType>(AFT)) {
4059 S +=
"(" + StructRef +
" *__cself)";
4061 S +=
"(" + StructRef +
" *__cself)";
4064 assert(FT &&
"SynthesizeBlockFunc: No function proto");
4067 S += StructRef +
" *__cself, ";
4068 std::string ParamStr;
4072 ParamStr = (*AI)->getNameAsString();
4074 (void)convertBlockPointerToFunctionPointer(QT);
4089 E = BlockByRefDecls.end(); I != E; ++I) {
4091 std::string Name = (*I)->getNameAsString();
4092 std::string TypeString;
4093 RewriteByRefString(TypeString, Name, (*I));
4095 Name = TypeString + Name;
4096 S += Name +
" = __cself->" + (*I)->getNameAsString() +
"; // bound by ref\n";
4100 E = BlockByCopyDecls.end(); I != E; ++I) {
4112 if (isTopLevelBlockPointerType((*I)->getType())) {
4113 RewriteBlockPointerTypeVariable(S, (*I));
4115 RewriteBlockPointerType(S, (*I)->getType());
4117 S +=
"__cself->" + (*I)->getNameAsString() +
"; // bound by copy\n";
4120 std::string Name = (*I)->getNameAsString();
4125 S += Name +
" = __cself->" +
4126 (*I)->getNameAsString() +
"; // bound by copy\n";
4129 std::string RewrittenStr = RewrittenBlockExprs[CE];
4130 const char *cstr = RewrittenStr.c_str();
4131 while (*cstr++ !=
'{') ;
4137 std::string RewriteModernObjC::SynthesizeBlockHelperFuncs(
BlockExpr *CE,
int i,
4140 std::string StructRef =
"struct " + Tag;
4141 std::string S =
"static void __";
4144 S +=
"_block_copy_" + utostr(i);
4145 S +=
"(" + StructRef;
4146 S +=
"*dst, " + StructRef;
4148 for (
ValueDecl *VD : ImportedBlockDecls) {
4149 S +=
"_Block_object_assign((void*)&dst->";
4151 S +=
", (void*)src->";
4153 if (BlockByRefDeclsPtrSet.count(VD))
4162 S +=
"\nstatic void __";
4164 S +=
"_block_dispose_" + utostr(i);
4165 S +=
"(" + StructRef;
4167 for (
ValueDecl *VD : ImportedBlockDecls) {
4168 S +=
"_Block_object_dispose((void*)src->";
4170 if (BlockByRefDeclsPtrSet.count(VD))
4181 std::string RewriteModernObjC::SynthesizeBlockImpl(
BlockExpr *CE, std::string Tag,
4183 std::string S =
"\nstruct " + Tag;
4184 std::string Constructor =
" " + Tag;
4186 S +=
" {\n struct __block_impl impl;\n";
4187 S +=
" struct " + Desc;
4190 Constructor +=
"(void *fp, ";
4191 Constructor +=
"struct " + Desc;
4192 Constructor +=
" *desc";
4194 if (BlockDeclRefs.size()) {
4197 E = BlockByCopyDecls.end(); I != E; ++I) {
4199 std::string FieldName = (*I)->getNameAsString();
4200 std::string ArgName =
"_" + FieldName;
4211 if (isTopLevelBlockPointerType((*I)->getType())) {
4212 S +=
"struct __block_impl *";
4213 Constructor +=
", void *" + ArgName;
4220 Constructor +=
", " + ArgName;
4222 S += FieldName +
";\n";
4226 E = BlockByRefDecls.end(); I != E; ++I) {
4228 std::string FieldName = (*I)->getNameAsString();
4229 std::string ArgName =
"_" + FieldName;
4231 std::string TypeString;
4232 RewriteByRefString(TypeString, FieldName, (*I));
4234 FieldName = TypeString + FieldName;
4235 ArgName = TypeString + ArgName;
4236 Constructor +=
", " + ArgName;
4238 S += FieldName +
"; // by ref\n";
4241 Constructor +=
", int flags=0)";
4243 bool firsTime =
true;
4245 E = BlockByCopyDecls.end(); I != E; ++I) {
4246 std::string Name = (*I)->getNameAsString();
4248 Constructor +=
" : ";
4252 Constructor +=
", ";
4253 if (isTopLevelBlockPointerType((*I)->getType()))
4254 Constructor += Name +
"((struct __block_impl *)_" + Name +
")";
4256 Constructor += Name +
"(_" + Name +
")";
4260 E = BlockByRefDecls.end(); I != E; ++I) {
4261 std::string Name = (*I)->getNameAsString();
4263 Constructor +=
" : ";
4267 Constructor +=
", ";
4268 Constructor += Name +
"(_" + Name +
"->__forwarding)";
4271 Constructor +=
" {\n";
4273 Constructor +=
" impl.isa = &_NSConcreteGlobalBlock;\n";
4275 Constructor +=
" impl.isa = &_NSConcreteStackBlock;\n";
4276 Constructor +=
" impl.Flags = flags;\n impl.FuncPtr = fp;\n";
4278 Constructor +=
" Desc = desc;\n";
4281 Constructor +=
", int flags=0) {\n";
4283 Constructor +=
" impl.isa = &_NSConcreteGlobalBlock;\n";
4285 Constructor +=
" impl.isa = &_NSConcreteStackBlock;\n";
4286 Constructor +=
" impl.Flags = flags;\n impl.FuncPtr = fp;\n";
4287 Constructor +=
" Desc = desc;\n";
4290 Constructor +=
"}\n";
4296 std::string RewriteModernObjC::SynthesizeBlockDescriptor(std::string DescTag,
4297 std::string ImplTag,
int i,
4300 std::string S =
"\nstatic struct " + DescTag;
4302 S +=
" {\n size_t reserved;\n";
4303 S +=
" size_t Block_size;\n";
4305 S +=
" void (*copy)(struct ";
4306 S += ImplTag; S +=
"*, struct ";
4307 S += ImplTag; S +=
"*);\n";
4309 S +=
" void (*dispose)(struct ";
4310 S += ImplTag; S +=
"*);\n";
4314 S += DescTag +
"_DATA = { 0, sizeof(struct ";
4317 S +=
", __" + FunName.str() +
"_block_copy_" + utostr(i);
4318 S +=
", __" + FunName.str() +
"_block_dispose_" + utostr(i);
4324 void RewriteModernObjC::SynthesizeBlockLiterals(
SourceLocation FunLocStart,
4325 StringRef FunName) {
4326 bool RewriteSC = (GlobalVarDecl &&
4331 std::string SC(
" void __");
4334 InsertText(FunLocStart, SC);
4338 for (
unsigned i = 0, count=0; i < Blocks.size(); i++) {
4339 CollectBlockDeclRefInfo(Blocks[i]);
4342 for (
int j = 0; j < InnerDeclRefsCount[i]; j++) {
4345 BlockDeclRefs.push_back(Exp);
4346 if (!VD->
hasAttr<BlocksAttr>()) {
4347 if (!BlockByCopyDeclsPtrSet.count(VD)) {
4348 BlockByCopyDeclsPtrSet.insert(VD);
4349 BlockByCopyDecls.push_back(VD);
4354 if (!BlockByRefDeclsPtrSet.count(VD)) {
4355 BlockByRefDeclsPtrSet.insert(VD);
4356 BlockByRefDecls.push_back(VD);
4363 ImportedBlockDecls.insert(VD);
4366 std::string ImplTag =
"__" + FunName.str() +
"_block_impl_" + utostr(i);
4367 std::string DescTag =
"__" + FunName.str() +
"_block_desc_" + utostr(i);
4369 std::string CI = SynthesizeBlockImpl(Blocks[i], ImplTag, DescTag);
4371 InsertText(FunLocStart, CI);
4373 std::string CF = SynthesizeBlockFunc(Blocks[i], i, FunName, ImplTag);
4375 InsertText(FunLocStart, CF);
4377 if (ImportedBlockDecls.size()) {
4378 std::string HF = SynthesizeBlockHelperFuncs(Blocks[i], i, FunName, ImplTag);
4379 InsertText(FunLocStart, HF);
4381 std::string BD = SynthesizeBlockDescriptor(DescTag, ImplTag, i, FunName,
4382 ImportedBlockDecls.size() > 0);
4383 InsertText(FunLocStart, BD);
4385 BlockDeclRefs.clear();
4386 BlockByRefDecls.clear();
4387 BlockByRefDeclsPtrSet.clear();
4388 BlockByCopyDecls.clear();
4389 BlockByCopyDeclsPtrSet.clear();
4390 ImportedBlockDecls.clear();
4404 InsertText(FunLocStart, SC);
4406 if (GlobalConstructionExp) {
4410 std::string Tag =
"__";
4412 Tag +=
"_block_impl_";
4413 Tag += utostr(Blocks.size()-1);
4414 std::string globalBuf =
"static ";
4415 globalBuf += Tag; globalBuf +=
" ";
4418 llvm::raw_string_ostream constructorExprBuf(SStr);
4419 GlobalConstructionExp->
printPretty(constructorExprBuf,
nullptr,
4421 globalBuf += constructorExprBuf.str();
4423 InsertText(FunLocStart, globalBuf);
4424 GlobalConstructionExp =
nullptr;
4428 InnerDeclRefsCount.clear();
4429 InnerDeclRefs.clear();
4430 RewrittenBlockExprs.clear();
4433 void RewriteModernObjC::InsertBlockLiteralsWithinFunction(
FunctionDecl *FD) {
4437 StringRef FuncName = FD->
getName();
4439 SynthesizeBlockLiterals(FunLocStart, FuncName);
4448 std::string::size_type loc = 0;
4449 while ((loc = Name.find(
':', loc)) != std::string::npos)
4450 Name.replace(loc, 1,
"_");
4453 void RewriteModernObjC::InsertBlockLiteralsWithinMethod(
ObjCMethodDecl *MD) {
4457 std::string FuncName;
4459 SynthesizeBlockLiterals(FunLocStart, FuncName);
4462 void RewriteModernObjC::GetBlockDeclRefExprs(
Stmt *S) {
4465 if (
BlockExpr *CBE = dyn_cast<BlockExpr>(SubStmt))
4466 GetBlockDeclRefExprs(CBE->getBody());
4468 GetBlockDeclRefExprs(SubStmt);
4472 if (DRE->refersToEnclosingVariableOrCapture() ||
4475 BlockDeclRefs.push_back(DRE);
4478 void RewriteModernObjC::GetInnerBlockDeclRefExprs(
Stmt *S,
4480 llvm::SmallPtrSetImpl<const DeclContext *> &InnerContexts) {
4483 if (
BlockExpr *CBE = dyn_cast<BlockExpr>(SubStmt)) {
4484 InnerContexts.insert(cast<DeclContext>(CBE->getBlockDecl()));
4485 GetInnerBlockDeclRefExprs(CBE->getBody(),
4490 GetInnerBlockDeclRefExprs(SubStmt, InnerBlockDeclRefs, InnerContexts);
4493 if (
DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(S)) {
4494 if (DRE->refersToEnclosingVariableOrCapture() ||
4496 if (!InnerContexts.count(DRE->getDecl()->getDeclContext()))
4497 InnerBlockDeclRefs.push_back(DRE);
4498 if (
VarDecl *Var = cast<VarDecl>(DRE->getDecl()))
4499 if (Var->isFunctionOrMethodVarDecl())
4500 ImportedLocalExternalDecls.insert(Var);
4508 bool RewriteModernObjC::convertObjCTypeToCStyleType(
QualType &T) {
4510 convertBlockPointerToFunctionPointer(T);
4516 T = convertFunctionTypeOfBlocks(FT);
4522 convertToUnqualifiedObjCType(T);
4536 bool modified = convertObjCTypeToCStyleType(Res);
4542 if (convertObjCTypeToCStyleType(t))
4544 ArgTypes.push_back(t);
4549 FuncType = getSimpleFunctionType(Res, ArgTypes);
4554 Stmt *RewriteModernObjC::SynthesizeBlockCall(
CallExpr *Exp,
const Expr *BlockExp) {
4558 if (
const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(BlockExp)) {
4560 }
else if (
const MemberExpr *MExpr = dyn_cast<MemberExpr>(BlockExp)) {
4563 else if (
const ParenExpr *PRE = dyn_cast<ParenExpr>(BlockExp)) {
4564 return SynthesizeBlockCall(Exp, PRE->getSubExpr());
4566 else if (
const ImplicitCastExpr *IEXPR = dyn_cast<ImplicitCastExpr>(BlockExp))
4569 dyn_cast<ConditionalOperator>(BlockExp)) {
4570 Expr *LHSExp = CEXPR->getLHS();
4571 Stmt *LHSStmt = SynthesizeBlockCall(Exp, LHSExp);
4572 Expr *RHSExp = CEXPR->getRHS();
4573 Stmt *RHSStmt = SynthesizeBlockCall(Exp, RHSExp);
4574 Expr *CONDExp = CEXPR->getCond();
4581 }
else if (
const ObjCIvarRefExpr *IRE = dyn_cast<ObjCIvarRefExpr>(BlockExp)) {
4584 = dyn_cast<PseudoObjectExpr>(BlockExp)) {
4587 assert(
false &&
"RewriteBlockClass: Bad type");
4589 assert(CPT &&
"RewriteBlockClass: Bad type");
4591 assert(FT &&
"RewriteBlockClass: Bad type");
4604 ArgTypes.push_back(PtrBlock);
4609 if (!convertBlockPointerToFunctionPointer(t))
4610 convertToUnqualifiedObjCType(t);
4611 ArgTypes.push_back(t);
4615 QualType PtrToFuncCastType = getSimpleFunctionType(Exp->
getType(), ArgTypes);
4619 CastExpr *BlkCast = NoTypeInfoCStyleCastExpr(Context, PtrBlock,
4621 const_cast<Expr*>(BlockExp));
4636 CastExpr *FunkCast = NoTypeInfoCStyleCastExpr(Context, PtrToFuncCastType,
4642 BlkExprs.push_back(BlkCast);
4645 E = Exp->
arg_end(); I != E; ++I) {
4646 BlkExprs.push_back(*I);
4666 Stmt *RewriteModernObjC::RewriteBlockDeclRefExpr(
DeclRefExpr *DeclRefExp) {
4682 StringRef Name = VD->
getName();
4695 ReplaceStmt(DeclRefExp, PE);
4702 Stmt *RewriteModernObjC::RewriteLocalVariableExternalStorage(
DeclRefExpr *DRE) {
4704 if (
VarDecl *Var = dyn_cast<VarDecl>(VD))
4705 if (!ImportedLocalExternalDecls.count(Var))
4713 ReplaceStmt(DRE, PE);
4731 const Type* TypePtr = QT->
getAs<Type>();
4732 if (isa<TypeOfExprType>(TypePtr)) {
4733 const TypeOfExprType *TypeOfExprTypePtr = cast<TypeOfExprType>(TypePtr);
4735 std::string TypeAsString =
"(";
4736 RewriteBlockPointerType(TypeAsString, QT);
4737 TypeAsString +=
")";
4738 ReplaceText(LocStart, endBuf-startBuf+1, TypeAsString);
4742 const char *argPtr = startBuf;
4744 while (*argPtr++ && (argPtr < endBuf)) {
4749 ReplaceText(LocStart, 1,
"*");
4755 void RewriteModernObjC::RewriteImplicitCastObjCExpr(
CastExpr *IC) {
4757 if (CastKind != CK_BlockPointerToObjCPointerCast &&
4758 CastKind != CK_AnyPointerToBlockPointerCast)
4762 (void)convertBlockPointerToFunctionPointer(QT);
4764 std::string Str =
"(";
4770 void RewriteModernObjC::RewriteBlockPointerFunctionArgs(
FunctionDecl *FD) {
4772 unsigned parenCount = 0;
4776 const char *startArgList = strchr(startBuf,
'(');
4778 assert((*startArgList ==
'(') &&
"Rewriter fuzzy parser confused");
4783 assert((DeclLoc.
isValid()) &&
"Invalid DeclLoc");
4785 const char *argPtr = startArgList;
4787 while (*argPtr++ && parenCount) {
4792 ReplaceText(DeclLoc, 1,
"*");
4804 bool RewriteModernObjC::PointerTypeTakesAnyBlockArguments(
QualType QT) {
4811 assert(BPT &&
"BlockPointerTypeTakeAnyBlockArguments(): not a block pointer type");
4816 if (isTopLevelBlockPointerType(I))
4822 bool RewriteModernObjC::PointerTypeTakesAnyObjCQualifiedType(
QualType QT) {
4829 assert(BPT &&
"BlockPointerTypeTakeAnyBlockArguments(): not a block pointer type");
4834 if (I->isObjCQualifiedIdType())
4836 if (I->isObjCObjectPointerType() &&
4837 I->getPointeeType()->isObjCQualifiedInterfaceType())
4845 void RewriteModernObjC::GetExtentOfArgList(
const char *Name,
const char *&LParen,
4846 const char *&RParen) {
4847 const char *argPtr = strchr(Name,
'(');
4848 assert((*argPtr ==
'(') &&
"Rewriter fuzzy parser confused");
4852 unsigned parenCount = 1;
4854 while (*argPtr && parenCount) {
4856 case '(': parenCount++;
break;
4857 case ')': parenCount--;
break;
4860 if (parenCount) argPtr++;
4862 assert((*argPtr ==
')') &&
"Rewriter fuzzy parser confused");
4866 void RewriteModernObjC::RewriteBlockPointerDecl(
NamedDecl *ND) {
4868 RewriteBlockPointerFunctionArgs(FD);
4874 if (
VarDecl *VD = dyn_cast<VarDecl>(ND))
4877 DeclT = TDD->getUnderlyingType();
4878 else if (
FieldDecl *FD = dyn_cast<FieldDecl>(ND))
4881 llvm_unreachable(
"RewriteBlockPointerDecl(): Decl type not yet handled");
4884 const char *endBuf = startBuf;
4886 while (*startBuf !=
'^' && *startBuf !=
';' && startBuf != MainFileStart)
4890 unsigned OrigLength=0;
4893 if (*startBuf ==
'^') {
4899 while (*startBuf !=
')') {
4907 if (PointerTypeTakesAnyBlockArguments(DeclT) ||
4908 PointerTypeTakesAnyObjCQualifiedType(DeclT)) {
4913 const char *argListBegin, *argListEnd;
4914 GetExtentOfArgList(startBuf, argListBegin, argListEnd);
4915 while (argListBegin < argListEnd) {
4916 if (*argListBegin ==
'^')
4918 else if (*argListBegin ==
'<') {
4920 buf += *argListBegin++;
4922 while (*argListBegin !=
'>') {
4923 buf += *argListBegin++;
4926 buf += *argListBegin;
4930 buf += *argListBegin;
4937 ReplaceText(Start, OrigLength, buf);
4960 std::string RewriteModernObjC::SynthesizeByrefCopyDestroyHelper(
VarDecl *VD,
4963 if (CopyDestroyCache.count(flag))
4965 CopyDestroyCache.insert(flag);
4966 S =
"static void __Block_byref_id_object_copy_";
4968 S +=
"(void *dst, void *src) {\n";
4974 unsigned VoidPtrSize =
4977 unsigned offset = (VoidPtrSize*4 + IntSize + IntSize)/Context->
getCharWidth();
4978 S +=
" _Block_object_assign((char*)dst + ";
4979 S += utostr(offset);
4980 S +=
", *(void * *) ((char*)src + ";
4981 S += utostr(offset);
4986 S +=
"static void __Block_byref_id_object_dispose_";
4988 S +=
"(void *src) {\n";
4989 S +=
" _Block_object_dispose(*(void * *) ((char*)src + ";
4990 S += utostr(offset);
5015 void RewriteModernObjC::RewriteByRefVar(
VarDecl *ND,
bool firstDecl,
5029 std::string ByrefType;
5030 RewriteByRefString(ByrefType, Name, ND,
true);
5031 ByrefType +=
" {\n";
5032 ByrefType +=
" void *__isa;\n";
5033 RewriteByRefString(ByrefType, Name, ND);
5034 ByrefType +=
" *__forwarding;\n";
5035 ByrefType +=
" int __flags;\n";
5036 ByrefType +=
" int __size;\n";
5041 if (HasCopyAndDispose) {
5042 ByrefType +=
" void (*__Block_byref_id_object_copy)(void*, void*);\n";
5043 ByrefType +=
" void (*__Block_byref_id_object_dispose)(void*);\n";
5047 (void)convertBlockPointerToFunctionPointer(T);
5050 ByrefType +=
" " + Name +
";\n";
5051 ByrefType +=
"};\n";
5057 assert(CurMethodDef &&
"RewriteByRefVar - CurMethodDef is null");
5060 InsertText(FunLocStart, ByrefType);
5066 if (HasCopyAndDispose) {
5074 std::string HF = SynthesizeByrefCopyDestroyHelper(ND, flag);
5082 bool hasInit = (ND->
getInit() !=
nullptr);
5093 if (HasCopyAndDispose)
5097 RewriteByRefString(ByrefType, Name, ND);
5098 std::string ForwardingCastType(
"(");
5099 ForwardingCastType += ByrefType +
" *)";
5100 ByrefType +=
" " + Name +
" = {(void*)";
5101 ByrefType += utostr(isa);
5102 ByrefType +=
"," + ForwardingCastType +
"&" + Name +
", ";
5103 ByrefType += utostr(flags);
5105 ByrefType +=
"sizeof(";
5106 RewriteByRefString(ByrefType, Name, ND);
5108 if (HasCopyAndDispose) {
5109 ByrefType +=
", __Block_byref_id_object_copy_";
5110 ByrefType += utostr(flag);
5111 ByrefType +=
", __Block_byref_id_object_dispose_";
5112 ByrefType += utostr(flag);
5121 const char *commaBuf = startDeclBuf;
5122 while (*commaBuf !=
',')
5124 assert((*commaBuf ==
',') &&
"RewriteByRefVar: can't find ','");
5126 startBuf = commaBuf;
5130 ByrefType +=
"};\n";
5131 unsigned nameSize = Name.size();
5136 ReplaceText(DeclLoc, endBuf-startBuf+nameSize, ByrefType);
5143 startLoc = ECE->getLParenLoc();
5148 ReplaceText(DeclLoc, endBuf-startBuf, ByrefType);
5150 const char separator = lastDecl ?
';' :
',';
5152 const char *separatorBuf = strchr(startInitializerBuf, separator);
5153 assert((*separatorBuf == separator) &&
5154 "RewriteByRefVar: can't find ';' or ','");
5158 InsertText(separatorLoc, lastDecl ?
"}" :
"};\n");
5162 void RewriteModernObjC::CollectBlockDeclRefInfo(
BlockExpr *Exp) {
5164 GetBlockDeclRefExprs(Exp->
getBody());
5165 if (BlockDeclRefs.size()) {
5167 for (
unsigned i = 0; i < BlockDeclRefs.size(); i++)
5168 if (!BlockDeclRefs[i]->getDecl()->hasAttr<BlocksAttr>()) {
5169 if (!BlockByCopyDeclsPtrSet.count(BlockDeclRefs[i]->getDecl())) {
5170 BlockByCopyDeclsPtrSet.insert(BlockDeclRefs[i]->getDecl());
5171 BlockByCopyDecls.push_back(BlockDeclRefs[i]->getDecl());
5175 for (
unsigned i = 0; i < BlockDeclRefs.size(); i++)
5176 if (BlockDeclRefs[i]->getDecl()->hasAttr<BlocksAttr>()) {
5177 if (!BlockByRefDeclsPtrSet.count(BlockDeclRefs[i]->getDecl())) {
5178 BlockByRefDeclsPtrSet.insert(BlockDeclRefs[i]->getDecl());
5179 BlockByRefDecls.push_back(BlockDeclRefs[i]->getDecl());
5183 for (
unsigned i = 0; i < BlockDeclRefs.size(); i++)
5184 if (BlockDeclRefs[i]->getDecl()->hasAttr<BlocksAttr>() ||
5185 BlockDeclRefs[i]->getType()->isObjCObjectPointerType() ||
5186 BlockDeclRefs[i]->getType()->isBlockPointerType())
5187 ImportedBlockDecls.insert(BlockDeclRefs[i]->getDecl());
5191 FunctionDecl *RewriteModernObjC::SynthBlockInitFunctionDecl(StringRef
name) {
5203 Blocks.push_back(Exp);
5205 CollectBlockDeclRefInfo(Exp);
5208 int countOfInnerDecls = 0;
5209 if (!InnerBlockDeclRefs.empty()) {
5210 for (
unsigned i = 0; i < InnerBlockDeclRefs.size(); i++) {
5213 if (!VD->
hasAttr<BlocksAttr>() && !BlockByCopyDeclsPtrSet.count(VD)) {
5217 InnerDeclRefs.push_back(Exp); countOfInnerDecls++;
5218 BlockDeclRefs.push_back(Exp);
5219 BlockByCopyDeclsPtrSet.insert(VD);
5220 BlockByCopyDecls.push_back(VD);
5222 if (VD->
hasAttr<BlocksAttr>() && !BlockByRefDeclsPtrSet.count(VD)) {
5223 InnerDeclRefs.push_back(Exp); countOfInnerDecls++;
5224 BlockDeclRefs.push_back(Exp);
5225 BlockByRefDeclsPtrSet.insert(VD);
5226 BlockByRefDecls.push_back(VD);
5230 for (
unsigned i = 0; i < InnerBlockDeclRefs.size(); i++)
5231 if (InnerBlockDeclRefs[i]->getDecl()->hasAttr<BlocksAttr>() ||
5232 InnerBlockDeclRefs[i]->getType()->isObjCObjectPointerType() ||
5233 InnerBlockDeclRefs[i]->getType()->isBlockPointerType())
5234 ImportedBlockDecls.insert(InnerBlockDeclRefs[i]->getDecl());
5236 InnerDeclRefsCount.push_back(countOfInnerDecls);
5238 std::string FuncName;
5242 else if (CurMethodDef)
5244 else if (GlobalVarDecl)
5247 bool GlobalBlockExpr =
5250 if (GlobalBlockExpr && !GlobalVarDecl) {
5252 GlobalBlockExpr =
false;
5255 std::string BlockNumber = utostr(Blocks.size()-1);
5257 std::string Func =
"__" + FuncName +
"_block_func_" + BlockNumber;
5269 if (GlobalBlockExpr)
5273 Tag += FuncName +
"_block_impl_" + BlockNumber;
5275 FD = SynthBlockInitFunctionDecl(Tag);
5282 FD = SynthBlockInitFunctionDecl(Func);
5287 InitExprs.push_back(castExpr);
5290 std::string DescData =
"__" + FuncName +
"_block_desc_" + BlockNumber +
"_DATA";
5300 InitExprs.push_back(DescRefExpr);
5303 if (BlockDeclRefs.size()) {
5307 E = BlockByCopyDecls.end(); I != E; ++I) {
5308 if (isObjCType((*I)->getType())) {
5310 FD = SynthBlockInitFunctionDecl((*I)->getName());
5320 }
else if (isTopLevelBlockPointerType((*I)->getType())) {
5321 FD = SynthBlockInitFunctionDecl((*I)->getName());
5324 Exp = NoTypeInfoCStyleCastExpr(Context, Context->
VoidPtrTy,
5327 FD = SynthBlockInitFunctionDecl((*I)->getName());
5339 InitExprs.push_back(Exp);
5343 E = BlockByRefDecls.end(); I != E; ++I) {
5346 std::string RecName;
5347 RewriteByRefString(RecName, Name, ND,
true);
5349 +
sizeof(
"struct"));
5353 assert(RD &&
"SynthBlockInitExpr(): Can't find RecordDecl");
5356 FD = SynthBlockInitFunctionDecl((*I)->getName());
5359 bool isNestedCapturedVar =
false;
5361 for (
const auto &CI : block->
captures()) {
5362 const VarDecl *variable = CI.getVariable();
5363 if (variable == ND && CI.isNested()) {
5364 assert (CI.isByRef() &&
5365 "SynthBlockInitExpr - captured block variable is not byref");
5366 isNestedCapturedVar =
true;
5372 if (!isNestedCapturedVar)
5377 Exp = NoTypeInfoCStyleCastExpr(Context, castT, CK_BitCast, Exp);
5378 InitExprs.push_back(Exp);
5381 if (ImportedBlockDecls.size()) {
5388 InitExprs.push_back(FlagExp);
5393 if (GlobalBlockExpr) {
5394 assert (!GlobalConstructionExp &&
5395 "SynthBlockInitExpr - GlobalConstructionExp must be null");
5396 GlobalConstructionExp = NewRep;
5403 NewRep = NoTypeInfoCStyleCastExpr(Context, FType, CK_BitCast,
5409 BlockDeclRefs.clear();
5410 BlockByRefDecls.clear();
5411 BlockByRefDeclsPtrSet.clear();
5412 BlockByCopyDecls.clear();
5413 BlockByCopyDeclsPtrSet.clear();
5414 ImportedBlockDecls.clear();
5418 bool RewriteModernObjC::IsDeclStmtInForeachHeader(
DeclStmt *DS) {
5420 dyn_cast<ObjCForCollectionStmt>(Stmts.back()))
5421 return CS->getElement() == DS;
5429 Stmt *RewriteModernObjC::RewriteFunctionBodyOrGlobalInitializer(
Stmt *S) {
5430 if (isa<SwitchStmt>(S) || isa<WhileStmt>(S) ||
5431 isa<DoStmt>(S) || isa<ForStmt>(S))
5433 else if (isa<ObjCForCollectionStmt>(S)) {
5435 ObjCBcLabelNo.push_back(++BcLabelCount);
5442 return RewritePropertyOrImplicitSetter(PseudoOp);
5444 return RewritePropertyOrImplicitGetter(PseudoOp);
5446 }
else if (
ObjCIvarRefExpr *IvarRefExpr = dyn_cast<ObjCIvarRefExpr>(S)) {
5447 return RewriteObjCIvarRefExpr(IvarRefExpr);
5449 else if (isa<OpaqueValueExpr>(S))
5450 S = cast<OpaqueValueExpr>(S)->getSourceExpr();
5457 Stmt *newStmt = RewriteFunctionBodyOrGlobalInitializer(childStmt);
5459 childStmt = newStmt;
5463 if (
BlockExpr *BE = dyn_cast<BlockExpr>(S)) {
5465 llvm::SmallPtrSet<const DeclContext *, 8> InnerContexts;
5466 InnerContexts.insert(BE->getBlockDecl());
5467 ImportedLocalExternalDecls.clear();
5468 GetInnerBlockDeclRefExprs(BE->getBody(),
5469 InnerBlockDeclRefs, InnerContexts);
5471 Stmt *SaveCurrentBody = CurrentBody;
5472 CurrentBody = BE->getBody();
5473 PropParentMap =
nullptr;
5479 bool saveDisableReplaceStmt = DisableReplaceStmt;
5480 DisableReplaceStmt =
false;
5481 RewriteFunctionBodyOrGlobalInitializer(BE->getBody());
5482 DisableReplaceStmt = saveDisableReplaceStmt;
5483 CurrentBody = SaveCurrentBody;
5484 PropParentMap =
nullptr;
5485 ImportedLocalExternalDecls.clear();
5488 RewrittenBlockExprs[BE] = Str;
5490 Stmt *blockTranscribed = SynthBlockInitExpr(BE, InnerBlockDeclRefs);
5493 ReplaceStmt(S, blockTranscribed);
5494 return blockTranscribed;
5498 return RewriteAtEncode(AtEncode);
5501 return RewriteAtSelector(AtSelector);
5504 return RewriteObjCStringLiteral(AtString);
5507 return RewriteObjCBoolLiteralExpr(BoolLitExpr);
5510 return RewriteObjCBoxedExpr(BoxedExpr);
5513 return RewriteObjCArrayLiteralExpr(ArrayLitExpr);
5516 dyn_cast<ObjCDictionaryLiteral>(S))
5517 return RewriteObjCDictionaryLiteralExpr(DictionaryLitExpr);
5528 std::string messString;
5529 messString +=
"// ";
5530 messString.append(startBuf, endBuf-startBuf+1);
5539 return RewriteMessageExpr(MessExpr);
5543 dyn_cast<ObjCAutoreleasePoolStmt>(S)) {
5544 return RewriteObjCAutoreleasePoolStmt(StmtAutoRelease);
5548 return RewriteObjCTryStmt(StmtTry);
5551 return RewriteObjCSynchronizedStmt(StmtTry);
5554 return RewriteObjCThrowStmt(StmtThrow);
5557 return RewriteObjCProtocolExpr(ProtocolExp);
5560 dyn_cast<ObjCForCollectionStmt>(S))
5561 return RewriteObjCForCollectionStmt(StmtForCollection,
5564 dyn_cast<BreakStmt>(S))
5565 return RewriteBreakStmt(StmtBreakStmt);
5567 dyn_cast<ContinueStmt>(S))
5568 return RewriteContinueStmt(StmtContinueStmt);
5572 if (
DeclStmt *DS = dyn_cast<DeclStmt>(S)) {
5582 if (Stmts.empty() || !IsDeclStmtInForeachHeader(DS))
5583 RewriteObjCQualifiedInterfaceTypes(*DS->
decl_begin());
5589 if (
ValueDecl *ND = dyn_cast<ValueDecl>(SD)) {
5590 if (isTopLevelBlockPointerType(ND->
getType()))
5591 RewriteBlockPointerDecl(ND);
5593 CheckFunctionPointerDecl(ND->
getType(), ND);
5594 if (
VarDecl *VD = dyn_cast<VarDecl>(SD)) {
5595 if (VD->
hasAttr<BlocksAttr>()) {
5596 static unsigned uniqueByrefDeclCount = 0;
5597 assert(!BlockByRefDeclNo.count(ND) &&
5598 "RewriteFunctionBodyOrGlobalInitializer: Duplicate byref decl");
5599 BlockByRefDeclNo[ND] = uniqueByrefDeclCount++;
5600 RewriteByRefVar(VD, (DI == DS->
decl_begin()), ((DI+1) == DE));
5603 RewriteTypeOfDecl(VD);
5607 if (isTopLevelBlockPointerType(TD->getUnderlyingType()))
5608 RewriteBlockPointerDecl(TD);
5609 else if (TD->getUnderlyingType()->isFunctionPointerType())
5610 CheckFunctionPointerDecl(TD->getUnderlyingType(), TD);
5616 RewriteObjCQualifiedInterfaceTypes(CE);
5618 if (isa<SwitchStmt>(S) || isa<WhileStmt>(S) ||
5619 isa<DoStmt>(S) || isa<ForStmt>(S)) {
5620 assert(!Stmts.empty() &&
"Statement stack is empty");
5621 assert ((isa<SwitchStmt>(Stmts.back()) || isa<WhileStmt>(Stmts.back()) ||
5622 isa<DoStmt>(Stmts.back()) || isa<ForStmt>(Stmts.back()))
5623 &&
"Statement stack mismatch");
5627 if (
DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(S)) {
5629 if (VD->
hasAttr<BlocksAttr>())
5630 return RewriteBlockDeclRefExpr(DRE);
5632 return RewriteLocalVariableExternalStorage(DRE);
5635 if (
CallExpr *CE = dyn_cast<CallExpr>(S)) {
5638 ReplaceStmt(S, BlockCall);
5643 RewriteCastExpr(CE);
5646 RewriteImplicitCastObjCExpr(ICE);
5656 llvm::raw_string_ostream Buf(SStr);
5658 const std::string &Str = Buf.str();
5660 printf(
"CAST = %s\n", &Str[0]);
5661 InsertText(ICE->getSubExpr()->getBeginLoc(), Str);
5670 void RewriteModernObjC::RewriteRecordBody(
RecordDecl *RD) {
5671 for (
auto *FD : RD->
fields()) {
5672 if (isTopLevelBlockPointerType(FD->
getType()))
5673 RewriteBlockPointerDecl(FD);
5676 RewriteObjCQualifiedInterfaceTypes(FD);
5682 void RewriteModernObjC::HandleDeclInMainFile(
Decl *D) {
5692 RewriteBlocksInFunctionProtoType(FD->
getType(), FD);
5699 CurFunctionDef = FD;
5702 cast_or_null<CompoundStmt>(RewriteFunctionBodyOrGlobalInitializer(Body));
5704 CurrentBody =
nullptr;
5705 if (PropParentMap) {
5706 delete PropParentMap;
5707 PropParentMap =
nullptr;
5711 InsertBlockLiteralsWithinFunction(FD);
5712 RewriteLineDirective(D);
5713 CurFunctionDef =
nullptr;
5717 case Decl::ObjCMethod: {
5723 cast_or_null<CompoundStmt>(RewriteFunctionBodyOrGlobalInitializer(Body));
5725 CurrentBody =
nullptr;
5726 if (PropParentMap) {
5727 delete PropParentMap;
5728 PropParentMap =
nullptr;
5730 InsertBlockLiteralsWithinMethod(MD);
5731 RewriteLineDirective(D);
5732 CurMethodDef =
nullptr;
5736 case Decl::ObjCImplementation: {
5738 ClassImplementation.push_back(CI);
5741 case Decl::ObjCCategoryImpl: {
5743 CategoryImplementation.push_back(CI);
5747 VarDecl *VD = cast<VarDecl>(D);
5748 RewriteObjCQualifiedInterfaceTypes(VD);
5749 if (isTopLevelBlockPointerType(VD->
getType()))
5750 RewriteBlockPointerDecl(VD);
5752 CheckFunctionPointerDecl(VD->
getType(), VD);
5755 RewriteCastExpr(CE);
5761 RewriteRecordBody(RD);
5766 RewriteFunctionBodyOrGlobalInitializer(VD->
getInit());
5767 CurrentBody =
nullptr;
5768 if (PropParentMap) {
5769 delete PropParentMap;
5770 PropParentMap =
nullptr;
5773 GlobalVarDecl =
nullptr;
5777 RewriteCastExpr(CE);
5782 case Decl::TypeAlias:
5783 case Decl::Typedef: {
5785 if (isTopLevelBlockPointerType(TD->getUnderlyingType()))
5786 RewriteBlockPointerDecl(TD);
5787 else if (TD->getUnderlyingType()->isFunctionPointerType())
5788 CheckFunctionPointerDecl(TD->getUnderlyingType(), TD);
5790 RewriteObjCQualifiedInterfaceTypes(TD);
5794 case Decl::CXXRecord:
5795 case Decl::Record: {
5798 RewriteRecordBody(RD);
5812 std::string &Result) {
5815 Result +=
"static ";
5816 Result +=
"struct _protocol_t *";
5817 Result +=
"_OBJC_PROTOCOL_REFERENCE_$_";
5824 void RewriteModernObjC::HandleTranslationUnit(
ASTContext &
C) {
5830 for (
unsigned i = 0, e = FunctionDefinitionsSeen.size(); i < e; i++) {
5835 HandleTopLevelSingleDecl(FDecl);
5841 RewriteObjCProtocolMetaData(ProtDecl, Preamble);
5847 if (ClassImplementation.size() || CategoryImplementation.size())
5848 RewriteImplementations();
5850 for (
unsigned i = 0, e = ObjCInterfacesSeen.size(); i < e; i++) {
5851 ObjCInterfaceDecl *CDecl = ObjCInterfacesSeen[i];
5856 RewriteInterfaceDecl(CDecl);
5864 *OutFile << std::string(RewriteBuf->begin(), RewriteBuf->end());
5866 llvm::errs() <<
"No changes\n";
5869 if (ClassImplementation.size() || CategoryImplementation.size() ||
5870 ProtocolExprDecls.size()) {
5872 std::string ResultStr;
5873 RewriteMetaDataIntoBuffer(ResultStr);
5875 *OutFile << ResultStr;
5879 std::string ResultStr;
5880 WriteImageInfo(ResultStr);
5881 *OutFile << ResultStr;
5886 void RewriteModernObjC::Initialize(
ASTContext &context) {
5887 InitializeCommon(context);
5889 Preamble +=
"#ifndef __OBJC2__\n";
5890 Preamble +=
"#define __OBJC2__\n";
5891 Preamble +=
"#endif\n";
5896 Preamble =
"#pragma once\n";
5897 Preamble +=
"struct objc_selector; struct objc_class;\n";
5898 Preamble +=
"struct __rw_objc_super { \n\tstruct objc_object *object; ";
5899 Preamble +=
"\n\tstruct objc_object *superClass; ";
5901 Preamble +=
"\n\t__rw_objc_super(struct objc_object *o, struct objc_object *s) ";
5902 Preamble +=
": object(o), superClass(s) {} ";
5903 Preamble +=
"\n};\n";
5905 if (LangOpts.MicrosoftExt) {
5908 Preamble +=
"\n#pragma section(\".objc_classlist$B\", long, read, write)\n";
5909 Preamble +=
"#pragma section(\".objc_catlist$B\", long, read, write)\n";
5910 Preamble +=
"#pragma section(\".objc_imageinfo$B\", long, read, write)\n";
5911 Preamble +=
"#pragma section(\".objc_nlclslist$B\", long, read, write)\n";
5912 Preamble +=
"#pragma section(\".objc_nlcatlist$B\", long, read, write)\n";
5914 Preamble +=
"#pragma section(\".cat_cls_meth$B\", long, read, write)\n";
5915 Preamble +=
"#pragma section(\".inst_meth$B\", long, read, write)\n";
5916 Preamble +=
"#pragma section(\".cls_meth$B\", long, read, write)\n";
5917 Preamble +=
"#pragma section(\".objc_ivar$B\", long, read, write)\n";
5921 Preamble +=
"#pragma section(\".objc_selrefs$B\", long, read, write)\n";
5922 Preamble +=
"#pragma section(\".objc_classrefs$B\", long, read, write)\n";
5923 Preamble +=
"#pragma section(\".objc_superrefs$B\", long, read, write)\n";
5926 Preamble +=
"#ifndef _REWRITER_typedef_Protocol\n";
5927 Preamble +=
"typedef struct objc_object Protocol;\n";
5928 Preamble +=
"#define _REWRITER_typedef_Protocol\n";
5929 Preamble +=
"#endif\n";
5930 if (LangOpts.MicrosoftExt) {
5931 Preamble +=
"#define __OBJC_RW_DLLIMPORT extern \"C\" __declspec(dllimport)\n";
5932 Preamble +=
"#define __OBJC_RW_STATICIMPORT extern \"C\"\n";
5935 Preamble +=
"#define __OBJC_RW_DLLIMPORT extern\n";
5937 Preamble +=
"__OBJC_RW_DLLIMPORT void objc_msgSend(void);\n";
5938 Preamble +=
"__OBJC_RW_DLLIMPORT void objc_msgSendSuper(void);\n";
5939 Preamble +=
"__OBJC_RW_DLLIMPORT void objc_msgSend_stret(void);\n";
5940 Preamble +=
"__OBJC_RW_DLLIMPORT void objc_msgSendSuper_stret(void);\n";
5941 Preamble +=
"__OBJC_RW_DLLIMPORT void objc_msgSend_fpret(void);\n";
5943 Preamble +=
"__OBJC_RW_DLLIMPORT struct objc_class *objc_getClass";
5944 Preamble +=
"(const char *);\n";
5945 Preamble +=
"__OBJC_RW_DLLIMPORT struct objc_class *class_getSuperclass";
5946 Preamble +=
"(struct objc_class *);\n";
5947 Preamble +=
"__OBJC_RW_DLLIMPORT struct objc_class *objc_getMetaClass";
5948 Preamble +=
"(const char *);\n";
5949 Preamble +=
"__OBJC_RW_DLLIMPORT void objc_exception_throw( struct objc_object *);\n";
5951 Preamble +=
"__OBJC_RW_DLLIMPORT int objc_sync_enter( struct objc_object *);\n";
5952 Preamble +=
"__OBJC_RW_DLLIMPORT int objc_sync_exit( struct objc_object *);\n";
5953 Preamble +=
"__OBJC_RW_DLLIMPORT Protocol *objc_getProtocol(const char *);\n";
5954 Preamble +=
"#ifdef _WIN64\n";
5955 Preamble +=
"typedef unsigned long long _WIN_NSUInteger;\n";
5956 Preamble +=
"#else\n";
5957 Preamble +=
"typedef unsigned int _WIN_NSUInteger;\n";
5958 Preamble +=
"#endif\n";
5959 Preamble +=
"#ifndef __FASTENUMERATIONSTATE\n";
5960 Preamble +=
"struct __objcFastEnumerationState {\n\t";
5961 Preamble +=
"unsigned long state;\n\t";
5962 Preamble +=
"void **itemsPtr;\n\t";
5963 Preamble +=
"unsigned long *mutationsPtr;\n\t";
5964 Preamble +=
"unsigned long extra[5];\n};\n";
5965 Preamble +=
"__OBJC_RW_DLLIMPORT void objc_enumerationMutation(struct objc_object *);\n";
5966 Preamble +=
"#define __FASTENUMERATIONSTATE\n";
5967 Preamble +=
"#endif\n";
5968 Preamble +=
"#ifndef __NSCONSTANTSTRINGIMPL\n";
5969 Preamble +=
"struct __NSConstantStringImpl {\n";
5970 Preamble +=
" int *isa;\n";
5971 Preamble +=
" int flags;\n";
5972 Preamble +=
" char *str;\n";
5973 Preamble +=
"#if _WIN64\n";
5974 Preamble +=
" long long length;\n";
5975 Preamble +=
"#else\n";
5976 Preamble +=
" long length;\n";
5977 Preamble +=
"#endif\n";
5979 Preamble +=
"#ifdef CF_EXPORT_CONSTANT_STRING\n";
5980 Preamble +=
"extern \"C\" __declspec(dllexport) int __CFConstantStringClassReference[];\n";
5981 Preamble +=
"#else\n";
5982 Preamble +=
"__OBJC_RW_DLLIMPORT int __CFConstantStringClassReference[];\n";
5983 Preamble +=
"#endif\n";
5984 Preamble +=
"#define __NSCONSTANTSTRINGIMPL\n";
5985 Preamble +=
"#endif\n";
5987 Preamble +=
"#ifndef BLOCK_IMPL\n";
5988 Preamble +=
"#define BLOCK_IMPL\n";
5989 Preamble +=
"struct __block_impl {\n";
5990 Preamble +=
" void *isa;\n";
5991 Preamble +=
" int Flags;\n";
5992 Preamble +=
" int Reserved;\n";
5993 Preamble +=
" void *FuncPtr;\n";
5995 Preamble +=
"// Runtime copy/destroy helper functions (from Block_private.h)\n";
5996 Preamble +=
"#ifdef __OBJC_EXPORT_BLOCKS\n";
5997 Preamble +=
"extern \"C\" __declspec(dllexport) " 5998 "void _Block_object_assign(void *, const void *, const int);\n";
5999 Preamble +=
"extern \"C\" __declspec(dllexport) void _Block_object_dispose(const void *, const int);\n";
6000 Preamble +=
"extern \"C\" __declspec(dllexport) void *_NSConcreteGlobalBlock[32];\n";
6001 Preamble +=
"extern \"C\" __declspec(dllexport) void *_NSConcreteStackBlock[32];\n";
6002 Preamble +=
"#else\n";
6003 Preamble +=
"__OBJC_RW_DLLIMPORT void _Block_object_assign(void *, const void *, const int);\n";
6004 Preamble +=
"__OBJC_RW_DLLIMPORT void _Block_object_dispose(const void *, const int);\n";
6005 Preamble +=
"__OBJC_RW_DLLIMPORT void *_NSConcreteGlobalBlock[32];\n";
6006 Preamble +=
"__OBJC_RW_DLLIMPORT void *_NSConcreteStackBlock[32];\n";
6007 Preamble +=
"#endif\n";
6008 Preamble +=
"#endif\n";
6009 if (LangOpts.MicrosoftExt) {
6010 Preamble +=
"#undef __OBJC_RW_DLLIMPORT\n";
6011 Preamble +=
"#undef __OBJC_RW_STATICIMPORT\n";
6012 Preamble +=
"#ifndef KEEP_ATTRIBUTES\n";
6013 Preamble +=
"#define __attribute__(X)\n";
6014 Preamble +=
"#endif\n";
6015 Preamble +=
"#ifndef __weak\n";
6016 Preamble +=
"#define __weak\n";
6017 Preamble +=
"#endif\n";
6018 Preamble +=
"#ifndef __block\n";
6019 Preamble +=
"#define __block\n";
6020 Preamble +=
"#endif\n";
6023 Preamble +=
"#define __block\n";
6024 Preamble +=
"#define __weak\n";
6028 Preamble +=
"\n#include <stdarg.h>\n";
6029 Preamble +=
"struct __NSContainer_literal {\n";
6030 Preamble +=
" void * *arr;\n";
6031 Preamble +=
" __NSContainer_literal (unsigned int count, ...) {\n";
6032 Preamble +=
"\tva_list marker;\n";
6033 Preamble +=
"\tva_start(marker, count);\n";
6034 Preamble +=
"\tarr = new void *[count];\n";
6035 Preamble +=
"\tfor (unsigned i = 0; i < count; i++)\n";
6036 Preamble +=
"\t arr[i] = va_arg(marker, void *);\n";
6037 Preamble +=
"\tva_end( marker );\n";
6038 Preamble +=
" };\n";
6039 Preamble +=
" ~__NSContainer_literal() {\n";
6040 Preamble +=
"\tdelete[] arr;\n";
6045 Preamble +=
"extern \"C\" __declspec(dllimport) void * objc_autoreleasePoolPush(void);\n";
6046 Preamble +=
"extern \"C\" __declspec(dllimport) void objc_autoreleasePoolPop(void *);\n\n";
6047 Preamble +=
"struct __AtAutoreleasePool {\n";
6048 Preamble +=
" __AtAutoreleasePool() {atautoreleasepoolobj = objc_autoreleasePoolPush();}\n";
6049 Preamble +=
" ~__AtAutoreleasePool() {objc_autoreleasePoolPop(atautoreleasepoolobj);}\n";
6050 Preamble +=
" void * atautoreleasepoolobj;\n";
6055 Preamble +=
"\n#define __OFFSETOFIVAR__(TYPE, MEMBER) ((long long) &((TYPE *)0)->MEMBER)\n";
6060 void RewriteModernObjC::RewriteIvarOffsetComputation(
ObjCIvarDecl *ivar,
6061 std::string &Result) {
6062 Result +=
"__OFFSETOFIVAR__(struct ";
6064 if (LangOpts.MicrosoftExt)
6068 ObjCIvarBitfieldGroupDecl(ivar, Result);
6177 static bool meta_data_declared =
false;
6178 if (meta_data_declared)
6181 Result +=
"\nstruct _prop_t {\n";
6182 Result +=
"\tconst char *name;\n";
6183 Result +=
"\tconst char *attributes;\n";
6186 Result +=
"\nstruct _protocol_t;\n";
6188 Result +=
"\nstruct _objc_method {\n";
6189 Result +=
"\tstruct objc_selector * _cmd;\n";
6190 Result +=
"\tconst char *method_type;\n";
6191 Result +=
"\tvoid *_imp;\n";
6194 Result +=
"\nstruct _protocol_t {\n";
6195 Result +=
"\tvoid * isa; // NULL\n";
6196 Result +=
"\tconst char *protocol_name;\n";
6197 Result +=
"\tconst struct _protocol_list_t * protocol_list; // super protocols\n";
6198 Result +=
"\tconst struct method_list_t *instance_methods;\n";
6199 Result +=
"\tconst struct method_list_t *class_methods;\n";
6200 Result +=
"\tconst struct method_list_t *optionalInstanceMethods;\n";
6201 Result +=
"\tconst struct method_list_t *optionalClassMethods;\n";
6202 Result +=
"\tconst struct _prop_list_t * properties;\n";
6203 Result +=
"\tconst unsigned int size; // sizeof(struct _protocol_t)\n";
6204 Result +=
"\tconst unsigned int flags; // = 0\n";
6205 Result +=
"\tconst char ** extendedMethodTypes;\n";
6208 Result +=
"\nstruct _ivar_t {\n";
6209 Result +=
"\tunsigned long int *offset; // pointer to ivar offset location\n";
6210 Result +=
"\tconst char *name;\n";
6211 Result +=
"\tconst char *type;\n";
6212 Result +=
"\tunsigned int alignment;\n";
6213 Result +=
"\tunsigned int size;\n";
6216 Result +=
"\nstruct _class_ro_t {\n";
6217 Result +=
"\tunsigned int flags;\n";
6218 Result +=
"\tunsigned int instanceStart;\n";
6219 Result +=
"\tunsigned int instanceSize;\n";
6221 if (Triple.getArch() == llvm::Triple::x86_64)
6222 Result +=
"\tunsigned int reserved;\n";
6223 Result +=
"\tconst unsigned char *ivarLayout;\n";
6224 Result +=
"\tconst char *name;\n";
6225 Result +=
"\tconst struct _method_list_t *baseMethods;\n";
6226 Result +=
"\tconst struct _objc_protocol_list *baseProtocols;\n";
6227 Result +=
"\tconst struct _ivar_list_t *ivars;\n";
6228 Result +=
"\tconst unsigned char *weakIvarLayout;\n";
6229 Result +=
"\tconst struct _prop_list_t *properties;\n";
6232 Result +=
"\nstruct _class_t {\n";
6233 Result +=
"\tstruct _class_t *isa;\n";
6234 Result +=
"\tstruct _class_t *superclass;\n";
6235 Result +=
"\tvoid *cache;\n";
6236 Result +=
"\tvoid *vtable;\n";
6237 Result +=
"\tstruct _class_ro_t *ro;\n";
6240 Result +=
"\nstruct _category_t {\n";
6241 Result +=
"\tconst char *name;\n";
6242 Result +=
"\tstruct _class_t *cls;\n";
6243 Result +=
"\tconst struct _method_list_t *instance_methods;\n";
6244 Result +=
"\tconst struct _method_list_t *class_methods;\n";
6245 Result +=
"\tconst struct _protocol_list_t *protocols;\n";
6246 Result +=
"\tconst struct _prop_list_t *properties;\n";
6249 Result +=
"extern \"C\" __declspec(dllimport) struct objc_cache _objc_empty_cache;\n";
6250 Result +=
"#pragma warning(disable:4273)\n";
6251 meta_data_declared =
true;
6255 long super_protocol_count) {
6256 Result +=
"struct /*_protocol_list_t*/"; Result +=
" {\n";
6257 Result +=
"\tlong protocol_count; // Note, this is 32/64 bit\n";
6258 Result +=
"\tstruct _protocol_t *super_protocols[";
6259 Result += utostr(super_protocol_count); Result +=
"];\n";
6264 unsigned int method_count) {
6265 Result +=
"struct /*_method_list_t*/"; Result +=
" {\n";
6266 Result +=
"\tunsigned int entsize; // sizeof(struct _objc_method)\n";
6267 Result +=
"\tunsigned int method_count;\n";
6268 Result +=
"\tstruct _objc_method method_list[";
6269 Result += utostr(method_count); Result +=
"];\n";
6274 unsigned int property_count) {
6275 Result +=
"struct /*_prop_list_t*/"; Result +=
" {\n";
6276 Result +=
"\tunsigned int entsize; // sizeof(struct _prop_t)\n";
6277 Result +=
"\tunsigned int count_of_properties;\n";
6278 Result +=
"\tstruct _prop_t prop_list[";
6279 Result += utostr(property_count); Result +=
"];\n";
6284 unsigned int ivar_count) {
6285 Result +=
"struct /*_ivar_list_t*/"; Result +=
" {\n";
6286 Result +=
"\tunsigned int entsize; // sizeof(struct _prop_t)\n";
6287 Result +=
"\tunsigned int count;\n";
6288 Result +=
"\tstruct _ivar_t ivar_list[";
6289 Result += utostr(ivar_count); Result +=
"];\n";
6296 StringRef ProtocolName) {
6297 if (SuperProtocols.size() > 0) {
6298 Result +=
"\nstatic ";
6300 Result +=
" "; Result += VarName;
6301 Result += ProtocolName;
6302 Result +=
" __attribute__ ((used, section (\"__DATA,__objc_const\"))) = {\n";
6303 Result +=
"\t"; Result += utostr(SuperProtocols.size()); Result +=
",\n";
6304 for (
unsigned i = 0, e = SuperProtocols.size(); i < e; i++) {
6306 Result +=
"\t&"; Result +=
"_OBJC_PROTOCOL_";
6320 StringRef TopLevelDeclName,
6322 if (Methods.size() > 0) {
6323 Result +=
"\nstatic ";
6325 Result +=
" "; Result += VarName;
6326 Result += TopLevelDeclName;
6327 Result +=
" __attribute__ ((used, section (\"__DATA,__objc_const\"))) = {\n";
6328 Result +=
"\t"; Result +=
"sizeof(_objc_method)"; Result +=
",\n";
6329 Result +=
"\t"; Result += utostr(Methods.size()); Result +=
",\n";
6330 for (
unsigned i = 0, e = Methods.size(); i < e; i++) {
6333 Result +=
"\t{{(struct objc_selector *)\"";
6335 Result +=
"\t{(struct objc_selector *)\"";
6336 Result += (MD)->getSelector().getAsString(); Result +=
"\"";
6339 Result +=
"\""; Result += MethodTypeString; Result +=
"\"";
6344 Result +=
"(void *)";
6345 Result += RewriteObj.MethodInternalNames[MD];
6359 const Decl *Container,
6361 StringRef ProtocolName) {
6362 if (Properties.size() > 0) {
6363 Result +=
"\nstatic ";
6365 Result +=
" "; Result += VarName;
6366 Result += ProtocolName;
6367 Result +=
" __attribute__ ((used, section (\"__DATA,__objc_const\"))) = {\n";
6368 Result +=
"\t"; Result +=
"sizeof(_prop_t)"; Result +=
",\n";
6369 Result +=
"\t"; Result += utostr(Properties.size()); Result +=
",\n";
6370 for (
unsigned i = 0, e = Properties.size(); i < e; i++) {
6376 Result += PropDecl->
getName(); Result +=
"\",";
6377 std::string PropertyTypeString =
6379 std::string QuotePropertyTypeString;
6380 RewriteObj.QuoteDoublequotes(PropertyTypeString, QuotePropertyTypeString);
6381 Result +=
"\""; Result += QuotePropertyTypeString; Result +=
"\"";
6407 const std::string &InstanceStart,
6408 const std::string &InstanceSize,
6414 StringRef ClassName) {
6415 Result +=
"\nstatic struct _class_ro_t ";
6416 Result += VarName; Result += ClassName;
6417 Result +=
" __attribute__ ((used, section (\"__DATA,__objc_const\"))) = {\n";
6419 Result += llvm::utostr(flags); Result +=
", ";
6420 Result += InstanceStart; Result +=
", ";
6421 Result += InstanceSize; Result +=
", \n";
6424 if (Triple.getArch() == llvm::Triple::x86_64)
6426 Result +=
"(unsigned int)0, \n\t";
6428 Result +=
"0, \n\t";
6429 Result +=
"\""; Result += ClassName; Result +=
"\",\n\t";
6430 bool metaclass = ((flags &
CLS_META) != 0);
6431 if (baseMethods.size() > 0) {
6432 Result +=
"(const struct _method_list_t *)&";
6434 Result +=
"_OBJC_$_CLASS_METHODS_";
6436 Result +=
"_OBJC_$_INSTANCE_METHODS_";
6437 Result += ClassName;
6441 Result +=
"0, \n\t";
6443 if (!metaclass && baseProtocols.size() > 0) {
6444 Result +=
"(const struct _objc_protocol_list *)&";
6445 Result +=
"_OBJC_CLASS_PROTOCOLS_$_"; Result += ClassName;
6449 Result +=
"0, \n\t";
6451 if (!metaclass && ivars.size() > 0) {
6452 Result +=
"(const struct _ivar_list_t *)&";
6453 Result +=
"_OBJC_$_INSTANCE_VARIABLES_"; Result += ClassName;
6457 Result +=
"0, \n\t";
6460 Result +=
"0, \n\t";
6461 if (!metaclass && Properties.size() > 0) {
6462 Result +=
"(const struct _prop_list_t *)&";
6463 Result +=
"_OBJC_$_PROP_LIST_"; Result += ClassName;
6474 const ObjCInterfaceDecl *CDecl,
bool metaclass) {
6476 const ObjCInterfaceDecl *RootClass = CDecl;
6486 if (metaclass && rootClass) {
6489 Result +=
"extern \"C\" ";
6491 Result +=
"__declspec(dllexport) ";
6493 Result +=
"__declspec(dllimport) ";
6495 Result +=
"struct _class_t OBJC_CLASS_$_";
6503 Result +=
"extern \"C\" ";
6505 Result +=
"__declspec(dllexport) ";
6507 Result +=
"__declspec(dllimport) ";
6509 Result +=
"struct _class_t ";
6514 if (metaclass && RootClass != SuperClass) {
6515 Result +=
"extern \"C\" ";
6517 Result +=
"__declspec(dllexport) ";
6519 Result +=
"__declspec(dllimport) ";
6521 Result +=
"struct _class_t ";
6528 Result +=
"\nextern \"C\" __declspec(dllexport) struct _class_t ";
6530 Result +=
" __attribute__ ((used, section (\"__DATA,__objc_data\"))) = {\n";
6534 Result +=
"0, // &"; Result += VarName;
6537 Result +=
"0, // &"; Result += VarName;
6542 Result +=
"0, // &"; Result += VarName;
6550 Result +=
"0, // &OBJC_METACLASS_$_";
6554 Result +=
"0, // &"; Result += VarName;
6561 Result +=
"0, // (void *)&_objc_empty_cache,\n\t";
6562 Result +=
"0, // unused, was (void *)&_objc_empty_vtable,\n\t";
6564 Result +=
"&_OBJC_METACLASS_RO_$_";
6566 Result +=
"&_OBJC_CLASS_RO_$_";
6568 Result +=
",\n};\n";
6575 const ObjCInterfaceDecl *SuperClass =
6578 Result +=
"static void OBJC_CLASS_SETUP_$_";
6580 Result +=
"(void ) {\n";
6582 Result +=
".isa = "; Result +=
"&OBJC_METACLASS_$_";
6586 Result +=
".superclass = ";
6588 Result +=
"&OBJC_CLASS_$_";
6590 Result +=
"&OBJC_METACLASS_$_";
6595 Result +=
".cache = "; Result +=
"&_objc_empty_cache"; Result +=
";\n";
6598 Result +=
".isa = "; Result +=
"&OBJC_METACLASS_$_";
6603 Result +=
".superclass = "; Result +=
"&OBJC_CLASS_$_";
6608 Result +=
".cache = "; Result +=
"&_objc_empty_cache"; Result +=
";\n";
6613 std::string &Result,
6615 ObjCInterfaceDecl *ClassDecl,
6620 StringRef CatName = CatDecl->
getName();
6621 StringRef ClassName = ClassDecl->
getName();
6625 Result +=
"extern \"C\" ";
6627 Result +=
"__declspec(dllexport) ";
6629 Result +=
"__declspec(dllimport) ";
6631 Result +=
"struct _class_t ";
6632 Result +=
"OBJC_CLASS_$_"; Result += ClassName;
6635 Result +=
"\nstatic struct _category_t ";
6636 Result +=
"_OBJC_$_CATEGORY_";
6637 Result += ClassName; Result +=
"_$_"; Result += CatName;
6638 Result +=
" __attribute__ ((used, section (\"__DATA,__objc_const\"))) = \n";
6640 Result +=
"\t\""; Result += ClassName; Result +=
"\",\n";
6641 Result +=
"\t0, // &"; Result +=
"OBJC_CLASS_$_"; Result += ClassName;
6643 if (InstanceMethods.size() > 0) {
6644 Result +=
"\t(const struct _method_list_t *)&";
6645 Result +=
"_OBJC_$_CATEGORY_INSTANCE_METHODS_";
6646 Result += ClassName; Result +=
"_$_"; Result += CatName;
6652 if (ClassMethods.size() > 0) {
6653 Result +=
"\t(const struct _method_list_t *)&";
6654 Result +=
"_OBJC_$_CATEGORY_CLASS_METHODS_";
6655 Result += ClassName; Result +=
"_$_"; Result += CatName;
6661 if (RefedProtocols.size() > 0) {
6662 Result +=
"\t(const struct _protocol_list_t *)&";
6663 Result +=
"_OBJC_CATEGORY_PROTOCOLS_$_";
6664 Result += ClassName; Result +=
"_$_"; Result += CatName;
6670 if (ClassProperties.size() > 0) {
6671 Result +=
"\t(const struct _prop_list_t *)&"; Result +=
"_OBJC_$_PROP_LIST_";
6672 Result += ClassName; Result +=
"_$_"; Result += CatName;
6681 Result +=
"static void OBJC_CATEGORY_SETUP_$_";
6685 Result +=
"(void ) {\n";
6686 Result +=
"\t_OBJC_$_CATEGORY_";
6690 Result +=
".cls = "; Result +=
"&OBJC_CLASS_$_"; Result += ClassName;
6698 StringRef ProtocolName) {
6699 if (Methods.size() == 0)
6702 Result +=
"\nstatic const char *";
6703 Result += VarName; Result += ProtocolName;
6704 Result +=
" [] __attribute__ ((used, section (\"__DATA,__objc_const\"))) = \n";
6706 for (
unsigned i = 0, e = Methods.size(); i < e; i++) {
6708 std::string MethodTypeString =
6710 std::string QuoteMethodTypeString;
6711 RewriteObj.QuoteDoublequotes(MethodTypeString, QuoteMethodTypeString);
6712 Result +=
"\t\""; Result += QuoteMethodTypeString; Result +=
"\"";
6723 std::string &Result,
6725 ObjCInterfaceDecl *CDecl) {
6738 for (
unsigned i =0, e = Ivars.size(); i < e; i++) {
6741 Result +=
"__declspec(allocate(\".objc_ivar$B\")) ";
6746 Result +=
"extern \"C\" unsigned long int ";
6748 Result +=
"extern \"C\" __declspec(dllexport) unsigned long int ";
6749 if (Ivars[i]->isBitField())
6750 RewriteObj.ObjCIvarBitfieldGroupOffset(IvarDecl, Result);
6753 Result +=
" __attribute__ ((used, section (\"__DATA,__objc_ivar\")))";
6755 RewriteObj.RewriteIvarOffsetComputation(IvarDecl, Result);
6757 if (Ivars[i]->isBitField()) {
6768 ObjCInterfaceDecl *CDecl) {
6769 if (OriginalIvars.size() > 0) {
6775 for (
unsigned i = 0, e = OriginalIvars.size(); i < e; i++) {
6776 if (OriginalIvars[i]->isBitField()) {
6777 Ivars.push_back(OriginalIvars[i]);
6782 Ivars.push_back(OriginalIvars[i]);
6785 Result +=
"\nstatic ";
6787 Result +=
" "; Result += VarName;
6789 Result +=
" __attribute__ ((used, section (\"__DATA,__objc_const\"))) = {\n";
6790 Result +=
"\t"; Result +=
"sizeof(_ivar_t)"; Result +=
",\n";
6791 Result +=
"\t"; Result += utostr(Ivars.size()); Result +=
",\n";
6792 for (
unsigned i =0, e = Ivars.size(); i < e; i++) {
6798 Result +=
"(unsigned long int *)&";
6799 if (Ivars[i]->isBitField())
6800 RewriteObj.ObjCIvarBitfieldGroupOffset(IvarDecl, Result);
6806 if (Ivars[i]->isBitField())
6807 RewriteObj.ObjCIvarBitfieldGroupDecl(Ivars[i], Result);
6809 Result += IvarDecl->
getName();
6814 IVQT = RewriteObj.GetGroupRecordTypeForObjCIvarBitfield(IvarDecl);
6816 std::string IvarTypeString, QuoteIvarTypeString;
6819 RewriteObj.QuoteDoublequotes(IvarTypeString, QuoteIvarTypeString);
6820 Result +=
"\""; Result += QuoteIvarTypeString; Result +=
"\", ";
6825 Align = llvm::Log2_32(Align);
6826 Result += llvm::utostr(Align); Result +=
", ";
6839 void RewriteModernObjC::RewriteObjCProtocolMetaData(
ObjCProtocolDecl *PDecl,
6840 std::string &Result) {
6852 RewriteObjCProtocolMetaData(I, Result);
6855 std::vector<ObjCMethodDecl *> InstanceMethods, ClassMethods;
6856 std::vector<ObjCMethodDecl *> OptInstanceMethods, OptClassMethods;
6859 OptInstanceMethods.push_back(MD);
6861 InstanceMethods.push_back(MD);
6867 OptClassMethods.push_back(MD);
6869 ClassMethods.push_back(MD);
6872 std::vector<ObjCMethodDecl *> AllMethods;
6873 for (
unsigned i = 0, e = InstanceMethods.size(); i < e; i++)
6874 AllMethods.push_back(InstanceMethods[i]);
6875 for (
unsigned i = 0, e = ClassMethods.size(); i < e; i++)
6876 AllMethods.push_back(ClassMethods[i]);
6877 for (
unsigned i = 0, e = OptInstanceMethods.size(); i < e; i++)
6878 AllMethods.push_back(OptInstanceMethods[i]);
6879 for (
unsigned i = 0, e = OptClassMethods.size(); i < e; i++)
6880 AllMethods.push_back(OptClassMethods[i]);
6884 "_OBJC_PROTOCOL_METHOD_TYPES_",
6889 "_OBJC_PROTOCOL_REFS_",
6893 "_OBJC_PROTOCOL_INSTANCE_METHODS_",
6897 "_OBJC_PROTOCOL_CLASS_METHODS_",
6901 "_OBJC_PROTOCOL_OPT_INSTANCE_METHODS_",
6905 "_OBJC_PROTOCOL_OPT_CLASS_METHODS_",
6913 "_OBJC_PROTOCOL_PROPERTIES_",
6918 if (LangOpts.MicrosoftExt)
6919 Result +=
"static ";
6920 Result +=
"struct _protocol_t _OBJC_PROTOCOL_";
6922 Result +=
" __attribute__ ((used)) = {\n";
6924 Result +=
"\t\""; Result += PDecl->
getNameAsString(); Result +=
"\",\n";
6925 if (SuperProtocols.size() > 0) {
6926 Result +=
"\t(const struct _protocol_list_t *)&"; Result +=
"_OBJC_PROTOCOL_REFS_";
6931 if (InstanceMethods.size() > 0) {
6932 Result +=
"\t(const struct method_list_t *)&_OBJC_PROTOCOL_INSTANCE_METHODS_";
6938 if (ClassMethods.size() > 0) {
6939 Result +=
"\t(const struct method_list_t *)&_OBJC_PROTOCOL_CLASS_METHODS_";
6945 if (OptInstanceMethods.size() > 0) {
6946 Result +=
"\t(const struct method_list_t *)&_OBJC_PROTOCOL_OPT_INSTANCE_METHODS_";
6952 if (OptClassMethods.size() > 0) {
6953 Result +=
"\t(const struct method_list_t *)&_OBJC_PROTOCOL_OPT_CLASS_METHODS_";
6959 if (ProtocolProperties.size() > 0) {
6960 Result +=
"\t(const struct _prop_list_t *)&_OBJC_PROTOCOL_PROPERTIES_";
6966 Result +=
"\t"; Result +=
"sizeof(_protocol_t)"; Result +=
",\n";
6969 if (AllMethods.size() > 0) {
6970 Result +=
"\t(const char **)&"; Result +=
"_OBJC_PROTOCOL_METHOD_TYPES_";
6975 Result +=
"\t0\n};\n";
6977 if (LangOpts.MicrosoftExt)
6978 Result +=
"static ";
6979 Result +=
"struct _protocol_t *";
6980 Result +=
"_OBJC_LABEL_PROTOCOL_$_"; Result += PDecl->
getNameAsString();
6986 llvm_unreachable(
"protocol already synthesized");
6993 const ObjCInterfaceDecl *OID) {
6994 if (OID->
hasAttr<ObjCExceptionAttr>())
7002 std::string &Result) {
7008 "Legacy implicit interface rewriting not supported in moder abi");
7016 if (!IVD->getDeclName())
7018 IVars.push_back(IVD);
7022 "_OBJC_$_INSTANCE_VARIABLES_",
7033 if (!Prop->getPropertyIvarDecl())
7040 InstanceMethods.push_back(Getter);
7045 InstanceMethods.push_back(Setter);
7049 "_OBJC_$_INSTANCE_METHODS_",
7055 "_OBJC_$_CLASS_METHODS_",
7060 std::vector<ObjCProtocolDecl *> RefedProtocols;
7063 E = Protocols.
end();
7065 RefedProtocols.push_back(*I);
7068 RewriteObjCProtocolMetaData(*I, Result);
7073 "_OBJC_CLASS_PROTOCOLS_$_",
7081 "_OBJC_$_PROP_LIST_",
7086 std::string InstanceSize;
7087 std::string InstanceStart;
7096 InstanceSize =
"sizeof(struct _class_t)";
7097 InstanceStart = InstanceSize;
7099 InstanceStart, InstanceSize,
7104 "_OBJC_METACLASS_RO_$_",
7119 InstanceSize.clear();
7120 InstanceStart.clear();
7121 if (!ObjCSynthesizedStructs.count(CDecl)) {
7123 InstanceStart =
"0";
7126 InstanceSize =
"sizeof(struct ";
7128 InstanceSize +=
"_IMPL)";
7132 RewriteIvarOffsetComputation(IVD, InstanceStart);
7135 InstanceStart = InstanceSize;
7138 InstanceStart, InstanceSize,
7143 "_OBJC_CLASS_RO_$_",
7147 "OBJC_METACLASS_$_",
7154 if (ImplementationIsNonLazy(IDecl))
7155 DefinedNonLazyClasses.push_back(CDecl);
7158 void RewriteModernObjC::RewriteClassSetupInitHook(std::string &Result) {
7159 int ClsDefCount = ClassImplementation.size();
7162 Result +=
"#pragma section(\".objc_inithooks$B\", long, read, write)\n";
7163 Result +=
"__declspec(allocate(\".objc_inithooks$B\")) ";
7164 Result +=
"static void *OBJC_CLASS_SETUP[] = {\n";
7165 for (
int i = 0; i < ClsDefCount; i++) {
7168 Result +=
"\t(void *)&OBJC_CLASS_SETUP_$_";
7169 Result += CDecl->
getName(); Result +=
",\n";
7174 void RewriteModernObjC::RewriteMetaDataIntoBuffer(std::string &Result) {
7175 int ClsDefCount = ClassImplementation.size();
7176 int CatDefCount = CategoryImplementation.size();
7179 for (
int i = 0; i < ClsDefCount; i++)
7180 RewriteObjCClassMetaData(ClassImplementation[i], Result);
7182 RewriteClassSetupInitHook(Result);
7185 for (
int i = 0; i < CatDefCount; i++)
7186 RewriteObjCCategoryImplDecl(CategoryImplementation[i], Result);
7188 RewriteCategorySetupInitHook(Result);
7190 if (ClsDefCount > 0) {
7191 if (LangOpts.MicrosoftExt)
7192 Result +=
"__declspec(allocate(\".objc_classlist$B\")) ";
7193 Result +=
"static struct _class_t *L_OBJC_LABEL_CLASS_$ [";
7194 Result += llvm::utostr(ClsDefCount); Result +=
"]";
7196 " __attribute__((used, section (\"__DATA, __objc_classlist," 7197 "regular,no_dead_strip\")))= {\n";
7198 for (
int i = 0; i < ClsDefCount; i++) {
7199 Result +=
"\t&OBJC_CLASS_$_";
7200 Result += ClassImplementation[i]->getNameAsString();
7205 if (!DefinedNonLazyClasses.empty()) {
7206 if (LangOpts.MicrosoftExt)
7207 Result +=
"__declspec(allocate(\".objc_nlclslist$B\")) \n";
7208 Result +=
"static struct _class_t *_OBJC_LABEL_NONLAZY_CLASS_$[] = {\n\t";
7209 for (
unsigned i = 0, e = DefinedNonLazyClasses.size(); i < e; i++) {
7210 Result +=
"\t&OBJC_CLASS_$_"; Result += DefinedNonLazyClasses[i]->getNameAsString();
7217 if (CatDefCount > 0) {
7218 if (LangOpts.MicrosoftExt)
7219 Result +=
"__declspec(allocate(\".objc_catlist$B\")) ";
7220 Result +=
"static struct _category_t *L_OBJC_LABEL_CATEGORY_$ [";
7221 Result += llvm::utostr(CatDefCount); Result +=
"]";
7223 " __attribute__((used, section (\"__DATA, __objc_catlist," 7224 "regular,no_dead_strip\")))= {\n";
7225 for (
int i = 0; i < CatDefCount; i++) {
7226 Result +=
"\t&_OBJC_$_CATEGORY_";
7228 CategoryImplementation[i]->getClassInterface()->getNameAsString();
7230 Result += CategoryImplementation[i]->getNameAsString();
7236 if (!DefinedNonLazyCategories.empty()) {
7237 if (LangOpts.MicrosoftExt)
7238 Result +=
"__declspec(allocate(\".objc_nlcatlist$B\")) \n";
7239 Result +=
"static struct _category_t *_OBJC_LABEL_NONLAZY_CATEGORY_$[] = {\n\t";
7240 for (
unsigned i = 0, e = DefinedNonLazyCategories.size(); i < e; i++) {
7241 Result +=
"\t&_OBJC_$_CATEGORY_";
7243 DefinedNonLazyCategories[i]->getClassInterface()->getNameAsString();
7245 Result += DefinedNonLazyCategories[i]->getNameAsString();
7252 void RewriteModernObjC::WriteImageInfo(std::string &Result) {
7253 if (LangOpts.MicrosoftExt)
7254 Result +=
"__declspec(allocate(\".objc_imageinfo$B\")) \n";
7256 Result +=
"static struct IMAGE_INFO { unsigned version; unsigned flag; } ";
7258 Result +=
"_OBJC_IMAGE_INFO = { 0, 2 };\n";
7264 std::string &Result) {
7272 FullCategoryName +=
"_$_";
7283 if (!Prop->getPropertyIvarDecl())
7289 InstanceMethods.push_back(Getter);
7293 InstanceMethods.push_back(Setter);
7297 "_OBJC_$_CATEGORY_INSTANCE_METHODS_",
7298 FullCategoryName,
true);
7303 "_OBJC_$_CATEGORY_CLASS_METHODS_",
7304 FullCategoryName,
true);
7312 RewriteObjCProtocolMetaData(I, Result);
7316 "_OBJC_CATEGORY_PROTOCOLS_$_",
7324 "_OBJC_$_PROP_LIST_",
7336 if (ImplementationIsNonLazy(IDecl))
7337 DefinedNonLazyCategories.push_back(CDecl);
7340 void RewriteModernObjC::RewriteCategorySetupInitHook(std::string &Result) {
7341 int CatDefCount = CategoryImplementation.size();
7344 Result +=
"#pragma section(\".objc_inithooks$B\", long, read, write)\n";
7345 Result +=
"__declspec(allocate(\".objc_inithooks$B\")) ";
7346 Result +=
"static void *OBJC_CATEGORY_SETUP[] = {\n";
7347 for (
int i = 0; i < CatDefCount; i++) {
7351 Result +=
"\t(void *)&OBJC_CATEGORY_SETUP_$_";
7352 Result += ClassDecl->
getName();
7362 template<
typename MethodIterator>
7363 void RewriteModernObjC::RewriteObjCMethodsMetaData(MethodIterator MethodBegin,
7364 MethodIterator MethodEnd,
7365 bool IsInstanceMethod,
7367 StringRef ClassName,
7368 std::string &Result) {
7369 if (MethodBegin == MethodEnd)
return;
7371 if (!objc_impl_method) {
7378 Result +=
"\nstruct _objc_method {\n";
7379 Result +=
"\tSEL _cmd;\n";
7380 Result +=
"\tchar *method_types;\n";
7381 Result +=
"\tvoid *_imp;\n";
7384 objc_impl_method =
true;
7395 unsigned NumMethods =
std::distance(MethodBegin, MethodEnd);
7397 if (LangOpts.MicrosoftExt) {
7398 if (IsInstanceMethod)
7399 Result +=
"__declspec(allocate(\".inst_meth$B\")) ";
7401 Result +=
"__declspec(allocate(\".cls_meth$B\")) ";
7403 Result +=
"static struct {\n";
7404 Result +=
"\tstruct _objc_method_list *next_method;\n";
7405 Result +=
"\tint method_count;\n";
7406 Result +=
"\tstruct _objc_method method_list[";
7407 Result += utostr(NumMethods);
7408 Result +=
"];\n} _OBJC_";
7410 Result += IsInstanceMethod ?
"INSTANCE" :
"CLASS";
7411 Result +=
"_METHODS_";
7412 Result += ClassName;
7413 Result +=
" __attribute__ ((used, section (\"__OBJC, __";
7414 Result += IsInstanceMethod ?
"inst" :
"cls";
7415 Result +=
"_meth\")))= ";
7416 Result +=
"{\n\t0, " + utostr(NumMethods) +
"\n";
7418 Result +=
"\t,{{(SEL)\"";
7419 Result += (*MethodBegin)->getSelector().getAsString().c_str();
7420 std::string MethodTypeString;
7423 Result += MethodTypeString;
7424 Result +=
"\", (void *)";
7425 Result += MethodInternalNames[*MethodBegin];
7427 for (++MethodBegin; MethodBegin != MethodEnd; ++MethodBegin) {
7428 Result +=
"\t ,{(SEL)\"";
7429 Result += (*MethodBegin)->getSelector().getAsString().c_str();
7430 std::string MethodTypeString;
7433 Result += MethodTypeString;
7434 Result +=
"\", (void *)";
7435 Result += MethodInternalNames[*MethodBegin];
7438 Result +=
"\t }\n};\n";
7447 DisableReplaceStmtScope S(*
this);
7448 BaseExpr = cast<Expr>(RewriteFunctionBodyOrGlobalInitializer(BaseExpr));
7454 Expr *Replacement = IV;
7459 assert(iFaceDecl &&
"RewriteObjCIvarRefExpr - iFaceDecl is null");
7461 ObjCInterfaceDecl *clsDeclared =
nullptr;
7464 assert(clsDeclared &&
"RewriteObjCIvarRefExpr(): Can't find class");
7467 std::string IvarOffsetName;
7469 ObjCIvarBitfieldGroupOffset(D, IvarOffsetName);
7473 ReferencedIvars[clsDeclared].insert(D);
7497 IvarT = GetGroupRecordTypeForObjCIvarBitfield(D);
7499 if (!isa<TypedefType>(IvarT) && IvarT->
isRecordType()) {
7509 std::string RecName = CDecl->
getName();
7515 unsigned UnsignedIntSize =
7520 Zero = NoTypeInfoCStyleCastExpr(Context, PtrStructIMPL, CK_BitCast, Zero);
7534 convertObjCTypeToCStyleType(IvarT);
7537 castExpr = NoTypeInfoCStyleCastExpr(Context,
7567 ReplaceStmtWithRange(IV, Replacement, OldRange);
7571 #endif // CLANG_ENABLE_OBJC_REWRITER unsigned getNumSemanticExprs() const
QualType getDecltypeType(Expr *e, QualType UnderlyingType) const
C++11 decltype.
SourceLocation getLocForStartOfFile(FileID FID) const
Return the source location corresponding to the first byte of the specified file. ...
The receiver is the instance of the superclass object.
const BlockDecl * getBlockDecl() const
static bool scanForProtocolRefs(const char *startBuf, const char *endBuf, const char *&startRef, const char *&endRef)
QualType withConst() const
Retrieves a version of this type with const applied.
Represents a function declaration or definition.
The receiver is an object instance.
Expr * getSyntacticForm()
Return the syntactic form of this expression, i.e.
ObjCDictionaryElement getKeyValueElement(unsigned Index) const
static void Write__prop_list_t_TypeDecl(std::string &Result, unsigned int property_count)
bool hasErrorOccurred() const
SourceLocation getLocWithOffset(int Offset) const
Return a source location with the specified offset from this SourceLocation.
const FunctionProtoType * getFunctionType() const
getFunctionType - Return the underlying function type for this block.
Smart pointer class that efficiently represents Objective-C method names.
QualType getObjCIdType() const
Represents the Objective-CC id type.
PointerType - C99 6.7.5.1 - Pointer Declarators.
QualType getPointeeType() const
A (possibly-)qualified type.
bool isBlockPointerType() const
bool isOverloadedOperator() const
Whether this function declaration represents an C++ overloaded operator, e.g., "operator+".
ObjCInterfaceDecl * getClassInterface()
Selector getSelector() const
ObjCInterfaceDecl * getClassInterface()
ASTConsumer - This is an abstract interface that should be implemented by clients that read ASTs...
bool isExternC() const
Determines whether this function is a function with external, C linkage.
bool isThisDeclarationADefinition() const
Determine whether this particular declaration of this class is actually also a definition.
ObjCIvarDecl * getPropertyIvarDecl() const
static void scanToNextArgument(const char *&argRef)
SourceLocation getRParenLoc() const
ObjCProtocolDecl * getProtocol() const
Stmt - This represents one statement.
const ObjCAtFinallyStmt * getFinallyStmt() const
Retrieve the @finally statement, if any.
Expr * getBitWidth() const
SourceLocation getEndLoc() const LLVM_READONLY
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.
bool isVariadic() const
Whether this function prototype is variadic.
SourceLocation getBeginLoc() 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.
Represents Objective-C's @throw statement.
CanQual< T > getUnqualifiedType() const
Retrieve the unqualified form of this type.
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
Represents an array type, per C99 6.7.5.2 - Array Declarators.
Represents a call to a C++ constructor.
const ObjCObjectPointerType * getAsObjCInterfacePointerType() const
bool isRestrictQualified() const
Determine whether this type is restrict-qualified.
virtual void completeDefinition()
Note that the definition of this type is now complete.
SourceLocation getEndLoc() const LLVM_READONLY
QualType withConst() const
SourceLocation getLParenLoc() const
const TargetInfo & getTargetInfo() const
A container of type source information.
Floating point control options.
constexpr XRayInstrMask Function
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, ConstexprSpecKind ConstexprKind=CSK_unspecified, Expr *TrailingRequiresClause=nullptr)
Represents a C++ constructor within a class.
float __ovld __cnfn distance(float p0, float p1)
Returns the distance between p0 and p1.
MutableArrayRef< ParmVarDecl * >::iterator param_iterator
QualType getElementType() const
bool isCompleteDefinition() const
Return true if this decl has its body fully specified.
StringRef getBufferData(FileID FID, bool *Invalid=nullptr) const
Return a StringRef to the source buffer data for the specified FileID.
unsigned getTypeAlign(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in bits.
bool isDefaultConstructor() const
Whether this constructor is a default constructor (C++ [class.ctor]p5), which can be used to default-...
enumerator_range enumerators() const
Represents a variable declaration or definition.
Objects with "hidden" visibility are not seen by the dynamic linker.
SourceLocation getBeginLoc() const LLVM_READONLY
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.
static MemberExpr * CreateImplicit(const ASTContext &C, Expr *Base, bool IsArrow, ValueDecl *MemberDecl, QualType T, ExprValueKind VK, ExprObjectKind OK)
Create an implicit MemberExpr, with no location, qualifier, template arguments, and so on...
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...
static void Write_RethrowObject(std::string &buf)
std::string getRewrittenText(CharSourceRange Range) const
getRewrittenText - Return the rewritten form of the text in the specified range.
QualType getObjCClassType() const
Represents the Objective-C Class type.
Describes how types, statements, expressions, and declarations should be printed. ...
classmeth_range class_methods() const
protocol_range protocols() const
const Stmt * getSubStmt() const
static void Write_protocol_list_initializer(ASTContext *Context, std::string &Result, ArrayRef< ObjCProtocolDecl *> SuperProtocols, StringRef VarName, StringRef ProtocolName)
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
static void Write__ivar_list_t_TypeDecl(std::string &Result, unsigned int ivar_count)
Represents a struct/union/class.
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
ObjCProtocolDecl * getCanonicalDecl() override
Retrieves the canonical declaration of this Objective-C protocol.
instprop_range instance_properties() const
One of these records is kept for each identifier that is lexed.
An element in an Objective-C dictionary literal.
QualType IgnoreParens() const
Returns the specified type after dropping any outer-level parentheses.
Represents a class type in Objective C.
static RecordDecl * Create(const ASTContext &C, TagKind TK, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, IdentifierInfo *Id, RecordDecl *PrevDecl=nullptr)
QualType getPointeeType() const
static void Write_method_list_t_TypeDecl(std::string &Result, unsigned int method_count)
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
ObjCMethodDecl * getClassMethod(Selector Sel, bool AllowHidden=false) const
RecordDecl * getDefinition() const
Returns the RecordDecl that actually defines this struct/union/class.
field_range fields() const
SourceLocation getBeginLoc() const LLVM_READONLY
Represents a member of a struct/union/class.
std::unique_ptr< ASTConsumer > CreateModernObjCRewriter(const std::string &InFile, std::unique_ptr< raw_ostream > OS, DiagnosticsEngine &Diags, const LangOptions &LOpts, bool SilenceRewriteMacroWarning, bool LineInfo)
ObjCMethodDecl * getSetterMethodDecl() const
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()
bool Zero(InterpState &S, CodePtr OpPC)
std::string getNameAsString() const
Get the name of the class associated with this interface.
SourceLocation getRParenLoc() 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
SourceLocation getEndLoc() const LLVM_READONLY
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.
ObjCMethodDecl * getGetterMethodDecl() const
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
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.
SourceLocation getBeginLoc() const LLVM_READONLY
SourceLocation getEndLoc() const LLVM_READONLY
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.
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)
static IntegerLiteral * Create(const ASTContext &C, const llvm::APInt &V, QualType type, SourceLocation l)
Returns a new integer literal with value 'V' and type 'type'.
An ordinary object is located at an address in memory.
Represents an ObjC class declaration.
Represents a linkage specification.
QualType getReturnType() const
SourceLocation getTypeSpecStartLoc() const
const Stmt * getBody() const
SourceLocation getLocation() const
static void WriteInternalIvarName(const ObjCInterfaceDecl *IDecl, ObjCIvarDecl *IvarDecl, std::string &Result)
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...
CompoundStmt - This represents a group of statements like { stmt stmt }.
Represents a prototype with parameter type info, e.g.
CastKind
CastKind - The kind of operation required for a conversion.
static ImplicitCastExpr * Create(const ASTContext &Context, QualType T, CastKind Kind, Expr *Operand, const CXXCastPath *BasePath, ExprValueKind Cat)
static void RewriteOneForwardClassDecl(ObjCInterfaceDecl *ForwardDecl, std::string &typedefString)
SourceLocation getLocation() const
static bool IsHeaderFile(const std::string &Filename)
SourceLocation getEndLoc() const LLVM_READONLY
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
static StringLiteral * Create(const ASTContext &Ctx, StringRef Str, StringKind Kind, bool Pascal, QualType Ty, const SourceLocation *Loc, unsigned NumConcatenated)
This is the "fully general" constructor that allows representation of strings formed from multiple co...
static CallExpr * Create(const ASTContext &Ctx, Expr *Fn, ArrayRef< Expr *> Args, QualType Ty, ExprValueKind VK, SourceLocation RParenLoc, unsigned MinNumArgs=0, ADLCallKind UsesADL=NotADL)
Create a call expression.
Represents a block literal declaration, which is like an unnamed FunctionDecl.
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
This represents one expression.
bool isVariadic() const
Whether this function is variadic.
Selector getSetterName() const
static unsigned MeasureTokenLength(SourceLocation Loc, const SourceManager &SM, const LangOptions &LangOpts)
MeasureTokenLength - Relex the token at the specified location and return its length in bytes in the ...
const T * castAs() const
Member-template castAs<specific type>.
std::string getObjCEncodingForPropertyDecl(const ObjCPropertyDecl *PD, const Decl *Container) const
getObjCEncodingForPropertyDecl - Return the encoded type for this method declaration.
unsigned getLine() const
Return the presumed line number of this location.
BlockExpr - Adaptor class for mixing a BlockDecl with expressions.
bool isThisDeclarationADefinition() const
Returns whether this specific declaration of the function is also a definition that does not contain ...
bool isThisDeclarationADefinition() const
Determine whether this particular declaration is also the definition.
SourceLocation getEndLoc() const LLVM_READONLY
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.
SourceLocation getBeginLoc() const LLVM_READONLY
bool refersToEnclosingVariableOrCapture() const
Does this DeclRefExpr refer to an enclosing local or a captured variable?
void getAsStringInternal(std::string &Str, const PrintingPolicy &Policy) const
IdentifierInfo * getAsIdentifierInfo() const
Retrieve the IdentifierInfo * stored in this declaration name, or null if this declaration name isn't...
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
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
SourceLocation getBeginLoc() const LLVM_READONLY
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
SourceLocation getBeginLoc() const LLVM_READONLY
SourceLocation getEndLoc() const
Expr * getArg(unsigned Arg)
getArg - Return the specified argument.
Expr * getUnderlyingExpr() const
SourceLocation getEndLoc() const LLVM_READONLY
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.
bool isSynthesizedAccessorStub() const
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
void setSourceMgr(SourceManager &SM, const LangOptions &LO)
PseudoObjectExpr - An expression which accesses a pseudo-object l-value.
param_type_range param_types() const
Encodes a location in the source.
ObjCInterfaceDecl * getDecl() const
Get the declaration of this interface.
SourceLocation getEndLoc() const LLVM_READONLY
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
Interfaces are the core concept in Objective-C for object oriented design.
CastKind getCastKind() const
static void Write_category_t(RewriteModernObjC &RewriteObj, ASTContext *Context, std::string &Result, ObjCCategoryDecl *CatDecl, ObjCInterfaceDecl *ClassDecl, ArrayRef< ObjCMethodDecl *> InstanceMethods, ArrayRef< ObjCMethodDecl *> ClassMethods, ArrayRef< ObjCProtocolDecl *> RefedProtocols, ArrayRef< ObjCPropertyDecl *> ClassProperties)
std::string getNameAsString() const
Get a human-readable name for the declaration, even if it is one of the special kinds of names (C++ c...
unsigned getNumElements() const
getNumElements - Return number of elements of objective-c dictionary literal.
Represents the declaration of a struct/union/class/enum.
static void Write_method_list_t_initializer(RewriteModernObjC &RewriteObj, ASTContext *Context, std::string &Result, ArrayRef< ObjCMethodDecl *> Methods, StringRef VarName, StringRef TopLevelDeclName, bool MethodImpl)
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.
Stmt * getBody() const override
Retrieve the body of this method, if it has one.
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 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
SourceLocation getBeginLoc() const
SourceLocation getBeginLoc() const LLVM_READONLY
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 llvm::MemoryBuffer * getBuffer(FileID FID, SourceLocation Loc, bool *Invalid=nullptr) const
Return the buffer for the specified FileID.
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
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.
SourceLocation getBeginLoc() const LLVM_READONLY
int printf(__constant const char *st,...) __attribute__((format(printf
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)
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...
Expr * IgnoreParenImpCasts() LLVM_READONLY
Skip past any parentheses and implicit casts which might surround this expression until reaching a fi...
SourceLocation getBeginLoc() const LLVM_READONLY
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...
Expr * IgnoreImplicit() LLVM_READONLY
Skip past any implicit AST nodes which might surround this expression until reaching a fixed point...
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
Iterator for iterating over Stmt * arrays that contain only T *.
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.
QualType getConstantArrayType(QualType EltTy, const llvm::APInt &ArySize, const Expr *SizeExpr, ArrayType::ArraySizeModifier ASM, unsigned IndexTypeQuals) const
Return the unique reference to the type for a constant array of the specified element type...
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 ...
SourceLocation getBeginLoc() const
Rewriter - This is the main interface to the rewrite buffers.
QualType getParamType(unsigned i) const
void printPretty(raw_ostream &OS, PrinterHelper *Helper, const PrintingPolicy &Policy, unsigned Indentation=0, StringRef NewlineSymbol="\, const ASTContext *Context=nullptr) const
TranslationUnitDecl * getTranslationUnitDecl() const
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
ContinueStmt - This represents a continue.
SourceLocation getBeginLoc() const LLVM_READONLY
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 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]).
SourceLocation getBeginLoc() const LLVM_READONLY
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
SourceLocation getBeginLoc() const LLVM_READONLY
static void Write_ProtocolExprReferencedMetadata(ASTContext *Context, ObjCProtocolDecl *PDecl, std::string &Result)
Write_ProtocolExprReferencedMetadata - This routine writer out the protocol reference symbols in the ...
ObjCBoolLiteralExpr - Objective-C Boolean Literal.
The top declaration context.
A reference to a declared variable, function, enum, etc.
ObjCPropertyDecl * getPropertyDecl() const
Visibility getVisibility() const
Determines the visibility of this entity.
SourceLocation getBeginLoc() const
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.
This represents a decl that may have a name.
ObjCIvarDecl * all_declared_ivar_begin()
all_declared_ivar_begin - return first ivar declared in this class, its extensions and its implementa...
ObjCMethodDecl * getInstanceMethod(Selector Sel, bool AllowHidden=false) const
AccessControl getAccessControl() const
SourceLocation getIvarRBraceLoc() const
Selector getGetterName() const
SourceLocation getEndOfDefinitionLoc() const
SourceLocation getRightLoc() const
bool isFunctionPointerType() const
static FieldDecl * Create(const ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, Expr *BW, bool Mutable, InClassInitStyle InitStyle)
The receiver is a superclass.
static void Write__ivar_list_t_initializer(RewriteModernObjC &RewriteObj, ASTContext *Context, std::string &Result, ArrayRef< ObjCIvarDecl *> OriginalIvars, StringRef VarName, ObjCInterfaceDecl *CDecl)
void getSelectorLocs(SmallVectorImpl< SourceLocation > &SelLocs) const
SourceLocation getBegin() const
const LangOptions & getLangOpts() const
Represents Objective-C's @autoreleasepool Statement.
FullSourceLoc getFullLoc(SourceLocation Loc) const
ObjCCategoryImplDecl - An object of this class encapsulates a category @implementation declaration...
SourceLocation getBeginLoc() const LLVM_READONLY
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...