24 #include "clang/Config/config.h" 27 #include "llvm/ADT/DenseSet.h" 28 #include "llvm/ADT/SmallPtrSet.h" 29 #include "llvm/ADT/StringExtras.h" 30 #include "llvm/Support/MemoryBuffer.h" 31 #include "llvm/Support/raw_ostream.h" 34 #if CLANG_ENABLE_OBJC_REWRITER 36 using namespace clang;
57 BLOCK_NEEDS_FREE = (1 << 24),
60 BLOCK_IS_GC = (1 << 27),
62 BLOCK_HAS_DESCRIPTOR = (1 << 29)
72 const char *MainFileStart, *MainFileEnd;
75 std::string InFileName;
76 std::unique_ptr<raw_ostream> OutFile;
81 Expr *GlobalConstructionExp;
82 unsigned RewriteFailedDiag;
83 unsigned GlobalBlockRewriteFailedDiag;
85 unsigned NumObjCStringLiterals;
86 VarDecl *ConstantStringClassReference;
92 unsigned TryFinallyContainsReturnDiag;
114 llvm::SmallPtrSet<ObjCInterfaceDecl*, 8> ObjCSynthesizedStructs;
115 llvm::SmallPtrSet<ObjCProtocolDecl*, 8> ObjCSynthesizedProtocols;
116 llvm::SmallPtrSet<ObjCInterfaceDecl*, 8> ObjCWrittenInterfaces;
117 llvm::SmallPtrSet<TagDecl*, 32> GlobalDefinedTags;
128 llvm::SmallPtrSet<ObjCProtocolDecl *, 32> ProtocolExprDecls;
141 llvm::SmallPtrSet<ValueDecl *, 8> BlockByCopyDeclsPtrSet;
143 llvm::SmallPtrSet<ValueDecl *, 8> BlockByRefDeclsPtrSet;
144 llvm::DenseMap<ValueDecl *, unsigned> BlockByRefDeclNo;
145 llvm::SmallPtrSet<ValueDecl *, 8> ImportedBlockDecls;
146 llvm::SmallPtrSet<VarDecl *, 8> ImportedLocalExternalDecls;
148 llvm::DenseMap<BlockExpr *, std::string> RewrittenBlockExprs;
154 llvm::DenseMap<const ObjCIvarDecl* , unsigned> IvarGroupNumber;
157 llvm::DenseMap<std::pair<const ObjCInterfaceDecl*, unsigned>,
QualType> GroupRecordType;
163 llvm::DenseMap<Stmt *, Stmt *> ReplacedNodes;
167 bool SilenceRewriteMacroWarning;
168 bool GenerateLineInfo;
169 bool objc_impl_method;
171 bool DisableReplaceStmt;
172 class DisableReplaceStmtScope {
173 RewriteModernObjC &R;
177 DisableReplaceStmtScope(RewriteModernObjC &R)
178 : R(R), SavedValue(R.DisableReplaceStmt) {
179 R.DisableReplaceStmt =
true;
181 ~DisableReplaceStmtScope() {
182 R.DisableReplaceStmt = SavedValue;
188 llvm::DenseMap<ObjCMethodDecl*, std::string> MethodInternalNames;
193 if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(*I)) {
194 if (!
Class->isThisDeclarationADefinition()) {
195 RewriteForwardClassDecl(D);
199 ObjCInterfacesSeen.push_back(Class);
205 if (!Proto->isThisDeclarationADefinition()) {
206 RewriteForwardProtocolDecl(D);
216 if (FDecl->isThisDeclarationADefinition() &&
218 !FDecl->isTopLevelDeclInObjCContainer()) {
219 FunctionDefinitionsSeen.push_back(FDecl);
223 HandleTopLevelSingleDecl(*I);
228 void HandleTopLevelDeclInObjCContainer(
DeclGroupRef D)
override {
231 if (isTopLevelBlockPointerType(TD->getUnderlyingType()))
232 RewriteBlockPointerDecl(TD);
233 else if (TD->getUnderlyingType()->isFunctionPointerType())
234 CheckFunctionPointerDecl(TD->getUnderlyingType(), TD);
236 RewriteObjCQualifiedInterfaceTypes(TD);
241 void HandleTopLevelSingleDecl(
Decl *D);
242 void HandleDeclInMainFile(
Decl *D);
243 RewriteModernObjC(std::string inFile, std::unique_ptr<raw_ostream> OS,
245 bool silenceMacroWarn,
bool LineInfo);
247 ~RewriteModernObjC()
override {}
249 void HandleTranslationUnit(
ASTContext &
C)
override;
251 void ReplaceStmt(
Stmt *Old,
Stmt *New) {
256 assert(Old !=
nullptr && New !=
nullptr &&
"Expected non-null Stmt's");
258 Stmt *ReplacingStmt = ReplacedNodes[Old];
262 if (DisableReplaceStmt)
274 llvm::raw_string_ostream S(SStr);
276 const std::string &Str = S.str();
280 ReplacedNodes[Old] = New;
283 if (SilenceRewriteMacroWarning)
290 bool InsertAfter =
true) {
292 if (!Rewrite.
InsertText(Loc, Str, InsertAfter) ||
293 SilenceRewriteMacroWarning)
302 if (!Rewrite.
ReplaceText(Start, OrigLength, Str) ||
303 SilenceRewriteMacroWarning)
311 void RewriteInclude();
312 void RewriteLineDirective(
const Decl *D);
314 std::string &LineString);
317 void RewriteForwardClassEpilogue(ObjCInterfaceDecl *ClassDecl,
318 const std::string &typedefString);
319 void RewriteImplementations();
323 void RewriteInterfaceDecl(ObjCInterfaceDecl *Dcl);
324 void RewriteImplementationDecl(
Decl *Dcl);
325 void RewriteObjCMethodDecl(
const ObjCInterfaceDecl *IDecl,
327 void RewriteTypeIntoString(
QualType T, std::string &ResultStr,
329 void RewriteByRefString(std::string &ResultStr,
const std::string &Name,
338 void RewriteBlockPointerType(std::string& Str,
QualType Type);
339 void RewriteBlockPointerTypeVariable(std::string& Str,
ValueDecl *VD);
341 void RewriteObjCQualifiedInterfaceTypes(
Decl *Dcl);
342 void RewriteTypeOfDecl(
VarDecl *VD);
343 void RewriteObjCQualifiedInterfaceTypes(
Expr *E);
348 Stmt *RewriteFunctionBodyOrGlobalInitializer(
Stmt *S);
369 void RewriteImplicitCastObjCExpr(
CastExpr *IE);
381 QualType SynthesizeBitfieldGroupStructType(
389 void RewriteBlockPointerDecl(
NamedDecl *VD);
390 void RewriteByRefVar(
VarDecl *VD,
bool firstDecl,
bool lastDecl);
395 void RewriteObjCInternalStruct(ObjCInterfaceDecl *CDecl,
400 bool &IsNamedDefinition);
406 void RewriteIvarOffsetSymbols(ObjCInterfaceDecl *CDecl,
409 void Initialize(
ASTContext &context)
override;
428 void SynthCountByEnumWithState(std::string &buf);
429 void SynthMsgSendFunctionDecl();
430 void SynthMsgSendSuperFunctionDecl();
431 void SynthMsgSendStretFunctionDecl();
432 void SynthMsgSendFpretFunctionDecl();
433 void SynthMsgSendSuperStretFunctionDecl();
434 void SynthGetClassFunctionDecl();
435 void SynthGetMetaClassFunctionDecl();
436 void SynthGetSuperClassFunctionDecl();
437 void SynthSelGetUidFunctionDecl();
438 void SynthSuperConstructorFunctionDecl();
441 template<
typename MethodIterator>
442 void RewriteObjCMethodsMetaData(MethodIterator MethodBegin,
443 MethodIterator MethodEnd,
444 bool IsInstanceMethod,
452 void RewriteClassSetupInitHook(std::string &
Result);
454 void RewriteMetaDataIntoBuffer(std::string &
Result);
455 void WriteImageInfo(std::string &
Result);
458 void RewriteCategorySetupInitHook(std::string &
Result);
466 std::string SynthesizeByrefCopyDestroyHelper(
VarDecl *VD,
int flag);
467 std::string SynthesizeBlockHelperFuncs(
BlockExpr *CE,
int i,
468 StringRef funcName, std::string Tag);
469 std::string SynthesizeBlockFunc(
BlockExpr *CE,
int i,
470 StringRef funcName, std::string Tag);
471 std::string SynthesizeBlockImpl(
BlockExpr *CE,
472 std::string Tag, std::string Desc);
473 std::string SynthesizeBlockDescriptor(std::string DescTag,
475 int i, StringRef funcName,
480 FunctionDecl *SynthBlockInitFunctionDecl(StringRef name);
486 void WarnAboutReturnGotoStmts(
Stmt *S);
488 void InsertBlockLiteralsWithinFunction(
FunctionDecl *FD);
491 bool IsDeclStmtInForeachHeader(
DeclStmt *DS);
492 void CollectBlockDeclRefInfo(
BlockExpr *Exp);
493 void GetBlockDeclRefExprs(
Stmt *S);
494 void GetInnerBlockDeclRefExprs(
Stmt *S,
496 llvm::SmallPtrSetImpl<const DeclContext *> &InnerContexts);
500 bool isTopLevelBlockPointerType(
QualType T) {
501 return isa<BlockPointerType>(T);
507 bool convertBlockPointerToFunctionPointer(
QualType &T) {
508 if (isTopLevelBlockPointerType(T)) {
516 bool convertObjCTypeToCStyleType(
QualType &T);
518 bool needToScanForQualifiers(
QualType T);
520 QualType getConstantStringStructType();
523 void convertToUnqualifiedObjCType(
QualType &T) {
554 if (isa<ObjCInterfaceType>(PT->getPointeeType()) ||
555 PT->getPointeeType()->isObjCQualifiedIdType())
561 bool PointerTypeTakesAnyBlockArguments(
QualType QT);
562 bool PointerTypeTakesAnyObjCQualifiedType(
QualType QT);
563 void GetExtentOfArgList(
const char *Name,
const char *&LParen,
564 const char *&RParen);
566 void QuoteDoublequotes(std::string &From, std::string &To) {
567 for (
unsigned i = 0; i < From.length(); i++) {
577 bool variadic =
false) {
593 bool ImplementationIsNonLazy(
const ObjCImplDecl *OD)
const {
609 void RewriteModernObjC::RewriteBlocksInFunctionProtoType(
QualType funcType,
612 = dyn_cast<FunctionProtoType>(funcType.
IgnoreParens())) {
613 for (
const auto &I : fproto->param_types())
614 if (isTopLevelBlockPointerType(I)) {
616 RewriteBlockPointerDecl(D);
622 void RewriteModernObjC::CheckFunctionPointerDecl(
QualType funcType,
NamedDecl *ND) {
624 if (PT && PointerTypeTakesAnyBlockArguments(funcType))
629 std::string::size_type DotPos = Filename.rfind(
'.');
631 if (DotPos == std::string::npos) {
636 std::string Ext = std::string(Filename.begin()+DotPos+1, Filename.end());
639 return Ext ==
"h" || Ext ==
"hh" || Ext ==
"H";
642 RewriteModernObjC::RewriteModernObjC(std::string inFile,
643 std::unique_ptr<raw_ostream> OS,
646 bool silenceMacroWarn,
bool LineInfo)
647 : Diags(D), LangOpts(LOpts), InFileName(inFile), OutFile(std::move(OS)),
648 SilenceRewriteMacroWarning(silenceMacroWarn), GenerateLineInfo(LineInfo) {
651 "rewriting sub-expression within a macro (may not be correct)");
655 "rewriting block literal declared in global scope is not implemented");
659 "rewriter doesn't support user-specified control flow semantics " 660 "for @try/@finally (code may not execute properly)");
664 const std::string &InFile, std::unique_ptr<raw_ostream> OS,
666 bool SilenceRewriteMacroWarning,
bool LineInfo) {
667 return llvm::make_unique<RewriteModernObjC>(InFile, std::move(OS), Diags,
668 LOpts, SilenceRewriteMacroWarning,
672 void RewriteModernObjC::InitializeCommon(
ASTContext &context) {
676 MsgSendFunctionDecl =
nullptr;
677 MsgSendSuperFunctionDecl =
nullptr;
678 MsgSendStretFunctionDecl =
nullptr;
679 MsgSendSuperStretFunctionDecl =
nullptr;
680 MsgSendFpretFunctionDecl =
nullptr;
681 GetClassFunctionDecl =
nullptr;
682 GetMetaClassFunctionDecl =
nullptr;
683 GetSuperClassFunctionDecl =
nullptr;
684 SelGetUidFunctionDecl =
nullptr;
685 CFStringFunctionDecl =
nullptr;
686 ConstantStringClassReference =
nullptr;
687 NSStringRecord =
nullptr;
688 CurMethodDef =
nullptr;
689 CurFunctionDef =
nullptr;
690 GlobalVarDecl =
nullptr;
691 GlobalConstructionExp =
nullptr;
692 SuperStructDecl =
nullptr;
693 ProtocolTypeDecl =
nullptr;
694 ConstantStringDecl =
nullptr;
696 SuperConstructorFunctionDecl =
nullptr;
697 NumObjCStringLiterals = 0;
698 PropParentMap =
nullptr;
699 CurrentBody =
nullptr;
700 DisableReplaceStmt =
false;
701 objc_impl_method =
false;
705 const llvm::MemoryBuffer *MainBuf = SM->
getBuffer(MainFileID);
706 MainFileStart = MainBuf->getBufferStart();
707 MainFileEnd = MainBuf->getBufferEnd();
716 void RewriteModernObjC::HandleTopLevelSingleDecl(
Decl *D) {
731 RewriteFunctionDecl(FD);
732 }
else if (
VarDecl *FVD = dyn_cast<VarDecl>(D)) {
734 if (FVD->getName() ==
"_NSConstantStringClassReference") {
735 ConstantStringClassReference = FVD;
739 RewriteCategoryDecl(CD);
741 if (PD->isThisDeclarationADefinition())
742 RewriteProtocolDecl(PD);
746 DIEnd = LSD->decls_end();
748 if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>((*DI))) {
749 if (!IFace->isThisDeclarationADefinition()) {
753 if (isa<ObjCInterfaceDecl>(*DI) &&
754 !cast<ObjCInterfaceDecl>(*DI)->isThisDeclarationADefinition() &&
755 StartLoc == (*DI)->getBeginLoc())
761 }
while (DI != DIEnd);
762 RewriteForwardClassDecl(DG);
767 ObjCInterfacesSeen.push_back(IFace);
774 if (!Proto->isThisDeclarationADefinition()) {
778 if (isa<ObjCProtocolDecl>(*DI) &&
779 !cast<ObjCProtocolDecl>(*DI)->isThisDeclarationADefinition() &&
780 StartLoc == (*DI)->getBeginLoc())
786 }
while (DI != DIEnd);
787 RewriteForwardProtocolDecl(DG);
792 HandleTopLevelSingleDecl(*DI);
798 return HandleDeclInMainFile(D);
805 void RewriteModernObjC::RewriteInclude() {
808 const char *MainBufStart = MainBuf.begin();
809 const char *MainBufEnd = MainBuf.end();
810 size_t ImportLen = strlen(
"import");
813 for (
const char *BufPtr = MainBufStart; BufPtr < MainBufEnd; ++BufPtr) {
814 if (*BufPtr ==
'#') {
815 if (++BufPtr == MainBufEnd)
817 while (*BufPtr ==
' ' || *BufPtr ==
'\t')
818 if (++BufPtr == MainBufEnd)
820 if (!strncmp(BufPtr,
"import", ImportLen)) {
824 ReplaceText(ImportLoc, ImportLen,
"include");
833 Result +=
"OBJC_IVAR_$_";
844 std::string IvarOffsetName;
846 ObjCIvarBitfieldGroupOffset(D, IvarOffsetName);
850 std::string S =
"(*(";
853 IvarT = GetGroupRecordTypeForObjCIvarBitfield(D);
855 if (!isa<TypedefType>(IvarT) && IvarT->
isRecordType()) {
864 CDecl = CatDecl->getClassInterface();
865 std::string RecName = CDecl->
getName();
871 unsigned UnsignedIntSize =
874 llvm::APInt(UnsignedIntSize, 0),
876 Zero = NoTypeInfoCStyleCastExpr(Context, PtrStructIMPL, CK_BitCast, Zero);
891 convertObjCTypeToCStyleType(IvarT);
898 S +=
"((char *)self + ";
905 ReferencedIvars[
const_cast<ObjCInterfaceDecl *
>(ClassDecl)].insert(D);
922 static bool objcGetPropertyDefined =
false;
923 static bool objcSetPropertyDefined =
false;
928 InsertText(startLoc,
"// ");
930 assert((*startBuf ==
'@') &&
"bogus @synthesize location");
931 const char *semiBuf = strchr(startBuf,
';');
932 assert((*semiBuf ==
';') &&
"@synthesize: can't find ';'");
943 assert(IMD && OID &&
"Synthesized ivars must be attached to @implementation");
951 if (GenGetProperty && !objcGetPropertyDefined) {
952 objcGetPropertyDefined =
true;
954 Getr =
"\nextern \"C\" __declspec(dllimport) " 955 "id objc_getProperty(id, SEL, long, bool);\n";
962 if (GenGetProperty) {
975 for (
unsigned i = 0, e = FT->getNumParams(); i != e; ++i) {
977 std::string ParamStr =
981 if (FT->isVariadic()) {
982 if (FT->getNumParams())
991 Getr +=
"return (_TYPE)";
992 Getr +=
"objc_getProperty(self, _cmd, ";
993 RewriteIvarOffsetComputation(OID, Getr);
999 InsertText(startGetterSetterLoc, Getr);
1010 if (GenSetProperty && !objcSetPropertyDefined) {
1011 objcSetPropertyDefined =
true;
1013 Setr =
"\nextern \"C\" __declspec(dllimport) " 1014 "void objc_setProperty (id, SEL, long, id, bool, bool);\n";
1022 if (GenSetProperty) {
1023 Setr +=
"objc_setProperty (self, _cmd, ";
1024 RewriteIvarOffsetComputation(OID, Setr);
1042 InsertText(startGetterSetterLoc, Setr);
1046 std::string &typedefString) {
1047 typedefString +=
"\n#ifndef _REWRITER_typedef_";
1049 typedefString +=
"\n";
1050 typedefString +=
"#define _REWRITER_typedef_";
1052 typedefString +=
"\n";
1053 typedefString +=
"typedef struct objc_object ";
1056 typedefString +=
";\ntypedef struct {} _objc_exc_";
1058 typedefString +=
";\n#endif\n";
1061 void RewriteModernObjC::RewriteForwardClassEpilogue(ObjCInterfaceDecl *ClassDecl,
1062 const std::string &typedefString) {
1065 const char *semiPtr = strchr(startBuf,
';');
1067 ReplaceText(startLoc, semiPtr-startBuf+1, typedefString);
1070 void RewriteModernObjC::RewriteForwardClassDecl(
DeclGroupRef D) {
1071 std::string typedefString;
1073 if (ObjCInterfaceDecl *ForwardDecl = dyn_cast<ObjCInterfaceDecl>(*I)) {
1074 if (I == D.
begin()) {
1078 typedefString +=
"// @class ";
1079 typedefString += ForwardDecl->getNameAsString();
1080 typedefString +=
";";
1085 HandleTopLevelSingleDecl(*I);
1088 RewriteForwardClassEpilogue(cast<ObjCInterfaceDecl>(*I), typedefString);
1091 void RewriteModernObjC::RewriteForwardClassDecl(
1093 std::string typedefString;
1094 for (
unsigned i = 0; i < D.size(); i++) {
1095 ObjCInterfaceDecl *ForwardDecl = cast<ObjCInterfaceDecl>(D[i]);
1097 typedefString +=
"// @class ";
1099 typedefString +=
";";
1103 RewriteForwardClassEpilogue(cast<ObjCInterfaceDecl>(D[0]), typedefString);
1106 void RewriteModernObjC::RewriteMethodDeclaration(
ObjCMethodDecl *Method) {
1116 InsertText(LocStart,
"#if 0\n");
1117 ReplaceText(LocEnd, 1,
";\n#endif\n");
1119 InsertText(LocStart,
"// ");
1126 ReplaceText(Loc, 0,
"// ");
1135 ReplaceText(LocStart, 1,
"/** ");
1139 ReplaceText(LocStart, 0,
"// ");
1146 RewriteMethodDeclaration(I);
1148 RewriteMethodDeclaration(I);
1152 strlen(
"@end"),
"/* @end */\n");
1160 ReplaceText(LocStart, 0,
"// ");
1163 RewriteMethodDeclaration(I);
1165 RewriteMethodDeclaration(I);
1171 ReplaceText(LocEnd, strlen(
"@end"),
"/* @end */\n");
1176 for (
const char *p = startBuf; p < endBuf; p++) {
1177 if (*p ==
'@' && !strncmp(p+1,
"optional", strlen(
"optional"))) {
1179 ReplaceText(OptionalLoc, strlen(
"@optional"),
"/* @optional */");
1182 else if (*p ==
'@' && !strncmp(p+1,
"required", strlen(
"required"))) {
1184 ReplaceText(OptionalLoc, strlen(
"@required"),
"/* @required */");
1190 void RewriteModernObjC::RewriteForwardProtocolDecl(
DeclGroupRef D) {
1193 llvm_unreachable(
"Invalid SourceLocation");
1195 ReplaceText(LocStart, 0,
"// ");
1202 llvm_unreachable(
"Invalid SourceLocation");
1204 ReplaceText(LocStart, 0,
"// ");
1207 void RewriteModernObjC::RewriteTypeIntoString(
QualType T, std::string &ResultStr,
1230 void RewriteModernObjC::RewriteObjCMethodDecl(
const ObjCInterfaceDecl *IDecl,
1232 std::string &ResultStr) {
1235 ResultStr +=
"\nstatic ";
1236 RewriteTypeIntoString(OMD->
getReturnType(), ResultStr, FPRetType);
1240 std::string NameStr;
1258 int len = selString.size();
1259 for (
int i = 0; i < len; i++)
1260 if (selString[i] ==
':')
1262 NameStr += selString;
1265 MethodInternalNames[OMD] = NameStr;
1266 ResultStr += NameStr;
1275 if (!LangOpts.MicrosoftExt) {
1276 if (ObjCSynthesizedStructs.count(const_cast<ObjCInterfaceDecl*>(IDecl)))
1277 ResultStr +=
"struct ";
1287 ResultStr +=
" self, ";
1289 ResultStr +=
" _cmd";
1292 for (
const auto *PDecl : OMD->
parameters()) {
1294 if (PDecl->getType()->isObjCQualifiedIdType()) {
1301 (void)convertBlockPointerToFunctionPointer(QT);
1307 ResultStr +=
", ...";
1316 for (
unsigned i = 0, e = FT->getNumParams(); i != e; ++i) {
1317 if (i) ResultStr +=
", ";
1318 std::string ParamStr =
1320 ResultStr += ParamStr;
1322 if (FT->isVariadic()) {
1323 if (FT->getNumParams())
1334 void RewriteModernObjC::RewriteImplementationDecl(
Decl *OID) {
1348 InsertText(CID->getBeginLoc(),
"// ");
1350 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()) {
1362 std::string ResultStr;
1369 ReplaceText(LocStart, endBuf-startBuf, ResultStr);
1371 for (
auto *I : IMD ? IMD->
property_impls() : CID->property_impls())
1372 RewritePropertyImplDecl(I, IMD, CID);
1374 InsertText(IMD ? IMD->
getEndLoc() : CID->getEndLoc(),
"// ");
1377 void RewriteModernObjC::RewriteInterfaceDecl(ObjCInterfaceDecl *ClassDecl) {
1379 if (ObjCSynthesizedStructs.count(ClassDecl))
1383 while (SuperClass) {
1384 RewriteInterfaceDecl(SuperClass);
1387 std::string ResultStr;
1391 RewriteIvarOffsetSymbols(ClassDecl, ResultStr);
1393 RewriteObjCInternalStruct(ClassDecl, ResultStr);
1400 RewriteMethodDeclaration(I);
1402 RewriteMethodDeclaration(I);
1424 DisableReplaceStmtScope S(*
this);
1430 Base = cast<OpaqueValueExpr>(Base)->getSourceExpr();
1431 Base = cast<Expr>(RewriteFunctionBodyOrGlobalInitializer(Base));
1435 for (
unsigned i = 0; i < numArgs; i++) {
1437 if (isa<OpaqueValueExpr>(Arg))
1438 Arg = cast<OpaqueValueExpr>(Arg)->getSourceExpr();
1439 Arg = cast<Expr>(RewriteFunctionBodyOrGlobalInitializer(Arg));
1440 Args.push_back(Arg);
1493 Stmt *Replacement = SynthMessageExpr(NewMsg);
1494 ReplaceStmtWithRange(PseudoOp, Replacement, OldRange);
1511 DisableReplaceStmtScope S(*
this);
1515 Base = cast<OpaqueValueExpr>(Base)->getSourceExpr();
1516 Base = cast<Expr>(RewriteFunctionBodyOrGlobalInitializer(Base));
1519 for (
unsigned i = 0; i < numArgs; i++) {
1521 if (isa<OpaqueValueExpr>(Arg))
1522 Arg = cast<OpaqueValueExpr>(Arg)->getSourceExpr();
1523 Arg = cast<Expr>(RewriteFunctionBodyOrGlobalInitializer(Arg));
1524 Args.push_back(Arg);
1576 Stmt *Replacement = SynthMessageExpr(NewMsg);
1577 ReplaceStmtWithRange(PseudoOp, Replacement, OldRange);
1590 void RewriteModernObjC::SynthCountByEnumWithState(std::string &buf) {
1591 buf +=
"((_WIN_NSUInteger (*) (id, SEL, struct __objcFastEnumerationState *, " 1592 "id *, _WIN_NSUInteger))(void *)objc_msgSend)";
1594 buf +=
"((id)l_collection,\n\t\t";
1595 buf +=
"sel_registerName(\"countByEnumeratingWithState:objects:count:\"),";
1597 buf +=
"&enumState, " 1598 "(id *)__rw_items, (_WIN_NSUInteger)16)";
1605 if (Stmts.empty() || !isa<ObjCForCollectionStmt>(Stmts.back()))
1611 buf =
"goto __break_label_";
1612 buf += utostr(ObjCBcLabelNo.back());
1613 ReplaceText(startLoc, strlen(
"break"), buf);
1618 void RewriteModernObjC::ConvertSourceLocationToLineDirective(
1620 std::string &LineString) {
1621 if (Loc.
isFileID() && GenerateLineInfo) {
1622 LineString +=
"\n#line ";
1624 LineString += utostr(PLoc.
getLine());
1625 LineString +=
" \"";
1627 LineString +=
"\"\n";
1635 if (Stmts.empty() || !isa<ObjCForCollectionStmt>(Stmts.back()))
1641 buf =
"goto __continue_label_";
1642 buf += utostr(ObjCBcLabelNo.back());
1643 ReplaceText(startLoc, strlen(
"continue"), buf);
1682 assert(!Stmts.empty() &&
"ObjCForCollectionStmt - Statement stack empty");
1683 assert(isa<ObjCForCollectionStmt>(Stmts.back()) &&
1684 "ObjCForCollectionStmt Statement stack mismatch");
1685 assert(!ObjCBcLabelNo.empty() &&
1686 "ObjCForCollectionStmt - Label No stack empty");
1690 StringRef elementName;
1691 std::string elementTypeAsString;
1695 ConvertSourceLocationToLineDirective(ForEachLoc, buf);
1699 NamedDecl* D = cast<NamedDecl>(DS->getSingleDecl());
1700 QualType ElementType = cast<ValueDecl>(D)->getType();
1701 if (ElementType->isObjCQualifiedIdType() ||
1702 ElementType->isObjCQualifiedInterfaceType())
1704 elementTypeAsString =
"id";
1707 buf += elementTypeAsString;
1720 elementTypeAsString =
"id";
1726 buf +=
"struct __objcFastEnumerationState enumState = { 0 };\n\t";
1728 buf +=
"id __rw_items[16];\n\t";
1730 buf +=
"id l_collection = (id)";
1732 const char *startCollectionBuf = startBuf;
1733 startCollectionBuf += 3;
1734 startCollectionBuf = strchr(startCollectionBuf,
'(');
1735 startCollectionBuf++;
1737 while (*startCollectionBuf !=
' ' ||
1738 *(startCollectionBuf+1) !=
'i' || *(startCollectionBuf+2) !=
'n' ||
1739 (*(startCollectionBuf+3) !=
' ' &&
1740 *(startCollectionBuf+3) !=
'[' && *(startCollectionBuf+3) !=
'('))
1741 startCollectionBuf++;
1742 startCollectionBuf += 3;
1745 ReplaceText(startLoc, startCollectionBuf - startBuf, buf);
1763 buf +=
"_WIN_NSUInteger limit =\n\t\t";
1764 SynthCountByEnumWithState(buf);
1774 buf +=
"if (limit) {\n\t";
1775 buf +=
"unsigned long startMutations = *enumState.mutationsPtr;\n\t";
1776 buf +=
"do {\n\t\t";
1777 buf +=
"unsigned long counter = 0;\n\t\t";
1778 buf +=
"do {\n\t\t\t";
1779 buf +=
"if (startMutations != *enumState.mutationsPtr)\n\t\t\t\t";
1780 buf +=
"objc_enumerationMutation(l_collection);\n\t\t\t";
1783 buf += elementTypeAsString;
1784 buf +=
")enumState.itemsPtr[counter++];";
1786 ReplaceText(lparenLoc, 1, buf);
1800 buf +=
"__continue_label_";
1801 buf += utostr(ObjCBcLabelNo.back());
1804 buf +=
"} while (counter < limit);\n\t";
1805 buf +=
"} while ((limit = ";
1806 SynthCountByEnumWithState(buf);
1810 buf += elementTypeAsString;
1812 buf +=
"__break_label_";
1813 buf += utostr(ObjCBcLabelNo.back());
1816 buf +=
"else\n\t\t";
1819 buf += elementTypeAsString;
1825 if (isa<CompoundStmt>(S->
getBody())) {
1827 InsertText(endBodyLoc, buf);
1837 const char *semiBuf = strchr(stmtBuf,
';');
1838 assert(semiBuf &&
"Can't find ';'");
1840 InsertText(endBodyLoc, buf);
1843 ObjCBcLabelNo.pop_back();
1848 buf +=
"{ struct _FIN { _FIN(id reth) : rethrow(reth) {}\n";
1849 buf +=
"\t~_FIN() { if (rethrow) objc_exception_throw(rethrow); }\n";
1850 buf +=
"\tid rethrow;\n";
1851 buf +=
"\t} _fin_force_rethow(_rethrow);";
1865 assert((*startBuf ==
'@') &&
"bogus @synchronized location");
1869 ConvertSourceLocationToLineDirective(SynchLoc, buf);
1870 buf +=
"{ id _rethrow = 0; id _sync_obj = (id)";
1872 const char *lparenBuf = startBuf;
1873 while (*lparenBuf !=
'(') lparenBuf++;
1874 ReplaceText(startLoc, lparenBuf-startBuf+1, buf);
1876 buf =
"; objc_sync_enter(_sync_obj);\n";
1877 buf +=
"try {\n\tstruct _SYNC_EXIT { _SYNC_EXIT(id arg) : sync_exit(arg) {}";
1878 buf +=
"\n\t~_SYNC_EXIT() {objc_sync_exit(sync_exit);}";
1879 buf +=
"\n\tid sync_exit;";
1880 buf +=
"\n\t} _sync_exit(_sync_obj);\n";
1887 while (*RParenExprLocBuf !=
')') RParenExprLocBuf--;
1892 assert (*LBraceLocBuf ==
'{');
1893 ReplaceText(RParenExprLoc, (LBraceLocBuf - SM->
getCharacterData(RParenExprLoc) + 1), buf);
1897 "bogus @synchronized block");
1899 buf =
"} catch (id e) {_rethrow = e;}\n";
1904 ReplaceText(startRBraceLoc, 1, buf);
1909 void RewriteModernObjC::WarnAboutReturnGotoStmts(
Stmt *S)
1914 WarnAboutReturnGotoStmts(SubStmt);
1916 if (isa<ReturnStmt>(S) || isa<GotoStmt>(S)) {
1918 TryFinallyContainsReturnDiag);
1924 ReplaceText(startLoc, strlen(
"@autoreleasepool"),
"/* @autoreleasepool */");
1926 "{ __AtAutoreleasePool __autoreleasepool; ");
1936 ConvertSourceLocationToLineDirective(TryLocation, buf);
1940 buf +=
"{ id volatile _rethrow = 0;\n";
1942 buf +=
"{ id volatile _rethrow = 0;\ntry {\n";
1949 assert((*startBuf ==
'@') &&
"bogus @try location");
1951 ReplaceText(startLoc, 1, buf);
1954 ReplaceText(startLoc, 1,
"");
1961 bool AtRemoved =
false;
1966 ObjCInterfaceDecl *IDecl = Ptr->getObjectType()->getInterface();
1972 assert((*startBuf ==
'@') &&
"bogus @catch location");
1980 ReplaceText(startLoc, rParenBuf-startBuf+1, Result);
1991 ReplaceText(lBraceLoc, 1, Result);
1998 ReplaceText(startLoc, 1,
"");
2006 ConvertSourceLocationToLineDirective(FinallyLoc, buf);
2007 buf +=
"catch (id e) {_rethrow = e;}\n";
2011 ConvertSourceLocationToLineDirective(FinallyLoc, buf);
2012 buf +=
"catch (id e) {_rethrow = e;}\n";
2016 ReplaceText(startFinalLoc, 8, buf);
2021 ReplaceText(startFinalBodyLoc, 1, buf);
2024 ReplaceText(endFinalBodyLoc, 1,
"}\n}");
2040 assert((*startBuf ==
'@') &&
"bogus @throw location");
2045 buf =
"objc_exception_throw(";
2050 const char *wBuf = strchr(startBuf,
'w');
2051 assert((*wBuf ==
'w') &&
"@throw: can't find 'w'");
2052 ReplaceText(startLoc, wBuf-startBuf+1, buf);
2056 const char *semiBuf = strchr(endBuf,
';');
2057 assert((*semiBuf ==
';') &&
"@throw: can't find ';'");
2060 ReplaceText(semiLoc, 1,
");");
2066 std::string StrEncoding;
2068 Expr *Replacement = getStringLiteral(StrEncoding);
2069 ReplaceStmt(Exp, Replacement);
2077 if (!SelGetUidFunctionDecl)
2078 SynthSelGetUidFunctionDecl();
2079 assert(SelGetUidFunctionDecl &&
"Can't find sel_registerName() decl");
2083 CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl,
2085 ReplaceStmt(Exp, SelExp);
2091 RewriteModernObjC::SynthesizeCallToFunctionDecl(
FunctionDecl *FD,
2116 const char *&startRef,
const char *&endRef) {
2117 while (startBuf < endBuf) {
2118 if (*startBuf ==
'<')
2119 startRef = startBuf;
2120 if (*startBuf ==
'>') {
2121 if (startRef && *startRef ==
'<') {
2134 while (*argRef !=
')' && (*argRef !=
',' || angle > 0)) {
2137 else if (*argRef ==
'>')
2141 assert(angle == 0 &&
"scanToNextArgument - bad protocol type syntax");
2144 bool RewriteModernObjC::needToScanForQualifiers(
QualType T) {
2157 return needToScanForQualifiers(ElemTy);
2162 void RewriteModernObjC::RewriteObjCQualifiedInterfaceTypes(
Expr *E) {
2164 if (needToScanForQualifiers(Type)) {
2168 Loc = ECE->getLParenLoc();
2169 EndLoc = ECE->getRParenLoc();
2180 const char *startRef =
nullptr, *endRef =
nullptr;
2186 InsertText(LessLoc,
"/*");
2187 InsertText(GreaterLoc,
"*/");
2192 void RewriteModernObjC::RewriteObjCQualifiedInterfaceTypes(
Decl *Dcl) {
2196 if (
VarDecl *VD = dyn_cast<VarDecl>(Dcl)) {
2197 Loc = VD->getLocation();
2198 Type = VD->getType();
2200 else if (
FunctionDecl *FD = dyn_cast<FunctionDecl>(Dcl)) {
2205 assert(funcType &&
"missing function type");
2211 else if (
FieldDecl *FD = dyn_cast<FieldDecl>(Dcl)) {
2216 Loc = TD->getLocation();
2217 Type = TD->getUnderlyingType();
2222 if (needToScanForQualifiers(Type)) {
2226 const char *startBuf = endBuf;
2227 while (*startBuf !=
';' && *startBuf !=
'<' && startBuf != MainFileStart)
2229 const char *startRef =
nullptr, *endRef =
nullptr;
2235 InsertText(LessLoc,
"/*");
2236 InsertText(GreaterLoc,
"*/");
2243 const char *startFuncBuf = startBuf;
2248 const char *endBuf = startBuf;
2251 const char *startRef =
nullptr, *endRef =
nullptr;
2259 InsertText(LessLoc,
"/*");
2260 InsertText(GreaterLoc,
"*/");
2262 startBuf = ++endBuf;
2267 while (*startBuf && *startBuf !=
')' && *startBuf !=
',')
2274 void RewriteModernObjC::RewriteTypeOfDecl(
VarDecl *ND) {
2277 if (!isa<TypeOfExprType>(TypePtr))
2279 while (isa<TypeOfExprType>(TypePtr)) {
2280 const TypeOfExprType *TypeOfExprTypePtr = cast<TypeOfExprType>(TypePtr);
2291 TypeAsString +=
" " + Name +
" = ";
2295 startLoc = ECE->getLParenLoc();
2300 ReplaceText(DeclLoc, endBuf-startBuf-1, TypeAsString);
2306 ReplaceText(DeclLoc, endBuf-startBuf-1, TypeAsString);
2311 void RewriteModernObjC::SynthSelGetUidFunctionDecl() {
2320 SelGetUidIdent, getFuncType,
2324 void RewriteModernObjC::RewriteFunctionDecl(
FunctionDecl *FD) {
2327 FD->
getName() ==
"sel_registerName") {
2328 SelGetUidFunctionDecl = FD;
2331 RewriteObjCQualifiedInterfaceTypes(FD);
2334 void RewriteModernObjC::RewriteBlockPointerType(std::string& Str,
QualType Type) {
2336 const char *argPtr = TypeString.c_str();
2337 if (!strchr(argPtr,
'^')) {
2342 Str += (*argPtr ==
'^' ?
'*' : *argPtr);
2348 void RewriteModernObjC::RewriteBlockPointerTypeVariable(std::string& Str,
2352 const char *argPtr = TypeString.c_str();
2377 void RewriteModernObjC::RewriteBlockLiteralFunctionDecl(
FunctionDecl *FD) {
2383 QualType Type = proto->getReturnType();
2388 unsigned numArgs = proto->getNumParams();
2389 for (
unsigned i = 0; i < numArgs; i++) {
2390 QualType ArgType = proto->getParamType(i);
2391 RewriteBlockPointerType(FdStr, ArgType);
2396 FdStr += (numArgs > 0) ?
", ...);\n" :
"...);\n";
2400 InsertText(FunLocStart, FdStr);
2404 void RewriteModernObjC::SynthSuperConstructorFunctionDecl() {
2405 if (SuperConstructorFunctionDecl)
2410 assert(!argT.
isNull() &&
"Can't find 'id' type");
2411 ArgTys.push_back(argT);
2412 ArgTys.push_back(argT);
2418 msgSendIdent, msgSendType,
2423 void RewriteModernObjC::SynthMsgSendFunctionDecl() {
2427 assert(!argT.
isNull() &&
"Can't find 'id' type");
2428 ArgTys.push_back(argT);
2430 assert(!argT.
isNull() &&
"Can't find 'SEL' type");
2431 ArgTys.push_back(argT);
2437 msgSendIdent, msgSendType,
nullptr,
2442 void RewriteModernObjC::SynthMsgSendSuperFunctionDecl() {
2445 ArgTys.push_back(Context->
VoidTy);
2451 msgSendIdent, msgSendType,
2456 void RewriteModernObjC::SynthMsgSendStretFunctionDecl() {
2460 assert(!argT.
isNull() &&
"Can't find 'id' type");
2461 ArgTys.push_back(argT);
2463 assert(!argT.
isNull() &&
"Can't find 'SEL' type");
2464 ArgTys.push_back(argT);
2470 msgSendIdent, msgSendType,
2476 void RewriteModernObjC::SynthMsgSendSuperStretFunctionDecl() {
2478 &Context->
Idents.
get(
"objc_msgSendSuper_stret");
2480 ArgTys.push_back(Context->
VoidTy);
2487 msgSendType,
nullptr,
2492 void RewriteModernObjC::SynthMsgSendFpretFunctionDecl() {
2496 assert(!argT.
isNull() &&
"Can't find 'id' type");
2497 ArgTys.push_back(argT);
2499 assert(!argT.
isNull() &&
"Can't find 'SEL' type");
2500 ArgTys.push_back(argT);
2506 msgSendIdent, msgSendType,
2511 void RewriteModernObjC::SynthGetClassFunctionDecl() {
2520 getClassIdent, getClassType,
2525 void RewriteModernObjC::SynthGetSuperClassFunctionDecl() {
2527 &Context->
Idents.
get(
"class_getSuperclass");
2536 getClassType,
nullptr,
2541 void RewriteModernObjC::SynthGetMetaClassFunctionDecl() {
2550 getClassIdent, getClassType,
2555 assert (Exp !=
nullptr &&
"Expected non-null ObjCStringLiteral");
2556 QualType strType = getConstantStringStructType();
2558 std::string S =
"__NSConstantStringImpl_";
2560 std::string tmpName = InFileName;
2562 for (i=0; i < tmpName.length(); i++) {
2563 char c = tmpName.at(i);
2570 S += utostr(NumObjCStringLiterals++);
2572 Preamble +=
"static __NSConstantStringImpl " + S;
2573 Preamble +=
" __attribute__ ((section (\"__DATA, __cfstring\"))) = {__CFConstantStringClassReference,";
2574 Preamble +=
"0x000007c8,";
2576 std::string prettyBufS;
2577 llvm::raw_string_ostream prettyBuf(prettyBufS);
2579 Preamble += prettyBuf.str();
2588 Expr *Unop =
new (Context)
2593 CK_CPointerToObjCPointerCast, Unop);
2594 ReplaceStmt(Exp, cast);
2604 llvm::APInt(IntSize, Exp->
getValue()),
2607 CK_BitCast, FlagExp);
2610 ReplaceStmt(Exp, PE);
2616 if (!SelGetUidFunctionDecl)
2617 SynthSelGetUidFunctionDecl();
2619 if (!MsgSendFunctionDecl)
2620 SynthMsgSendFunctionDecl();
2621 if (!GetClassFunctionDecl)
2622 SynthGetClassFunctionDecl();
2637 ClsExprs.push_back(getStringLiteral(clsName->
getName()));
2638 CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl, ClsExprs,
2640 MsgExprs.push_back(Cls);
2647 CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl,
2648 SelExprs, StartLoc, EndLoc);
2649 MsgExprs.push_back(SelExp);
2658 CK = CK_IntegralToBoolean;
2659 subExpr = NoTypeInfoCStyleCastExpr(Context, type, CK, subExpr);
2661 MsgExprs.push_back(subExpr);
2666 for (
const auto PI : BoxingMethod->
parameters())
2667 ArgTypes.push_back(PI->getType());
2682 getSimpleFunctionType(returnType, ArgTypes, BoxingMethod->
isVariadic());
2684 cast = NoTypeInfoCStyleCastExpr(Context, castType, CK_BitCast,
2693 ReplaceStmt(Exp, CE);
2699 if (!SelGetUidFunctionDecl)
2700 SynthSelGetUidFunctionDecl();
2702 if (!MsgSendFunctionDecl)
2703 SynthMsgSendFunctionDecl();
2704 if (!GetClassFunctionDecl)
2705 SynthGetClassFunctionDecl();
2714 getSimpleFunctionType(Context->
VoidTy, IntQT,
true);
2715 std::string NSArrayFName(
"__NSContainer_literal");
2716 FunctionDecl *NSArrayFD = SynthBlockInitFunctionDecl(NSArrayFName);
2722 unsigned UnsignedIntSize =
2725 llvm::APInt(UnsignedIntSize, NumElements),
2727 InitExprs.push_back(count);
2728 for (
unsigned i = 0; i < NumElements; i++)
2730 Expr *NSArrayCallExpr =
2745 NoTypeInfoCStyleCastExpr(Context,
2756 ObjCInterfaceDecl *Class =
2760 ClsExprs.push_back(getStringLiteral(clsName->
getName()));
2761 CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl, ClsExprs,
2763 MsgExprs.push_back(Cls);
2771 CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl,
2772 SelExprs, StartLoc, EndLoc);
2773 MsgExprs.push_back(SelExp);
2776 MsgExprs.push_back(ArrayLiteralObjects);
2780 llvm::APInt(UnsignedIntSize, NumElements),
2782 MsgExprs.push_back(cnt);
2787 for (
const auto *PI : ArrayMethod->
parameters())
2788 ArgTypes.push_back(PI->getType());
2803 getSimpleFunctionType(returnType, ArgTypes, ArrayMethod->
isVariadic());
2805 cast = NoTypeInfoCStyleCastExpr(Context, castType, CK_BitCast,
2814 ReplaceStmt(Exp, CE);
2820 if (!SelGetUidFunctionDecl)
2821 SynthSelGetUidFunctionDecl();
2823 if (!MsgSendFunctionDecl)
2824 SynthMsgSendFunctionDecl();
2825 if (!GetClassFunctionDecl)
2826 SynthGetClassFunctionDecl();
2835 getSimpleFunctionType(Context->
VoidTy, IntQT,
true);
2836 std::string NSDictFName(
"__NSContainer_literal");
2837 FunctionDecl *NSDictFD = SynthBlockInitFunctionDecl(NSDictFName);
2845 unsigned UnsignedIntSize =
2848 llvm::APInt(UnsignedIntSize, NumElements),
2850 KeyExprs.push_back(count);
2851 ValueExprs.push_back(count);
2852 for (
unsigned i = 0; i < NumElements; i++) {
2854 KeyExprs.push_back(Element.
Key);
2855 ValueExprs.push_back(Element.
Value);
2859 Expr *NSValueCallExpr =
2869 MemberExpr *DictLiteralValueME =
new (Context)
2874 NoTypeInfoCStyleCastExpr(Context,
2877 DictLiteralValueME);
2887 NoTypeInfoCStyleCastExpr(Context,
2898 ObjCInterfaceDecl *Class =
2902 ClsExprs.push_back(getStringLiteral(clsName->
getName()));
2903 CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl, ClsExprs,
2905 MsgExprs.push_back(Cls);
2912 CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl,
2913 SelExprs, StartLoc, EndLoc);
2914 MsgExprs.push_back(SelExp);
2917 MsgExprs.push_back(DictValueObjects);
2920 MsgExprs.push_back(DictKeyObjects);
2924 llvm::APInt(UnsignedIntSize, NumElements),
2926 MsgExprs.push_back(cnt);
2931 for (
const auto *PI : DictMethod->
parameters()) {
2935 convertToUnqualifiedObjCType(PointeeTy);
2938 ArgTypes.push_back(T);
2954 getSimpleFunctionType(returnType, ArgTypes, DictMethod->
isVariadic());
2956 cast = NoTypeInfoCStyleCastExpr(Context, castType, CK_BitCast,
2965 ReplaceStmt(Exp, CE);
2972 QualType RewriteModernObjC::getSuperStructType() {
2973 if (!SuperStructDecl) {
2976 &Context->
Idents.
get(
"__rw_objc_super"));
2985 for (
unsigned i = 0; i < 2; ++i) {
2989 FieldTypes[i],
nullptr,
3000 QualType RewriteModernObjC::getConstantStringStructType() {
3001 if (!ConstantStringDecl) {
3004 &Context->
Idents.
get(
"__NSConstantStringImpl"));
3010 FieldTypes[1] = Context->
IntTy;
3014 FieldTypes[3] = Context->
LongTy;
3017 for (
unsigned i = 0; i < 4; ++i) {
3022 FieldTypes[i],
nullptr,
3042 if (!LSD->getRBraceLoc().isValid())
3043 return LSD->getExternLoc();
3046 R.RewriteBlockLiteralFunctionDecl(FD);
3050 void RewriteModernObjC::RewriteLineDirective(
const Decl *D) {
3054 if (Location.
isFileID() && GenerateLineInfo) {
3055 std::string LineString(
"\n#line ");
3057 LineString += utostr(PLoc.
getLine());
3058 LineString +=
" \"";
3060 if (isa<ObjCMethodDecl>(D))
3062 else LineString +=
"\"\n";
3065 if (
const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
3070 if (!LSD->getRBraceLoc().isValid())
3071 Location = LSD->getExternLoc();
3074 InsertText(Location, LineString);
3088 Expr *RewriteModernObjC::SynthMsgSendStretCallExpr(
FunctionDecl *MsgSendStretFlavor,
3094 QualType FuncType = getSimpleFunctionType(
3095 returnType, ArgTypes, Method ? Method->
isVariadic() :
false);
3099 static unsigned stretCount=0;
3100 std::string name =
"__Stret"; name += utostr(stretCount);
3102 "extern \"C\" void * __cdecl memset(void *_Dst, int _Val, size_t _Size);\n";
3103 str +=
"namespace {\n";
3104 str +=
"struct "; str += name;
3107 str +=
"(id receiver, SEL sel";
3108 for (
unsigned i = 2; i < ArgTypes.size(); i++) {
3109 std::string ArgName =
"arg"; ArgName += utostr(i);
3111 str +=
", "; str += ArgName;
3114 for (
unsigned i = ArgTypes.size(); i < MsgExprs.size(); i++) {
3115 std::string ArgName =
"arg"; ArgName += utostr(i);
3116 MsgExprs[i]->getType().getAsStringInternal(ArgName,
3118 str +=
", "; str += ArgName;
3122 str +=
"\t unsigned size = sizeof(";
3125 str +=
"\t if (size == 1 || size == 2 || size == 4 || size == 8)\n";
3128 str +=
")(void *)objc_msgSend)(receiver, sel";
3129 for (
unsigned i = 2; i < ArgTypes.size(); i++) {
3130 str +=
", arg"; str += utostr(i);
3133 for (
unsigned i = ArgTypes.size(); i < MsgExprs.size(); i++) {
3134 str +=
", arg"; str += utostr(i);
3138 str +=
"\t else if (receiver == 0)\n";
3139 str +=
"\t memset((void*)&s, 0, sizeof(s));\n";
3143 str +=
")(void *)objc_msgSend_stret)(receiver, sel";
3144 for (
unsigned i = 2; i < ArgTypes.size(); i++) {
3145 str +=
", arg"; str += utostr(i);
3148 for (
unsigned i = ArgTypes.size(); i < MsgExprs.size(); i++) {
3149 str +=
", arg"; str += utostr(i);
3156 str +=
"};\n};\n\n";
3161 assert(CurMethodDef &&
"SynthMsgSendStretCallExpr - CurMethodDef is null");
3165 InsertText(FunLocStart, str);
3172 ID, FuncType,
nullptr,
SC_Extern,
false,
false);
3181 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 +=
" = ";
3679 llvm::APSInt Val = EC->getInitVal();
3680 Result += Val.toString(10);
3689 convertObjCTypeToCStyleType(Type);
3697 std::string &Result) {
3701 bool EleboratedType = RewriteObjCFieldDeclType(Type, Result);
3702 if (!EleboratedType)
3713 llvm::APInt Dim = CAT->getSize();
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));
4637 CastExpr *FunkCast = NoTypeInfoCStyleCastExpr(Context, PtrToFuncCastType,
4643 BlkExprs.push_back(BlkCast);
4646 E = Exp->
arg_end(); I != E; ++I) {
4647 BlkExprs.push_back(*I);
4667 Stmt *RewriteModernObjC::RewriteBlockDeclRefExpr(
DeclRefExpr *DeclRefExp) {
4684 StringRef Name = VD->
getName();
4698 ReplaceStmt(DeclRefExp, PE);
4705 Stmt *RewriteModernObjC::RewriteLocalVariableExternalStorage(
DeclRefExpr *DRE) {
4707 if (
VarDecl *Var = dyn_cast<VarDecl>(VD))
4708 if (!ImportedLocalExternalDecls.count(Var))
4716 ReplaceStmt(DRE, PE);
4734 const Type* TypePtr = QT->
getAs<Type>();
4735 if (isa<TypeOfExprType>(TypePtr)) {
4736 const TypeOfExprType *TypeOfExprTypePtr = cast<TypeOfExprType>(TypePtr);
4738 std::string TypeAsString =
"(";
4739 RewriteBlockPointerType(TypeAsString, QT);
4740 TypeAsString +=
")";
4741 ReplaceText(LocStart, endBuf-startBuf+1, TypeAsString);
4745 const char *argPtr = startBuf;
4747 while (*argPtr++ && (argPtr < endBuf)) {
4752 ReplaceText(LocStart, 1,
"*");
4758 void RewriteModernObjC::RewriteImplicitCastObjCExpr(
CastExpr *IC) {
4760 if (CastKind != CK_BlockPointerToObjCPointerCast &&
4761 CastKind != CK_AnyPointerToBlockPointerCast)
4765 (void)convertBlockPointerToFunctionPointer(QT);
4767 std::string Str =
"(";
4773 void RewriteModernObjC::RewriteBlockPointerFunctionArgs(
FunctionDecl *FD) {
4775 unsigned parenCount = 0;
4779 const char *startArgList = strchr(startBuf,
'(');
4781 assert((*startArgList ==
'(') &&
"Rewriter fuzzy parser confused");
4786 assert((DeclLoc.
isValid()) &&
"Invalid DeclLoc");
4788 const char *argPtr = startArgList;
4790 while (*argPtr++ && parenCount) {
4795 ReplaceText(DeclLoc, 1,
"*");
4807 bool RewriteModernObjC::PointerTypeTakesAnyBlockArguments(
QualType QT) {
4814 assert(BPT &&
"BlockPointerTypeTakeAnyBlockArguments(): not a block pointer type");
4819 if (isTopLevelBlockPointerType(I))
4825 bool RewriteModernObjC::PointerTypeTakesAnyObjCQualifiedType(
QualType QT) {
4832 assert(BPT &&
"BlockPointerTypeTakeAnyBlockArguments(): not a block pointer type");
4837 if (I->isObjCQualifiedIdType())
4839 if (I->isObjCObjectPointerType() &&
4840 I->getPointeeType()->isObjCQualifiedInterfaceType())
4848 void RewriteModernObjC::GetExtentOfArgList(
const char *Name,
const char *&LParen,
4849 const char *&RParen) {
4850 const char *argPtr = strchr(Name,
'(');
4851 assert((*argPtr ==
'(') &&
"Rewriter fuzzy parser confused");
4855 unsigned parenCount = 1;
4857 while (*argPtr && parenCount) {
4859 case '(': parenCount++;
break;
4860 case ')': parenCount--;
break;
4863 if (parenCount) argPtr++;
4865 assert((*argPtr ==
')') &&
"Rewriter fuzzy parser confused");
4869 void RewriteModernObjC::RewriteBlockPointerDecl(
NamedDecl *ND) {
4871 RewriteBlockPointerFunctionArgs(FD);
4877 if (
VarDecl *VD = dyn_cast<VarDecl>(ND))
4880 DeclT = TDD->getUnderlyingType();
4881 else if (
FieldDecl *FD = dyn_cast<FieldDecl>(ND))
4884 llvm_unreachable(
"RewriteBlockPointerDecl(): Decl type not yet handled");
4887 const char *endBuf = startBuf;
4889 while (*startBuf !=
'^' && *startBuf !=
';' && startBuf != MainFileStart)
4893 unsigned OrigLength=0;
4896 if (*startBuf ==
'^') {
4902 while (*startBuf !=
')') {
4910 if (PointerTypeTakesAnyBlockArguments(DeclT) ||
4911 PointerTypeTakesAnyObjCQualifiedType(DeclT)) {
4916 const char *argListBegin, *argListEnd;
4917 GetExtentOfArgList(startBuf, argListBegin, argListEnd);
4918 while (argListBegin < argListEnd) {
4919 if (*argListBegin ==
'^')
4921 else if (*argListBegin ==
'<') {
4923 buf += *argListBegin++;
4925 while (*argListBegin !=
'>') {
4926 buf += *argListBegin++;
4929 buf += *argListBegin;
4933 buf += *argListBegin;
4940 ReplaceText(Start, OrigLength, buf);
4963 std::string RewriteModernObjC::SynthesizeByrefCopyDestroyHelper(
VarDecl *VD,
4966 if (CopyDestroyCache.count(flag))
4968 CopyDestroyCache.insert(flag);
4969 S =
"static void __Block_byref_id_object_copy_";
4971 S +=
"(void *dst, void *src) {\n";
4977 unsigned VoidPtrSize =
4980 unsigned offset = (VoidPtrSize*4 + IntSize + IntSize)/Context->
getCharWidth();
4981 S +=
" _Block_object_assign((char*)dst + ";
4982 S += utostr(offset);
4983 S +=
", *(void * *) ((char*)src + ";
4984 S += utostr(offset);
4989 S +=
"static void __Block_byref_id_object_dispose_";
4991 S +=
"(void *src) {\n";
4992 S +=
" _Block_object_dispose(*(void * *) ((char*)src + ";
4993 S += utostr(offset);
5018 void RewriteModernObjC::RewriteByRefVar(
VarDecl *ND,
bool firstDecl,
5032 std::string ByrefType;
5033 RewriteByRefString(ByrefType, Name, ND,
true);
5034 ByrefType +=
" {\n";
5035 ByrefType +=
" void *__isa;\n";
5036 RewriteByRefString(ByrefType, Name, ND);
5037 ByrefType +=
" *__forwarding;\n";
5038 ByrefType +=
" int __flags;\n";
5039 ByrefType +=
" int __size;\n";
5044 if (HasCopyAndDispose) {
5045 ByrefType +=
" void (*__Block_byref_id_object_copy)(void*, void*);\n";
5046 ByrefType +=
" void (*__Block_byref_id_object_dispose)(void*);\n";
5050 (void)convertBlockPointerToFunctionPointer(T);
5053 ByrefType +=
" " + Name +
";\n";
5054 ByrefType +=
"};\n";
5060 assert(CurMethodDef &&
"RewriteByRefVar - CurMethodDef is null");
5063 InsertText(FunLocStart, ByrefType);
5069 if (HasCopyAndDispose) {
5077 std::string HF = SynthesizeByrefCopyDestroyHelper(ND, flag);
5085 bool hasInit = (ND->
getInit() !=
nullptr);
5096 if (HasCopyAndDispose)
5100 RewriteByRefString(ByrefType, Name, ND);
5101 std::string ForwardingCastType(
"(");
5102 ForwardingCastType += ByrefType +
" *)";
5103 ByrefType +=
" " + Name +
" = {(void*)";
5104 ByrefType += utostr(isa);
5105 ByrefType +=
"," + ForwardingCastType +
"&" + Name +
", ";
5106 ByrefType += utostr(flags);
5108 ByrefType +=
"sizeof(";
5109 RewriteByRefString(ByrefType, Name, ND);
5111 if (HasCopyAndDispose) {
5112 ByrefType +=
", __Block_byref_id_object_copy_";
5113 ByrefType += utostr(flag);
5114 ByrefType +=
", __Block_byref_id_object_dispose_";
5115 ByrefType += utostr(flag);
5124 const char *commaBuf = startDeclBuf;
5125 while (*commaBuf !=
',')
5127 assert((*commaBuf ==
',') &&
"RewriteByRefVar: can't find ','");
5129 startBuf = commaBuf;
5133 ByrefType +=
"};\n";
5134 unsigned nameSize = Name.size();
5139 ReplaceText(DeclLoc, endBuf-startBuf+nameSize, ByrefType);
5146 startLoc = ECE->getLParenLoc();
5151 ReplaceText(DeclLoc, endBuf-startBuf, ByrefType);
5153 const char separator = lastDecl ?
';' :
',';
5155 const char *separatorBuf = strchr(startInitializerBuf, separator);
5156 assert((*separatorBuf == separator) &&
5157 "RewriteByRefVar: can't find ';' or ','");
5161 InsertText(separatorLoc, lastDecl ?
"}" :
"};\n");
5165 void RewriteModernObjC::CollectBlockDeclRefInfo(
BlockExpr *Exp) {
5167 GetBlockDeclRefExprs(Exp->
getBody());
5168 if (BlockDeclRefs.size()) {
5170 for (
unsigned i = 0; i < BlockDeclRefs.size(); i++)
5171 if (!BlockDeclRefs[i]->getDecl()->hasAttr<BlocksAttr>()) {
5172 if (!BlockByCopyDeclsPtrSet.count(BlockDeclRefs[i]->getDecl())) {
5173 BlockByCopyDeclsPtrSet.insert(BlockDeclRefs[i]->getDecl());
5174 BlockByCopyDecls.push_back(BlockDeclRefs[i]->getDecl());
5178 for (
unsigned i = 0; i < BlockDeclRefs.size(); i++)
5179 if (BlockDeclRefs[i]->getDecl()->hasAttr<BlocksAttr>()) {
5180 if (!BlockByRefDeclsPtrSet.count(BlockDeclRefs[i]->getDecl())) {
5181 BlockByRefDeclsPtrSet.insert(BlockDeclRefs[i]->getDecl());
5182 BlockByRefDecls.push_back(BlockDeclRefs[i]->getDecl());
5186 for (
unsigned i = 0; i < BlockDeclRefs.size(); i++)
5187 if (BlockDeclRefs[i]->getDecl()->hasAttr<BlocksAttr>() ||
5188 BlockDeclRefs[i]->getType()->isObjCObjectPointerType() ||
5189 BlockDeclRefs[i]->getType()->isBlockPointerType())
5190 ImportedBlockDecls.insert(BlockDeclRefs[i]->getDecl());
5194 FunctionDecl *RewriteModernObjC::SynthBlockInitFunctionDecl(StringRef name) {
5206 Blocks.push_back(Exp);
5208 CollectBlockDeclRefInfo(Exp);
5211 int countOfInnerDecls = 0;
5212 if (!InnerBlockDeclRefs.empty()) {
5213 for (
unsigned i = 0; i < InnerBlockDeclRefs.size(); i++) {
5216 if (!VD->
hasAttr<BlocksAttr>() && !BlockByCopyDeclsPtrSet.count(VD)) {
5220 InnerDeclRefs.push_back(Exp); countOfInnerDecls++;
5221 BlockDeclRefs.push_back(Exp);
5222 BlockByCopyDeclsPtrSet.insert(VD);
5223 BlockByCopyDecls.push_back(VD);
5225 if (VD->
hasAttr<BlocksAttr>() && !BlockByRefDeclsPtrSet.count(VD)) {
5226 InnerDeclRefs.push_back(Exp); countOfInnerDecls++;
5227 BlockDeclRefs.push_back(Exp);
5228 BlockByRefDeclsPtrSet.insert(VD);
5229 BlockByRefDecls.push_back(VD);
5233 for (
unsigned i = 0; i < InnerBlockDeclRefs.size(); i++)
5234 if (InnerBlockDeclRefs[i]->getDecl()->hasAttr<BlocksAttr>() ||
5235 InnerBlockDeclRefs[i]->getType()->isObjCObjectPointerType() ||
5236 InnerBlockDeclRefs[i]->getType()->isBlockPointerType())
5237 ImportedBlockDecls.insert(InnerBlockDeclRefs[i]->getDecl());
5239 InnerDeclRefsCount.push_back(countOfInnerDecls);
5241 std::string FuncName;
5245 else if (CurMethodDef)
5247 else if (GlobalVarDecl)
5250 bool GlobalBlockExpr =
5253 if (GlobalBlockExpr && !GlobalVarDecl) {
5255 GlobalBlockExpr =
false;
5258 std::string BlockNumber = utostr(Blocks.size()-1);
5260 std::string Func =
"__" + FuncName +
"_block_func_" + BlockNumber;
5272 if (GlobalBlockExpr)
5276 Tag += FuncName +
"_block_impl_" + BlockNumber;
5278 FD = SynthBlockInitFunctionDecl(Tag);
5285 FD = SynthBlockInitFunctionDecl(Func);
5290 InitExprs.push_back(castExpr);
5293 std::string DescData =
"__" + FuncName +
"_block_desc_" + BlockNumber +
"_DATA";
5303 InitExprs.push_back(DescRefExpr);
5306 if (BlockDeclRefs.size()) {
5310 E = BlockByCopyDecls.end(); I != E; ++I) {
5311 if (isObjCType((*I)->getType())) {
5313 FD = SynthBlockInitFunctionDecl((*I)->getName());
5323 }
else if (isTopLevelBlockPointerType((*I)->getType())) {
5324 FD = SynthBlockInitFunctionDecl((*I)->getName());
5327 Exp = NoTypeInfoCStyleCastExpr(Context, Context->
VoidPtrTy,
5330 FD = SynthBlockInitFunctionDecl((*I)->getName());
5342 InitExprs.push_back(Exp);
5346 E = BlockByRefDecls.end(); I != E; ++I) {
5349 std::string RecName;
5350 RewriteByRefString(RecName, Name, ND,
true);
5352 +
sizeof(
"struct"));
5356 assert(RD &&
"SynthBlockInitExpr(): Can't find RecordDecl");
5359 FD = SynthBlockInitFunctionDecl((*I)->getName());
5362 bool isNestedCapturedVar =
false;
5364 for (
const auto &CI : block->
captures()) {
5365 const VarDecl *variable = CI.getVariable();
5366 if (variable == ND && CI.isNested()) {
5367 assert (CI.isByRef() &&
5368 "SynthBlockInitExpr - captured block variable is not byref");
5369 isNestedCapturedVar =
true;
5375 if (!isNestedCapturedVar)
5380 Exp = NoTypeInfoCStyleCastExpr(Context, castT, CK_BitCast, Exp);
5381 InitExprs.push_back(Exp);
5384 if (ImportedBlockDecls.size()) {
5391 InitExprs.push_back(FlagExp);
5396 if (GlobalBlockExpr) {
5397 assert (!GlobalConstructionExp &&
5398 "SynthBlockInitExpr - GlobalConstructionExp must be null");
5399 GlobalConstructionExp = NewRep;
5406 NewRep = NoTypeInfoCStyleCastExpr(Context, FType, CK_BitCast,
5412 BlockDeclRefs.clear();
5413 BlockByRefDecls.clear();
5414 BlockByRefDeclsPtrSet.clear();
5415 BlockByCopyDecls.clear();
5416 BlockByCopyDeclsPtrSet.clear();
5417 ImportedBlockDecls.clear();
5421 bool RewriteModernObjC::IsDeclStmtInForeachHeader(
DeclStmt *DS) {
5423 dyn_cast<ObjCForCollectionStmt>(Stmts.back()))
5424 return CS->getElement() == DS;
5432 Stmt *RewriteModernObjC::RewriteFunctionBodyOrGlobalInitializer(
Stmt *S) {
5433 if (isa<SwitchStmt>(S) || isa<WhileStmt>(S) ||
5434 isa<DoStmt>(S) || isa<ForStmt>(S))
5436 else if (isa<ObjCForCollectionStmt>(S)) {
5438 ObjCBcLabelNo.push_back(++BcLabelCount);
5445 return RewritePropertyOrImplicitSetter(PseudoOp);
5447 return RewritePropertyOrImplicitGetter(PseudoOp);
5449 }
else if (
ObjCIvarRefExpr *IvarRefExpr = dyn_cast<ObjCIvarRefExpr>(S)) {
5450 return RewriteObjCIvarRefExpr(IvarRefExpr);
5452 else if (isa<OpaqueValueExpr>(S))
5453 S = cast<OpaqueValueExpr>(S)->getSourceExpr();
5460 Stmt *newStmt = RewriteFunctionBodyOrGlobalInitializer(childStmt);
5462 childStmt = newStmt;
5466 if (
BlockExpr *BE = dyn_cast<BlockExpr>(S)) {
5468 llvm::SmallPtrSet<const DeclContext *, 8> InnerContexts;
5469 InnerContexts.insert(BE->getBlockDecl());
5470 ImportedLocalExternalDecls.clear();
5471 GetInnerBlockDeclRefExprs(BE->getBody(),
5472 InnerBlockDeclRefs, InnerContexts);
5474 Stmt *SaveCurrentBody = CurrentBody;
5475 CurrentBody = BE->getBody();
5476 PropParentMap =
nullptr;
5482 bool saveDisableReplaceStmt = DisableReplaceStmt;
5483 DisableReplaceStmt =
false;
5484 RewriteFunctionBodyOrGlobalInitializer(BE->getBody());
5485 DisableReplaceStmt = saveDisableReplaceStmt;
5486 CurrentBody = SaveCurrentBody;
5487 PropParentMap =
nullptr;
5488 ImportedLocalExternalDecls.clear();
5491 RewrittenBlockExprs[BE] = Str;
5493 Stmt *blockTranscribed = SynthBlockInitExpr(BE, InnerBlockDeclRefs);
5496 ReplaceStmt(S, blockTranscribed);
5497 return blockTranscribed;
5501 return RewriteAtEncode(AtEncode);
5504 return RewriteAtSelector(AtSelector);
5507 return RewriteObjCStringLiteral(AtString);
5510 return RewriteObjCBoolLiteralExpr(BoolLitExpr);
5513 return RewriteObjCBoxedExpr(BoxedExpr);
5516 return RewriteObjCArrayLiteralExpr(ArrayLitExpr);
5519 dyn_cast<ObjCDictionaryLiteral>(S))
5520 return RewriteObjCDictionaryLiteralExpr(DictionaryLitExpr);
5531 std::string messString;
5532 messString +=
"// ";
5533 messString.append(startBuf, endBuf-startBuf+1);
5542 return RewriteMessageExpr(MessExpr);
5546 dyn_cast<ObjCAutoreleasePoolStmt>(S)) {
5547 return RewriteObjCAutoreleasePoolStmt(StmtAutoRelease);
5551 return RewriteObjCTryStmt(StmtTry);
5554 return RewriteObjCSynchronizedStmt(StmtTry);
5557 return RewriteObjCThrowStmt(StmtThrow);
5560 return RewriteObjCProtocolExpr(ProtocolExp);
5563 dyn_cast<ObjCForCollectionStmt>(S))
5564 return RewriteObjCForCollectionStmt(StmtForCollection,
5567 dyn_cast<BreakStmt>(S))
5568 return RewriteBreakStmt(StmtBreakStmt);
5570 dyn_cast<ContinueStmt>(S))
5571 return RewriteContinueStmt(StmtContinueStmt);
5575 if (
DeclStmt *DS = dyn_cast<DeclStmt>(S)) {
5585 if (Stmts.empty() || !IsDeclStmtInForeachHeader(DS))
5586 RewriteObjCQualifiedInterfaceTypes(*DS->
decl_begin());
5592 if (
ValueDecl *ND = dyn_cast<ValueDecl>(SD)) {
5593 if (isTopLevelBlockPointerType(ND->
getType()))
5594 RewriteBlockPointerDecl(ND);
5596 CheckFunctionPointerDecl(ND->
getType(), ND);
5597 if (
VarDecl *VD = dyn_cast<VarDecl>(SD)) {
5598 if (VD->
hasAttr<BlocksAttr>()) {
5599 static unsigned uniqueByrefDeclCount = 0;
5600 assert(!BlockByRefDeclNo.count(ND) &&
5601 "RewriteFunctionBodyOrGlobalInitializer: Duplicate byref decl");
5602 BlockByRefDeclNo[ND] = uniqueByrefDeclCount++;
5603 RewriteByRefVar(VD, (DI == DS->
decl_begin()), ((DI+1) == DE));
5606 RewriteTypeOfDecl(VD);
5610 if (isTopLevelBlockPointerType(TD->getUnderlyingType()))
5611 RewriteBlockPointerDecl(TD);
5612 else if (TD->getUnderlyingType()->isFunctionPointerType())
5613 CheckFunctionPointerDecl(TD->getUnderlyingType(), TD);
5619 RewriteObjCQualifiedInterfaceTypes(CE);
5621 if (isa<SwitchStmt>(S) || isa<WhileStmt>(S) ||
5622 isa<DoStmt>(S) || isa<ForStmt>(S)) {
5623 assert(!Stmts.empty() &&
"Statement stack is empty");
5624 assert ((isa<SwitchStmt>(Stmts.back()) || isa<WhileStmt>(Stmts.back()) ||
5625 isa<DoStmt>(Stmts.back()) || isa<ForStmt>(Stmts.back()))
5626 &&
"Statement stack mismatch");
5630 if (
DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(S)) {
5632 if (VD->
hasAttr<BlocksAttr>())
5633 return RewriteBlockDeclRefExpr(DRE);
5635 return RewriteLocalVariableExternalStorage(DRE);
5638 if (
CallExpr *CE = dyn_cast<CallExpr>(S)) {
5641 ReplaceStmt(S, BlockCall);
5646 RewriteCastExpr(CE);
5649 RewriteImplicitCastObjCExpr(ICE);
5659 llvm::raw_string_ostream Buf(SStr);
5661 const std::string &Str = Buf.str();
5663 printf(
"CAST = %s\n", &Str[0]);
5664 InsertText(ICE->getSubExpr()->getBeginLoc(), Str);
5673 void RewriteModernObjC::RewriteRecordBody(
RecordDecl *RD) {
5674 for (
auto *FD : RD->
fields()) {
5675 if (isTopLevelBlockPointerType(FD->
getType()))
5676 RewriteBlockPointerDecl(FD);
5679 RewriteObjCQualifiedInterfaceTypes(FD);
5685 void RewriteModernObjC::HandleDeclInMainFile(
Decl *D) {
5695 RewriteBlocksInFunctionProtoType(FD->
getType(), FD);
5702 CurFunctionDef = FD;
5705 cast_or_null<CompoundStmt>(RewriteFunctionBodyOrGlobalInitializer(Body));
5707 CurrentBody =
nullptr;
5708 if (PropParentMap) {
5709 delete PropParentMap;
5710 PropParentMap =
nullptr;
5714 InsertBlockLiteralsWithinFunction(FD);
5715 RewriteLineDirective(D);
5716 CurFunctionDef =
nullptr;
5720 case Decl::ObjCMethod: {
5726 cast_or_null<CompoundStmt>(RewriteFunctionBodyOrGlobalInitializer(Body));
5728 CurrentBody =
nullptr;
5729 if (PropParentMap) {
5730 delete PropParentMap;
5731 PropParentMap =
nullptr;
5733 InsertBlockLiteralsWithinMethod(MD);
5734 RewriteLineDirective(D);
5735 CurMethodDef =
nullptr;
5739 case Decl::ObjCImplementation: {
5741 ClassImplementation.push_back(CI);
5744 case Decl::ObjCCategoryImpl: {
5746 CategoryImplementation.push_back(CI);
5750 VarDecl *VD = cast<VarDecl>(D);
5751 RewriteObjCQualifiedInterfaceTypes(VD);
5752 if (isTopLevelBlockPointerType(VD->
getType()))
5753 RewriteBlockPointerDecl(VD);
5755 CheckFunctionPointerDecl(VD->
getType(), VD);
5758 RewriteCastExpr(CE);
5764 RewriteRecordBody(RD);
5769 RewriteFunctionBodyOrGlobalInitializer(VD->
getInit());
5770 CurrentBody =
nullptr;
5771 if (PropParentMap) {
5772 delete PropParentMap;
5773 PropParentMap =
nullptr;
5776 GlobalVarDecl =
nullptr;
5780 RewriteCastExpr(CE);
5785 case Decl::TypeAlias:
5786 case Decl::Typedef: {
5788 if (isTopLevelBlockPointerType(TD->getUnderlyingType()))
5789 RewriteBlockPointerDecl(TD);
5790 else if (TD->getUnderlyingType()->isFunctionPointerType())
5791 CheckFunctionPointerDecl(TD->getUnderlyingType(), TD);
5793 RewriteObjCQualifiedInterfaceTypes(TD);
5797 case Decl::CXXRecord:
5798 case Decl::Record: {
5801 RewriteRecordBody(RD);
5815 std::string &Result) {
5818 Result +=
"static ";
5819 Result +=
"struct _protocol_t *";
5820 Result +=
"_OBJC_PROTOCOL_REFERENCE_$_";
5827 void RewriteModernObjC::HandleTranslationUnit(
ASTContext &
C) {
5833 for (
unsigned i = 0, e = FunctionDefinitionsSeen.size(); i < e; i++) {
5838 HandleTopLevelSingleDecl(FDecl);
5844 RewriteObjCProtocolMetaData(ProtDecl, Preamble);
5850 if (ClassImplementation.size() || CategoryImplementation.size())
5851 RewriteImplementations();
5853 for (
unsigned i = 0, e = ObjCInterfacesSeen.size(); i < e; i++) {
5854 ObjCInterfaceDecl *CDecl = ObjCInterfacesSeen[i];
5859 RewriteInterfaceDecl(CDecl);
5867 *OutFile << std::string(RewriteBuf->begin(), RewriteBuf->end());
5869 llvm::errs() <<
"No changes\n";
5872 if (ClassImplementation.size() || CategoryImplementation.size() ||
5873 ProtocolExprDecls.size()) {
5875 std::string ResultStr;
5876 RewriteMetaDataIntoBuffer(ResultStr);
5878 *OutFile << ResultStr;
5882 std::string ResultStr;
5883 WriteImageInfo(ResultStr);
5884 *OutFile << ResultStr;
5889 void RewriteModernObjC::Initialize(
ASTContext &context) {
5890 InitializeCommon(context);
5892 Preamble +=
"#ifndef __OBJC2__\n";
5893 Preamble +=
"#define __OBJC2__\n";
5894 Preamble +=
"#endif\n";
5899 Preamble =
"#pragma once\n";
5900 Preamble +=
"struct objc_selector; struct objc_class;\n";
5901 Preamble +=
"struct __rw_objc_super { \n\tstruct objc_object *object; ";
5902 Preamble +=
"\n\tstruct objc_object *superClass; ";
5904 Preamble +=
"\n\t__rw_objc_super(struct objc_object *o, struct objc_object *s) ";
5905 Preamble +=
": object(o), superClass(s) {} ";
5906 Preamble +=
"\n};\n";
5908 if (LangOpts.MicrosoftExt) {
5911 Preamble +=
"\n#pragma section(\".objc_classlist$B\", long, read, write)\n";
5912 Preamble +=
"#pragma section(\".objc_catlist$B\", long, read, write)\n";
5913 Preamble +=
"#pragma section(\".objc_imageinfo$B\", long, read, write)\n";
5914 Preamble +=
"#pragma section(\".objc_nlclslist$B\", long, read, write)\n";
5915 Preamble +=
"#pragma section(\".objc_nlcatlist$B\", long, read, write)\n";
5917 Preamble +=
"#pragma section(\".cat_cls_meth$B\", long, read, write)\n";
5918 Preamble +=
"#pragma section(\".inst_meth$B\", long, read, write)\n";
5919 Preamble +=
"#pragma section(\".cls_meth$B\", long, read, write)\n";
5920 Preamble +=
"#pragma section(\".objc_ivar$B\", long, read, write)\n";
5924 Preamble +=
"#pragma section(\".objc_selrefs$B\", long, read, write)\n";
5925 Preamble +=
"#pragma section(\".objc_classrefs$B\", long, read, write)\n";
5926 Preamble +=
"#pragma section(\".objc_superrefs$B\", long, read, write)\n";
5929 Preamble +=
"#ifndef _REWRITER_typedef_Protocol\n";
5930 Preamble +=
"typedef struct objc_object Protocol;\n";
5931 Preamble +=
"#define _REWRITER_typedef_Protocol\n";
5932 Preamble +=
"#endif\n";
5933 if (LangOpts.MicrosoftExt) {
5934 Preamble +=
"#define __OBJC_RW_DLLIMPORT extern \"C\" __declspec(dllimport)\n";
5935 Preamble +=
"#define __OBJC_RW_STATICIMPORT extern \"C\"\n";
5938 Preamble +=
"#define __OBJC_RW_DLLIMPORT extern\n";
5940 Preamble +=
"__OBJC_RW_DLLIMPORT void objc_msgSend(void);\n";
5941 Preamble +=
"__OBJC_RW_DLLIMPORT void objc_msgSendSuper(void);\n";
5942 Preamble +=
"__OBJC_RW_DLLIMPORT void objc_msgSend_stret(void);\n";
5943 Preamble +=
"__OBJC_RW_DLLIMPORT void objc_msgSendSuper_stret(void);\n";
5944 Preamble +=
"__OBJC_RW_DLLIMPORT void objc_msgSend_fpret(void);\n";
5946 Preamble +=
"__OBJC_RW_DLLIMPORT struct objc_class *objc_getClass";
5947 Preamble +=
"(const char *);\n";
5948 Preamble +=
"__OBJC_RW_DLLIMPORT struct objc_class *class_getSuperclass";
5949 Preamble +=
"(struct objc_class *);\n";
5950 Preamble +=
"__OBJC_RW_DLLIMPORT struct objc_class *objc_getMetaClass";
5951 Preamble +=
"(const char *);\n";
5952 Preamble +=
"__OBJC_RW_DLLIMPORT void objc_exception_throw( struct objc_object *);\n";
5954 Preamble +=
"__OBJC_RW_DLLIMPORT int objc_sync_enter( struct objc_object *);\n";
5955 Preamble +=
"__OBJC_RW_DLLIMPORT int objc_sync_exit( struct objc_object *);\n";
5956 Preamble +=
"__OBJC_RW_DLLIMPORT Protocol *objc_getProtocol(const char *);\n";
5957 Preamble +=
"#ifdef _WIN64\n";
5958 Preamble +=
"typedef unsigned long long _WIN_NSUInteger;\n";
5959 Preamble +=
"#else\n";
5960 Preamble +=
"typedef unsigned int _WIN_NSUInteger;\n";
5961 Preamble +=
"#endif\n";
5962 Preamble +=
"#ifndef __FASTENUMERATIONSTATE\n";
5963 Preamble +=
"struct __objcFastEnumerationState {\n\t";
5964 Preamble +=
"unsigned long state;\n\t";
5965 Preamble +=
"void **itemsPtr;\n\t";
5966 Preamble +=
"unsigned long *mutationsPtr;\n\t";
5967 Preamble +=
"unsigned long extra[5];\n};\n";
5968 Preamble +=
"__OBJC_RW_DLLIMPORT void objc_enumerationMutation(struct objc_object *);\n";
5969 Preamble +=
"#define __FASTENUMERATIONSTATE\n";
5970 Preamble +=
"#endif\n";
5971 Preamble +=
"#ifndef __NSCONSTANTSTRINGIMPL\n";
5972 Preamble +=
"struct __NSConstantStringImpl {\n";
5973 Preamble +=
" int *isa;\n";
5974 Preamble +=
" int flags;\n";
5975 Preamble +=
" char *str;\n";
5976 Preamble +=
"#if _WIN64\n";
5977 Preamble +=
" long long length;\n";
5978 Preamble +=
"#else\n";
5979 Preamble +=
" long length;\n";
5980 Preamble +=
"#endif\n";
5982 Preamble +=
"#ifdef CF_EXPORT_CONSTANT_STRING\n";
5983 Preamble +=
"extern \"C\" __declspec(dllexport) int __CFConstantStringClassReference[];\n";
5984 Preamble +=
"#else\n";
5985 Preamble +=
"__OBJC_RW_DLLIMPORT int __CFConstantStringClassReference[];\n";
5986 Preamble +=
"#endif\n";
5987 Preamble +=
"#define __NSCONSTANTSTRINGIMPL\n";
5988 Preamble +=
"#endif\n";
5990 Preamble +=
"#ifndef BLOCK_IMPL\n";
5991 Preamble +=
"#define BLOCK_IMPL\n";
5992 Preamble +=
"struct __block_impl {\n";
5993 Preamble +=
" void *isa;\n";
5994 Preamble +=
" int Flags;\n";
5995 Preamble +=
" int Reserved;\n";
5996 Preamble +=
" void *FuncPtr;\n";
5998 Preamble +=
"// Runtime copy/destroy helper functions (from Block_private.h)\n";
5999 Preamble +=
"#ifdef __OBJC_EXPORT_BLOCKS\n";
6000 Preamble +=
"extern \"C\" __declspec(dllexport) " 6001 "void _Block_object_assign(void *, const void *, const int);\n";
6002 Preamble +=
"extern \"C\" __declspec(dllexport) void _Block_object_dispose(const void *, const int);\n";
6003 Preamble +=
"extern \"C\" __declspec(dllexport) void *_NSConcreteGlobalBlock[32];\n";
6004 Preamble +=
"extern \"C\" __declspec(dllexport) void *_NSConcreteStackBlock[32];\n";
6005 Preamble +=
"#else\n";
6006 Preamble +=
"__OBJC_RW_DLLIMPORT void _Block_object_assign(void *, const void *, const int);\n";
6007 Preamble +=
"__OBJC_RW_DLLIMPORT void _Block_object_dispose(const void *, const int);\n";
6008 Preamble +=
"__OBJC_RW_DLLIMPORT void *_NSConcreteGlobalBlock[32];\n";
6009 Preamble +=
"__OBJC_RW_DLLIMPORT void *_NSConcreteStackBlock[32];\n";
6010 Preamble +=
"#endif\n";
6011 Preamble +=
"#endif\n";
6012 if (LangOpts.MicrosoftExt) {
6013 Preamble +=
"#undef __OBJC_RW_DLLIMPORT\n";
6014 Preamble +=
"#undef __OBJC_RW_STATICIMPORT\n";
6015 Preamble +=
"#ifndef KEEP_ATTRIBUTES\n";
6016 Preamble +=
"#define __attribute__(X)\n";
6017 Preamble +=
"#endif\n";
6018 Preamble +=
"#ifndef __weak\n";
6019 Preamble +=
"#define __weak\n";
6020 Preamble +=
"#endif\n";
6021 Preamble +=
"#ifndef __block\n";
6022 Preamble +=
"#define __block\n";
6023 Preamble +=
"#endif\n";
6026 Preamble +=
"#define __block\n";
6027 Preamble +=
"#define __weak\n";
6031 Preamble +=
"\n#include <stdarg.h>\n";
6032 Preamble +=
"struct __NSContainer_literal {\n";
6033 Preamble +=
" void * *arr;\n";
6034 Preamble +=
" __NSContainer_literal (unsigned int count, ...) {\n";
6035 Preamble +=
"\tva_list marker;\n";
6036 Preamble +=
"\tva_start(marker, count);\n";
6037 Preamble +=
"\tarr = new void *[count];\n";
6038 Preamble +=
"\tfor (unsigned i = 0; i < count; i++)\n";
6039 Preamble +=
"\t arr[i] = va_arg(marker, void *);\n";
6040 Preamble +=
"\tva_end( marker );\n";
6041 Preamble +=
" };\n";
6042 Preamble +=
" ~__NSContainer_literal() {\n";
6043 Preamble +=
"\tdelete[] arr;\n";
6048 Preamble +=
"extern \"C\" __declspec(dllimport) void * objc_autoreleasePoolPush(void);\n";
6049 Preamble +=
"extern \"C\" __declspec(dllimport) void objc_autoreleasePoolPop(void *);\n\n";
6050 Preamble +=
"struct __AtAutoreleasePool {\n";
6051 Preamble +=
" __AtAutoreleasePool() {atautoreleasepoolobj = objc_autoreleasePoolPush();}\n";
6052 Preamble +=
" ~__AtAutoreleasePool() {objc_autoreleasePoolPop(atautoreleasepoolobj);}\n";
6053 Preamble +=
" void * atautoreleasepoolobj;\n";
6058 Preamble +=
"\n#define __OFFSETOFIVAR__(TYPE, MEMBER) ((long long) &((TYPE *)0)->MEMBER)\n";
6063 void RewriteModernObjC::RewriteIvarOffsetComputation(
ObjCIvarDecl *ivar,
6064 std::string &Result) {
6065 Result +=
"__OFFSETOFIVAR__(struct ";
6067 if (LangOpts.MicrosoftExt)
6071 ObjCIvarBitfieldGroupDecl(ivar, Result);
6180 static bool meta_data_declared =
false;
6181 if (meta_data_declared)
6184 Result +=
"\nstruct _prop_t {\n";
6185 Result +=
"\tconst char *name;\n";
6186 Result +=
"\tconst char *attributes;\n";
6189 Result +=
"\nstruct _protocol_t;\n";
6191 Result +=
"\nstruct _objc_method {\n";
6192 Result +=
"\tstruct objc_selector * _cmd;\n";
6193 Result +=
"\tconst char *method_type;\n";
6194 Result +=
"\tvoid *_imp;\n";
6197 Result +=
"\nstruct _protocol_t {\n";
6198 Result +=
"\tvoid * isa; // NULL\n";
6199 Result +=
"\tconst char *protocol_name;\n";
6200 Result +=
"\tconst struct _protocol_list_t * protocol_list; // super protocols\n";
6201 Result +=
"\tconst struct method_list_t *instance_methods;\n";
6202 Result +=
"\tconst struct method_list_t *class_methods;\n";
6203 Result +=
"\tconst struct method_list_t *optionalInstanceMethods;\n";
6204 Result +=
"\tconst struct method_list_t *optionalClassMethods;\n";
6205 Result +=
"\tconst struct _prop_list_t * properties;\n";
6206 Result +=
"\tconst unsigned int size; // sizeof(struct _protocol_t)\n";
6207 Result +=
"\tconst unsigned int flags; // = 0\n";
6208 Result +=
"\tconst char ** extendedMethodTypes;\n";
6211 Result +=
"\nstruct _ivar_t {\n";
6212 Result +=
"\tunsigned long int *offset; // pointer to ivar offset location\n";
6213 Result +=
"\tconst char *name;\n";
6214 Result +=
"\tconst char *type;\n";
6215 Result +=
"\tunsigned int alignment;\n";
6216 Result +=
"\tunsigned int size;\n";
6219 Result +=
"\nstruct _class_ro_t {\n";
6220 Result +=
"\tunsigned int flags;\n";
6221 Result +=
"\tunsigned int instanceStart;\n";
6222 Result +=
"\tunsigned int instanceSize;\n";
6224 if (Triple.getArch() == llvm::Triple::x86_64)
6225 Result +=
"\tunsigned int reserved;\n";
6226 Result +=
"\tconst unsigned char *ivarLayout;\n";
6227 Result +=
"\tconst char *name;\n";
6228 Result +=
"\tconst struct _method_list_t *baseMethods;\n";
6229 Result +=
"\tconst struct _objc_protocol_list *baseProtocols;\n";
6230 Result +=
"\tconst struct _ivar_list_t *ivars;\n";
6231 Result +=
"\tconst unsigned char *weakIvarLayout;\n";
6232 Result +=
"\tconst struct _prop_list_t *properties;\n";
6235 Result +=
"\nstruct _class_t {\n";
6236 Result +=
"\tstruct _class_t *isa;\n";
6237 Result +=
"\tstruct _class_t *superclass;\n";
6238 Result +=
"\tvoid *cache;\n";
6239 Result +=
"\tvoid *vtable;\n";
6240 Result +=
"\tstruct _class_ro_t *ro;\n";
6243 Result +=
"\nstruct _category_t {\n";
6244 Result +=
"\tconst char *name;\n";
6245 Result +=
"\tstruct _class_t *cls;\n";
6246 Result +=
"\tconst struct _method_list_t *instance_methods;\n";
6247 Result +=
"\tconst struct _method_list_t *class_methods;\n";
6248 Result +=
"\tconst struct _protocol_list_t *protocols;\n";
6249 Result +=
"\tconst struct _prop_list_t *properties;\n";
6252 Result +=
"extern \"C\" __declspec(dllimport) struct objc_cache _objc_empty_cache;\n";
6253 Result +=
"#pragma warning(disable:4273)\n";
6254 meta_data_declared =
true;
6258 long super_protocol_count) {
6259 Result +=
"struct /*_protocol_list_t*/"; Result +=
" {\n";
6260 Result +=
"\tlong protocol_count; // Note, this is 32/64 bit\n";
6261 Result +=
"\tstruct _protocol_t *super_protocols[";
6262 Result += utostr(super_protocol_count); Result +=
"];\n";
6267 unsigned int method_count) {
6268 Result +=
"struct /*_method_list_t*/"; Result +=
" {\n";
6269 Result +=
"\tunsigned int entsize; // sizeof(struct _objc_method)\n";
6270 Result +=
"\tunsigned int method_count;\n";
6271 Result +=
"\tstruct _objc_method method_list[";
6272 Result += utostr(method_count); Result +=
"];\n";
6277 unsigned int property_count) {
6278 Result +=
"struct /*_prop_list_t*/"; Result +=
" {\n";
6279 Result +=
"\tunsigned int entsize; // sizeof(struct _prop_t)\n";
6280 Result +=
"\tunsigned int count_of_properties;\n";
6281 Result +=
"\tstruct _prop_t prop_list[";
6282 Result += utostr(property_count); Result +=
"];\n";
6287 unsigned int ivar_count) {
6288 Result +=
"struct /*_ivar_list_t*/"; Result +=
" {\n";
6289 Result +=
"\tunsigned int entsize; // sizeof(struct _prop_t)\n";
6290 Result +=
"\tunsigned int count;\n";
6291 Result +=
"\tstruct _ivar_t ivar_list[";
6292 Result += utostr(ivar_count); Result +=
"];\n";
6299 StringRef ProtocolName) {
6300 if (SuperProtocols.size() > 0) {
6301 Result +=
"\nstatic ";
6303 Result +=
" "; Result += VarName;
6304 Result += ProtocolName;
6305 Result +=
" __attribute__ ((used, section (\"__DATA,__objc_const\"))) = {\n";
6306 Result +=
"\t"; Result += utostr(SuperProtocols.size()); Result +=
",\n";
6307 for (
unsigned i = 0, e = SuperProtocols.size(); i < e; i++) {
6309 Result +=
"\t&"; Result +=
"_OBJC_PROTOCOL_";
6323 StringRef TopLevelDeclName,
6325 if (Methods.size() > 0) {
6326 Result +=
"\nstatic ";
6328 Result +=
" "; Result += VarName;
6329 Result += TopLevelDeclName;
6330 Result +=
" __attribute__ ((used, section (\"__DATA,__objc_const\"))) = {\n";
6331 Result +=
"\t"; Result +=
"sizeof(_objc_method)"; Result +=
",\n";
6332 Result +=
"\t"; Result += utostr(Methods.size()); Result +=
",\n";
6333 for (
unsigned i = 0, e = Methods.size(); i < e; i++) {
6336 Result +=
"\t{{(struct objc_selector *)\"";
6338 Result +=
"\t{(struct objc_selector *)\"";
6339 Result += (MD)->getSelector().getAsString(); Result +=
"\"";
6342 Result +=
"\""; Result += MethodTypeString; Result +=
"\"";
6347 Result +=
"(void *)";
6348 Result += RewriteObj.MethodInternalNames[MD];
6362 const Decl *Container,
6364 StringRef ProtocolName) {
6365 if (Properties.size() > 0) {
6366 Result +=
"\nstatic ";
6368 Result +=
" "; Result += VarName;
6369 Result += ProtocolName;
6370 Result +=
" __attribute__ ((used, section (\"__DATA,__objc_const\"))) = {\n";
6371 Result +=
"\t"; Result +=
"sizeof(_prop_t)"; Result +=
",\n";
6372 Result +=
"\t"; Result += utostr(Properties.size()); Result +=
",\n";
6373 for (
unsigned i = 0, e = Properties.size(); i < e; i++) {
6379 Result += PropDecl->
getName(); Result +=
"\",";
6380 std::string PropertyTypeString =
6382 std::string QuotePropertyTypeString;
6383 RewriteObj.QuoteDoublequotes(PropertyTypeString, QuotePropertyTypeString);
6384 Result +=
"\""; Result += QuotePropertyTypeString; Result +=
"\"";
6410 const std::string &InstanceStart,
6411 const std::string &InstanceSize,
6417 StringRef ClassName) {
6418 Result +=
"\nstatic struct _class_ro_t ";
6419 Result += VarName; Result += ClassName;
6420 Result +=
" __attribute__ ((used, section (\"__DATA,__objc_const\"))) = {\n";
6422 Result += llvm::utostr(flags); Result +=
", ";
6423 Result += InstanceStart; Result +=
", ";
6424 Result += InstanceSize; Result +=
", \n";
6427 if (Triple.getArch() == llvm::Triple::x86_64)
6429 Result +=
"(unsigned int)0, \n\t";
6431 Result +=
"0, \n\t";
6432 Result +=
"\""; Result += ClassName; Result +=
"\",\n\t";
6433 bool metaclass = ((flags &
CLS_META) != 0);
6434 if (baseMethods.size() > 0) {
6435 Result +=
"(const struct _method_list_t *)&";
6437 Result +=
"_OBJC_$_CLASS_METHODS_";
6439 Result +=
"_OBJC_$_INSTANCE_METHODS_";
6440 Result += ClassName;
6444 Result +=
"0, \n\t";
6446 if (!metaclass && baseProtocols.size() > 0) {
6447 Result +=
"(const struct _objc_protocol_list *)&";
6448 Result +=
"_OBJC_CLASS_PROTOCOLS_$_"; Result += ClassName;
6452 Result +=
"0, \n\t";
6454 if (!metaclass && ivars.size() > 0) {
6455 Result +=
"(const struct _ivar_list_t *)&";
6456 Result +=
"_OBJC_$_INSTANCE_VARIABLES_"; Result += ClassName;
6460 Result +=
"0, \n\t";
6463 Result +=
"0, \n\t";
6464 if (!metaclass && Properties.size() > 0) {
6465 Result +=
"(const struct _prop_list_t *)&";
6466 Result +=
"_OBJC_$_PROP_LIST_"; Result += ClassName;
6477 const ObjCInterfaceDecl *CDecl,
bool metaclass) {
6479 const ObjCInterfaceDecl *RootClass = CDecl;
6489 if (metaclass && rootClass) {
6492 Result +=
"extern \"C\" ";
6494 Result +=
"__declspec(dllexport) ";
6496 Result +=
"__declspec(dllimport) ";
6498 Result +=
"struct _class_t OBJC_CLASS_$_";
6506 Result +=
"extern \"C\" ";
6508 Result +=
"__declspec(dllexport) ";
6510 Result +=
"__declspec(dllimport) ";
6512 Result +=
"struct _class_t ";
6517 if (metaclass && RootClass != SuperClass) {
6518 Result +=
"extern \"C\" ";
6520 Result +=
"__declspec(dllexport) ";
6522 Result +=
"__declspec(dllimport) ";
6524 Result +=
"struct _class_t ";
6531 Result +=
"\nextern \"C\" __declspec(dllexport) struct _class_t ";
6533 Result +=
" __attribute__ ((used, section (\"__DATA,__objc_data\"))) = {\n";
6537 Result +=
"0, // &"; Result += VarName;
6540 Result +=
"0, // &"; Result += VarName;
6545 Result +=
"0, // &"; Result += VarName;
6553 Result +=
"0, // &OBJC_METACLASS_$_";
6557 Result +=
"0, // &"; Result += VarName;
6564 Result +=
"0, // (void *)&_objc_empty_cache,\n\t";
6565 Result +=
"0, // unused, was (void *)&_objc_empty_vtable,\n\t";
6567 Result +=
"&_OBJC_METACLASS_RO_$_";
6569 Result +=
"&_OBJC_CLASS_RO_$_";
6571 Result +=
",\n};\n";
6578 const ObjCInterfaceDecl *SuperClass =
6581 Result +=
"static void OBJC_CLASS_SETUP_$_";
6583 Result +=
"(void ) {\n";
6585 Result +=
".isa = "; Result +=
"&OBJC_METACLASS_$_";
6589 Result +=
".superclass = ";
6591 Result +=
"&OBJC_CLASS_$_";
6593 Result +=
"&OBJC_METACLASS_$_";
6598 Result +=
".cache = "; Result +=
"&_objc_empty_cache"; Result +=
";\n";
6601 Result +=
".isa = "; Result +=
"&OBJC_METACLASS_$_";
6606 Result +=
".superclass = "; Result +=
"&OBJC_CLASS_$_";
6611 Result +=
".cache = "; Result +=
"&_objc_empty_cache"; Result +=
";\n";
6616 std::string &Result,
6618 ObjCInterfaceDecl *ClassDecl,
6623 StringRef CatName = CatDecl->
getName();
6624 StringRef ClassName = ClassDecl->
getName();
6628 Result +=
"extern \"C\" ";
6630 Result +=
"__declspec(dllexport) ";
6632 Result +=
"__declspec(dllimport) ";
6634 Result +=
"struct _class_t ";
6635 Result +=
"OBJC_CLASS_$_"; Result += ClassName;
6638 Result +=
"\nstatic struct _category_t ";
6639 Result +=
"_OBJC_$_CATEGORY_";
6640 Result += ClassName; Result +=
"_$_"; Result += CatName;
6641 Result +=
" __attribute__ ((used, section (\"__DATA,__objc_const\"))) = \n";
6643 Result +=
"\t\""; Result += ClassName; Result +=
"\",\n";
6644 Result +=
"\t0, // &"; Result +=
"OBJC_CLASS_$_"; Result += ClassName;
6646 if (InstanceMethods.size() > 0) {
6647 Result +=
"\t(const struct _method_list_t *)&";
6648 Result +=
"_OBJC_$_CATEGORY_INSTANCE_METHODS_";
6649 Result += ClassName; Result +=
"_$_"; Result += CatName;
6655 if (ClassMethods.size() > 0) {
6656 Result +=
"\t(const struct _method_list_t *)&";
6657 Result +=
"_OBJC_$_CATEGORY_CLASS_METHODS_";
6658 Result += ClassName; Result +=
"_$_"; Result += CatName;
6664 if (RefedProtocols.size() > 0) {
6665 Result +=
"\t(const struct _protocol_list_t *)&";
6666 Result +=
"_OBJC_CATEGORY_PROTOCOLS_$_";
6667 Result += ClassName; Result +=
"_$_"; Result += CatName;
6673 if (ClassProperties.size() > 0) {
6674 Result +=
"\t(const struct _prop_list_t *)&"; Result +=
"_OBJC_$_PROP_LIST_";
6675 Result += ClassName; Result +=
"_$_"; Result += CatName;
6684 Result +=
"static void OBJC_CATEGORY_SETUP_$_";
6688 Result +=
"(void ) {\n";
6689 Result +=
"\t_OBJC_$_CATEGORY_";
6693 Result +=
".cls = "; Result +=
"&OBJC_CLASS_$_"; Result += ClassName;
6701 StringRef ProtocolName) {
6702 if (Methods.size() == 0)
6705 Result +=
"\nstatic const char *";
6706 Result += VarName; Result += ProtocolName;
6707 Result +=
" [] __attribute__ ((used, section (\"__DATA,__objc_const\"))) = \n";
6709 for (
unsigned i = 0, e = Methods.size(); i < e; i++) {
6711 std::string MethodTypeString =
6713 std::string QuoteMethodTypeString;
6714 RewriteObj.QuoteDoublequotes(MethodTypeString, QuoteMethodTypeString);
6715 Result +=
"\t\""; Result += QuoteMethodTypeString; Result +=
"\"";
6726 std::string &Result,
6728 ObjCInterfaceDecl *CDecl) {
6741 for (
unsigned i =0, e = Ivars.size(); i < e; i++) {
6744 Result +=
"__declspec(allocate(\".objc_ivar$B\")) ";
6749 Result +=
"extern \"C\" unsigned long int ";
6751 Result +=
"extern \"C\" __declspec(dllexport) unsigned long int ";
6752 if (Ivars[i]->isBitField())
6753 RewriteObj.ObjCIvarBitfieldGroupOffset(IvarDecl, Result);
6756 Result +=
" __attribute__ ((used, section (\"__DATA,__objc_ivar\")))";
6758 RewriteObj.RewriteIvarOffsetComputation(IvarDecl, Result);
6760 if (Ivars[i]->isBitField()) {
6771 ObjCInterfaceDecl *CDecl) {
6772 if (OriginalIvars.size() > 0) {
6778 for (
unsigned i = 0, e = OriginalIvars.size(); i < e; i++) {
6779 if (OriginalIvars[i]->isBitField()) {
6780 Ivars.push_back(OriginalIvars[i]);
6785 Ivars.push_back(OriginalIvars[i]);
6788 Result +=
"\nstatic ";
6790 Result +=
" "; Result += VarName;
6792 Result +=
" __attribute__ ((used, section (\"__DATA,__objc_const\"))) = {\n";
6793 Result +=
"\t"; Result +=
"sizeof(_ivar_t)"; Result +=
",\n";
6794 Result +=
"\t"; Result += utostr(Ivars.size()); Result +=
",\n";
6795 for (
unsigned i =0, e = Ivars.size(); i < e; i++) {
6801 Result +=
"(unsigned long int *)&";
6802 if (Ivars[i]->isBitField())
6803 RewriteObj.ObjCIvarBitfieldGroupOffset(IvarDecl, Result);
6809 if (Ivars[i]->isBitField())
6810 RewriteObj.ObjCIvarBitfieldGroupDecl(Ivars[i], Result);
6812 Result += IvarDecl->
getName();
6817 IVQT = RewriteObj.GetGroupRecordTypeForObjCIvarBitfield(IvarDecl);
6819 std::string IvarTypeString, QuoteIvarTypeString;
6822 RewriteObj.QuoteDoublequotes(IvarTypeString, QuoteIvarTypeString);
6823 Result +=
"\""; Result += QuoteIvarTypeString; Result +=
"\", ";
6828 Align = llvm::Log2_32(Align);
6829 Result += llvm::utostr(Align); Result +=
", ";
6842 void RewriteModernObjC::RewriteObjCProtocolMetaData(
ObjCProtocolDecl *PDecl,
6843 std::string &Result) {
6855 RewriteObjCProtocolMetaData(I, Result);
6858 std::vector<ObjCMethodDecl *> InstanceMethods, ClassMethods;
6859 std::vector<ObjCMethodDecl *> OptInstanceMethods, OptClassMethods;
6862 OptInstanceMethods.push_back(MD);
6864 InstanceMethods.push_back(MD);
6870 OptClassMethods.push_back(MD);
6872 ClassMethods.push_back(MD);
6875 std::vector<ObjCMethodDecl *> AllMethods;
6876 for (
unsigned i = 0, e = InstanceMethods.size(); i < e; i++)
6877 AllMethods.push_back(InstanceMethods[i]);
6878 for (
unsigned i = 0, e = ClassMethods.size(); i < e; i++)
6879 AllMethods.push_back(ClassMethods[i]);
6880 for (
unsigned i = 0, e = OptInstanceMethods.size(); i < e; i++)
6881 AllMethods.push_back(OptInstanceMethods[i]);
6882 for (
unsigned i = 0, e = OptClassMethods.size(); i < e; i++)
6883 AllMethods.push_back(OptClassMethods[i]);
6887 "_OBJC_PROTOCOL_METHOD_TYPES_",
6892 "_OBJC_PROTOCOL_REFS_",
6896 "_OBJC_PROTOCOL_INSTANCE_METHODS_",
6900 "_OBJC_PROTOCOL_CLASS_METHODS_",
6904 "_OBJC_PROTOCOL_OPT_INSTANCE_METHODS_",
6908 "_OBJC_PROTOCOL_OPT_CLASS_METHODS_",
6916 "_OBJC_PROTOCOL_PROPERTIES_",
6921 if (LangOpts.MicrosoftExt)
6922 Result +=
"static ";
6923 Result +=
"struct _protocol_t _OBJC_PROTOCOL_";
6925 Result +=
" __attribute__ ((used)) = {\n";
6927 Result +=
"\t\""; Result += PDecl->
getNameAsString(); Result +=
"\",\n";
6928 if (SuperProtocols.size() > 0) {
6929 Result +=
"\t(const struct _protocol_list_t *)&"; Result +=
"_OBJC_PROTOCOL_REFS_";
6934 if (InstanceMethods.size() > 0) {
6935 Result +=
"\t(const struct method_list_t *)&_OBJC_PROTOCOL_INSTANCE_METHODS_";
6941 if (ClassMethods.size() > 0) {
6942 Result +=
"\t(const struct method_list_t *)&_OBJC_PROTOCOL_CLASS_METHODS_";
6948 if (OptInstanceMethods.size() > 0) {
6949 Result +=
"\t(const struct method_list_t *)&_OBJC_PROTOCOL_OPT_INSTANCE_METHODS_";
6955 if (OptClassMethods.size() > 0) {
6956 Result +=
"\t(const struct method_list_t *)&_OBJC_PROTOCOL_OPT_CLASS_METHODS_";
6962 if (ProtocolProperties.size() > 0) {
6963 Result +=
"\t(const struct _prop_list_t *)&_OBJC_PROTOCOL_PROPERTIES_";
6969 Result +=
"\t"; Result +=
"sizeof(_protocol_t)"; Result +=
",\n";
6972 if (AllMethods.size() > 0) {
6973 Result +=
"\t(const char **)&"; Result +=
"_OBJC_PROTOCOL_METHOD_TYPES_";
6978 Result +=
"\t0\n};\n";
6980 if (LangOpts.MicrosoftExt)
6981 Result +=
"static ";
6982 Result +=
"struct _protocol_t *";
6983 Result +=
"_OBJC_LABEL_PROTOCOL_$_"; Result += PDecl->
getNameAsString();
6989 llvm_unreachable(
"protocol already synthesized");
6996 const ObjCInterfaceDecl *OID) {
6997 if (OID->
hasAttr<ObjCExceptionAttr>())
7005 std::string &Result) {
7011 "Legacy implicit interface rewriting not supported in moder abi");
7019 if (!IVD->getDeclName())
7021 IVars.push_back(IVD);
7025 "_OBJC_$_INSTANCE_VARIABLES_",
7036 if (!Prop->getPropertyIvarDecl())
7043 InstanceMethods.push_back(Getter);
7048 InstanceMethods.push_back(Setter);
7052 "_OBJC_$_INSTANCE_METHODS_",
7058 "_OBJC_$_CLASS_METHODS_",
7063 std::vector<ObjCProtocolDecl *> RefedProtocols;
7066 E = Protocols.
end();
7068 RefedProtocols.push_back(*I);
7071 RewriteObjCProtocolMetaData(*I, Result);
7076 "_OBJC_CLASS_PROTOCOLS_$_",
7084 "_OBJC_$_PROP_LIST_",
7089 std::string InstanceSize;
7090 std::string InstanceStart;
7099 InstanceSize =
"sizeof(struct _class_t)";
7100 InstanceStart = InstanceSize;
7102 InstanceStart, InstanceSize,
7107 "_OBJC_METACLASS_RO_$_",
7122 InstanceSize.clear();
7123 InstanceStart.clear();
7124 if (!ObjCSynthesizedStructs.count(CDecl)) {
7126 InstanceStart =
"0";
7129 InstanceSize =
"sizeof(struct ";
7131 InstanceSize +=
"_IMPL)";
7135 RewriteIvarOffsetComputation(IVD, InstanceStart);
7138 InstanceStart = InstanceSize;
7141 InstanceStart, InstanceSize,
7146 "_OBJC_CLASS_RO_$_",
7150 "OBJC_METACLASS_$_",
7157 if (ImplementationIsNonLazy(IDecl))
7158 DefinedNonLazyClasses.push_back(CDecl);
7161 void RewriteModernObjC::RewriteClassSetupInitHook(std::string &Result) {
7162 int ClsDefCount = ClassImplementation.size();
7165 Result +=
"#pragma section(\".objc_inithooks$B\", long, read, write)\n";
7166 Result +=
"__declspec(allocate(\".objc_inithooks$B\")) ";
7167 Result +=
"static void *OBJC_CLASS_SETUP[] = {\n";
7168 for (
int i = 0; i < ClsDefCount; i++) {
7171 Result +=
"\t(void *)&OBJC_CLASS_SETUP_$_";
7172 Result += CDecl->
getName(); Result +=
",\n";
7177 void RewriteModernObjC::RewriteMetaDataIntoBuffer(std::string &Result) {
7178 int ClsDefCount = ClassImplementation.size();
7179 int CatDefCount = CategoryImplementation.size();
7182 for (
int i = 0; i < ClsDefCount; i++)
7183 RewriteObjCClassMetaData(ClassImplementation[i], Result);
7185 RewriteClassSetupInitHook(Result);
7188 for (
int i = 0; i < CatDefCount; i++)
7189 RewriteObjCCategoryImplDecl(CategoryImplementation[i], Result);
7191 RewriteCategorySetupInitHook(Result);
7193 if (ClsDefCount > 0) {
7194 if (LangOpts.MicrosoftExt)
7195 Result +=
"__declspec(allocate(\".objc_classlist$B\")) ";
7196 Result +=
"static struct _class_t *L_OBJC_LABEL_CLASS_$ [";
7197 Result += llvm::utostr(ClsDefCount); Result +=
"]";
7199 " __attribute__((used, section (\"__DATA, __objc_classlist," 7200 "regular,no_dead_strip\")))= {\n";
7201 for (
int i = 0; i < ClsDefCount; i++) {
7202 Result +=
"\t&OBJC_CLASS_$_";
7203 Result += ClassImplementation[i]->getNameAsString();
7208 if (!DefinedNonLazyClasses.empty()) {
7209 if (LangOpts.MicrosoftExt)
7210 Result +=
"__declspec(allocate(\".objc_nlclslist$B\")) \n";
7211 Result +=
"static struct _class_t *_OBJC_LABEL_NONLAZY_CLASS_$[] = {\n\t";
7212 for (
unsigned i = 0, e = DefinedNonLazyClasses.size(); i < e; i++) {
7213 Result +=
"\t&OBJC_CLASS_$_"; Result += DefinedNonLazyClasses[i]->getNameAsString();
7220 if (CatDefCount > 0) {
7221 if (LangOpts.MicrosoftExt)
7222 Result +=
"__declspec(allocate(\".objc_catlist$B\")) ";
7223 Result +=
"static struct _category_t *L_OBJC_LABEL_CATEGORY_$ [";
7224 Result += llvm::utostr(CatDefCount); Result +=
"]";
7226 " __attribute__((used, section (\"__DATA, __objc_catlist," 7227 "regular,no_dead_strip\")))= {\n";
7228 for (
int i = 0; i < CatDefCount; i++) {
7229 Result +=
"\t&_OBJC_$_CATEGORY_";
7231 CategoryImplementation[i]->getClassInterface()->getNameAsString();
7233 Result += CategoryImplementation[i]->getNameAsString();
7239 if (!DefinedNonLazyCategories.empty()) {
7240 if (LangOpts.MicrosoftExt)
7241 Result +=
"__declspec(allocate(\".objc_nlcatlist$B\")) \n";
7242 Result +=
"static struct _category_t *_OBJC_LABEL_NONLAZY_CATEGORY_$[] = {\n\t";
7243 for (
unsigned i = 0, e = DefinedNonLazyCategories.size(); i < e; i++) {
7244 Result +=
"\t&_OBJC_$_CATEGORY_";
7246 DefinedNonLazyCategories[i]->getClassInterface()->getNameAsString();
7248 Result += DefinedNonLazyCategories[i]->getNameAsString();
7255 void RewriteModernObjC::WriteImageInfo(std::string &Result) {
7256 if (LangOpts.MicrosoftExt)
7257 Result +=
"__declspec(allocate(\".objc_imageinfo$B\")) \n";
7259 Result +=
"static struct IMAGE_INFO { unsigned version; unsigned flag; } ";
7261 Result +=
"_OBJC_IMAGE_INFO = { 0, 2 };\n";
7267 std::string &Result) {
7275 FullCategoryName +=
"_$_";
7286 if (!Prop->getPropertyIvarDecl())
7292 InstanceMethods.push_back(Getter);
7296 InstanceMethods.push_back(Setter);
7300 "_OBJC_$_CATEGORY_INSTANCE_METHODS_",
7301 FullCategoryName,
true);
7306 "_OBJC_$_CATEGORY_CLASS_METHODS_",
7307 FullCategoryName,
true);
7315 RewriteObjCProtocolMetaData(I, Result);
7319 "_OBJC_CATEGORY_PROTOCOLS_$_",
7327 "_OBJC_$_PROP_LIST_",
7339 if (ImplementationIsNonLazy(IDecl))
7340 DefinedNonLazyCategories.push_back(CDecl);
7343 void RewriteModernObjC::RewriteCategorySetupInitHook(std::string &Result) {
7344 int CatDefCount = CategoryImplementation.size();
7347 Result +=
"#pragma section(\".objc_inithooks$B\", long, read, write)\n";
7348 Result +=
"__declspec(allocate(\".objc_inithooks$B\")) ";
7349 Result +=
"static void *OBJC_CATEGORY_SETUP[] = {\n";
7350 for (
int i = 0; i < CatDefCount; i++) {
7354 Result +=
"\t(void *)&OBJC_CATEGORY_SETUP_$_";
7355 Result += ClassDecl->
getName();
7365 template<
typename MethodIterator>
7366 void RewriteModernObjC::RewriteObjCMethodsMetaData(MethodIterator MethodBegin,
7367 MethodIterator MethodEnd,
7368 bool IsInstanceMethod,
7370 StringRef ClassName,
7371 std::string &Result) {
7372 if (MethodBegin == MethodEnd)
return;
7374 if (!objc_impl_method) {
7381 Result +=
"\nstruct _objc_method {\n";
7382 Result +=
"\tSEL _cmd;\n";
7383 Result +=
"\tchar *method_types;\n";
7384 Result +=
"\tvoid *_imp;\n";
7387 objc_impl_method =
true;
7398 unsigned NumMethods =
std::distance(MethodBegin, MethodEnd);
7400 if (LangOpts.MicrosoftExt) {
7401 if (IsInstanceMethod)
7402 Result +=
"__declspec(allocate(\".inst_meth$B\")) ";
7404 Result +=
"__declspec(allocate(\".cls_meth$B\")) ";
7406 Result +=
"static struct {\n";
7407 Result +=
"\tstruct _objc_method_list *next_method;\n";
7408 Result +=
"\tint method_count;\n";
7409 Result +=
"\tstruct _objc_method method_list[";
7410 Result += utostr(NumMethods);
7411 Result +=
"];\n} _OBJC_";
7413 Result += IsInstanceMethod ?
"INSTANCE" :
"CLASS";
7414 Result +=
"_METHODS_";
7415 Result += ClassName;
7416 Result +=
" __attribute__ ((used, section (\"__OBJC, __";
7417 Result += IsInstanceMethod ?
"inst" :
"cls";
7418 Result +=
"_meth\")))= ";
7419 Result +=
"{\n\t0, " + utostr(NumMethods) +
"\n";
7421 Result +=
"\t,{{(SEL)\"";
7422 Result += (*MethodBegin)->getSelector().getAsString().c_str();
7423 std::string MethodTypeString;
7426 Result += MethodTypeString;
7427 Result +=
"\", (void *)";
7428 Result += MethodInternalNames[*MethodBegin];
7430 for (++MethodBegin; MethodBegin != MethodEnd; ++MethodBegin) {
7431 Result +=
"\t ,{(SEL)\"";
7432 Result += (*MethodBegin)->getSelector().getAsString().c_str();
7433 std::string MethodTypeString;
7436 Result += MethodTypeString;
7437 Result +=
"\", (void *)";
7438 Result += MethodInternalNames[*MethodBegin];
7441 Result +=
"\t }\n};\n";
7450 DisableReplaceStmtScope S(*
this);
7451 BaseExpr = cast<Expr>(RewriteFunctionBodyOrGlobalInitializer(BaseExpr));
7457 Expr *Replacement = IV;
7462 assert(iFaceDecl &&
"RewriteObjCIvarRefExpr - iFaceDecl is null");
7464 ObjCInterfaceDecl *clsDeclared =
nullptr;
7467 assert(clsDeclared &&
"RewriteObjCIvarRefExpr(): Can't find class");
7470 std::string IvarOffsetName;
7472 ObjCIvarBitfieldGroupOffset(D, IvarOffsetName);
7476 ReferencedIvars[clsDeclared].insert(D);
7500 IvarT = GetGroupRecordTypeForObjCIvarBitfield(D);
7502 if (!isa<TypedefType>(IvarT) && IvarT->
isRecordType()) {
7512 std::string RecName = CDecl->
getName();
7518 unsigned UnsignedIntSize =
7521 llvm::APInt(UnsignedIntSize, 0),
7523 Zero = NoTypeInfoCStyleCastExpr(Context, PtrStructIMPL, CK_BitCast, Zero);
7538 convertObjCTypeToCStyleType(IvarT);
7541 castExpr = NoTypeInfoCStyleCastExpr(Context,
7571 ReplaceStmtWithRange(IV, Replacement, OldRange);
7575 #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
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.
ObjCMethodDecl - Represents an instance or class method declaration.
SourceLocation getLeftLoc() const
RewriteBuffer - As code is rewritten, SourceBuffer's from the original input with modifications get a...
Expr * IgnoreImplicit() LLVM_READONLY
IgnoreImplicit - Skip past any implicit AST nodes which might surround this expression.
static void Write_RethrowObject(std::string &buf)
QualType getObjCClassType() const
Represents the Objective-C Class type.
Describes how types, statements, expressions, and declarations should be printed. ...
classmeth_range class_methods() const
std::string getRewrittenText(SourceRange Range) const
getRewrittenText - Return the rewritten form of the text in the specified range.
protocol_range protocols() const
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)
static ObjCMessageExpr * Create(const ASTContext &Context, QualType T, ExprValueKind VK, SourceLocation LBracLoc, SourceLocation SuperLoc, bool IsInstanceSuper, QualType SuperType, Selector Sel, ArrayRef< SourceLocation > SelLocs, ObjCMethodDecl *Method, ArrayRef< Expr *> Args, SourceLocation RBracLoc, bool isImplicit)
Create a message send to super.
instmeth_range instance_methods() const
StringLiteral * getString()
std::string getNameAsString() const
Get the name of the class associated with this interface.
SourceLocation getRParenLoc() const
ObjCMethodDecl * getSetterMethodDecl() const
bool ReplaceText(SourceLocation Start, unsigned OrigLength, StringRef NewStr)
ReplaceText - This method replaces a range of characters in the input buffer with a new string...
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
ObjCArrayLiteral - used for objective-c array containers; as in: @["Hello", NSApp, [NSNumber numberWithInt:42]];.
bool isObjCQualifiedClassType() const
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.
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 FunctionDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation NLoc, DeclarationName N, QualType T, TypeSourceInfo *TInfo, StorageClass SC, bool isInlineSpecified=false, bool hasWrittenPrototype=true, bool isConstexprSpecified=false)
static void WriteInternalIvarName(const ObjCInterfaceDecl *IDecl, ObjCIvarDecl *IvarDecl, std::string &Result)
Iterator for iterating over Stmt * arrays that contain only Expr *.
std::string getObjCEncodingForMethodDecl(const ObjCMethodDecl *Decl, bool Extended=false) const
Emit the encoded type for the method declaration Decl into S.
ObjCMethodDecl * getDictWithObjectsMethod() const
static void Write_prop_list_t_initializer(RewriteModernObjC &RewriteObj, ASTContext *Context, std::string &Result, ArrayRef< ObjCPropertyDecl *> Properties, const Decl *Container, StringRef VarName, StringRef ProtocolName)
static void Write_protocol_list_t_TypeDecl(std::string &Result, long super_protocol_count)
const ObjCAtCatchStmt * getCatchStmt(unsigned I) const
Retrieve a @catch statement.
ObjCPropertyImplDecl - Represents implementation declaration of a property in a class or category imp...
ConditionalOperator - The ?: ternary operator.
static bool hasObjCExceptionAttribute(ASTContext &Context, const ObjCInterfaceDecl *OID)
hasObjCExceptionAttribute - Return true if this class or any super class has the objc_exception attri...
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.
Pepresents a block literal declaration, which is like an unnamed FunctionDecl.
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
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
QualType getConstantArrayType(QualType EltTy, const llvm::APInt &ArySize, ArrayType::ArraySizeModifier ASM, unsigned IndexTypeQuals) const
Return the unique reference to the type for a constant array of the specified element type...
const Stmt * getTryBody() const
Retrieve the @try body.
QualType getEncodedType() const
bool isa(CodeGen::Address addr)
An expression that sends a message to the given Objective-C object or class.
SourceLocation getAtLoc() const
Represents an unpacked "presumed" location which can be presented to the user.
QualType getObjCInterfaceType(const ObjCInterfaceDecl *Decl, ObjCInterfaceDecl *PrevDecl=nullptr) const
getObjCInterfaceType - Return the unique reference to the type for the specified ObjC interface decl...
SourceLocation getEnd() const
#define SKIP_BITFIELDS(IX, ENDIX, VEC)
UnaryOperator - This represents the unary-expression's (except sizeof and alignof), the postinc/postdec operators from postfix-expression, and various extensions.
bool isInstanceMethod() const
QualType getFunctionType(QualType ResultTy, ArrayRef< QualType > Args, const FunctionProtoType::ExtProtoInfo &EPI) const
Return a normal function type with a typed argument list.
ReceiverKind getReceiverKind() const
Determine the kind of receiver that this message is being sent to.
static void BuildUniqueMethodName(std::string &Name, ObjCMethodDecl *MD)
int getRangeSize(SourceRange Range, RewriteOptions opts=RewriteOptions()) const
getRangeSize - Return the size in bytes of the specified range if they are in the same file...
Selector getSelector() const
QualType getTypeDeclType(const TypeDecl *Decl, const TypeDecl *PrevDecl=nullptr) const
Return the unique reference to the type for the specified type declaration.
The result type of a method or function.
unsigned getExpansionLineNumber(SourceLocation Loc, bool *Invalid=nullptr) const
SourceLocation getForLoc() const
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.
unsigned getNumArgs() const
Return the number of actual arguments in this message, not counting the receiver. ...
std::string getAsString() const
Derive the full selector name (e.g.
SelectorTable & Selectors
llvm::MemoryBuffer * getBuffer(FileID FID, SourceLocation Loc, bool *Invalid=nullptr) const
Return the buffer for the specified FileID.
void setSourceMgr(SourceManager &SM, const LangOptions &LO)
PseudoObjectExpr - An expression which accesses a pseudo-object l-value.
param_type_range param_types() const
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.
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 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
static std::string getAsString(SplitQualType split, const PrintingPolicy &Policy)
bool isBooleanType() const
QualType getFunctionNoProtoType(QualType ResultTy, const FunctionType::ExtInfo &Info) const
Return a K&R style C function type like 'int()'.
U cast(CodeGen::Address addr)
int printf(__constant const char *st,...)
PresumedLoc getPresumedLoc(SourceLocation Loc, bool UseLineDirectives=true) const
Returns the "presumed" location of a SourceLocation specifies.
const ObjCInterfaceDecl * getContainingInterface() const
Return the class interface that this ivar is logically contained in; this is either the interface whe...
QualType getCallResultType(const ASTContext &Context) const
Determine the type of an expression that calls a function of this type.
Expr * IgnoreParenImpCasts() LLVM_READONLY
IgnoreParenImpCasts - Ignore parentheses and implicit casts.
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...
SourceLocation getRParenLoc() const
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
(Obsolete) ARC-specific: this class has a .release_ivars method
unsigned getNumElements() const
getNumElements - Return number of elements of objective-c array literal.
Represents Objective-C's collection statement.
CanQualType UnsignedLongTy
ObjCEncodeExpr, used for @encode in Objective-C.
Selector getSelector(unsigned NumArgs, IdentifierInfo **IIV)
Can create any sort of selector.
static CStyleCastExpr * Create(const ASTContext &Context, QualType T, ExprValueKind VK, CastKind K, Expr *Op, const CXXCastPath *BasePath, TypeSourceInfo *WrittenTy, SourceLocation L, SourceLocation R)
uint64_t getCharWidth() const
Return the size of the character type, in bits.
void getObjCEncodingForType(QualType T, std::string &S, const FieldDecl *Field=nullptr, QualType *NotEncodedT=nullptr) const
Emit the Objective-CC type encoding for the given type T into S.
bool isObjCQualifiedIdType() const
DeclContext * getRedeclContext()
getRedeclContext - Retrieve the context in which an entity conflicts with other entities of the same ...
ObjCInterfaceDecl * getCanonicalDecl() override
Retrieves the canonical declaration of this Objective-C class.
Represents Objective-C's @finally statement.
void addDecl(Decl *D)
Add the declaration D into this context.
const Expr * getBase() const
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
ObjCIvarRefExpr - A reference to an ObjC instance variable.
SourceManager & getSourceManager()
ImplementationControl getImplementationControl() const
CanQualType getCanonicalType(QualType T) const
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
SourceRange getAtEndRange() const
X
Add a minimal nested name specifier fixit hint to allow lookup of a tag name from an outer enclosing ...
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.
ObjCMethodDecl * getGetterMethodDecl() const
This represents a decl that may have a name.
ObjCIvarDecl * all_declared_ivar_begin()
all_declared_ivar_begin - return first ivar declared in this class, its extensions and its implementa...
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...