26 #include "llvm/ADT/DenseSet.h"
27 #include "llvm/ADT/SmallPtrSet.h"
28 #include "llvm/ADT/StringExtras.h"
29 #include "llvm/Support/MemoryBuffer.h"
30 #include "llvm/Support/raw_ostream.h"
33 #ifdef CLANG_ENABLE_OBJC_REWRITER
35 using namespace clang;
56 BLOCK_NEEDS_FREE = (1 << 24),
59 BLOCK_IS_GC = (1 << 27),
61 BLOCK_HAS_DESCRIPTOR = (1 << 29)
71 const char *MainFileStart, *MainFileEnd;
74 std::string InFileName;
75 std::unique_ptr<raw_ostream> OutFile;
80 Expr *GlobalConstructionExp;
81 unsigned RewriteFailedDiag;
82 unsigned GlobalBlockRewriteFailedDiag;
84 unsigned NumObjCStringLiterals;
85 VarDecl *ConstantStringClassReference;
91 unsigned TryFinallyContainsReturnDiag;
111 SmallVector<ObjCImplementationDecl *, 8> ClassImplementation;
112 SmallVector<ObjCCategoryImplDecl *, 8> CategoryImplementation;
113 llvm::SmallPtrSet<ObjCInterfaceDecl*, 8> ObjCSynthesizedStructs;
114 llvm::SmallPtrSet<ObjCProtocolDecl*, 8> ObjCSynthesizedProtocols;
115 llvm::SmallPtrSet<ObjCInterfaceDecl*, 8> ObjCWrittenInterfaces;
116 llvm::SmallPtrSet<TagDecl*, 32> GlobalDefinedTags;
117 SmallVector<ObjCInterfaceDecl*, 32> ObjCInterfacesSeen;
119 SmallVector<ObjCInterfaceDecl*, 8> DefinedNonLazyClasses;
122 SmallVector<ObjCCategoryDecl *, 8> DefinedNonLazyCategories;
124 SmallVector<Stmt *, 32> Stmts;
125 SmallVector<int, 8> ObjCBcLabelNo;
127 llvm::SmallPtrSet<ObjCProtocolDecl *, 32> ProtocolExprDecls;
132 SmallVector<BlockExpr *, 32> Blocks;
133 SmallVector<int, 32> InnerDeclRefsCount;
134 SmallVector<DeclRefExpr *, 32> InnerDeclRefs;
136 SmallVector<DeclRefExpr *, 32> BlockDeclRefs;
139 SmallVector<ValueDecl *, 8> BlockByCopyDecls;
140 llvm::SmallPtrSet<ValueDecl *, 8> BlockByCopyDeclsPtrSet;
141 SmallVector<ValueDecl *, 8> BlockByRefDecls;
142 llvm::SmallPtrSet<ValueDecl *, 8> BlockByRefDeclsPtrSet;
143 llvm::DenseMap<ValueDecl *, unsigned> BlockByRefDeclNo;
144 llvm::SmallPtrSet<ValueDecl *, 8> ImportedBlockDecls;
145 llvm::SmallPtrSet<VarDecl *, 8> ImportedLocalExternalDecls;
147 llvm::DenseMap<BlockExpr *, std::string> RewrittenBlockExprs;
149 llvm::SmallPtrSet<ObjCIvarDecl *, 8> > ReferencedIvars;
153 llvm::DenseMap<const ObjCIvarDecl* , unsigned> IvarGroupNumber;
156 llvm::DenseMap<std::pair<const ObjCInterfaceDecl*, unsigned>,
QualType> GroupRecordType;
157 SmallVector<FunctionDecl*, 32> FunctionDefinitionsSeen;
162 llvm::DenseMap<Stmt *, Stmt *> ReplacedNodes;
166 bool SilenceRewriteMacroWarning;
167 bool GenerateLineInfo;
168 bool objc_impl_method;
170 bool DisableReplaceStmt;
171 class DisableReplaceStmtScope {
172 RewriteModernObjC &R;
176 DisableReplaceStmtScope(RewriteModernObjC &R)
177 : R(R), SavedValue(R.DisableReplaceStmt) {
178 R.DisableReplaceStmt =
true;
180 ~DisableReplaceStmtScope() {
181 R.DisableReplaceStmt = SavedValue;
187 llvm::DenseMap<ObjCMethodDecl*, std::string> MethodInternalNames;
193 if (!
Class->isThisDeclarationADefinition()) {
194 RewriteForwardClassDecl(D);
198 ObjCInterfacesSeen.push_back(Class);
204 if (!Proto->isThisDeclarationADefinition()) {
205 RewriteForwardProtocolDecl(D);
215 if (FDecl->isThisDeclarationADefinition() &&
217 !FDecl->isTopLevelDeclInObjCContainer()) {
218 FunctionDefinitionsSeen.push_back(FDecl);
222 HandleTopLevelSingleDecl(*
I);
227 void HandleTopLevelDeclInObjCContainer(
DeclGroupRef D)
override {
230 if (isTopLevelBlockPointerType(TD->getUnderlyingType()))
231 RewriteBlockPointerDecl(TD);
232 else if (TD->getUnderlyingType()->isFunctionPointerType())
233 CheckFunctionPointerDecl(TD->getUnderlyingType(), TD);
235 RewriteObjCQualifiedInterfaceTypes(TD);
240 void HandleTopLevelSingleDecl(
Decl *D);
241 void HandleDeclInMainFile(
Decl *D);
242 RewriteModernObjC(std::string inFile, std::unique_ptr<raw_ostream> OS,
244 bool silenceMacroWarn,
bool LineInfo);
246 ~RewriteModernObjC()
override {}
248 void HandleTranslationUnit(
ASTContext &C)
override;
250 void ReplaceStmt(
Stmt *Old,
Stmt *New) {
251 ReplaceStmtWithRange(Old, New, Old->getSourceRange());
255 assert(Old !=
nullptr && New !=
nullptr &&
"Expected non-null Stmt's");
257 Stmt *ReplacingStmt = ReplacedNodes[Old];
261 if (DisableReplaceStmt)
265 int Size = Rewrite.getRangeSize(SrcRange);
268 << Old->getSourceRange();
273 llvm::raw_string_ostream
S(SStr);
275 const std::string &Str =
S.str();
278 if (!Rewrite.ReplaceText(SrcRange.
getBegin(), Size, Str)) {
279 ReplacedNodes[Old] = New;
282 if (SilenceRewriteMacroWarning)
285 << Old->getSourceRange();
289 bool InsertAfter =
true) {
291 if (!Rewrite.InsertText(Loc, Str, InsertAfter) ||
292 SilenceRewriteMacroWarning)
301 if (!Rewrite.ReplaceText(Start, OrigLength, Str) ||
302 SilenceRewriteMacroWarning)
310 void RewriteInclude();
311 void RewriteLineDirective(
const Decl *D);
313 std::string &LineString);
315 void RewriteForwardClassDecl(
const SmallVectorImpl<Decl *> &DG);
317 const std::string &typedefString);
318 void RewriteImplementations();
323 void RewriteImplementationDecl(
Decl *Dcl);
326 void RewriteTypeIntoString(
QualType T, std::string &ResultStr,
328 void RewriteByRefString(std::string &ResultStr,
const std::string &
Name,
333 void RewriteForwardProtocolDecl(
const SmallVectorImpl<Decl *> &DG);
337 void RewriteBlockPointerType(std::string& Str,
QualType Type);
338 void RewriteBlockPointerTypeVariable(std::string& Str,
ValueDecl *VD);
340 void RewriteObjCQualifiedInterfaceTypes(
Decl *Dcl);
341 void RewriteTypeOfDecl(
VarDecl *VD);
342 void RewriteObjCQualifiedInterfaceTypes(
Expr *
E);
347 Stmt *RewriteFunctionBodyOrGlobalInitializer(
Stmt *
S);
368 void RewriteImplicitCastObjCExpr(
CastExpr *IE);
380 QualType SynthesizeBitfieldGroupStructType(
382 SmallVectorImpl<ObjCIvarDecl *> &IVars);
388 void RewriteBlockPointerDecl(
NamedDecl *VD);
389 void RewriteByRefVar(
VarDecl *VD,
bool firstDecl,
bool lastDecl);
399 bool &IsNamedDefinition);
408 void Initialize(
ASTContext &context)
override;
413 ArrayRef<Expr *> Args,
419 SmallVectorImpl<QualType> &ArgTypes,
420 SmallVectorImpl<Expr*> &MsgExprs,
427 void SynthCountByEnumWithState(std::string &buf);
428 void SynthMsgSendFunctionDecl();
429 void SynthMsgSendSuperFunctionDecl();
430 void SynthMsgSendStretFunctionDecl();
431 void SynthMsgSendFpretFunctionDecl();
432 void SynthMsgSendSuperStretFunctionDecl();
433 void SynthGetClassFunctionDecl();
434 void SynthGetMetaClassFunctionDecl();
435 void SynthGetSuperClassFunctionDecl();
436 void SynthSelGetUidFunctionDecl();
437 void SynthSuperConstructorFunctionDecl();
440 template<
typename MethodIterator>
441 void RewriteObjCMethodsMetaData(MethodIterator MethodBegin,
442 MethodIterator MethodEnd,
443 bool IsInstanceMethod,
451 void RewriteClassSetupInitHook(std::string &
Result);
453 void RewriteMetaDataIntoBuffer(std::string &
Result);
454 void WriteImageInfo(std::string &
Result);
457 void RewriteCategorySetupInitHook(std::string &
Result);
465 std::string SynthesizeByrefCopyDestroyHelper(
VarDecl *VD,
int flag);
466 std::string SynthesizeBlockHelperFuncs(
BlockExpr *CE,
int i,
467 StringRef funcName, std::string Tag);
468 std::string SynthesizeBlockFunc(
BlockExpr *CE,
int i,
469 StringRef funcName, std::string Tag);
470 std::string SynthesizeBlockImpl(
BlockExpr *CE,
471 std::string Tag, std::string Desc);
472 std::string SynthesizeBlockDescriptor(std::string DescTag,
474 int i, StringRef funcName,
479 FunctionDecl *SynthBlockInitFunctionDecl(StringRef name);
481 const SmallVectorImpl<DeclRefExpr *> &InnerBlockDeclRefs);
485 void WarnAboutReturnGotoStmts(
Stmt *
S);
487 void InsertBlockLiteralsWithinFunction(
FunctionDecl *FD);
490 bool IsDeclStmtInForeachHeader(
DeclStmt *DS);
491 void CollectBlockDeclRefInfo(
BlockExpr *Exp);
492 void GetBlockDeclRefExprs(
Stmt *
S);
493 void GetInnerBlockDeclRefExprs(
Stmt *
S,
494 SmallVectorImpl<DeclRefExpr *> &InnerBlockDeclRefs,
495 llvm::SmallPtrSetImpl<const DeclContext *> &InnerContexts);
499 bool isTopLevelBlockPointerType(
QualType T) {
500 return isa<BlockPointerType>(T);
506 bool convertBlockPointerToFunctionPointer(
QualType &T) {
507 if (isTopLevelBlockPointerType(T)) {
515 bool convertObjCTypeToCStyleType(
QualType &T);
517 bool needToScanForQualifiers(
QualType T);
519 QualType getConstantStringStructType();
522 void convertToUnqualifiedObjCType(
QualType &T) {
543 if (!LangOpts.ObjC1 && !LangOpts.ObjC2)
553 if (isa<ObjCInterfaceType>(PT->getPointeeType()) ||
554 PT->getPointeeType()->isObjCQualifiedIdType())
560 bool PointerTypeTakesAnyBlockArguments(
QualType QT);
561 bool PointerTypeTakesAnyObjCQualifiedType(
QualType QT);
562 void GetExtentOfArgList(
const char *
Name,
const char *&LParen,
563 const char *&RParen);
565 void QuoteDoublequotes(std::string &From, std::string &To) {
566 for (
unsigned i = 0; i < From.length(); i++) {
575 ArrayRef<QualType> args,
576 bool variadic =
false) {
592 bool ImplementationIsNonLazy(
const ObjCImplDecl *OD)
const {
608 void RewriteModernObjC::RewriteBlocksInFunctionProtoType(
QualType funcType,
611 = dyn_cast<FunctionProtoType>(funcType.
IgnoreParens())) {
612 for (
const auto &
I : fproto->param_types())
613 if (isTopLevelBlockPointerType(
I)) {
615 RewriteBlockPointerDecl(D);
621 void RewriteModernObjC::CheckFunctionPointerDecl(
QualType funcType,
NamedDecl *ND) {
623 if (PT && PointerTypeTakesAnyBlockArguments(funcType))
627 static bool IsHeaderFile(
const std::string &
Filename) {
628 std::string::size_type DotPos = Filename.rfind(
'.');
630 if (DotPos == std::string::npos) {
635 std::string Ext = std::string(Filename.begin()+DotPos+1, Filename.end());
638 return Ext ==
"h" || Ext ==
"hh" || Ext ==
"H";
641 RewriteModernObjC::RewriteModernObjC(std::string inFile,
642 std::unique_ptr<raw_ostream> OS,
645 bool silenceMacroWarn,
bool LineInfo)
646 : Diags(D), LangOpts(LOpts), InFileName(inFile), OutFile(std::move(OS)),
647 SilenceRewriteMacroWarning(silenceMacroWarn), GenerateLineInfo(LineInfo) {
648 IsHeader = IsHeaderFile(inFile);
650 "rewriting sub-expression within a macro (may not be correct)");
654 "rewriting block literal declared in global scope is not implemented");
656 TryFinallyContainsReturnDiag = Diags.getCustomDiagID(
658 "rewriter doesn't support user-specified control flow semantics "
659 "for @try/@finally (code may not execute properly)");
663 const std::string &InFile, std::unique_ptr<raw_ostream> OS,
665 bool SilenceRewriteMacroWarning,
bool LineInfo) {
666 return llvm::make_unique<RewriteModernObjC>(InFile, std::move(OS), Diags,
667 LOpts, SilenceRewriteMacroWarning,
671 void RewriteModernObjC::InitializeCommon(
ASTContext &context) {
675 MsgSendFunctionDecl =
nullptr;
676 MsgSendSuperFunctionDecl =
nullptr;
677 MsgSendStretFunctionDecl =
nullptr;
678 MsgSendSuperStretFunctionDecl =
nullptr;
679 MsgSendFpretFunctionDecl =
nullptr;
680 GetClassFunctionDecl =
nullptr;
681 GetMetaClassFunctionDecl =
nullptr;
682 GetSuperClassFunctionDecl =
nullptr;
683 SelGetUidFunctionDecl =
nullptr;
684 CFStringFunctionDecl =
nullptr;
685 ConstantStringClassReference =
nullptr;
686 NSStringRecord =
nullptr;
687 CurMethodDef =
nullptr;
688 CurFunctionDef =
nullptr;
689 GlobalVarDecl =
nullptr;
690 GlobalConstructionExp =
nullptr;
691 SuperStructDecl =
nullptr;
692 ProtocolTypeDecl =
nullptr;
693 ConstantStringDecl =
nullptr;
695 SuperConstructorFunctionDecl =
nullptr;
696 NumObjCStringLiterals = 0;
697 PropParentMap =
nullptr;
698 CurrentBody =
nullptr;
699 DisableReplaceStmt =
false;
700 objc_impl_method =
false;
704 const llvm::MemoryBuffer *MainBuf =
SM->
getBuffer(MainFileID);
705 MainFileStart = MainBuf->getBufferStart();
706 MainFileEnd = MainBuf->getBufferEnd();
715 void RewriteModernObjC::HandleTopLevelSingleDecl(
Decl *D) {
716 if (Diags.hasErrorOccurred())
730 RewriteFunctionDecl(FD);
731 }
else if (
VarDecl *FVD = dyn_cast<VarDecl>(D)) {
733 if (FVD->getName() ==
"_NSConstantStringClassReference") {
734 ConstantStringClassReference = FVD;
738 RewriteCategoryDecl(CD);
740 if (PD->isThisDeclarationADefinition())
741 RewriteProtocolDecl(PD);
745 DIEnd = LSD->decls_end();
748 if (!IFace->isThisDeclarationADefinition()) {
749 SmallVector<Decl *, 8> DG;
752 if (isa<ObjCInterfaceDecl>(*DI) &&
753 !cast<ObjCInterfaceDecl>(*DI)->isThisDeclarationADefinition() &&
754 StartLoc == (*DI)->getLocStart())
760 }
while (DI != DIEnd);
761 RewriteForwardClassDecl(DG);
766 ObjCInterfacesSeen.push_back(IFace);
773 if (!Proto->isThisDeclarationADefinition()) {
774 SmallVector<Decl *, 8> DG;
777 if (isa<ObjCProtocolDecl>(*DI) &&
778 !cast<ObjCProtocolDecl>(*DI)->isThisDeclarationADefinition() &&
779 StartLoc == (*DI)->getLocStart())
785 }
while (DI != DIEnd);
786 RewriteForwardProtocolDecl(DG);
791 HandleTopLevelSingleDecl(*DI);
797 return HandleDeclInMainFile(D);
804 void RewriteModernObjC::RewriteInclude() {
807 const char *MainBufStart = MainBuf.begin();
808 const char *MainBufEnd = MainBuf.end();
809 size_t ImportLen = strlen(
"import");
812 for (
const char *BufPtr = MainBufStart; BufPtr < MainBufEnd; ++BufPtr) {
813 if (*BufPtr ==
'#') {
814 if (++BufPtr == MainBufEnd)
816 while (*BufPtr ==
' ' || *BufPtr ==
'\t')
817 if (++BufPtr == MainBufEnd)
819 if (!strncmp(BufPtr,
"import", ImportLen)) {
823 ReplaceText(ImportLoc, ImportLen,
"include");
832 Result +=
"OBJC_IVAR_$_";
839 RewriteModernObjC::getIvarAccessString(
ObjCIvarDecl *D) {
843 std::string IvarOffsetName;
845 ObjCIvarBitfieldGroupOffset(D, IvarOffsetName);
847 WriteInternalIvarName(ClassDecl, D, IvarOffsetName);
849 std::string
S =
"(*(";
852 IvarT = GetGroupRecordTypeForObjCIvarBitfield(D);
854 if (!isa<TypedefType>(IvarT) && IvarT->
isRecordType()) {
863 CDecl = CatDecl->getClassInterface();
864 std::string RecName = CDecl->
getName();
870 unsigned UnsignedIntSize =
873 llvm::APInt(UnsignedIntSize, 0),
875 Zero = NoTypeInfoCStyleCastExpr(
Context, PtrStructIMPL, CK_BitCast, Zero);
890 convertObjCTypeToCStyleType(IvarT);
897 S +=
"((char *)self + ";
921 static bool objcGetPropertyDefined =
false;
922 static bool objcSetPropertyDefined =
false;
927 InsertText(startLoc,
"// ");
929 assert((*startBuf ==
'@') &&
"bogus @synthesize location");
930 const char *semiBuf = strchr(startBuf,
';');
931 assert((*semiBuf ==
';') &&
"@synthesize: can't find ';'");
935 startGetterSetterLoc = IMD ? IMD->getLocEnd() : CID->getLocEnd();
943 assert(IMD && OID &&
"Synthesized ivars must be attached to @implementation");
946 if (mustSynthesizeSetterGetterMethod(IMD, PD,
true )) {
947 bool GenGetProperty = !(Attributes & ObjCPropertyDecl::OBJC_PR_nonatomic) &&
948 (Attributes & (ObjCPropertyDecl::OBJC_PR_retain |
949 ObjCPropertyDecl::OBJC_PR_copy));
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);
997 Getr +=
"return " + getIvarAccessString(OID);
999 InsertText(startGetterSetterLoc, Getr);
1003 !mustSynthesizeSetterGetterMethod(IMD, PD,
false ))
1008 bool GenSetProperty = Attributes & (ObjCPropertyDecl::OBJC_PR_retain |
1009 ObjCPropertyDecl::OBJC_PR_copy);
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);
1028 if (Attributes & ObjCPropertyDecl::OBJC_PR_nonatomic)
1032 if (Attributes & ObjCPropertyDecl::OBJC_PR_copy)
1038 Setr += getIvarAccessString(OID) +
" = ";
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;
1078 typedefString +=
"// @class ";
1080 typedefString +=
";";
1082 RewriteOneForwardClassDecl(ForwardDecl, typedefString);
1085 HandleTopLevelSingleDecl(*
I);
1088 RewriteForwardClassEpilogue(cast<ObjCInterfaceDecl>(*I), typedefString);
1091 void RewriteModernObjC::RewriteForwardClassDecl(
1092 const SmallVectorImpl<Decl *> &D) {
1093 std::string typedefString;
1094 for (
unsigned i = 0; i < D.size(); i++) {
1097 typedefString +=
"// @class ";
1099 typedefString +=
";";
1101 RewriteOneForwardClassDecl(ForwardDecl, typedefString);
1103 RewriteForwardClassEpilogue(cast<ObjCInterfaceDecl>(D[0]), typedefString);
1106 void RewriteModernObjC::RewriteMethodDeclaration(
ObjCMethodDecl *Method) {
1109 if (Method->isImplicit())
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,
"// ");
1199 RewriteModernObjC::RewriteForwardProtocolDecl(
const SmallVectorImpl<Decl *> &DG) {
1202 llvm_unreachable(
"Invalid SourceLocation");
1204 ReplaceText(LocStart, 0,
"// ");
1207 void RewriteModernObjC::RewriteTypeIntoString(
QualType T, std::string &ResultStr,
1232 std::string &ResultStr) {
1235 ResultStr +=
"\nstatic ";
1236 RewriteTypeIntoString(OMD->
getReturnType(), ResultStr, FPRetType);
1240 std::string NameStr;
1251 dyn_cast<ObjCCategoryImplDecl>(OMD->getDeclContext())) {
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) {
1340 ReplaceText(IMD->getLocStart(), 1,
"/** ");
1344 InsertText(IMD->getLocStart(),
"// ");
1348 InsertText(CID->getLocStart(),
"// ");
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->getLocEnd() : CID->getLocEnd(),
"// ");
1379 if (ObjCSynthesizedStructs.count(ClassDecl))
1383 while (SuperClass) {
1384 RewriteInterfaceDecl(SuperClass);
1387 std::string ResultStr;
1390 RewriteOneForwardClassDecl(ClassDecl, ResultStr);
1391 RewriteIvarOffsetSymbols(ClassDecl, ResultStr);
1393 RewriteObjCInternalStruct(ClassDecl, ResultStr);
1400 RewriteMethodDeclaration(I);
1402 RewriteMethodDeclaration(I);
1411 SourceRange OldRange = PseudoOp->getSourceRange();
1422 SmallVector<Expr*, 2> Args;
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);
1445 SmallVector<SourceLocation, 1> SelLocs;
1450 case ObjCMessageExpr::Class:
1463 case ObjCMessageExpr::Instance:
1476 case ObjCMessageExpr::SuperClass:
1477 case ObjCMessageExpr::SuperInstance:
1494 ReplaceStmtWithRange(PseudoOp, Replacement, OldRange);
1499 SourceRange OldRange = PseudoOp->getSourceRange();
1508 Expr *Base =
nullptr;
1509 SmallVector<Expr*, 1> Args;
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);
1529 SmallVector<SourceLocation, 1> SelLocs;
1533 case ObjCMessageExpr::Class:
1546 case ObjCMessageExpr::Instance:
1559 case ObjCMessageExpr::SuperClass:
1560 case ObjCMessageExpr::SuperInstance:
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 +=
" \"";
1626 LineString += Lexer::Stringify(PLoc.
getFilename());
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();
1847 static void Write_RethrowObject(std::string &buf) {
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";
1900 Write_RethrowObject(buf);
1904 ReplaceText(startRBraceLoc, 1, buf);
1909 void RewriteModernObjC::WarnAboutReturnGotoStmts(
Stmt *S)
1912 for (
Stmt *SubStmt : S->children())
1914 WarnAboutReturnGotoStmts(SubStmt);
1916 if (isa<ReturnStmt>(S) || isa<GotoStmt>(S)) {
1918 TryFinallyContainsReturnDiag);
1924 ReplaceText(startLoc, strlen(
"@autoreleasepool"),
"/* @autoreleasepool */");
1925 ReplaceText(S->
getSubStmt()->getLocStart(), 1,
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;
1969 ConvertSourceLocationToLineDirective(Catch->
getLocStart(), Result);
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);
2020 Write_RethrowObject(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;
2069 ReplaceStmt(Exp, Replacement);
2077 if (!SelGetUidFunctionDecl)
2078 SynthSelGetUidFunctionDecl();
2079 assert(SelGetUidFunctionDecl &&
"Can't find sel_registerName() decl");
2081 SmallVector<Expr*, 8> SelExprs;
2083 CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl,
2085 ReplaceStmt(Exp, SelExp);
2091 RewriteModernObjC::SynthesizeCallToFunctionDecl(
FunctionDecl *FD,
2092 ArrayRef<Expr *> Args,
2116 static bool scanForProtocolRefs(
const char *startBuf,
const char *endBuf,
2117 const char *&startRef,
const char *&endRef) {
2118 while (startBuf < endBuf) {
2119 if (*startBuf ==
'<')
2120 startRef = startBuf;
2121 if (*startBuf ==
'>') {
2122 if (startRef && *startRef ==
'<') {
2133 static void scanToNextArgument(
const char *&argRef) {
2135 while (*argRef !=
')' && (*argRef !=
',' || angle > 0)) {
2138 else if (*argRef ==
'>')
2142 assert(angle == 0 &&
"scanToNextArgument - bad protocol type syntax");
2145 bool RewriteModernObjC::needToScanForQualifiers(
QualType T) {
2158 return needToScanForQualifiers(ElemTy);
2163 void RewriteModernObjC::RewriteObjCQualifiedInterfaceTypes(
Expr *E) {
2165 if (needToScanForQualifiers(Type)) {
2169 Loc = ECE->getLParenLoc();
2170 EndLoc = ECE->getRParenLoc();
2172 Loc = E->getLocStart();
2173 EndLoc = E->getLocEnd();
2181 const char *startRef =
nullptr, *endRef =
nullptr;
2182 if (scanForProtocolRefs(startBuf, endBuf, startRef, endRef)) {
2187 InsertText(LessLoc,
"/*");
2188 InsertText(GreaterLoc,
"*/");
2193 void RewriteModernObjC::RewriteObjCQualifiedInterfaceTypes(
Decl *Dcl) {
2197 if (
VarDecl *VD = dyn_cast<VarDecl>(Dcl)) {
2198 Loc = VD->getLocation();
2201 else if (
FunctionDecl *FD = dyn_cast<FunctionDecl>(Dcl)) {
2202 Loc = FD->getLocation();
2206 assert(funcType &&
"missing function type");
2212 else if (
FieldDecl *FD = dyn_cast<FieldDecl>(Dcl)) {
2213 Loc = FD->getLocation();
2217 Loc = TD->getLocation();
2218 Type = TD->getUnderlyingType();
2223 if (needToScanForQualifiers(Type)) {
2227 const char *startBuf = endBuf;
2228 while (*startBuf !=
';' && *startBuf !=
'<' && startBuf != MainFileStart)
2230 const char *startRef =
nullptr, *endRef =
nullptr;
2231 if (scanForProtocolRefs(startBuf, endBuf, startRef, endRef)) {
2236 InsertText(LessLoc,
"/*");
2237 InsertText(GreaterLoc,
"*/");
2244 const char *startFuncBuf = startBuf;
2249 const char *endBuf = startBuf;
2251 scanToNextArgument(endBuf);
2252 const char *startRef =
nullptr, *endRef =
nullptr;
2253 if (scanForProtocolRefs(startBuf, endBuf, startRef, endRef)) {
2260 InsertText(LessLoc,
"/*");
2261 InsertText(GreaterLoc,
"*/");
2263 startBuf = ++endBuf;
2268 while (*startBuf && *startBuf !=
')' && *startBuf !=
',')
2275 void RewriteModernObjC::RewriteTypeOfDecl(
VarDecl *ND) {
2277 const Type* TypePtr = QT->
getAs<Type>();
2278 if (!isa<TypeOfExprType>(TypePtr))
2280 while (isa<TypeOfExprType>(TypePtr)) {
2281 const TypeOfExprType *TypeOfExprTypePtr = cast<TypeOfExprType>(TypePtr);
2283 TypePtr = QT->
getAs<Type>();
2292 TypeAsString +=
" " + Name +
" = ";
2296 startLoc = ECE->getLParenLoc();
2298 startLoc = E->getLocStart();
2301 ReplaceText(DeclLoc, endBuf-startBuf-1, TypeAsString);
2307 ReplaceText(DeclLoc, endBuf-startBuf-1, TypeAsString);
2312 void RewriteModernObjC::SynthSelGetUidFunctionDecl() {
2314 SmallVector<QualType, 16> ArgTys;
2321 SelGetUidIdent, getFuncType,
2325 void RewriteModernObjC::RewriteFunctionDecl(
FunctionDecl *FD) {
2328 FD->
getName() ==
"sel_registerName") {
2329 SelGetUidFunctionDecl = FD;
2332 RewriteObjCQualifiedInterfaceTypes(FD);
2335 void RewriteModernObjC::RewriteBlockPointerType(std::string& Str,
QualType Type) {
2337 const char *argPtr = TypeString.c_str();
2338 if (!strchr(argPtr,
'^')) {
2343 Str += (*argPtr ==
'^' ?
'*' : *argPtr);
2349 void RewriteModernObjC::RewriteBlockPointerTypeVariable(std::string& Str,
2353 const char *argPtr = TypeString.c_str();
2378 void RewriteModernObjC::RewriteBlockLiteralFunctionDecl(
FunctionDecl *FD) {
2384 QualType Type = proto->getReturnType();
2389 unsigned numArgs = proto->getNumParams();
2390 for (
unsigned i = 0; i < numArgs; i++) {
2391 QualType ArgType = proto->getParamType(i);
2392 RewriteBlockPointerType(FdStr, ArgType);
2397 FdStr += (numArgs > 0) ?
", ...);\n" :
"...);\n";
2401 InsertText(FunLocStart, FdStr);
2405 void RewriteModernObjC::SynthSuperConstructorFunctionDecl() {
2406 if (SuperConstructorFunctionDecl)
2409 SmallVector<QualType, 16> ArgTys;
2411 assert(!argT.
isNull() &&
"Can't find 'id' type");
2412 ArgTys.push_back(argT);
2413 ArgTys.push_back(argT);
2419 msgSendIdent, msgSendType,
2424 void RewriteModernObjC::SynthMsgSendFunctionDecl() {
2426 SmallVector<QualType, 16> ArgTys;
2428 assert(!argT.
isNull() &&
"Can't find 'id' type");
2429 ArgTys.push_back(argT);
2431 assert(!argT.
isNull() &&
"Can't find 'SEL' type");
2432 ArgTys.push_back(argT);
2438 msgSendIdent, msgSendType,
nullptr,
2443 void RewriteModernObjC::SynthMsgSendSuperFunctionDecl() {
2445 SmallVector<QualType, 2> ArgTys;
2452 msgSendIdent, msgSendType,
2457 void RewriteModernObjC::SynthMsgSendStretFunctionDecl() {
2459 SmallVector<QualType, 16> ArgTys;
2461 assert(!argT.
isNull() &&
"Can't find 'id' type");
2462 ArgTys.push_back(argT);
2464 assert(!argT.
isNull() &&
"Can't find 'SEL' type");
2465 ArgTys.push_back(argT);
2471 msgSendIdent, msgSendType,
2477 void RewriteModernObjC::SynthMsgSendSuperStretFunctionDecl() {
2480 SmallVector<QualType, 2> ArgTys;
2488 msgSendType,
nullptr,
2493 void RewriteModernObjC::SynthMsgSendFpretFunctionDecl() {
2495 SmallVector<QualType, 16> ArgTys;
2497 assert(!argT.
isNull() &&
"Can't find 'id' type");
2498 ArgTys.push_back(argT);
2500 assert(!argT.
isNull() &&
"Can't find 'SEL' type");
2501 ArgTys.push_back(argT);
2507 msgSendIdent, msgSendType,
2512 void RewriteModernObjC::SynthGetClassFunctionDecl() {
2514 SmallVector<QualType, 16> ArgTys;
2521 getClassIdent, getClassType,
2526 void RewriteModernObjC::SynthGetSuperClassFunctionDecl() {
2529 SmallVector<QualType, 16> ArgTys;
2537 getClassType,
nullptr,
2542 void RewriteModernObjC::SynthGetMetaClassFunctionDecl() {
2544 SmallVector<QualType, 16> ArgTys;
2551 getClassIdent, getClassType,
2556 assert (Exp !=
nullptr &&
"Expected non-null ObjCStringLiteral");
2557 QualType strType = getConstantStringStructType();
2559 std::string S =
"__NSConstantStringImpl_";
2561 std::string tmpName = InFileName;
2563 for (i=0; i < tmpName.length(); i++) {
2564 char c = tmpName.at(i);
2571 S += utostr(NumObjCStringLiterals++);
2573 Preamble +=
"static __NSConstantStringImpl " +
S;
2574 Preamble +=
" __attribute__ ((section (\"__DATA, __cfstring\"))) = {__CFConstantStringClassReference,";
2575 Preamble +=
"0x000007c8,";
2577 std::string prettyBufS;
2578 llvm::raw_string_ostream prettyBuf(prettyBufS);
2580 Preamble += prettyBuf.str();
2595 CK_CPointerToObjCPointerCast, Unop);
2596 ReplaceStmt(Exp, cast);
2606 llvm::APInt(IntSize, Exp->
getValue()),
2609 CK_BitCast, FlagExp);
2612 ReplaceStmt(Exp, PE);
2618 if (!SelGetUidFunctionDecl)
2619 SynthSelGetUidFunctionDecl();
2621 if (!MsgSendFunctionDecl)
2622 SynthMsgSendFunctionDecl();
2623 if (!GetClassFunctionDecl)
2624 SynthGetClassFunctionDecl();
2631 SmallVector<Expr*, 4> MsgExprs;
2632 SmallVector<Expr*, 4> ClsExprs;
2639 ClsExprs.push_back(getStringLiteral(clsName->
getName()));
2640 CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl, ClsExprs,
2642 MsgExprs.push_back(Cls);
2646 SmallVector<Expr*, 4> SelExprs;
2649 CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl,
2650 SelExprs, StartLoc, EndLoc);
2651 MsgExprs.push_back(SelExp);
2660 CK = CK_IntegralToBoolean;
2661 subExpr = NoTypeInfoCStyleCastExpr(
Context, type, CK, subExpr);
2663 MsgExprs.push_back(subExpr);
2665 SmallVector<QualType, 4> ArgTypes;
2668 for (
const auto PI : BoxingMethod->
parameters())
2669 ArgTypes.push_back(PI->getType());
2685 getSimpleFunctionType(returnType, ArgTypes, BoxingMethod->
isVariadic());
2687 cast = NoTypeInfoCStyleCastExpr(
Context, castType, CK_BitCast,
2696 ReplaceStmt(Exp, CE);
2702 if (!SelGetUidFunctionDecl)
2703 SynthSelGetUidFunctionDecl();
2705 if (!MsgSendFunctionDecl)
2706 SynthMsgSendFunctionDecl();
2707 if (!GetClassFunctionDecl)
2708 SynthGetClassFunctionDecl();
2718 std::string NSArrayFName(
"__NSContainer_literal");
2719 FunctionDecl *NSArrayFD = SynthBlockInitFunctionDecl(NSArrayFName);
2724 SmallVector<Expr*, 16> InitExprs;
2726 unsigned UnsignedIntSize =
2729 llvm::APInt(UnsignedIntSize, NumElements),
2731 InitExprs.push_back(count);
2732 for (
unsigned i = 0; i < NumElements; i++)
2734 Expr *NSArrayCallExpr =
2749 NoTypeInfoCStyleCastExpr(
Context,
2755 SmallVector<Expr*, 32> MsgExprs;
2756 SmallVector<Expr*, 4> ClsExprs;
2764 ClsExprs.push_back(getStringLiteral(clsName->
getName()));
2765 CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl, ClsExprs,
2767 MsgExprs.push_back(Cls);
2771 SmallVector<Expr*, 4> SelExprs;
2775 CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl,
2776 SelExprs, StartLoc, EndLoc);
2777 MsgExprs.push_back(SelExp);
2780 MsgExprs.push_back(ArrayLiteralObjects);
2784 llvm::APInt(UnsignedIntSize, NumElements),
2786 MsgExprs.push_back(cnt);
2788 SmallVector<QualType, 4> ArgTypes;
2791 for (
const auto *PI : ArrayMethod->
parameters())
2792 ArgTypes.push_back(PI->getType());
2808 getSimpleFunctionType(returnType, ArgTypes, ArrayMethod->
isVariadic());
2810 cast = NoTypeInfoCStyleCastExpr(
Context, castType, CK_BitCast,
2819 ReplaceStmt(Exp, CE);
2825 if (!SelGetUidFunctionDecl)
2826 SynthSelGetUidFunctionDecl();
2828 if (!MsgSendFunctionDecl)
2829 SynthMsgSendFunctionDecl();
2830 if (!GetClassFunctionDecl)
2831 SynthGetClassFunctionDecl();
2841 std::string NSDictFName(
"__NSContainer_literal");
2842 FunctionDecl *NSDictFD = SynthBlockInitFunctionDecl(NSDictFName);
2847 SmallVector<Expr*, 16> KeyExprs;
2848 SmallVector<Expr*, 16> ValueExprs;
2851 unsigned UnsignedIntSize =
2854 llvm::APInt(UnsignedIntSize, NumElements),
2856 KeyExprs.push_back(count);
2857 ValueExprs.push_back(count);
2858 for (
unsigned i = 0; i < NumElements; i++) {
2860 KeyExprs.push_back(Element.
Key);
2861 ValueExprs.push_back(Element.
Value);
2865 Expr *NSValueCallExpr =
2880 NoTypeInfoCStyleCastExpr(
Context,
2883 DictLiteralValueME);
2885 Expr *NSKeyCallExpr =
2894 NoTypeInfoCStyleCastExpr(
Context,
2900 SmallVector<Expr*, 32> MsgExprs;
2901 SmallVector<Expr*, 4> ClsExprs;
2909 ClsExprs.push_back(getStringLiteral(clsName->
getName()));
2910 CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl, ClsExprs,
2912 MsgExprs.push_back(Cls);
2916 SmallVector<Expr*, 4> SelExprs;
2919 CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl,
2920 SelExprs, StartLoc, EndLoc);
2921 MsgExprs.push_back(SelExp);
2924 MsgExprs.push_back(DictValueObjects);
2927 MsgExprs.push_back(DictKeyObjects);
2931 llvm::APInt(UnsignedIntSize, NumElements),
2933 MsgExprs.push_back(cnt);
2935 SmallVector<QualType, 8> ArgTypes;
2938 for (
const auto *PI : DictMethod->
parameters()) {
2942 convertToUnqualifiedObjCType(PointeeTy);
2945 ArgTypes.push_back(T);
2962 getSimpleFunctionType(returnType, ArgTypes, DictMethod->
isVariadic());
2964 cast = NoTypeInfoCStyleCastExpr(
Context, castType, CK_BitCast,
2973 ReplaceStmt(Exp, CE);
2980 QualType RewriteModernObjC::getSuperStructType() {
2981 if (!SuperStructDecl) {
2993 for (
unsigned i = 0; i < 2; ++i) {
2997 FieldTypes[i],
nullptr,
3003 SuperStructDecl->completeDefinition();
3008 QualType RewriteModernObjC::getConstantStringStructType() {
3009 if (!ConstantStringDecl) {
3025 for (
unsigned i = 0; i < 4; ++i) {
3030 FieldTypes[i],
nullptr,
3036 ConstantStringDecl->completeDefinition();
3044 static SourceLocation getFunctionSourceLocation (RewriteModernObjC &R,
3050 if (!LSD->getRBraceLoc().isValid())
3051 return LSD->getExternLoc();
3054 R.RewriteBlockLiteralFunctionDecl(FD);
3058 void RewriteModernObjC::RewriteLineDirective(
const Decl *D) {
3062 if (Location.
isFileID() && GenerateLineInfo) {
3063 std::string LineString(
"\n#line ");
3065 LineString += utostr(PLoc.
getLine());
3066 LineString +=
" \"";
3067 LineString += Lexer::Stringify(PLoc.
getFilename());
3068 if (isa<ObjCMethodDecl>(D))
3070 else LineString +=
"\"\n";
3072 Location = D->getLocStart();
3073 if (
const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
3078 if (!LSD->getRBraceLoc().isValid())
3079 Location = LSD->getExternLoc();
3082 InsertText(Location, LineString);
3096 Expr *RewriteModernObjC::SynthMsgSendStretCallExpr(
FunctionDecl *MsgSendStretFlavor,
3098 SmallVectorImpl<QualType> &ArgTypes,
3099 SmallVectorImpl<Expr*> &MsgExprs,
3102 QualType castType = getSimpleFunctionType(returnType, ArgTypes,
3108 static unsigned stretCount=0;
3109 std::string name =
"__Stret"; name += utostr(stretCount);
3111 "extern \"C\" void * __cdecl memset(void *_Dst, int _Val, size_t _Size);\n";
3112 str +=
"namespace {\n";
3113 str +=
"struct "; str += name;
3116 str +=
"(id receiver, SEL sel";
3117 for (
unsigned i = 2; i < ArgTypes.size(); i++) {
3118 std::string ArgName =
"arg"; ArgName += utostr(i);
3120 str +=
", "; str += ArgName;
3123 for (
unsigned i = ArgTypes.size(); i < MsgExprs.size(); i++) {
3124 std::string ArgName =
"arg"; ArgName += utostr(i);
3125 MsgExprs[i]->getType().getAsStringInternal(ArgName,
3127 str +=
", "; str += ArgName;
3131 str +=
"\t unsigned size = sizeof(";
3134 str +=
"\t if (size == 1 || size == 2 || size == 4 || size == 8)\n";
3137 str +=
")(void *)objc_msgSend)(receiver, sel";
3138 for (
unsigned i = 2; i < ArgTypes.size(); i++) {
3139 str +=
", arg"; str += utostr(i);
3142 for (
unsigned i = ArgTypes.size(); i < MsgExprs.size(); i++) {
3143 str +=
", arg"; str += utostr(i);
3147 str +=
"\t else if (receiver == 0)\n";
3148 str +=
"\t memset((void*)&s, 0, sizeof(s));\n";
3152 str +=
")(void *)objc_msgSend_stret)(receiver, sel";
3153 for (
unsigned i = 2; i < ArgTypes.size(); i++) {
3154 str +=
", arg"; str += utostr(i);
3157 for (
unsigned i = ArgTypes.size(); i < MsgExprs.size(); i++) {
3158 str +=
", arg"; str += utostr(i);
3165 str +=
"};\n};\n\n";
3168 FunLocStart = getFunctionSourceLocation(*
this, CurFunctionDef);
3170 assert(CurMethodDef &&
"SynthMsgSendStretCallExpr - CurMethodDef is null");
3171 FunLocStart = CurMethodDef->getLocStart();
3174 InsertText(FunLocStart, str);
3190 returnType,
nullptr,
3203 if (!SelGetUidFunctionDecl)
3204 SynthSelGetUidFunctionDecl();
3205 if (!MsgSendFunctionDecl)
3206 SynthMsgSendFunctionDecl();
3207 if (!MsgSendSuperFunctionDecl)
3208 SynthMsgSendSuperFunctionDecl();
3209 if (!MsgSendStretFunctionDecl)
3210 SynthMsgSendStretFunctionDecl();
3211 if (!MsgSendSuperStretFunctionDecl)
3212 SynthMsgSendSuperStretFunctionDecl();
3213 if (!MsgSendFpretFunctionDecl)
3214 SynthMsgSendFpretFunctionDecl();
3215 if (!GetClassFunctionDecl)
3216 SynthGetClassFunctionDecl();
3217 if (!GetSuperClassFunctionDecl)
3218 SynthGetSuperClassFunctionDecl();
3219 if (!GetMetaClassFunctionDecl)
3220 SynthGetMetaClassFunctionDecl();
3227 QualType resultType = mDecl->getReturnType();
3229 MsgSendStretFlavor = MsgSendStretFunctionDecl;
3231 MsgSendFlavor = MsgSendFpretFunctionDecl;
3235 SmallVector<Expr*, 8> MsgExprs;
3237 case ObjCMessageExpr::SuperClass: {
3238 MsgSendFlavor = MsgSendSuperFunctionDecl;
3239 if (MsgSendStretFlavor)
3240 MsgSendStretFlavor = MsgSendSuperStretFunctionDecl;
3241 assert(MsgSendFlavor &&
"MsgSendFlavor is NULL!");
3245 SmallVector<Expr*, 4> InitExprs;
3248 InitExprs.push_back(
3259 SmallVector<Expr*, 8> ClsExprs;
3262 CallExpr *Cls = SynthesizeCallToFunctionDecl(GetMetaClassFunctionDecl,
3263 ClsExprs, StartLoc, EndLoc);
3265 ClsExprs.push_back(Cls);
3266 Cls = SynthesizeCallToFunctionDecl(GetSuperClassFunctionDecl, ClsExprs,
3271 InitExprs.push_back(
3272 NoTypeInfoCStyleCastExpr(
Context,
3276 QualType superType = getSuperStructType();
3279 if (LangOpts.MicrosoftExt) {
3280 SynthSuperConstructorFunctionDecl();
3298 SuperRep = NoTypeInfoCStyleCastExpr(
Context,
3300 CK_BitCast, SuperRep);
3317 MsgExprs.push_back(SuperRep);
3321 case ObjCMessageExpr::Class: {
3322 SmallVector<Expr*, 8> ClsExprs;
3326 ClsExprs.push_back(getStringLiteral(clsName->
getName()));
3327 CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl, ClsExprs,
3332 MsgExprs.push_back(ArgExpr);
3336 case ObjCMessageExpr::SuperInstance:{
3337 MsgSendFlavor = MsgSendSuperFunctionDecl;
3338 if (MsgSendStretFlavor)
3339 MsgSendStretFlavor = MsgSendSuperStretFunctionDecl;
3340 assert(MsgSendFlavor &&
"MsgSendFlavor is NULL!");
3342 SmallVector<Expr*, 4> InitExprs;
3344 InitExprs.push_back(
3354 SmallVector<Expr*, 8> ClsExprs;
3357 CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl, ClsExprs,
3360 ClsExprs.push_back(Cls);
3361 Cls = SynthesizeCallToFunctionDecl(GetSuperClassFunctionDecl, ClsExprs,
3366 InitExprs.push_back(
3371 QualType superType = getSuperStructType();
3374 if (LangOpts.MicrosoftExt) {
3375 SynthSuperConstructorFunctionDecl();
3378 false, superType, VK_LValue,
3392 SuperRep = NoTypeInfoCStyleCastExpr(
Context,
3394 CK_BitCast, SuperRep);
3406 MsgExprs.push_back(SuperRep);
3410 case ObjCMessageExpr::Instance: {
3415 recExpr = CE->getSubExpr();
3418 ? CK_BlockPointerToObjCPointerCast
3419 : CK_CPointerToObjCPointerCast;
3423 MsgExprs.push_back(recExpr);
3429 SmallVector<Expr*, 8> SelExprs;
3431 CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl,
3432 SelExprs, StartLoc, EndLoc);
3433 MsgExprs.push_back(SelExp);
3436 for (
unsigned i = 0; i < Exp->
getNumArgs(); i++) {
3442 if (needToScanForQualifiers(type))
3445 (void)convertBlockPointerToFunctionPointer(type);
3450 CK = CK_IntegralToBoolean;
3453 CK = CK_BlockPointerToObjCPointerCast;
3455 CK = CK_CPointerToObjCPointerCast;
3463 userExpr = NoTypeInfoCStyleCastExpr(
Context, type, CK, userExpr);
3466 else if (
CStyleCastExpr *CE = dyn_cast<CStyleCastExpr>(userExpr)) {
3467 if (CE->getType()->isObjCQualifiedIdType()) {
3468 while ((CE = dyn_cast<CStyleCastExpr>(userExpr)))
3469 userExpr = CE->getSubExpr();
3472 CK = CK_IntegralToPointer;
3474 CK = CK_BlockPointerToObjCPointerCast;
3476 CK = CK_CPointerToObjCPointerCast;
3484 MsgExprs.push_back(userExpr);
3492 SmallVector<QualType, 8> ArgTypes;
3496 if (MsgSendFlavor == MsgSendSuperFunctionDecl)
3508 (void)convertBlockPointerToFunctionPointer(t);
3509 ArgTypes.push_back(t);
3512 convertToUnqualifiedObjCType(returnType);
3513 (void)convertBlockPointerToFunctionPointer(returnType);
3528 cast = NoTypeInfoCStyleCastExpr(
Context,
3536 getSimpleFunctionType(returnType, ArgTypes, MD ? MD->isVariadic() :
true);
3538 cast = NoTypeInfoCStyleCastExpr(
Context, castType, CK_BitCast,
3547 Stmt *ReplacingStmt = CE;
3548 if (MsgSendStretFlavor) {
3554 Expr *STCE = SynthMsgSendStretCallExpr(MsgSendStretFlavor,
3558 ReplacingStmt = STCE;
3561 return ReplacingStmt;
3569 ReplaceStmt(Exp, ReplacingStmt);
3572 return ReplacingStmt;
3576 QualType RewriteModernObjC::getProtocolType() {
3577 if (!ProtocolTypeDecl) {
3593 std::string Name =
"_OBJC_PROTOCOL_REFERENCE_$_" +
3602 NoTypeInfoCStyleCastExpr(
3604 ReplaceStmt(Exp, castExpr);
3614 bool &IsNamedDefinition) {
3618 if (
RecordDecl *RD = dyn_cast<RecordDecl>(Tag)) {
3622 IsNamedDefinition =
true;
3623 TagLocation = RD->getLocation();
3625 IDecl->getLocation(), TagLocation);
3627 if (
EnumDecl *ED = dyn_cast<EnumDecl>(Tag)) {
3628 if (!ED || !ED->getDeclName().getAsIdentifierInfo())
3630 IsNamedDefinition =
true;
3631 TagLocation = ED->getLocation();
3633 IDecl->getLocation(), TagLocation);
3640 bool RewriteModernObjC::RewriteObjCFieldDeclType(
QualType &Type,
3641 std::string &Result) {
3642 if (isa<TypedefType>(Type)) {
3649 return RewriteObjCFieldDeclType(ElemTy, Result);
3655 Result +=
"\n\tstruct ";
3657 Result +=
"\n\tunion ";
3659 assert(
false &&
"class not allowed as an ivar type");
3662 if (GlobalDefinedTags.count(RD)) {
3668 for (
auto *FD : RD->
fields())
3669 RewriteObjCFieldDecl(FD, Result);
3677 Result +=
"\n\tenum ";
3679 if (GlobalDefinedTags.count(ED)) {
3687 Result +=
"\t"; Result += EC->getName(); Result +=
" = ";
3688 llvm::APSInt Val = EC->getInitVal();
3689 Result += Val.toString(10);
3698 convertObjCTypeToCStyleType(Type);
3706 std::string &Result) {
3710 bool EleboratedType = RewriteObjCFieldDeclType(Type, Result);
3711 if (!EleboratedType)
3722 llvm::APInt Dim = CAT->getSize();
3723 Result += utostr(Dim.getZExtValue());
3735 void RewriteModernObjC::RewriteLocallyDefinedNamedAggregates(
FieldDecl *fieldDecl,
3736 std::string &Result) {
3738 if (isa<TypedefType>(Type))
3754 if (GlobalDefinedTags.count(TD))
3757 bool IsNamedDefinition =
false;
3758 if (IsTagDefinedInsideClass(IDecl, TD, IsNamedDefinition)) {
3759 RewriteObjCFieldDeclType(Type, Result);
3762 if (IsNamedDefinition)
3763 GlobalDefinedTags.insert(TD);
3767 unsigned RewriteModernObjC::ObjCIvarBitfieldGroupNo(
ObjCIvarDecl *IV) {
3769 if (ObjCInterefaceHasBitfieldGroups.count(CDecl)) {
3770 return IvarGroupNumber[IV];
3772 unsigned GroupNo = 0;
3773 SmallVector<const ObjCIvarDecl *, 8> IVars;
3776 IVars.push_back(IVD);
3778 for (
unsigned i = 0, e = IVars.size(); i < e; i++)
3779 if (IVars[i]->isBitField()) {
3780 IvarGroupNumber[IVars[i++]] = ++GroupNo;
3781 while (i < e && IVars[i]->isBitField())
3782 IvarGroupNumber[IVars[i++]] = GroupNo;
3787 ObjCInterefaceHasBitfieldGroups.insert(CDecl);
3788 return IvarGroupNumber[IV];
3791 QualType RewriteModernObjC::SynthesizeBitfieldGroupStructType(
3793 SmallVectorImpl<ObjCIvarDecl *> &IVars) {
3794 std::string StructTagName;
3795 ObjCIvarBitfieldGroupType(IV, StructTagName);
3800 for (
unsigned i=0, e = IVars.size(); i < e; i++) {
3814 unsigned GroupNo = ObjCIvarBitfieldGroupNo(IV);
3815 std::pair<const ObjCInterfaceDecl*, unsigned> tuple = std::make_pair(CDecl, GroupNo);
3816 if (GroupRecordType.count(tuple))
3817 return GroupRecordType[tuple];
3819 SmallVector<ObjCIvarDecl *, 8> IVars;
3822 if (IVD->isBitField())
3823 IVars.push_back(const_cast<ObjCIvarDecl *>(IVD));
3825 if (!IVars.empty()) {
3826 unsigned GroupNo = ObjCIvarBitfieldGroupNo(IVars[0]);
3828 GroupRecordType[std::make_pair(CDecl, GroupNo)] =
3829 SynthesizeBitfieldGroupStructType(IVars[0], IVars);
3834 if (!IVars.empty()) {
3836 unsigned GroupNo = ObjCIvarBitfieldGroupNo(IVars[0]);
3837 GroupRecordType[std::make_pair(CDecl, GroupNo)] =
3838 SynthesizeBitfieldGroupStructType(IVars[0], IVars);
3840 QualType RetQT = GroupRecordType[tuple];
3841 assert(!RetQT.
isNull() &&
"GetGroupRecordTypeForObjCIvarBitfield struct type is NULL");
3848 void RewriteModernObjC::ObjCIvarBitfieldGroupDecl(
ObjCIvarDecl *IV,
3849 std::string &Result) {
3852 Result +=
"__GRBF_";
3853 unsigned GroupNo = ObjCIvarBitfieldGroupNo(IV);
3854 Result += utostr(GroupNo);
3860 void RewriteModernObjC::ObjCIvarBitfieldGroupType(
ObjCIvarDecl *IV,
3861 std::string &Result) {
3865 unsigned GroupNo = ObjCIvarBitfieldGroupNo(IV);
3866 Result += utostr(GroupNo);
3872 void RewriteModernObjC::ObjCIvarBitfieldGroupOffset(
ObjCIvarDecl *IV,
3873 std::string &Result) {
3874 Result +=
"OBJC_IVAR_$_";
3875 ObjCIvarBitfieldGroupDecl(IV, Result);
3878 #define SKIP_BITFIELDS(IX, ENDIX, VEC) { \
3879 while ((IX < ENDIX) && VEC[IX]->isBitField()) \
3888 std::string &Result) {
3889 assert(CDecl &&
"Class missing in SynthesizeObjCInternalStruct");
3890 assert(CDecl->
getName() !=
"" &&
3891 "Name missing in SynthesizeObjCInternalStruct");
3893 SmallVector<ObjCIvarDecl *, 8> IVars;
3896 IVars.push_back(IVD);
3907 (!RCDecl || !ObjCSynthesizedStructs.count(RCDecl))) {
3908 endBuf += Lexer::MeasureTokenLength(LocEnd, *
SM, LangOpts);
3909 ReplaceText(LocStart, endBuf-startBuf, Result);
3916 for (
unsigned i = 0, e = IVars.size(); i < e; i++)
3917 RewriteLocallyDefinedNamedAggregates(IVars[i], Result);
3921 for (
unsigned i = 0, e = IVars.size(); i < e; i++)
3922 if (IVars[i]->isBitField()) {
3924 QualType QT = GetGroupRecordTypeForObjCIvarBitfield(IV);
3925 RewriteObjCFieldDeclType(QT, Result);
3928 SKIP_BITFIELDS(i , e, IVars);
3931 Result +=
"\nstruct ";
3933 Result +=
"_IMPL {\n";
3935 if (RCDecl && ObjCSynthesizedStructs.count(RCDecl)) {
3936 Result +=
"\tstruct "; Result += RCDecl->getNameAsString();
3937 Result +=
"_IMPL "; Result += RCDecl->getNameAsString();
3938 Result +=
"_IVARS;\n";
3941 for (
unsigned i = 0, e = IVars.size(); i < e; i++) {
3942 if (IVars[i]->isBitField()) {
3944 Result +=
"\tstruct ";
3945 ObjCIvarBitfieldGroupType(IV, Result); Result +=
" ";
3946 ObjCIvarBitfieldGroupDecl(IV, Result); Result +=
";\n";
3948 SKIP_BITFIELDS(i , e, IVars);
3951 RewriteObjCFieldDecl(IVars[i], Result);
3955 endBuf += Lexer::MeasureTokenLength(LocEnd, *
SM, LangOpts);
3956 ReplaceText(LocStart, endBuf-startBuf, Result);
3958 if (!ObjCSynthesizedStructs.insert(CDecl).second)
3959 llvm_unreachable(
"struct already synthesize- RewriteObjCInternalStruct");
3965 std::string &Result) {
3968 llvm::SmallPtrSet<ObjCIvarDecl *, 8> Ivars = ReferencedIvars[CDecl];
3975 unsigned GroupNo = 0;
3977 GroupNo = ObjCIvarBitfieldGroupNo(IvarDecl);
3978 if (GroupSymbolOutput.count(std::make_pair(IDecl, GroupNo)))
3982 if (LangOpts.MicrosoftExt)
3983 Result +=
"__declspec(allocate(\".objc_ivar$B\")) ";
3984 Result +=
"extern \"C\" ";
3985 if (LangOpts.MicrosoftExt &&
3988 Result +=
"__declspec(dllimport) ";
3990 Result +=
"unsigned long ";
3992 ObjCIvarBitfieldGroupOffset(IvarDecl, Result);
3993 GroupSymbolOutput.insert(std::make_pair(IDecl, GroupNo));
3996 WriteInternalIvarName(CDecl, IvarDecl, Result);
4008 void RewriteModernObjC::RewriteImplementations() {
4009 int ClsDefCount = ClassImplementation.size();
4010 int CatDefCount = CategoryImplementation.size();
4013 for (
int i = 0; i < ClsDefCount; i++) {
4018 "Legacy implicit interface rewriting not supported in moder abi");
4019 RewriteImplementationDecl(OIMP);
4022 for (
int i = 0; i < CatDefCount; i++) {
4027 "Legacy implicit interface rewriting not supported in moder abi");
4028 RewriteImplementationDecl(CIMP);
4032 void RewriteModernObjC::RewriteByRefString(std::string &ResultStr,
4033 const std::string &Name,
4035 assert(BlockByRefDeclNo.count(VD) &&
4036 "RewriteByRefString: ByRef decl missing");
4038 ResultStr +=
"struct ";
4039 ResultStr +=
"__Block_byref_" + Name +
4040 "_" + utostr(BlockByRefDeclNo[VD]) ;
4043 static bool HasLocalVariableExternalStorage(
ValueDecl *VD) {
4044 if (
VarDecl *Var = dyn_cast<VarDecl>(VD))
4045 return (Var->isFunctionOrMethodVarDecl() && !Var->hasLocalStorage());
4049 std::string RewriteModernObjC::SynthesizeBlockFunc(
BlockExpr *CE,
int i,
4054 std::string StructRef =
"struct " + Tag;
4057 ConvertSourceLocationToLineDirective(BlockLoc, S);
4060 funcName.str() +
"_block_func_" + utostr(i);
4064 if (isa<FunctionNoProtoType>(AFT)) {
4067 S +=
"(" + StructRef +
" *__cself)";
4069 S +=
"(" + StructRef +
" *__cself)";
4072 assert(FT &&
"SynthesizeBlockFunc: No function proto");
4075 S += StructRef +
" *__cself, ";
4076 std::string ParamStr;
4080 ParamStr = (*AI)->getNameAsString();
4082 (void)convertBlockPointerToFunctionPointer(QT);
4097 E = BlockByRefDecls.end(); I !=
E; ++
I) {
4099 std::string Name = (*I)->getNameAsString();
4100 std::string TypeString;
4101 RewriteByRefString(TypeString, Name, (*I));
4103 Name = TypeString +
Name;
4104 S += Name +
" = __cself->" + (*I)->getNameAsString() +
"; // bound by ref\n";
4108 E = BlockByCopyDecls.end(); I !=
E; ++
I) {
4120 if (isTopLevelBlockPointerType((*I)->getType())) {
4121 RewriteBlockPointerTypeVariable(S, (*I));
4123 RewriteBlockPointerType(S, (*I)->getType());
4125 S +=
"__cself->" + (*I)->getNameAsString() +
"; // bound by copy\n";
4128 std::string Name = (*I)->getNameAsString();
4130 if (HasLocalVariableExternalStorage(*I))
4133 S += Name +
" = __cself->" +
4134 (*I)->getNameAsString() +
"; // bound by copy\n";
4137 std::string RewrittenStr = RewrittenBlockExprs[CE];
4138 const char *cstr = RewrittenStr.c_str();
4139 while (*cstr++ !=
'{') ;
4145 std::string RewriteModernObjC::SynthesizeBlockHelperFuncs(
BlockExpr *CE,
int i,
4148 std::string StructRef =
"struct " + Tag;
4149 std::string S =
"static void __";
4152 S +=
"_block_copy_" + utostr(i);
4153 S +=
"(" + StructRef;
4154 S +=
"*dst, " + StructRef;
4156 for (
ValueDecl *VD : ImportedBlockDecls) {
4157 S +=
"_Block_object_assign((void*)&dst->";
4159 S +=
", (void*)src->";
4161 if (BlockByRefDeclsPtrSet.count(VD))
4170 S +=
"\nstatic void __";
4172 S +=
"_block_dispose_" + utostr(i);
4173 S +=
"(" + StructRef;
4175 for (
ValueDecl *VD : ImportedBlockDecls) {
4176 S +=
"_Block_object_dispose((void*)src->";
4178 if (BlockByRefDeclsPtrSet.count(VD))
4189 std::string RewriteModernObjC::SynthesizeBlockImpl(
BlockExpr *CE, std::string Tag,
4191 std::string S =
"\nstruct " + Tag;
4194 S +=
" {\n struct __block_impl impl;\n";
4195 S +=
" struct " + Desc;
4198 Constructor +=
"(void *fp, ";
4199 Constructor +=
"struct " + Desc;
4200 Constructor +=
" *desc";
4202 if (BlockDeclRefs.size()) {
4205 E = BlockByCopyDecls.end(); I !=
E; ++
I) {
4207 std::string FieldName = (*I)->getNameAsString();
4208 std::string ArgName =
"_" + FieldName;
4219 if (isTopLevelBlockPointerType((*I)->getType())) {
4220 S +=
"struct __block_impl *";
4221 Constructor +=
", void *" + ArgName;
4224 if (HasLocalVariableExternalStorage(*I))
4228 Constructor +=
", " + ArgName;
4230 S += FieldName +
";\n";
4234 E = BlockByRefDecls.end(); I !=
E; ++
I) {
4236 std::string FieldName = (*I)->getNameAsString();
4237 std::string ArgName =
"_" + FieldName;
4239 std::string TypeString;
4240 RewriteByRefString(TypeString, FieldName, (*I));
4242 FieldName = TypeString + FieldName;
4243 ArgName = TypeString + ArgName;
4244 Constructor +=
", " + ArgName;
4246 S += FieldName +
"; // by ref\n";
4249 Constructor +=
", int flags=0)";
4251 bool firsTime =
true;
4253 E = BlockByCopyDecls.end(); I !=
E; ++
I) {
4254 std::string Name = (*I)->getNameAsString();
4256 Constructor +=
" : ";
4260 Constructor +=
", ";
4261 if (isTopLevelBlockPointerType((*I)->getType()))
4262 Constructor += Name +
"((struct __block_impl *)_" + Name +
")";
4264 Constructor += Name +
"(_" + Name +
")";
4268 E = BlockByRefDecls.end(); I !=
E; ++
I) {
4269 std::string Name = (*I)->getNameAsString();
4271 Constructor +=
" : ";
4275 Constructor +=
", ";
4276 Constructor += Name +
"(_" + Name +
"->__forwarding)";
4279 Constructor +=
" {\n";
4281 Constructor +=
" impl.isa = &_NSConcreteGlobalBlock;\n";
4283 Constructor +=
" impl.isa = &_NSConcreteStackBlock;\n";
4284 Constructor +=
" impl.Flags = flags;\n impl.FuncPtr = fp;\n";
4286 Constructor +=
" Desc = desc;\n";
4289 Constructor +=
", int flags=0) {\n";
4291 Constructor +=
" impl.isa = &_NSConcreteGlobalBlock;\n";
4293 Constructor +=
" impl.isa = &_NSConcreteStackBlock;\n";
4294 Constructor +=
" impl.Flags = flags;\n impl.FuncPtr = fp;\n";
4295 Constructor +=
" Desc = desc;\n";
4298 Constructor +=
"}\n";
4304 std::string RewriteModernObjC::SynthesizeBlockDescriptor(std::string DescTag,
4305 std::string ImplTag,
int i,
4308 std::string S =
"\nstatic struct " + DescTag;
4310 S +=
" {\n size_t reserved;\n";
4311 S +=
" size_t Block_size;\n";
4313 S +=
" void (*copy)(struct ";
4314 S += ImplTag; S +=
"*, struct ";
4315 S += ImplTag; S +=
"*);\n";
4317 S +=
" void (*dispose)(struct ";
4318 S += ImplTag; S +=
"*);\n";
4322 S += DescTag +
"_DATA = { 0, sizeof(struct ";
4325 S +=
", __" + FunName.str() +
"_block_copy_" + utostr(i);
4326 S +=
", __" + FunName.str() +
"_block_dispose_" + utostr(i);
4332 void RewriteModernObjC::SynthesizeBlockLiterals(
SourceLocation FunLocStart,
4333 StringRef FunName) {
4334 bool RewriteSC = (GlobalVarDecl &&
4336 GlobalVarDecl->getStorageClass() ==
SC_Static &&
4337 GlobalVarDecl->getType().getCVRQualifiers());
4339 std::string SC(
" void __");
4340 SC += GlobalVarDecl->getNameAsString();
4342 InsertText(FunLocStart, SC);
4346 for (
unsigned i = 0, count=0; i < Blocks.size(); i++) {
4347 CollectBlockDeclRefInfo(Blocks[i]);
4350 for (
int j = 0; j < InnerDeclRefsCount[i]; j++) {
4353 BlockDeclRefs.push_back(Exp);
4354 if (!VD->hasAttr<BlocksAttr>()) {
4355 if (!BlockByCopyDeclsPtrSet.count(VD)) {
4356 BlockByCopyDeclsPtrSet.insert(VD);
4357 BlockByCopyDecls.push_back(VD);
4362 if (!BlockByRefDeclsPtrSet.count(VD)) {
4363 BlockByRefDeclsPtrSet.insert(VD);
4364 BlockByRefDecls.push_back(VD);
4371 ImportedBlockDecls.insert(VD);
4374 std::string ImplTag =
"__" + FunName.str() +
"_block_impl_" + utostr(i);
4375 std::string DescTag =
"__" + FunName.str() +
"_block_desc_" + utostr(i);
4377 std::string CI = SynthesizeBlockImpl(Blocks[i], ImplTag, DescTag);
4379 InsertText(FunLocStart, CI);
4381 std::string CF = SynthesizeBlockFunc(Blocks[i], i, FunName, ImplTag);
4383 InsertText(FunLocStart, CF);
4385 if (ImportedBlockDecls.size()) {
4386 std::string HF = SynthesizeBlockHelperFuncs(Blocks[i], i, FunName, ImplTag);
4387 InsertText(FunLocStart, HF);
4389 std::string BD = SynthesizeBlockDescriptor(DescTag, ImplTag, i, FunName,
4390 ImportedBlockDecls.size() > 0);
4391 InsertText(FunLocStart, BD);
4393 BlockDeclRefs.clear();
4394 BlockByRefDecls.clear();
4395 BlockByRefDeclsPtrSet.clear();
4396 BlockByCopyDecls.clear();
4397 BlockByCopyDeclsPtrSet.clear();
4398 ImportedBlockDecls.clear();
4404 if (GlobalVarDecl->getStorageClass() ==
SC_Static)
4406 if (GlobalVarDecl->getType().isConstQualified())
4408 if (GlobalVarDecl->getType().isVolatileQualified())
4410 if (GlobalVarDecl->getType().isRestrictQualified())
4412 InsertText(FunLocStart, SC);
4414 if (GlobalConstructionExp) {
4418 std::string Tag =
"__";
4420 Tag +=
"_block_impl_";
4421 Tag += utostr(Blocks.size()-1);
4422 std::string globalBuf =
"static ";
4423 globalBuf += Tag; globalBuf +=
" ";
4426 llvm::raw_string_ostream constructorExprBuf(SStr);
4427 GlobalConstructionExp->printPretty(constructorExprBuf,
nullptr,
4429 globalBuf += constructorExprBuf.str();
4431 InsertText(FunLocStart, globalBuf);
4432 GlobalConstructionExp =
nullptr;
4436 InnerDeclRefsCount.clear();
4437 InnerDeclRefs.clear();
4438 RewrittenBlockExprs.clear();
4441 void RewriteModernObjC::InsertBlockLiteralsWithinFunction(
FunctionDecl *FD) {
4443 (!Blocks.empty()) ? getFunctionSourceLocation(*
this, FD)
4445 StringRef FuncName = FD->
getName();
4447 SynthesizeBlockLiterals(FunLocStart, FuncName);
4450 static void BuildUniqueMethodName(std::string &Name,
4456 std::string::size_type loc = 0;
4457 while ((loc = Name.find(
":", loc)) != std::string::npos)
4458 Name.replace(loc, 1,
"_");
4461 void RewriteModernObjC::InsertBlockLiteralsWithinMethod(
ObjCMethodDecl *MD) {
4465 std::string FuncName;
4466 BuildUniqueMethodName(FuncName, MD);
4467 SynthesizeBlockLiterals(FunLocStart, FuncName);
4470 void RewriteModernObjC::GetBlockDeclRefExprs(
Stmt *S) {
4471 for (
Stmt *SubStmt : S->children())
4473 if (
BlockExpr *CBE = dyn_cast<BlockExpr>(SubStmt))
4474 GetBlockDeclRefExprs(CBE->getBody());
4476 GetBlockDeclRefExprs(SubStmt);
4481 HasLocalVariableExternalStorage(DRE->
getDecl()))
4483 BlockDeclRefs.push_back(DRE);
4486 void RewriteModernObjC::GetInnerBlockDeclRefExprs(
Stmt *S,
4487 SmallVectorImpl<DeclRefExpr *> &InnerBlockDeclRefs,
4488 llvm::SmallPtrSetImpl<const DeclContext *> &InnerContexts) {
4489 for (
Stmt *SubStmt : S->children())
4491 if (
BlockExpr *CBE = dyn_cast<BlockExpr>(SubStmt)) {
4492 InnerContexts.insert(cast<DeclContext>(CBE->getBlockDecl()));
4493 GetInnerBlockDeclRefExprs(CBE->getBody(),
4498 GetInnerBlockDeclRefExprs(SubStmt, InnerBlockDeclRefs, InnerContexts);
4501 if (
DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(S)) {
4503 HasLocalVariableExternalStorage(DRE->
getDecl())) {
4504 if (!InnerContexts.count(DRE->
getDecl()->getDeclContext()))
4505 InnerBlockDeclRefs.push_back(DRE);
4507 if (Var->isFunctionOrMethodVarDecl())
4508 ImportedLocalExternalDecls.insert(Var);
4516 bool RewriteModernObjC::convertObjCTypeToCStyleType(
QualType &T) {
4518 convertBlockPointerToFunctionPointer(T);
4524 T = convertFunctionTypeOfBlocks(FT);
4530 convertToUnqualifiedObjCType(T);
4542 SmallVector<QualType, 8> ArgTypes;
4544 bool modified = convertObjCTypeToCStyleType(Res);
4550 if (convertObjCTypeToCStyleType(t))
4552 ArgTypes.push_back(t);
4557 FuncType = getSimpleFunctionType(Res, ArgTypes);
4562 Stmt *RewriteModernObjC::SynthesizeBlockCall(
CallExpr *Exp,
const Expr *BlockExp) {
4566 if (
const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(BlockExp)) {
4568 }
else if (
const MemberExpr *MExpr = dyn_cast<MemberExpr>(BlockExp)) {
4571 else if (
const ParenExpr *PRE = dyn_cast<ParenExpr>(BlockExp)) {
4572 return SynthesizeBlockCall(Exp, PRE->getSubExpr());
4574 else if (
const ImplicitCastExpr *IEXPR = dyn_cast<ImplicitCastExpr>(BlockExp))
4577 dyn_cast<ConditionalOperator>(BlockExp)) {
4578 Expr *LHSExp = CEXPR->getLHS();
4579 Stmt *LHSStmt = SynthesizeBlockCall(Exp, LHSExp);
4580 Expr *RHSExp = CEXPR->getRHS();
4581 Stmt *RHSStmt = SynthesizeBlockCall(Exp, RHSExp);
4582 Expr *CONDExp = CEXPR->getCond();
4589 }
else if (
const ObjCIvarRefExpr *IRE = dyn_cast<ObjCIvarRefExpr>(BlockExp)) {
4592 = dyn_cast<PseudoObjectExpr>(BlockExp)) {
4595 assert(
false &&
"RewriteBlockClass: Bad type");
4597 assert(CPT &&
"RewriteBlockClass: Bad type");
4599 assert(FT &&
"RewriteBlockClass: Bad type");
4609 SmallVector<QualType, 8> ArgTypes;
4612 ArgTypes.push_back(PtrBlock);
4617 if (!convertBlockPointerToFunctionPointer(t))
4618 convertToUnqualifiedObjCType(t);
4619 ArgTypes.push_back(t);
4623 QualType PtrToFuncCastType = getSimpleFunctionType(Exp->
getType(), ArgTypes);
4629 const_cast<Expr*>(BlockExp));
4645 CastExpr *FunkCast = NoTypeInfoCStyleCastExpr(
Context, PtrToFuncCastType,
4649 SmallVector<Expr*, 8> BlkExprs;
4651 BlkExprs.push_back(BlkCast);
4655 BlkExprs.push_back(*I);
4676 Stmt *RewriteModernObjC::RewriteBlockDeclRefExpr(
DeclRefExpr *DeclRefExp) {
4681 HasLocalVariableExternalStorage(DeclRefExp->
getDecl());
4693 StringRef Name = VD->
getName();
4707 ReplaceStmt(DeclRefExp, PE);
4714 Stmt *RewriteModernObjC::RewriteLocalVariableExternalStorage(
DeclRefExpr *DRE) {
4716 if (
VarDecl *Var = dyn_cast<VarDecl>(VD))
4717 if (!ImportedLocalExternalDecls.count(Var))
4725 ReplaceStmt(DRE, PE);
4737 if (!Rewriter::isRewritable(LocStart) || !Rewriter::isRewritable(LocEnd))
4743 const Type* TypePtr = QT->
getAs<Type>();
4744 if (isa<TypeOfExprType>(TypePtr)) {
4745 const TypeOfExprType *TypeOfExprTypePtr = cast<TypeOfExprType>(TypePtr);
4747 std::string TypeAsString =
"(";
4748 RewriteBlockPointerType(TypeAsString, QT);
4749 TypeAsString +=
")";
4750 ReplaceText(LocStart, endBuf-startBuf+1, TypeAsString);
4754 const char *argPtr = startBuf;
4756 while (*argPtr++ && (argPtr < endBuf)) {
4761 ReplaceText(LocStart, 1,
"*");
4767 void RewriteModernObjC::RewriteImplicitCastObjCExpr(
CastExpr *IC) {
4769 if (CastKind != CK_BlockPointerToObjCPointerCast &&
4770 CastKind != CK_AnyPointerToBlockPointerCast)
4774 (void)convertBlockPointerToFunctionPointer(QT);
4776 std::string Str =
"(";
4779 InsertText(IC->
getSubExpr()->getLocStart(), Str);
4782 void RewriteModernObjC::RewriteBlockPointerFunctionArgs(
FunctionDecl *FD) {
4784 unsigned parenCount = 0;
4788 const char *startArgList = strchr(startBuf,
'(');
4790 assert((*startArgList ==
'(') &&
"Rewriter fuzzy parser confused");
4795 assert((DeclLoc.
isValid()) &&
"Invalid DeclLoc");
4797 const char *argPtr = startArgList;
4799 while (*argPtr++ && parenCount) {
4804 ReplaceText(DeclLoc, 1,
"*");
4816 bool RewriteModernObjC::PointerTypeTakesAnyBlockArguments(
QualType QT) {
4823 assert(BPT &&
"BlockPointerTypeTakeAnyBlockArguments(): not a block pointer type");
4828 if (isTopLevelBlockPointerType(I))
4834 bool RewriteModernObjC::PointerTypeTakesAnyObjCQualifiedType(
QualType QT) {
4841 assert(BPT &&
"BlockPointerTypeTakeAnyBlockArguments(): not a block pointer type");
4846 if (I->isObjCQualifiedIdType())
4848 if (I->isObjCObjectPointerType() &&
4849 I->getPointeeType()->isObjCQualifiedInterfaceType())
4857 void RewriteModernObjC::GetExtentOfArgList(
const char *Name,
const char *&LParen,
4858 const char *&RParen) {
4859 const char *argPtr = strchr(Name,
'(');
4860 assert((*argPtr ==
'(') &&
"Rewriter fuzzy parser confused");
4864 unsigned parenCount = 1;
4866 while (*argPtr && parenCount) {
4868 case '(': parenCount++;
break;
4869 case ')': parenCount--;
break;
4872 if (parenCount) argPtr++;
4874 assert((*argPtr ==
')') &&
"Rewriter fuzzy parser confused");
4878 void RewriteModernObjC::RewriteBlockPointerDecl(
NamedDecl *ND) {
4880 RewriteBlockPointerFunctionArgs(FD);
4886 if (
VarDecl *VD = dyn_cast<VarDecl>(ND))
4889 DeclT = TDD->getUnderlyingType();
4890 else if (
FieldDecl *FD = dyn_cast<FieldDecl>(ND))
4893 llvm_unreachable(
"RewriteBlockPointerDecl(): Decl type not yet handled");
4896 const char *endBuf = startBuf;
4898 while (*startBuf !=
'^' && *startBuf !=
';' && startBuf != MainFileStart)
4902 unsigned OrigLength=0;
4905 if (*startBuf ==
'^') {
4911 while (*startBuf !=
')') {
4919 if (PointerTypeTakesAnyBlockArguments(DeclT) ||
4920 PointerTypeTakesAnyObjCQualifiedType(DeclT)) {
4923 DeclLoc = ND->getLocation();
4925 const char *argListBegin, *argListEnd;
4926 GetExtentOfArgList(startBuf, argListBegin, argListEnd);
4927 while (argListBegin < argListEnd) {
4928 if (*argListBegin ==
'^')
4930 else if (*argListBegin ==
'<') {
4932 buf += *argListBegin++;
4934 while (*argListBegin !=
'>') {
4935 buf += *argListBegin++;
4938 buf += *argListBegin;
4942 buf += *argListBegin;
4949 ReplaceText(Start, OrigLength, buf);
4972 std::string RewriteModernObjC::SynthesizeByrefCopyDestroyHelper(
VarDecl *VD,
4975 if (CopyDestroyCache.count(flag))
4977 CopyDestroyCache.insert(flag);
4978 S =
"static void __Block_byref_id_object_copy_";
4980 S +=
"(void *dst, void *src) {\n";
4986 unsigned VoidPtrSize =
4990 S +=
" _Block_object_assign((char*)dst + ";
4991 S += utostr(offset);
4992 S +=
", *(void * *) ((char*)src + ";
4993 S += utostr(offset);
4998 S +=
"static void __Block_byref_id_object_dispose_";
5000 S +=
"(void *src) {\n";
5001 S +=
" _Block_object_dispose(*(void * *) ((char*)src + ";
5002 S += utostr(offset);
5027 void RewriteModernObjC::RewriteByRefVar(
VarDecl *ND,
bool firstDecl,
5035 DeclLoc = ND->getLocation();
5041 std::string ByrefType;
5042 RewriteByRefString(ByrefType, Name, ND,
true);
5043 ByrefType +=
" {\n";
5044 ByrefType +=
" void *__isa;\n";
5045 RewriteByRefString(ByrefType, Name, ND);
5046 ByrefType +=
" *__forwarding;\n";
5047 ByrefType +=
" int __flags;\n";
5048 ByrefType +=
" int __size;\n";
5053 if (HasCopyAndDispose) {
5054 ByrefType +=
" void (*__Block_byref_id_object_copy)(void*, void*);\n";
5055 ByrefType +=
" void (*__Block_byref_id_object_dispose)(void*);\n";
5059 (void)convertBlockPointerToFunctionPointer(T);
5062 ByrefType +=
" " + Name +
";\n";
5063 ByrefType +=
"};\n";
5067 FunLocStart = getFunctionSourceLocation(*
this, CurFunctionDef);
5069 assert(CurMethodDef &&
"RewriteByRefVar - CurMethodDef is null");
5070 FunLocStart = CurMethodDef->getLocStart();
5072 InsertText(FunLocStart, ByrefType);
5078 if (HasCopyAndDispose) {
5086 std::string HF = SynthesizeByrefCopyDestroyHelper(ND, flag);
5094 bool hasInit = (ND->
getInit() !=
nullptr);
5105 if (HasCopyAndDispose)
5109 RewriteByRefString(ByrefType, Name, ND);
5110 std::string ForwardingCastType(
"(");
5111 ForwardingCastType += ByrefType +
" *)";
5112 ByrefType +=
" " + Name +
" = {(void*)";
5113 ByrefType += utostr(isa);
5114 ByrefType +=
"," + ForwardingCastType +
"&" + Name +
", ";
5115 ByrefType += utostr(flags);
5117 ByrefType +=
"sizeof(";
5118 RewriteByRefString(ByrefType, Name, ND);
5120 if (HasCopyAndDispose) {
5121 ByrefType +=
", __Block_byref_id_object_copy_";
5122 ByrefType += utostr(flag);
5123 ByrefType +=
", __Block_byref_id_object_dispose_";
5124 ByrefType += utostr(flag);
5131 DeclLoc = ND->getLocation();
5133 const char *commaBuf = startDeclBuf;
5134 while (*commaBuf !=
',')
5136 assert((*commaBuf ==
',') &&
"RewriteByRefVar: can't find ','");
5138 startBuf = commaBuf;
5142 ByrefType +=
"};\n";
5143 unsigned nameSize = Name.size();
5148 ReplaceText(DeclLoc, endBuf-startBuf+nameSize, ByrefType);
5155 startLoc = ECE->getLParenLoc();
5157 startLoc = E->getLocStart();
5160 ReplaceText(DeclLoc, endBuf-startBuf, ByrefType);
5162 const char separator = lastDecl ?
';' :
',';
5164 const char *separatorBuf = strchr(startInitializerBuf, separator);
5165 assert((*separatorBuf == separator) &&
5166 "RewriteByRefVar: can't find ';' or ','");
5170 InsertText(separatorLoc, lastDecl ?
"}" :
"};\n");
5174 void RewriteModernObjC::CollectBlockDeclRefInfo(
BlockExpr *Exp) {
5176 GetBlockDeclRefExprs(Exp->
getBody());
5177 if (BlockDeclRefs.size()) {
5179 for (
unsigned i = 0; i < BlockDeclRefs.size(); i++)
5180 if (!BlockDeclRefs[i]->getDecl()->hasAttr<BlocksAttr>()) {
5181 if (!BlockByCopyDeclsPtrSet.count(BlockDeclRefs[i]->getDecl())) {
5182 BlockByCopyDeclsPtrSet.insert(BlockDeclRefs[i]->getDecl());
5183 BlockByCopyDecls.push_back(BlockDeclRefs[i]->getDecl());
5187 for (
unsigned i = 0; i < BlockDeclRefs.size(); i++)
5188 if (BlockDeclRefs[i]->getDecl()->hasAttr<BlocksAttr>()) {
5189 if (!BlockByRefDeclsPtrSet.count(BlockDeclRefs[i]->getDecl())) {
5190 BlockByRefDeclsPtrSet.insert(BlockDeclRefs[i]->getDecl());
5191 BlockByRefDecls.push_back(BlockDeclRefs[i]->getDecl());
5195 for (
unsigned i = 0; i < BlockDeclRefs.size(); i++)
5196 if (BlockDeclRefs[i]->getDecl()->hasAttr<BlocksAttr>() ||
5197 BlockDeclRefs[i]->getType()->isObjCObjectPointerType() ||
5198 BlockDeclRefs[i]->getType()->isBlockPointerType())
5199 ImportedBlockDecls.insert(BlockDeclRefs[i]->getDecl());
5203 FunctionDecl *RewriteModernObjC::SynthBlockInitFunctionDecl(StringRef name) {
5212 const SmallVectorImpl<DeclRefExpr *> &InnerBlockDeclRefs) {
5215 Blocks.push_back(Exp);
5217 CollectBlockDeclRefInfo(Exp);
5220 int countOfInnerDecls = 0;
5221 if (!InnerBlockDeclRefs.empty()) {
5222 for (
unsigned i = 0; i < InnerBlockDeclRefs.size(); i++) {
5225 if (!VD->hasAttr<BlocksAttr>() && !BlockByCopyDeclsPtrSet.count(VD)) {
5229 InnerDeclRefs.push_back(Exp); countOfInnerDecls++;
5230 BlockDeclRefs.push_back(Exp);
5231 BlockByCopyDeclsPtrSet.insert(VD);
5232 BlockByCopyDecls.push_back(VD);
5234 if (VD->hasAttr<BlocksAttr>() && !BlockByRefDeclsPtrSet.count(VD)) {
5235 InnerDeclRefs.push_back(Exp); countOfInnerDecls++;
5236 BlockDeclRefs.push_back(Exp);
5237 BlockByRefDeclsPtrSet.insert(VD);
5238 BlockByRefDecls.push_back(VD);
5242 for (
unsigned i = 0; i < InnerBlockDeclRefs.size(); i++)
5243 if (InnerBlockDeclRefs[i]->getDecl()->hasAttr<BlocksAttr>() ||
5244 InnerBlockDeclRefs[i]->getType()->isObjCObjectPointerType() ||
5245 InnerBlockDeclRefs[i]->getType()->isBlockPointerType())
5246 ImportedBlockDecls.insert(InnerBlockDeclRefs[i]->getDecl());
5248 InnerDeclRefsCount.push_back(countOfInnerDecls);
5250 std::string FuncName;
5254 else if (CurMethodDef)
5255 BuildUniqueMethodName(FuncName, CurMethodDef);
5256 else if (GlobalVarDecl)
5257 FuncName = std::string(GlobalVarDecl->getNameAsString());
5259 bool GlobalBlockExpr =
5262 if (GlobalBlockExpr && !GlobalVarDecl) {
5263 Diags.Report(block->getLocation(), GlobalBlockRewriteFailedDiag);
5264 GlobalBlockExpr =
false;
5267 std::string BlockNumber = utostr(Blocks.size()-1);
5269 std::string Func =
"__" + FuncName +
"_block_func_" + BlockNumber;
5272 QualType BFT = convertFunctionTypeOfBlocks(Exp->getFunctionType());
5281 if (GlobalBlockExpr)
5285 Tag += FuncName +
"_block_impl_" + BlockNumber;
5287 FD = SynthBlockInitFunctionDecl(Tag);
5291 SmallVector<Expr*, 4> InitExprs;
5294 FD = SynthBlockInitFunctionDecl(Func);
5299 InitExprs.push_back(castExpr);
5302 std::string DescData =
"__" + FuncName +
"_block_desc_" + BlockNumber +
"_DATA";
5318 InitExprs.push_back(DescRefExpr);
5321 if (BlockDeclRefs.size()) {
5325 E = BlockByCopyDecls.end(); I !=
E; ++
I) {
5326 if (isObjCType((*I)->getType())) {
5328 FD = SynthBlockInitFunctionDecl((*I)->getName());
5331 if (HasLocalVariableExternalStorage(*I)) {
5337 }
else if (isTopLevelBlockPointerType((*I)->getType())) {
5338 FD = SynthBlockInitFunctionDecl((*I)->getName());
5344 FD = SynthBlockInitFunctionDecl((*I)->getName());
5347 if (HasLocalVariableExternalStorage(*I)) {
5355 InitExprs.push_back(Exp);
5359 E = BlockByRefDecls.end(); I !=
E; ++
I) {
5362 std::string RecName;
5363 RewriteByRefString(RecName, Name, ND,
true);
5365 +
sizeof(
"struct"));
5369 assert(RD &&
"SynthBlockInitExpr(): Can't find RecordDecl");
5372 FD = SynthBlockInitFunctionDecl((*I)->getName());
5375 bool isNestedCapturedVar =
false;
5377 for (
const auto &CI : block->
captures()) {
5378 const VarDecl *variable = CI.getVariable();
5379 if (variable == ND && CI.isNested()) {
5380 assert (CI.isByRef() &&
5381 "SynthBlockInitExpr - captured block variable is not byref");
5382 isNestedCapturedVar =
true;
5388 if (!isNestedCapturedVar)
5392 Exp = NoTypeInfoCStyleCastExpr(
Context, castT, CK_BitCast, Exp);
5393 InitExprs.push_back(Exp);
5396 if (ImportedBlockDecls.size()) {
5403 InitExprs.push_back(FlagExp);
5408 if (GlobalBlockExpr) {
5409 assert (!GlobalConstructionExp &&
5410 "SynthBlockInitExpr - GlobalConstructionExp must be null");
5411 GlobalConstructionExp = NewRep;
5418 NewRep = NoTypeInfoCStyleCastExpr(
Context, FType, CK_BitCast,
5424 BlockDeclRefs.clear();
5425 BlockByRefDecls.clear();
5426 BlockByRefDeclsPtrSet.clear();
5427 BlockByCopyDecls.clear();
5428 BlockByCopyDeclsPtrSet.clear();
5429 ImportedBlockDecls.clear();
5433 bool RewriteModernObjC::IsDeclStmtInForeachHeader(
DeclStmt *DS) {
5435 dyn_cast<ObjCForCollectionStmt>(Stmts.back()))
5436 return CS->getElement() == DS;
5444 Stmt *RewriteModernObjC::RewriteFunctionBodyOrGlobalInitializer(
Stmt *S) {
5445 if (isa<SwitchStmt>(S) || isa<WhileStmt>(S) ||
5446 isa<DoStmt>(S) || isa<ForStmt>(S))
5448 else if (isa<ObjCForCollectionStmt>(S)) {
5450 ObjCBcLabelNo.push_back(++BcLabelCount);
5457 return RewritePropertyOrImplicitSetter(PseudoOp);
5459 return RewritePropertyOrImplicitGetter(PseudoOp);
5461 }
else if (
ObjCIvarRefExpr *IvarRefExpr = dyn_cast<ObjCIvarRefExpr>(S)) {
5462 return RewriteObjCIvarRefExpr(IvarRefExpr);
5464 else if (isa<OpaqueValueExpr>(S))
5465 S = cast<OpaqueValueExpr>(
S)->getSourceExpr();
5470 for (
Stmt *&childStmt : S->children())
5472 Stmt *newStmt = RewriteFunctionBodyOrGlobalInitializer(childStmt);
5474 childStmt = newStmt;
5478 if (
BlockExpr *BE = dyn_cast<BlockExpr>(S)) {
5479 SmallVector<DeclRefExpr *, 8> InnerBlockDeclRefs;
5480 llvm::SmallPtrSet<const DeclContext *, 8> InnerContexts;
5481 InnerContexts.insert(BE->getBlockDecl());
5482 ImportedLocalExternalDecls.clear();
5483 GetInnerBlockDeclRefExprs(BE->getBody(),
5484 InnerBlockDeclRefs, InnerContexts);
5486 Stmt *SaveCurrentBody = CurrentBody;
5487 CurrentBody = BE->getBody();
5488 PropParentMap =
nullptr;
5494 bool saveDisableReplaceStmt = DisableReplaceStmt;
5495 DisableReplaceStmt =
false;
5496 RewriteFunctionBodyOrGlobalInitializer(BE->getBody());
5497 DisableReplaceStmt = saveDisableReplaceStmt;
5498 CurrentBody = SaveCurrentBody;
5499 PropParentMap =
nullptr;
5500 ImportedLocalExternalDecls.clear();
5502 std::string Str = Rewrite.getRewrittenText(BE->getSourceRange());
5503 RewrittenBlockExprs[BE] = Str;
5505 Stmt *blockTranscribed = SynthBlockInitExpr(BE, InnerBlockDeclRefs);
5508 ReplaceStmt(S, blockTranscribed);
5509 return blockTranscribed;
5513 return RewriteAtEncode(AtEncode);
5516 return RewriteAtSelector(AtSelector);
5519 return RewriteObjCStringLiteral(AtString);
5522 return RewriteObjCBoolLiteralExpr(BoolLitExpr);
5525 return RewriteObjCBoxedExpr(BoxedExpr);
5528 return RewriteObjCArrayLiteralExpr(ArrayLitExpr);
5531 dyn_cast<ObjCDictionaryLiteral>(S))
5532 return RewriteObjCDictionaryLiteralExpr(DictionaryLitExpr);
5543 std::string messString;
5544 messString +=
"// ";
5545 messString.append(startBuf, endBuf-startBuf+1);
5554 return RewriteMessageExpr(MessExpr);
5558 dyn_cast<ObjCAutoreleasePoolStmt>(S)) {
5559 return RewriteObjCAutoreleasePoolStmt(StmtAutoRelease);
5563 return RewriteObjCTryStmt(StmtTry);
5566 return RewriteObjCSynchronizedStmt(StmtTry);
5569 return RewriteObjCThrowStmt(StmtThrow);
5572 return RewriteObjCProtocolExpr(ProtocolExp);
5575 dyn_cast<ObjCForCollectionStmt>(S))
5576 return RewriteObjCForCollectionStmt(StmtForCollection,
5579 dyn_cast<BreakStmt>(S))
5580 return RewriteBreakStmt(StmtBreakStmt);
5582 dyn_cast<ContinueStmt>(S))
5583 return RewriteContinueStmt(StmtContinueStmt);
5587 if (
DeclStmt *DS = dyn_cast<DeclStmt>(S)) {
5597 if (Stmts.empty() || !IsDeclStmtInForeachHeader(DS))
5598 RewriteObjCQualifiedInterfaceTypes(*DS->
decl_begin());
5604 if (
ValueDecl *ND = dyn_cast<ValueDecl>(SD)) {
5605 if (isTopLevelBlockPointerType(ND->
getType()))
5606 RewriteBlockPointerDecl(ND);
5608 CheckFunctionPointerDecl(ND->
getType(), ND);
5609 if (
VarDecl *VD = dyn_cast<VarDecl>(SD)) {
5610 if (VD->hasAttr<BlocksAttr>()) {
5611 static unsigned uniqueByrefDeclCount = 0;
5612 assert(!BlockByRefDeclNo.count(ND) &&
5613 "RewriteFunctionBodyOrGlobalInitializer: Duplicate byref decl");
5614 BlockByRefDeclNo[ND] = uniqueByrefDeclCount++;
5615 RewriteByRefVar(VD, (DI == DS->
decl_begin()), ((DI+1) == DE));
5618 RewriteTypeOfDecl(VD);
5622 if (isTopLevelBlockPointerType(TD->getUnderlyingType()))
5623 RewriteBlockPointerDecl(TD);
5624 else if (TD->getUnderlyingType()->isFunctionPointerType())
5625 CheckFunctionPointerDecl(TD->getUnderlyingType(), TD);
5631 RewriteObjCQualifiedInterfaceTypes(CE);
5633 if (isa<SwitchStmt>(S) || isa<WhileStmt>(
S) ||
5634 isa<DoStmt>(S) || isa<ForStmt>(
S)) {
5635 assert(!Stmts.empty() &&
"Statement stack is empty");
5636 assert ((isa<SwitchStmt>(Stmts.back()) || isa<WhileStmt>(Stmts.back()) ||
5637 isa<DoStmt>(Stmts.back()) || isa<ForStmt>(Stmts.back()))
5638 &&
"Statement stack mismatch");
5642 if (
DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(S)) {
5644 if (VD->hasAttr<BlocksAttr>())
5645 return RewriteBlockDeclRefExpr(DRE);
5646 if (HasLocalVariableExternalStorage(VD))
5647 return RewriteLocalVariableExternalStorage(DRE);
5650 if (
CallExpr *CE = dyn_cast<CallExpr>(S)) {
5653 ReplaceStmt(S, BlockCall);
5658 RewriteCastExpr(CE);
5661 RewriteImplicitCastObjCExpr(ICE);
5671 llvm::raw_string_ostream Buf(SStr);
5672 Replacement->printPretty(Buf);
5673 const std::string &Str = Buf.str();
5675 printf(
"CAST = %s\n", &Str[0]);
5676 InsertText(ICE->
getSubExpr()->getLocStart(), Str);
5685 void RewriteModernObjC::RewriteRecordBody(
RecordDecl *RD) {
5686 for (
auto *FD : RD->
fields()) {
5687 if (isTopLevelBlockPointerType(FD->
getType()))
5688 RewriteBlockPointerDecl(FD);
5691 RewriteObjCQualifiedInterfaceTypes(FD);
5697 void RewriteModernObjC::HandleDeclInMainFile(
Decl *D) {
5698 switch (D->getKind()) {
5699 case Decl::Function: {
5707 RewriteBlocksInFunctionProtoType(FD->
getType(), FD);
5714 CurFunctionDef = FD;
5717 cast_or_null<CompoundStmt>(RewriteFunctionBodyOrGlobalInitializer(Body));
5719 CurrentBody =
nullptr;
5720 if (PropParentMap) {
5721 delete PropParentMap;
5722 PropParentMap =
nullptr;
5726 InsertBlockLiteralsWithinFunction(FD);
5727 RewriteLineDirective(D);
5728 CurFunctionDef =
nullptr;
5732 case Decl::ObjCMethod: {
5738 cast_or_null<CompoundStmt>(RewriteFunctionBodyOrGlobalInitializer(Body));
5740 CurrentBody =
nullptr;
5741 if (PropParentMap) {
5742 delete PropParentMap;
5743 PropParentMap =
nullptr;
5745 InsertBlockLiteralsWithinMethod(MD);
5746 RewriteLineDirective(D);
5747 CurMethodDef =
nullptr;
5751 case Decl::ObjCImplementation: {
5753 ClassImplementation.push_back(CI);
5756 case Decl::ObjCCategoryImpl: {
5758 CategoryImplementation.push_back(CI);
5762 VarDecl *VD = cast<VarDecl>(D);
5763 RewriteObjCQualifiedInterfaceTypes(VD);
5764 if (isTopLevelBlockPointerType(VD->
getType()))
5765 RewriteBlockPointerDecl(VD);
5767 CheckFunctionPointerDecl(VD->
getType(), VD);
5770 RewriteCastExpr(CE);
5776 RewriteRecordBody(RD);
5781 RewriteFunctionBodyOrGlobalInitializer(VD->
getInit());
5782 CurrentBody =
nullptr;
5783 if (PropParentMap) {
5784 delete PropParentMap;
5785 PropParentMap =
nullptr;
5788 GlobalVarDecl =
nullptr;
5792 RewriteCastExpr(CE);
5798 case Decl::Typedef: {
5800 if (isTopLevelBlockPointerType(TD->getUnderlyingType()))
5801 RewriteBlockPointerDecl(TD);
5802 else if (TD->getUnderlyingType()->isFunctionPointerType())
5803 CheckFunctionPointerDecl(TD->getUnderlyingType(), TD);
5805 RewriteObjCQualifiedInterfaceTypes(TD);
5809 case Decl::CXXRecord:
5810 case Decl::Record: {
5813 RewriteRecordBody(RD);
5827 std::string &Result) {
5830 Result +=
"static ";
5831 Result +=
"struct _protocol_t *";
5832 Result +=
"_OBJC_PROTOCOL_REFERENCE_$_";
5839 void RewriteModernObjC::HandleTranslationUnit(
ASTContext &
C) {
5840 if (Diags.hasErrorOccurred())
5845 for (
unsigned i = 0, e = FunctionDefinitionsSeen.size(); i < e; i++) {
5850 HandleTopLevelSingleDecl(FDecl);
5856 RewriteObjCProtocolMetaData(ProtDecl, Preamble);
5857 Write_ProtocolExprReferencedMetadata(Context, ProtDecl, Preamble);
5862 if (ClassImplementation.size() || CategoryImplementation.size())
5863 RewriteImplementations();
5865 for (
unsigned i = 0, e = ObjCInterfacesSeen.size(); i < e; i++) {
5871 RewriteInterfaceDecl(CDecl);
5877 Rewrite.getRewriteBufferFor(MainFileID)) {
5879 *OutFile << std::string(RewriteBuf->begin(), RewriteBuf->end());
5881 llvm::errs() <<
"No changes\n";
5884 if (ClassImplementation.size() || CategoryImplementation.size() ||
5885 ProtocolExprDecls.size()) {
5887 std::string ResultStr;
5888 RewriteMetaDataIntoBuffer(ResultStr);
5890 *OutFile << ResultStr;
5894 std::string ResultStr;
5895 WriteImageInfo(ResultStr);
5896 *OutFile << ResultStr;
5901 void RewriteModernObjC::Initialize(
ASTContext &context) {
5902 InitializeCommon(context);
5904 Preamble +=
"#ifndef __OBJC2__\n";
5905 Preamble +=
"#define __OBJC2__\n";
5906 Preamble +=
"#endif\n";
5911 Preamble =
"#pragma once\n";
5912 Preamble +=
"struct objc_selector; struct objc_class;\n";
5913 Preamble +=
"struct __rw_objc_super { \n\tstruct objc_object *object; ";
5914 Preamble +=
"\n\tstruct objc_object *superClass; ";
5916 Preamble +=
"\n\t__rw_objc_super(struct objc_object *o, struct objc_object *s) ";
5917 Preamble +=
": object(o), superClass(s) {} ";
5918 Preamble +=
"\n};\n";
5920 if (LangOpts.MicrosoftExt) {
5923 Preamble +=
"\n#pragma section(\".objc_classlist$B\", long, read, write)\n";
5924 Preamble +=
"#pragma section(\".objc_catlist$B\", long, read, write)\n";
5925 Preamble +=
"#pragma section(\".objc_imageinfo$B\", long, read, write)\n";
5926 Preamble +=
"#pragma section(\".objc_nlclslist$B\", long, read, write)\n";
5927 Preamble +=
"#pragma section(\".objc_nlcatlist$B\", long, read, write)\n";
5929 Preamble +=
"#pragma section(\".cat_cls_meth$B\", long, read, write)\n";
5930 Preamble +=
"#pragma section(\".inst_meth$B\", long, read, write)\n";
5931 Preamble +=
"#pragma section(\".cls_meth$B\", long, read, write)\n";
5932 Preamble +=
"#pragma section(\".objc_ivar$B\", long, read, write)\n";
5936 Preamble +=
"#pragma section(\".objc_selrefs$B\", long, read, write)\n";
5937 Preamble +=
"#pragma section(\".objc_classrefs$B\", long, read, write)\n";
5938 Preamble +=
"#pragma section(\".objc_superrefs$B\", long, read, write)\n";
5941 Preamble +=
"#ifndef _REWRITER_typedef_Protocol\n";
5942 Preamble +=
"typedef struct objc_object Protocol;\n";
5943 Preamble +=
"#define _REWRITER_typedef_Protocol\n";
5944 Preamble +=
"#endif\n";
5945 if (LangOpts.MicrosoftExt) {
5946 Preamble +=
"#define __OBJC_RW_DLLIMPORT extern \"C\" __declspec(dllimport)\n";
5947 Preamble +=
"#define __OBJC_RW_STATICIMPORT extern \"C\"\n";
5950 Preamble +=
"#define __OBJC_RW_DLLIMPORT extern\n";
5952 Preamble +=
"__OBJC_RW_DLLIMPORT void objc_msgSend(void);\n";
5953 Preamble +=
"__OBJC_RW_DLLIMPORT void objc_msgSendSuper(void);\n";
5954 Preamble +=
"__OBJC_RW_DLLIMPORT void objc_msgSend_stret(void);\n";
5955 Preamble +=
"__OBJC_RW_DLLIMPORT void objc_msgSendSuper_stret(void);\n";
5956 Preamble +=
"__OBJC_RW_DLLIMPORT void objc_msgSend_fpret(void);\n";
5958 Preamble +=
"__OBJC_RW_DLLIMPORT struct objc_class *objc_getClass";
5959 Preamble +=
"(const char *);\n";
5960 Preamble +=
"__OBJC_RW_DLLIMPORT struct objc_class *class_getSuperclass";
5961 Preamble +=
"(struct objc_class *);\n";
5962 Preamble +=
"__OBJC_RW_DLLIMPORT struct objc_class *objc_getMetaClass";
5963 Preamble +=
"(const char *);\n";
5964 Preamble +=
"__OBJC_RW_DLLIMPORT void objc_exception_throw( struct objc_object *);\n";
5966 Preamble +=
"__OBJC_RW_DLLIMPORT int objc_sync_enter( struct objc_object *);\n";
5967 Preamble +=
"__OBJC_RW_DLLIMPORT int objc_sync_exit( struct objc_object *);\n";
5968 Preamble +=
"__OBJC_RW_DLLIMPORT Protocol *objc_getProtocol(const char *);\n";
5969 Preamble +=
"#ifdef _WIN64\n";
5970 Preamble +=
"typedef unsigned long long _WIN_NSUInteger;\n";
5971 Preamble +=
"#else\n";
5972 Preamble +=
"typedef unsigned int _WIN_NSUInteger;\n";
5973 Preamble +=
"#endif\n";
5974 Preamble +=
"#ifndef __FASTENUMERATIONSTATE\n";
5975 Preamble +=
"struct __objcFastEnumerationState {\n\t";
5976 Preamble +=
"unsigned long state;\n\t";
5977 Preamble +=
"void **itemsPtr;\n\t";
5978 Preamble +=
"unsigned long *mutationsPtr;\n\t";
5979 Preamble +=
"unsigned long extra[5];\n};\n";
5980 Preamble +=
"__OBJC_RW_DLLIMPORT void objc_enumerationMutation(struct objc_object *);\n";
5981 Preamble +=
"#define __FASTENUMERATIONSTATE\n";
5982 Preamble +=
"#endif\n";
5983 Preamble +=
"#ifndef __NSCONSTANTSTRINGIMPL\n";
5984 Preamble +=
"struct __NSConstantStringImpl {\n";
5985 Preamble +=
" int *isa;\n";
5986 Preamble +=
" int flags;\n";
5987 Preamble +=
" char *str;\n";
5988 Preamble +=
"#if _WIN64\n";
5989 Preamble +=
" long long length;\n";
5990 Preamble +=
"#else\n";
5991 Preamble +=
" long length;\n";
5992 Preamble +=
"#endif\n";
5994 Preamble +=
"#ifdef CF_EXPORT_CONSTANT_STRING\n";
5995 Preamble +=
"extern \"C\" __declspec(dllexport) int __CFConstantStringClassReference[];\n";
5996 Preamble +=
"#else\n";
5997 Preamble +=
"__OBJC_RW_DLLIMPORT int __CFConstantStringClassReference[];\n";
5998 Preamble +=
"#endif\n";
5999 Preamble +=
"#define __NSCONSTANTSTRINGIMPL\n";
6000 Preamble +=
"#endif\n";
6002 Preamble +=
"#ifndef BLOCK_IMPL\n";
6003 Preamble +=
"#define BLOCK_IMPL\n";
6004 Preamble +=
"struct __block_impl {\n";
6005 Preamble +=
" void *isa;\n";
6006 Preamble +=
" int Flags;\n";
6007 Preamble +=
" int Reserved;\n";
6008 Preamble +=
" void *FuncPtr;\n";
6010 Preamble +=
"// Runtime copy/destroy helper functions (from Block_private.h)\n";
6011 Preamble +=
"#ifdef __OBJC_EXPORT_BLOCKS\n";
6012 Preamble +=
"extern \"C\" __declspec(dllexport) "
6013 "void _Block_object_assign(void *, const void *, const int);\n";
6014 Preamble +=
"extern \"C\" __declspec(dllexport) void _Block_object_dispose(const void *, const int);\n";
6015 Preamble +=
"extern \"C\" __declspec(dllexport) void *_NSConcreteGlobalBlock[32];\n";
6016 Preamble +=
"extern \"C\" __declspec(dllexport) void *_NSConcreteStackBlock[32];\n";
6017 Preamble +=
"#else\n";
6018 Preamble +=
"__OBJC_RW_DLLIMPORT void _Block_object_assign(void *, const void *, const int);\n";
6019 Preamble +=
"__OBJC_RW_DLLIMPORT void _Block_object_dispose(const void *, const int);\n";
6020 Preamble +=
"__OBJC_RW_DLLIMPORT void *_NSConcreteGlobalBlock[32];\n";
6021 Preamble +=
"__OBJC_RW_DLLIMPORT void *_NSConcreteStackBlock[32];\n";
6022 Preamble +=
"#endif\n";
6023 Preamble +=
"#endif\n";
6024 if (LangOpts.MicrosoftExt) {
6025 Preamble +=
"#undef __OBJC_RW_DLLIMPORT\n";
6026 Preamble +=
"#undef __OBJC_RW_STATICIMPORT\n";
6027 Preamble +=
"#ifndef KEEP_ATTRIBUTES\n";
6028 Preamble +=
"#define __attribute__(X)\n";
6029 Preamble +=
"#endif\n";
6030 Preamble +=
"#ifndef __weak\n";
6031 Preamble +=
"#define __weak\n";
6032 Preamble +=
"#endif\n";
6033 Preamble +=
"#ifndef __block\n";
6034 Preamble +=
"#define __block\n";
6035 Preamble +=
"#endif\n";
6038 Preamble +=
"#define __block\n";
6039 Preamble +=
"#define __weak\n";
6043 Preamble +=
"\n#include <stdarg.h>\n";
6044 Preamble +=
"struct __NSContainer_literal {\n";
6045 Preamble +=
" void * *arr;\n";
6046 Preamble +=
" __NSContainer_literal (unsigned int count, ...) {\n";
6047 Preamble +=
"\tva_list marker;\n";
6048 Preamble +=
"\tva_start(marker, count);\n";
6049 Preamble +=
"\tarr = new void *[count];\n";
6050 Preamble +=
"\tfor (unsigned i = 0; i < count; i++)\n";
6051 Preamble +=
"\t arr[i] = va_arg(marker, void *);\n";
6052 Preamble +=
"\tva_end( marker );\n";
6053 Preamble +=
" };\n";
6054 Preamble +=
" ~__NSContainer_literal() {\n";
6055 Preamble +=
"\tdelete[] arr;\n";
6060 Preamble +=
"extern \"C\" __declspec(dllimport) void * objc_autoreleasePoolPush(void);\n";
6061 Preamble +=
"extern \"C\" __declspec(dllimport) void objc_autoreleasePoolPop(void *);\n\n";
6062 Preamble +=
"struct __AtAutoreleasePool {\n";
6063 Preamble +=
" __AtAutoreleasePool() {atautoreleasepoolobj = objc_autoreleasePoolPush();}\n";
6064 Preamble +=
" ~__AtAutoreleasePool() {objc_autoreleasePoolPop(atautoreleasepoolobj);}\n";
6065 Preamble +=
" void * atautoreleasepoolobj;\n";
6070 Preamble +=
"\n#define __OFFSETOFIVAR__(TYPE, MEMBER) ((long long) &((TYPE *)0)->MEMBER)\n";
6075 void RewriteModernObjC::RewriteIvarOffsetComputation(
ObjCIvarDecl *ivar,
6076 std::string &Result) {
6077 Result +=
"__OFFSETOFIVAR__(struct ";
6079 if (LangOpts.MicrosoftExt)
6083 ObjCIvarBitfieldGroupDecl(ivar, Result);
6191 static void WriteModernMetadataDeclarations(
ASTContext *Context, std::string &Result) {
6192 static bool meta_data_declared =
false;
6193 if (meta_data_declared)
6196 Result +=
"\nstruct _prop_t {\n";
6197 Result +=
"\tconst char *name;\n";
6198 Result +=
"\tconst char *attributes;\n";
6201 Result +=
"\nstruct _protocol_t;\n";
6203 Result +=
"\nstruct _objc_method {\n";
6204 Result +=
"\tstruct objc_selector * _cmd;\n";
6205 Result +=
"\tconst char *method_type;\n";
6206 Result +=
"\tvoid *_imp;\n";
6209 Result +=
"\nstruct _protocol_t {\n";
6210 Result +=
"\tvoid * isa; // NULL\n";
6211 Result +=
"\tconst char *protocol_name;\n";
6212 Result +=
"\tconst struct _protocol_list_t * protocol_list; // super protocols\n";
6213 Result +=
"\tconst struct method_list_t *instance_methods;\n";
6214 Result +=
"\tconst struct method_list_t *class_methods;\n";
6215 Result +=
"\tconst struct method_list_t *optionalInstanceMethods;\n";
6216 Result +=
"\tconst struct method_list_t *optionalClassMethods;\n";
6217 Result +=
"\tconst struct _prop_list_t * properties;\n";
6218 Result +=
"\tconst unsigned int size; // sizeof(struct _protocol_t)\n";
6219 Result +=
"\tconst unsigned int flags; // = 0\n";
6220 Result +=
"\tconst char ** extendedMethodTypes;\n";
6223 Result +=
"\nstruct _ivar_t {\n";
6224 Result +=
"\tunsigned long int *offset; // pointer to ivar offset location\n";
6225 Result +=
"\tconst char *name;\n";
6226 Result +=
"\tconst char *type;\n";
6227 Result +=
"\tunsigned int alignment;\n";
6228 Result +=
"\tunsigned int size;\n";
6231 Result +=
"\nstruct _class_ro_t {\n";
6232 Result +=
"\tunsigned int flags;\n";
6233 Result +=
"\tunsigned int instanceStart;\n";
6234 Result +=
"\tunsigned int instanceSize;\n";
6236 if (Triple.getArch() == llvm::Triple::x86_64)
6237 Result +=
"\tunsigned int reserved;\n";
6238 Result +=
"\tconst unsigned char *ivarLayout;\n";
6239 Result +=
"\tconst char *name;\n";
6240 Result +=
"\tconst struct _method_list_t *baseMethods;\n";
6241 Result +=
"\tconst struct _objc_protocol_list *baseProtocols;\n";
6242 Result +=
"\tconst struct _ivar_list_t *ivars;\n";
6243 Result +=
"\tconst unsigned char *weakIvarLayout;\n";
6244 Result +=
"\tconst struct _prop_list_t *properties;\n";
6247 Result +=
"\nstruct _class_t {\n";
6248 Result +=
"\tstruct _class_t *isa;\n";
6249 Result +=
"\tstruct _class_t *superclass;\n";
6250 Result +=
"\tvoid *cache;\n";
6251 Result +=
"\tvoid *vtable;\n";
6252 Result +=
"\tstruct _class_ro_t *ro;\n";
6255 Result +=
"\nstruct _category_t {\n";
6256 Result +=
"\tconst char *name;\n";
6257 Result +=
"\tstruct _class_t *cls;\n";
6258 Result +=
"\tconst struct _method_list_t *instance_methods;\n";
6259 Result +=
"\tconst struct _method_list_t *class_methods;\n";
6260 Result +=
"\tconst struct _protocol_list_t *protocols;\n";
6261 Result +=
"\tconst struct _prop_list_t *properties;\n";
6264 Result +=
"extern \"C\" __declspec(dllimport) struct objc_cache _objc_empty_cache;\n";
6265 Result +=
"#pragma warning(disable:4273)\n";
6266 meta_data_declared =
true;
6269 static void Write_protocol_list_t_TypeDecl(std::string &Result,
6270 long super_protocol_count) {
6271 Result +=
"struct /*_protocol_list_t*/"; Result +=
" {\n";
6272 Result +=
"\tlong protocol_count; // Note, this is 32/64 bit\n";
6273 Result +=
"\tstruct _protocol_t *super_protocols[";
6274 Result += utostr(super_protocol_count); Result +=
"];\n";
6278 static void Write_method_list_t_TypeDecl(std::string &Result,
6279 unsigned int method_count) {
6280 Result +=
"struct /*_method_list_t*/"; Result +=
" {\n";
6281 Result +=
"\tunsigned int entsize; // sizeof(struct _objc_method)\n";
6282 Result +=
"\tunsigned int method_count;\n";
6283 Result +=
"\tstruct _objc_method method_list[";
6284 Result += utostr(method_count); Result +=
"];\n";
6288 static void Write__prop_list_t_TypeDecl(std::string &Result,
6289 unsigned int property_count) {
6290 Result +=
"struct /*_prop_list_t*/"; Result +=
" {\n";
6291 Result +=
"\tunsigned int entsize; // sizeof(struct _prop_t)\n";
6292 Result +=
"\tunsigned int count_of_properties;\n";
6293 Result +=
"\tstruct _prop_t prop_list[";
6294 Result += utostr(property_count); Result +=
"];\n";
6298 static void Write__ivar_list_t_TypeDecl(std::string &Result,
6299 unsigned int ivar_count) {
6300 Result +=
"struct /*_ivar_list_t*/"; Result +=
" {\n";
6301 Result +=
"\tunsigned int entsize; // sizeof(struct _prop_t)\n";
6302 Result +=
"\tunsigned int count;\n";
6303 Result +=
"\tstruct _ivar_t ivar_list[";
6304 Result += utostr(ivar_count); Result +=
"];\n";
6308 static void Write_protocol_list_initializer(
ASTContext *Context, std::string &Result,
6309 ArrayRef<ObjCProtocolDecl *> SuperProtocols,
6311 StringRef ProtocolName) {
6312 if (SuperProtocols.size() > 0) {
6313 Result +=
"\nstatic ";
6314 Write_protocol_list_t_TypeDecl(Result, SuperProtocols.size());
6315 Result +=
" "; Result += VarName;
6316 Result += ProtocolName;
6317 Result +=
" __attribute__ ((used, section (\"__DATA,__objc_const\"))) = {\n";
6318 Result +=
"\t"; Result += utostr(SuperProtocols.size()); Result +=
",\n";
6319 for (
unsigned i = 0, e = SuperProtocols.size(); i < e; i++) {
6321 Result +=
"\t&"; Result +=
"_OBJC_PROTOCOL_";
6331 static void Write_method_list_t_initializer(RewriteModernObjC &RewriteObj,
6333 ArrayRef<ObjCMethodDecl *> Methods,
6335 StringRef TopLevelDeclName,
6337 if (Methods.size() > 0) {
6338 Result +=
"\nstatic ";
6339 Write_method_list_t_TypeDecl(Result, Methods.size());
6340 Result +=
" "; Result += VarName;
6341 Result += TopLevelDeclName;
6342 Result +=
" __attribute__ ((used, section (\"__DATA,__objc_const\"))) = {\n";
6343 Result +=
"\t"; Result +=
"sizeof(_objc_method)"; Result +=
",\n";
6344 Result +=
"\t"; Result += utostr(Methods.size()); Result +=
",\n";
6345 for (
unsigned i = 0, e = Methods.size(); i < e; i++) {
6348 Result +=
"\t{{(struct objc_selector *)\"";
6350 Result +=
"\t{(struct objc_selector *)\"";
6351 Result += (MD)->getSelector().getAsString(); Result +=
"\"";
6353 std::string MethodTypeString;
6355 Result +=
"\""; Result += MethodTypeString; Result +=
"\"";
6360 Result +=
"(void *)";
6361 Result += RewriteObj.MethodInternalNames[MD];
6372 static void Write_prop_list_t_initializer(RewriteModernObjC &RewriteObj,
6374 ArrayRef<ObjCPropertyDecl *> Properties,
6375 const Decl *Container,
6377 StringRef ProtocolName) {
6378 if (Properties.size() > 0) {
6379 Result +=
"\nstatic ";
6380 Write__prop_list_t_TypeDecl(Result, Properties.size());
6381 Result +=
" "; Result += VarName;
6382 Result += ProtocolName;
6383 Result +=
" __attribute__ ((used, section (\"__DATA,__objc_const\"))) = {\n";
6384 Result +=
"\t"; Result +=
"sizeof(_prop_t)"; Result +=
",\n";
6385 Result +=
"\t"; Result += utostr(Properties.size()); Result +=
",\n";
6386 for (
unsigned i = 0, e = Properties.size(); i < e; i++) {
6392 Result += PropDecl->
getName(); Result +=
"\",";
6393 std::string PropertyTypeString, QuotePropertyTypeString;
6395 RewriteObj.QuoteDoublequotes(PropertyTypeString, QuotePropertyTypeString);
6396 Result +=
"\""; Result += QuotePropertyTypeString; Result +=
"\"";
6407 enum MetaDataDlags {
6411 OBJC2_CLS_HIDDEN = 0x10,
6412 CLS_EXCEPTION = 0x20,
6415 CLS_HAS_IVAR_RELEASER = 0x40,
6417 CLS_COMPILED_BY_ARC = 0x80
6420 static void Write__class_ro_t_initializer(
ASTContext *Context, std::string &Result,
6422 const std::string &InstanceStart,
6423 const std::string &InstanceSize,
6424 ArrayRef<ObjCMethodDecl *>baseMethods,
6425 ArrayRef<ObjCProtocolDecl *>baseProtocols,
6426 ArrayRef<ObjCIvarDecl *>ivars,
6427 ArrayRef<ObjCPropertyDecl *>Properties,
6429 StringRef ClassName) {
6430 Result +=
"\nstatic struct _class_ro_t ";
6431 Result += VarName; Result += ClassName;
6432 Result +=
" __attribute__ ((used, section (\"__DATA,__objc_const\"))) = {\n";
6434 Result += llvm::utostr(flags); Result +=
", ";
6435 Result += InstanceStart; Result +=
", ";
6436 Result += InstanceSize; Result +=
", \n";
6439 if (Triple.getArch() == llvm::Triple::x86_64)
6441 Result +=
"(unsigned int)0, \n\t";
6443 Result +=
"0, \n\t";
6444 Result +=
"\""; Result += ClassName; Result +=
"\",\n\t";
6445 bool metaclass = ((flags & CLS_META) != 0);
6446 if (baseMethods.size() > 0) {
6447 Result +=
"(const struct _method_list_t *)&";
6449 Result +=
"_OBJC_$_CLASS_METHODS_";
6451 Result +=
"_OBJC_$_INSTANCE_METHODS_";
6452 Result += ClassName;
6456 Result +=
"0, \n\t";
6458 if (!metaclass && baseProtocols.size() > 0) {
6459 Result +=
"(const struct _objc_protocol_list *)&";
6460 Result +=
"_OBJC_CLASS_PROTOCOLS_$_"; Result += ClassName;
6464 Result +=
"0, \n\t";
6466 if (!metaclass && ivars.size() > 0) {
6467 Result +=
"(const struct _ivar_list_t *)&";
6468 Result +=
"_OBJC_$_INSTANCE_VARIABLES_"; Result += ClassName;
6472 Result +=
"0, \n\t";
6475 Result +=
"0, \n\t";
6476 if (!metaclass && Properties.size() > 0) {
6477 Result +=
"(const struct _prop_list_t *)&";
6478 Result +=
"_OBJC_$_PROP_LIST_"; Result += ClassName;
6487 static void Write_class_t(
ASTContext *Context, std::string &Result,
6501 if (metaclass && rootClass) {
6504 Result +=
"extern \"C\" ";
6506 Result +=
"__declspec(dllexport) ";
6508 Result +=
"__declspec(dllimport) ";
6510 Result +=
"struct _class_t OBJC_CLASS_$_";
6518 Result +=
"extern \"C\" ";
6520 Result +=
"__declspec(dllexport) ";
6522 Result +=
"__declspec(dllimport) ";
6524 Result +=
"struct _class_t ";
6529 if (metaclass && RootClass != SuperClass) {
6530 Result +=
"extern \"C\" ";
6532 Result +=
"__declspec(dllexport) ";
6534 Result +=
"__declspec(dllimport) ";
6536 Result +=
"struct _class_t ";
6543 Result +=
"\nextern \"C\" __declspec(dllexport) struct _class_t ";
6545 Result +=
" __attribute__ ((used, section (\"__DATA,__objc_data\"))) = {\n";
6549 Result +=
"0, // &"; Result += VarName;
6552 Result +=
"0, // &"; Result += VarName;
6557 Result +=
"0, // &"; Result += VarName;
6565 Result +=
"0, // &OBJC_METACLASS_$_";
6569 Result +=
"0, // &"; Result += VarName;
6576 Result +=
"0, // (void *)&_objc_empty_cache,\n\t";
6577 Result +=
"0, // unused, was (void *)&_objc_empty_vtable,\n\t";
6579 Result +=
"&_OBJC_METACLASS_RO_$_";
6581 Result +=
"&_OBJC_CLASS_RO_$_";
6583 Result +=
",\n};\n";
6593 Result +=
"static void OBJC_CLASS_SETUP_$_";
6595 Result +=
"(void ) {\n";
6597 Result +=
".isa = "; Result +=
"&OBJC_METACLASS_$_";
6601 Result +=
".superclass = ";
6603 Result +=
"&OBJC_CLASS_$_";
6605 Result +=
"&OBJC_METACLASS_$_";
6610 Result +=
".cache = "; Result +=
"&_objc_empty_cache"; Result +=
";\n";
6613 Result +=
".isa = "; Result +=
"&OBJC_METACLASS_$_";
6618 Result +=
".superclass = "; Result +=
"&OBJC_CLASS_$_";
6623 Result +=
".cache = "; Result +=
"&_objc_empty_cache"; Result +=
";\n";
6627 static void Write_category_t(RewriteModernObjC &RewriteObj,
ASTContext *Context,
6628 std::string &Result,
6631 ArrayRef<ObjCMethodDecl *> InstanceMethods,
6632 ArrayRef<ObjCMethodDecl *> ClassMethods,
6633 ArrayRef<ObjCProtocolDecl *> RefedProtocols,
6634 ArrayRef<ObjCPropertyDecl *> ClassProperties) {
6635 StringRef CatName = CatDecl->
getName();
6636 StringRef ClassName = ClassDecl->
getName();
6640 Result +=
"extern \"C\" ";
6642 Result +=
"__declspec(dllexport) ";
6644 Result +=
"__declspec(dllimport) ";
6646 Result +=
"struct _class_t ";
6647 Result +=
"OBJC_CLASS_$_"; Result += ClassName;
6650 Result +=
"\nstatic struct _category_t ";
6651 Result +=
"_OBJC_$_CATEGORY_";
6652 Result += ClassName; Result +=
"_$_"; Result += CatName;
6653 Result +=
" __attribute__ ((used, section (\"__DATA,__objc_const\"))) = \n";
6655 Result +=
"\t\""; Result += ClassName; Result +=
"\",\n";
6656 Result +=
"\t0, // &"; Result +=
"OBJC_CLASS_$_"; Result += ClassName;
6658 if (InstanceMethods.size() > 0) {
6659 Result +=
"\t(const struct _method_list_t *)&";
6660 Result +=
"_OBJC_$_CATEGORY_INSTANCE_METHODS_";
6661 Result += ClassName; Result +=
"_$_"; Result += CatName;
6667 if (ClassMethods.size() > 0) {
6668 Result +=
"\t(const struct _method_list_t *)&";
6669 Result +=
"_OBJC_$_CATEGORY_CLASS_METHODS_";
6670 Result += ClassName; Result +=
"_$_"; Result += CatName;
6676 if (RefedProtocols.size() > 0) {
6677 Result +=
"\t(const struct _protocol_list_t *)&";
6678 Result +=
"_OBJC_CATEGORY_PROTOCOLS_$_";
6679 Result += ClassName; Result +=
"_$_"; Result += CatName;
6685 if (ClassProperties.size() > 0) {
6686 Result +=
"\t(const struct _prop_list_t *)&"; Result +=
"_OBJC_$_PROP_LIST_";
6687 Result += ClassName; Result +=
"_$_"; Result += CatName;
6696 Result +=
"static void OBJC_CATEGORY_SETUP_$_";
6700 Result +=
"(void ) {\n";
6701 Result +=
"\t_OBJC_$_CATEGORY_";
6705 Result +=
".cls = "; Result +=
"&OBJC_CLASS_$_"; Result += ClassName;
6709 static void Write__extendedMethodTypes_initializer(RewriteModernObjC &RewriteObj,
6711 ArrayRef<ObjCMethodDecl *> Methods,
6713 StringRef ProtocolName) {
6714 if (Methods.size() == 0)
6717 Result +=
"\nstatic const char *";
6718 Result += VarName; Result += ProtocolName;
6719 Result +=
" [] __attribute__ ((used, section (\"__DATA,__objc_const\"))) = \n";
6721 for (
unsigned i = 0, e = Methods.size(); i < e; i++) {
6723 std::string MethodTypeString, QuoteMethodTypeString;
6725 RewriteObj.QuoteDoublequotes(MethodTypeString, QuoteMethodTypeString);
6726 Result +=
"\t\""; Result += QuoteMethodTypeString; Result +=
"\"";
6735 static void Write_IvarOffsetVar(RewriteModernObjC &RewriteObj,
6737 std::string &Result,
6738 ArrayRef<ObjCIvarDecl *> Ivars,
6752 for (
unsigned i =0, e = Ivars.size(); i < e; i++) {
6755 Result +=
"__declspec(allocate(\".objc_ivar$B\")) ";
6760 Result +=
"extern \"C\" unsigned long int ";
6762 Result +=
"extern \"C\" __declspec(dllexport) unsigned long int ";
6763 if (Ivars[i]->isBitField())
6764 RewriteObj.ObjCIvarBitfieldGroupOffset(IvarDecl, Result);
6766 WriteInternalIvarName(CDecl, IvarDecl, Result);
6767 Result +=
" __attribute__ ((used, section (\"__DATA,__objc_ivar\")))";
6769 RewriteObj.RewriteIvarOffsetComputation(IvarDecl, Result);
6771 if (Ivars[i]->isBitField()) {
6773 SKIP_BITFIELDS(i , e, Ivars);
6778 static void Write__ivar_list_t_initializer(RewriteModernObjC &RewriteObj,
6780 ArrayRef<ObjCIvarDecl *> OriginalIvars,
6783 if (OriginalIvars.size() > 0) {
6784 Write_IvarOffsetVar(RewriteObj, Context, Result, OriginalIvars, CDecl);
6785 SmallVector<ObjCIvarDecl *, 8> Ivars;
6789 for (
unsigned i = 0, e = OriginalIvars.size(); i < e; i++) {
6790 if (OriginalIvars[i]->isBitField()) {
6791 Ivars.push_back(OriginalIvars[i]);
6793 SKIP_BITFIELDS(i , e, OriginalIvars);
6796 Ivars.push_back(OriginalIvars[i]);
6799 Result +=
"\nstatic ";
6800 Write__ivar_list_t_TypeDecl(Result, Ivars.size());
6801 Result +=
" "; Result += VarName;
6803 Result +=
" __attribute__ ((used, section (\"__DATA,__objc_const\"))) = {\n";
6804 Result +=
"\t"; Result +=
"sizeof(_ivar_t)"; Result +=
",\n";
6805 Result +=
"\t"; Result += utostr(Ivars.size()); Result +=
",\n";
6806 for (
unsigned i =0, e = Ivars.size(); i < e; i++) {
6812 Result +=
"(unsigned long int *)&";
6813 if (Ivars[i]->isBitField())
6814 RewriteObj.ObjCIvarBitfieldGroupOffset(IvarDecl, Result);
6816 WriteInternalIvarName(CDecl, IvarDecl, Result);
6820 if (Ivars[i]->isBitField())
6821 RewriteObj.ObjCIvarBitfieldGroupDecl(Ivars[i], Result);
6823 Result += IvarDecl->
getName();
6828 IVQT = RewriteObj.GetGroupRecordTypeForObjCIvarBitfield(IvarDecl);
6830 std::string IvarTypeString, QuoteIvarTypeString;
6833 RewriteObj.QuoteDoublequotes(IvarTypeString, QuoteIvarTypeString);
6834 Result +=
"\""; Result += QuoteIvarTypeString; Result +=
"\", ";
6839 Align = llvm::Log2_32(Align);
6840 Result += llvm::utostr(Align); Result +=
", ";
6853 void RewriteModernObjC::RewriteObjCProtocolMetaData(
ObjCProtocolDecl *PDecl,
6854 std::string &Result) {
6859 WriteModernMetadataDeclarations(Context, Result);
6866 RewriteObjCProtocolMetaData(I, Result);
6869 std::vector<ObjCMethodDecl *> InstanceMethods, ClassMethods;
6870 std::vector<ObjCMethodDecl *> OptInstanceMethods, OptClassMethods;
6873 OptInstanceMethods.push_back(MD);
6875 InstanceMethods.push_back(MD);
6881 OptClassMethods.push_back(MD);
6883 ClassMethods.push_back(MD);
6886 std::vector<ObjCMethodDecl *> AllMethods;
6887 for (
unsigned i = 0, e = InstanceMethods.size(); i < e; i++)
6888 AllMethods.push_back(InstanceMethods[i]);
6889 for (
unsigned i = 0, e = ClassMethods.size(); i < e; i++)
6890 AllMethods.push_back(ClassMethods[i]);
6891 for (
unsigned i = 0, e = OptInstanceMethods.size(); i < e; i++)
6892 AllMethods.push_back(OptInstanceMethods[i]);
6893 for (
unsigned i = 0, e = OptClassMethods.size(); i < e; i++)
6894 AllMethods.push_back(OptClassMethods[i]);
6896 Write__extendedMethodTypes_initializer(*
this, Context, Result,
6898 "_OBJC_PROTOCOL_METHOD_TYPES_",
6901 SmallVector<ObjCProtocolDecl *, 8> SuperProtocols(PDecl->
protocols());
6902 Write_protocol_list_initializer(Context, Result, SuperProtocols,
6903 "_OBJC_PROTOCOL_REFS_",
6906 Write_method_list_t_initializer(*
this, Context, Result, InstanceMethods,
6907 "_OBJC_PROTOCOL_INSTANCE_METHODS_",
6910 Write_method_list_t_initializer(*
this, Context, Result, ClassMethods,
6911 "_OBJC_PROTOCOL_CLASS_METHODS_",
6914 Write_method_list_t_initializer(*
this, Context, Result, OptInstanceMethods,
6915 "_OBJC_PROTOCOL_OPT_INSTANCE_METHODS_",
6918 Write_method_list_t_initializer(*
this, Context, Result, OptClassMethods,
6919 "_OBJC_PROTOCOL_OPT_CLASS_METHODS_",
6923 SmallVector<ObjCPropertyDecl *, 8> ProtocolProperties(
6925 Write_prop_list_t_initializer(*
this, Context, Result, ProtocolProperties,
6927 "_OBJC_PROTOCOL_PROPERTIES_",
6932 if (LangOpts.MicrosoftExt)
6933 Result +=
"static ";
6934 Result +=
"struct _protocol_t _OBJC_PROTOCOL_";
6936 Result +=
" __attribute__ ((used)) = {\n";
6938 Result +=
"\t\""; Result += PDecl->
getNameAsString(); Result +=
"\",\n";
6939 if (SuperProtocols.size() > 0) {
6940 Result +=
"\t(const struct _protocol_list_t *)&"; Result +=
"_OBJC_PROTOCOL_REFS_";
6945 if (InstanceMethods.size() > 0) {
6946 Result +=
"\t(const struct method_list_t *)&_OBJC_PROTOCOL_INSTANCE_METHODS_";
6952 if (ClassMethods.size() > 0) {
6953 Result +=
"\t(const struct method_list_t *)&_OBJC_PROTOCOL_CLASS_METHODS_";
6959 if (OptInstanceMethods.size() > 0) {
6960 Result +=
"\t(const struct method_list_t *)&_OBJC_PROTOCOL_OPT_INSTANCE_METHODS_";
6966 if (OptClassMethods.size() > 0) {
6967 Result +=
"\t(const struct method_list_t *)&_OBJC_PROTOCOL_OPT_CLASS_METHODS_";
6973 if (ProtocolProperties.size() > 0) {
6974 Result +=
"\t(const struct _prop_list_t *)&_OBJC_PROTOCOL_PROPERTIES_";
6980 Result +=
"\t"; Result +=
"sizeof(_protocol_t)"; Result +=
",\n";
6983 if (AllMethods.size() > 0) {
6984 Result +=
"\t(const char **)&"; Result +=
"_OBJC_PROTOCOL_METHOD_TYPES_";
6989 Result +=
"\t0\n};\n";
6991 if (LangOpts.MicrosoftExt)
6992 Result +=
"static ";
6993 Result +=
"struct _protocol_t *";
6994 Result +=
"_OBJC_LABEL_PROTOCOL_$_"; Result += PDecl->
getNameAsString();
7000 llvm_unreachable(
"protocol already synthesized");
7008 if (OID->hasAttr<ObjCExceptionAttr>())
7016 std::string &Result) {
7022 "Legacy implicit interface rewriting not supported in moder abi");
7024 WriteModernMetadataDeclarations(Context, Result);
7025 SmallVector<ObjCIvarDecl *, 8> IVars;
7030 if (!IVD->getDeclName())
7032 IVars.push_back(IVD);
7035 Write__ivar_list_t_initializer(*
this, Context, Result, IVars,
7036 "_OBJC_$_INSTANCE_VARIABLES_",
7040 SmallVector<ObjCMethodDecl *, 32> InstanceMethods(IDecl->
instance_methods());
7045 if (Prop->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic)
7047 if (!Prop->getPropertyIvarDecl())
7053 if (mustSynthesizeSetterGetterMethod(IDecl, PD,
true ))
7054 InstanceMethods.push_back(Getter);
7058 if (mustSynthesizeSetterGetterMethod(IDecl, PD,
false ))
7059 InstanceMethods.push_back(Setter);
7062 Write_method_list_t_initializer(*
this, Context, Result, InstanceMethods,
7063 "_OBJC_$_INSTANCE_METHODS_",
7066 SmallVector<ObjCMethodDecl *, 32> ClassMethods(IDecl->
class_methods());
7068 Write_method_list_t_initializer(*
this, Context, Result, ClassMethods,
7069 "_OBJC_$_CLASS_METHODS_",
7074 std::vector<ObjCProtocolDecl *> RefedProtocols;
7077 E = Protocols.
end();
7079 RefedProtocols.push_back(*I);
7082 RewriteObjCProtocolMetaData(*I, Result);
7085 Write_protocol_list_initializer(Context, Result,
7087 "_OBJC_CLASS_PROTOCOLS_$_",
7091 SmallVector<ObjCPropertyDecl *, 8> ClassProperties(
7093 Write_prop_list_t_initializer(*
this, Context, Result, ClassProperties,
7095 "_OBJC_$_PROP_LIST_",
7099 uint32_t flags = CLS_META;
7100 std::string InstanceSize;
7101 std::string InstanceStart;
7105 flags |= OBJC2_CLS_HIDDEN;
7110 InstanceSize =
"sizeof(struct _class_t)";
7111 InstanceStart = InstanceSize;
7112 Write__class_ro_t_initializer(Context, Result, flags,
7113 InstanceStart, InstanceSize,
7118 "_OBJC_METACLASS_RO_$_",
7124 flags |= OBJC2_CLS_HIDDEN;
7127 flags |= CLS_EXCEPTION;
7133 InstanceSize.clear();
7134 InstanceStart.clear();
7135 if (!ObjCSynthesizedStructs.count(CDecl)) {
7137 InstanceStart =
"0";
7140 InstanceSize =
"sizeof(struct ";
7142 InstanceSize +=
"_IMPL)";
7146 RewriteIvarOffsetComputation(IVD, InstanceStart);
7149 InstanceStart = InstanceSize;
7151 Write__class_ro_t_initializer(Context, Result, flags,
7152 InstanceStart, InstanceSize,
7157 "_OBJC_CLASS_RO_$_",
7160 Write_class_t(Context, Result,
7161 "OBJC_METACLASS_$_",
7164 Write_class_t(Context, Result,
7168 if (ImplementationIsNonLazy(IDecl))
7169 DefinedNonLazyClasses.push_back(CDecl);
7172 void RewriteModernObjC::RewriteClassSetupInitHook(std::string &Result) {
7173 int ClsDefCount = ClassImplementation.size();
7176 Result +=
"#pragma section(\".objc_inithooks$B\", long, read, write)\n";
7177 Result +=
"__declspec(allocate(\".objc_inithooks$B\")) ";
7178 Result +=
"static void *OBJC_CLASS_SETUP[] = {\n";
7179 for (
int i = 0; i < ClsDefCount; i++) {
7182 Result +=
"\t(void *)&OBJC_CLASS_SETUP_$_";
7183 Result += CDecl->
getName(); Result +=
",\n";
7188 void RewriteModernObjC::RewriteMetaDataIntoBuffer(std::string &Result) {
7189 int ClsDefCount = ClassImplementation.size();
7190 int CatDefCount = CategoryImplementation.size();
7193 for (
int i = 0; i < ClsDefCount; i++)
7194 RewriteObjCClassMetaData(ClassImplementation[i], Result);
7196 RewriteClassSetupInitHook(Result);
7199 for (
int i = 0; i < CatDefCount; i++)
7200 RewriteObjCCategoryImplDecl(CategoryImplementation[i], Result);
7202 RewriteCategorySetupInitHook(Result);
7204 if (ClsDefCount > 0) {
7205 if (LangOpts.MicrosoftExt)
7206 Result +=
"__declspec(allocate(\".objc_classlist$B\")) ";
7207 Result +=
"static struct _class_t *L_OBJC_LABEL_CLASS_$ [";
7208 Result += llvm::utostr(ClsDefCount); Result +=
"]";
7210 " __attribute__((used, section (\"__DATA, __objc_classlist,"
7211 "regular,no_dead_strip\")))= {\n";
7212 for (
int i = 0; i < ClsDefCount; i++) {
7213 Result +=
"\t&OBJC_CLASS_$_";
7214 Result += ClassImplementation[i]->getNameAsString();
7219 if (!DefinedNonLazyClasses.empty()) {
7220 if (LangOpts.MicrosoftExt)
7221 Result +=
"__declspec(allocate(\".objc_nlclslist$B\")) \n";
7222 Result +=
"static struct _class_t *_OBJC_LABEL_NONLAZY_CLASS_$[] = {\n\t";
7223 for (
unsigned i = 0, e = DefinedNonLazyClasses.size(); i < e; i++) {
7224 Result +=
"\t&OBJC_CLASS_$_"; Result += DefinedNonLazyClasses[i]->getNameAsString();
7231 if (CatDefCount > 0) {
7232 if (LangOpts.MicrosoftExt)
7233 Result +=
"__declspec(allocate(\".objc_catlist$B\")) ";
7234 Result +=
"static struct _category_t *L_OBJC_LABEL_CATEGORY_$ [";
7235 Result += llvm::utostr(CatDefCount); Result +=
"]";
7237 " __attribute__((used, section (\"__DATA, __objc_catlist,"
7238 "regular,no_dead_strip\")))= {\n";
7239 for (
int i = 0; i < CatDefCount; i++) {
7240 Result +=
"\t&_OBJC_$_CATEGORY_";
7242 CategoryImplementation[i]->getClassInterface()->getNameAsString();
7244 Result += CategoryImplementation[i]->getNameAsString();
7250 if (!DefinedNonLazyCategories.empty()) {
7251 if (LangOpts.MicrosoftExt)
7252 Result +=
"__declspec(allocate(\".objc_nlcatlist$B\")) \n";
7253 Result +=
"static struct _category_t *_OBJC_LABEL_NONLAZY_CATEGORY_$[] = {\n\t";
7254 for (
unsigned i = 0, e = DefinedNonLazyCategories.size(); i < e; i++) {
7255 Result +=
"\t&_OBJC_$_CATEGORY_";
7257 DefinedNonLazyCategories[i]->getClassInterface()->getNameAsString();
7259 Result += DefinedNonLazyCategories[i]->getNameAsString();
7266 void RewriteModernObjC::WriteImageInfo(std::string &Result) {
7267 if (LangOpts.MicrosoftExt)
7268 Result +=
"__declspec(allocate(\".objc_imageinfo$B\")) \n";
7270 Result +=
"static struct IMAGE_INFO { unsigned version; unsigned flag; } ";
7272 Result +=
"_OBJC_IMAGE_INFO = { 0, 2 };\n";
7278 std::string &Result) {
7279 WriteModernMetadataDeclarations(Context, Result);
7286 FullCategoryName +=
"_$_";
7290 SmallVector<ObjCMethodDecl *, 32> InstanceMethods(IDecl->
instance_methods());
7295 if (Prop->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic)
7297 if (!Prop->getPropertyIvarDecl())
7303 InstanceMethods.push_back(Getter);
7307 InstanceMethods.push_back(Setter);
7310 Write_method_list_t_initializer(*
this, Context, Result, InstanceMethods,
7311 "_OBJC_$_CATEGORY_INSTANCE_METHODS_",
7312 FullCategoryName,
true);
7314 SmallVector<ObjCMethodDecl *, 32> ClassMethods(IDecl->
class_methods());
7316 Write_method_list_t_initializer(*
this, Context, Result, ClassMethods,
7317 "_OBJC_$_CATEGORY_CLASS_METHODS_",
7318 FullCategoryName,
true);
7322 SmallVector<ObjCProtocolDecl *, 8> RefedProtocols(CDecl->
protocols());
7326 RewriteObjCProtocolMetaData(I, Result);
7328 Write_protocol_list_initializer(Context, Result,
7330 "_OBJC_CATEGORY_PROTOCOLS_$_",
7334 SmallVector<ObjCPropertyDecl *, 8> ClassProperties(
7336 Write_prop_list_t_initializer(*
this, Context, Result, ClassProperties,
7338 "_OBJC_$_PROP_LIST_",
7341 Write_category_t(*
this, Context, Result,
7350 if (ImplementationIsNonLazy(IDecl))
7351 DefinedNonLazyCategories.push_back(CDecl);
7354 void RewriteModernObjC::RewriteCategorySetupInitHook(std::string &Result) {
7355 int CatDefCount = CategoryImplementation.size();
7358 Result +=
"#pragma section(\".objc_inithooks$B\", long, read, write)\n";
7359 Result +=
"__declspec(allocate(\".objc_inithooks$B\")) ";
7360 Result +=
"static void *OBJC_CATEGORY_SETUP[] = {\n";
7361 for (
int i = 0; i < CatDefCount; i++) {
7365 Result +=
"\t(void *)&OBJC_CATEGORY_SETUP_$_";
7366 Result += ClassDecl->
getName();
7376 template<
typename MethodIterator>
7377 void RewriteModernObjC::RewriteObjCMethodsMetaData(MethodIterator MethodBegin,
7378 MethodIterator MethodEnd,
7379 bool IsInstanceMethod,
7381 StringRef ClassName,
7382 std::string &Result) {
7383 if (MethodBegin == MethodEnd)
return;
7385 if (!objc_impl_method) {
7392 Result +=
"\nstruct _objc_method {\n";
7393 Result +=
"\tSEL _cmd;\n";
7394 Result +=
"\tchar *method_types;\n";
7395 Result +=
"\tvoid *_imp;\n";
7398 objc_impl_method =
true;
7409 unsigned NumMethods =
std::distance(MethodBegin, MethodEnd);
7411 if (LangOpts.MicrosoftExt) {
7412 if (IsInstanceMethod)
7413 Result +=
"__declspec(allocate(\".inst_meth$B\")) ";
7415 Result +=
"__declspec(allocate(\".cls_meth$B\")) ";
7417 Result +=
"static struct {\n";
7418 Result +=
"\tstruct _objc_method_list *next_method;\n";
7419 Result +=
"\tint method_count;\n";
7420 Result +=
"\tstruct _objc_method method_list[";
7421 Result += utostr(NumMethods);
7422 Result +=
"];\n} _OBJC_";
7424 Result += IsInstanceMethod ?
"INSTANCE" :
"CLASS";
7425 Result +=
"_METHODS_";
7426 Result += ClassName;
7427 Result +=
" __attribute__ ((used, section (\"__OBJC, __";
7428 Result += IsInstanceMethod ?
"inst" :
"cls";
7429 Result +=
"_meth\")))= ";
7430 Result +=
"{\n\t0, " + utostr(NumMethods) +
"\n";
7432 Result +=
"\t,{{(SEL)\"";
7433 Result += (*MethodBegin)->getSelector().getAsString().c_str();
7434 std::string MethodTypeString;
7437 Result += MethodTypeString;
7438 Result +=
"\", (void *)";
7439 Result += MethodInternalNames[*MethodBegin];
7441 for (++MethodBegin; MethodBegin != MethodEnd; ++MethodBegin) {
7442 Result +=
"\t ,{(SEL)\"";
7443 Result += (*MethodBegin)->getSelector().getAsString().c_str();
7444 std::string MethodTypeString;
7447 Result += MethodTypeString;
7448 Result +=
"\", (void *)";
7449 Result += MethodInternalNames[*MethodBegin];
7452 Result +=
"\t }\n};\n";
7461 DisableReplaceStmtScope
S(*
this);
7462 BaseExpr = cast<Expr>(RewriteFunctionBodyOrGlobalInitializer(BaseExpr));
7468 Expr *Replacement = IV;
7473 assert(iFaceDecl &&
"RewriteObjCIvarRefExpr - iFaceDecl is null");
7478 assert(clsDeclared &&
"RewriteObjCIvarRefExpr(): Can't find class");
7481 std::string IvarOffsetName;
7483 ObjCIvarBitfieldGroupOffset(D, IvarOffsetName);
7485 WriteInternalIvarName(clsDeclared, D, IvarOffsetName);
7487 ReferencedIvars[clsDeclared].insert(D);
7490 CastExpr *castExpr = NoTypeInfoCStyleCastExpr(Context,
7511 IvarT = GetGroupRecordTypeForObjCIvarBitfield(D);
7513 if (!isa<TypedefType>(IvarT) && IvarT->
isRecordType()) {
7523 std::string RecName = CDecl->
getName();
7529 unsigned UnsignedIntSize =
7532 llvm::APInt(UnsignedIntSize, 0),
7534 Zero = NoTypeInfoCStyleCastExpr(Context, PtrStructIMPL, CK_BitCast, Zero);
7549 convertObjCTypeToCStyleType(IvarT);
7552 castExpr = NoTypeInfoCStyleCastExpr(Context,
7559 VK_LValue, OK_Ordinary,
7582 ReplaceStmtWithRange(IV, Replacement, OldRange);
7586 #endif // CLANG_ENABLE_OBJC_REWRITER
SourceLocation getEnd() const
const Expr * getBase() const
ObjCInterfaceDecl * getDecl() const
Get the declaration of this interface.
CastKind getCastKind() const
FunctionDecl - An instance of this class is created to represent a function declaration or definition...
StringRef getName() const
getName - Get the name of identifier for this declaration as a StringRef.
protocol_range protocols() const
Expr * getSyntacticForm()
Return the syntactic form of this expression, i.e.
Smart pointer class that efficiently represents Objective-C method names.
SourceLocation getLocStart() const LLVM_READONLY
PointerType - C99 6.7.5.1 - Pointer Declarators.
const ObjCAtFinallyStmt * getFinallyStmt() const
Retrieve the @finally statement, if any.
A (possibly-)qualified type.
ArrayRef< Capture > captures() const
ImplementationControl getImplementationControl() const
QualType getCallResultType(const ASTContext &Context) const
Determine the type of an expression that calls a function of this type.
ObjCInterfaceDecl * getClassInterface()
ObjCInterfaceDecl * getClassInterface()
bool isBitField() const
Determines whether this field is a bitfield.
ASTConsumer - This is an abstract interface that should be implemented by clients that read ASTs...
QualType getClassReceiver() const
Returns the type of a class message send, or NULL if the message is not a class message.
IdentifierInfo * getIdentifier() const
getIdentifier - Get the identifier that names this declaration, if there is one.
CanQual< T > getUnqualifiedType() const
Retrieve the unqualified form of this type.
FunctionType - C99 6.7.5.3 - Function Declarators.
bool isMain() const
Determines whether this function is "main", which is the entry point into an executable program...
bool isThisDeclarationADefinition() const
Determine whether this particular declaration of this class is actually also a definition.
Defines the SourceManager interface.
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
SourceLocation getForLoc() const
bool isRecordType() const
SourceLocation getLocEnd() const LLVM_READONLY
const char * getCharacterData(SourceLocation SL, bool *Invalid=nullptr) const
Return a pointer to the start of the specified location in the appropriate spelling MemoryBuffer...
param_iterator param_end()
llvm::MemoryBuffer * getBuffer(FileID FID, SourceLocation Loc, bool *Invalid=nullptr) const
Return the buffer for the specified FileID.
bool isEnumeralType() const
ParenExpr - This represents a parethesized expression, e.g.
void getSelectorLocs(SmallVectorImpl< SourceLocation > &SelLocs) const
std::string getAsString() const
FullSourceLoc getFullLoc(SourceLocation Loc) const
IdentifierInfo * getAsIdentifierInfo() const
getAsIdentifierInfo - Retrieve the IdentifierInfo * stored in this declaration name, or NULL if this declaration name isn't a simple identifier.
The base class of the type hierarchy.
SourceLocation getLocStart() const LLVM_READONLY
bool isObjCQualifiedClassType() const
Represents Objective-C's @throw statement.
SourceLocation getLocStart() const LLVM_READONLY
Represents an array type, per C99 6.7.5.2 - Array Declarators.
const Expr * getInit() const
Represents a call to a C++ constructor.
virtual void completeDefinition()
completeDefinition - Notes that the definition of this type is now complete.
static bool hasObjCExceptionAttribute(ASTContext &Context, const ObjCInterfaceDecl *OID)
hasObjCExceptionAttribute - Return true if this class or any super class has the objc_exception attri...
bool isBooleanType() const
A container of type source information.
bool isBlockPointerType() const
static StringLiteral * Create(const ASTContext &C, StringRef Str, StringKind Kind, bool Pascal, QualType Ty, const SourceLocation *Loc, unsigned NumStrs)
This is the "fully general" constructor that allows representation of strings formed from multiple co...
protocol_range protocols() const
SourceLocation getLocStart() const LLVM_READONLY
Represents a C++ constructor within a class.
float __ovld __cnfn distance(float p0, float p1)
Returns the distance between p0 and p1.
ObjCDictionaryElement getKeyValueElement(unsigned Index) const
VarDecl - An instance of this class is created to represent a variable declaration or definition...
Objects with "hidden" visibility are not seen by the dynamic linker.
CompoundLiteralExpr - [C99 6.5.2.5].
SourceLocation getIvarRBraceLoc() const
Extra information about a function prototype.
SourceLocation getLocStart() const LLVM_READONLY
QualType getObjCClassType() const
Represents the Objective-C Class type.
const FunctionProtoType * getFunctionType() const
getFunctionType - Return the underlying function type for this block.
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
ObjCMethodDecl - Represents an instance or class method declaration.
RewriteBuffer - As code is rewritten, SourceBuffer's from the original input with modifications get a...
Expr * IgnoreImplicit() LLVM_READONLY
IgnoreImplicit - Skip past any implicit AST nodes which might surround this expression.
Visibility getVisibility() const
Determines the visibility of this entity.
Describes how types, statements, expressions, and declarations should be printed. ...
void getAsStringInternal(std::string &Str, const PrintingPolicy &Policy) const
SourceLocation getLocation() const
QualType getFunctionNoProtoType(QualType ResultTy, const FunctionType::ExtInfo &Info) const
Return a K&R style C function type like 'int()'.
IdentifierInfo * getIdentifier() const
getIdentifier - Get the identifier that names the category interface associated with this implementat...
SourceLocation getLocStart() const LLVM_READONLY
QualType withConst() const
Retrieves a version of this type with const applied.
unsigned getNumParams() const
Kind getPropertyImplementation() const
RecordDecl - Represents a struct/union/class.
bool isExternC() const
Determines whether this function is a function with external, C linkage.
ObjCProtocolDecl * getCanonicalDecl() override
Retrieves the canonical declaration of this Objective-C protocol.
One of these records is kept for each identifier that is lexed.
ObjCProtocolDecl * getProtocol() const
An element in an Objective-C dictionary literal.
const ObjCInterfaceDecl * getContainingInterface() const
Return the class interface that this ivar is logically contained in; this is either the interface whe...
class LLVM_ALIGNAS(8) DependentTemplateSpecializationType const IdentifierInfo * Name
Represents a template specialization type whose template cannot be resolved, e.g. ...
Represents a class type in Objective C.
StringRef getBufferData(FileID FID, bool *Invalid=nullptr) const
Return a StringRef to the source buffer data for the specified FileID.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
unsigned getNumSemanticExprs() const
std::string getNameAsString() const
Get the name of the class associated with this interface.
FieldDecl - An instance of this class is created by Sema::ActOnField to represent a member of a struc...
bool isCompleteDefinition() const
isCompleteDefinition - Return true if this decl has its body fully specified.
StringLiteral * getString()
const Stmt * getBody() const
ObjCMethodDecl * getClassMethod(Selector Sel, bool AllowHidden=false) 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]];.
QualType getTypeDeclType(const TypeDecl *Decl, const TypeDecl *PrevDecl=nullptr) const
Return the unique reference to the type for the specified type declaration.
An r-value expression (a pr-value in the C++11 taxonomy) produces a temporary value.
SourceLocation getSuperLoc() const
Retrieve the location of the 'super' keyword for a class or instance message to 'super', otherwise an invalid source location.
const VarDecl * getCatchParamDecl() const
Represents Objective-C's @catch statement.
const CompoundStmt * getSynchBody() const
Describes an C or C++ initializer list.
param_type_range param_types() const
ObjCMethodDecl * getBoxingMethod() const
const Stmt * getFinallyBody() const
const TargetInfo & getTargetInfo() const
SourceLocation getLocWithOffset(int Offset) const
Return a source location with the specified offset from this SourceLocation.
ObjCContainerDecl - Represents a container for method declarations.
const LangOptions & getLangOpts() const
CharUnits - This is an opaque type for sizes expressed in character units.
QualType getReturnType() const
QualType getSuperType() const
Retrieve the type referred to by 'super'.
field_range fields() const
Concrete class used by the front-end to report problems and issues.
const ArrayType * getAsArrayType(QualType T) const
Type Query functions.
Represents a typeof (or typeof) expression (a GCC extension).
TypeDecl - Represents a declaration of a type.
A builtin binary operation expression such as "x + y" or "x <= y".
Selector getSelector() const
Selector getSetterName() const
bool isOverloadedOperator() const
isOverloadedOperator - Whether this function declaration represents an C++ overloaded operator...
std::string getNameAsString() const
getNameAsString - Get a human-readable name for the declaration, even if it is one of the special kin...
ObjCStringLiteral, used for Objective-C string literals i.e.
ObjCProtocolDecl * getDefinition()
Retrieve the definition of this protocol, if any.
bool isVariadic() const
Whether this function is variadic.
const Stmt * getCatchBody() const
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
CompoundStmt * getCompoundBody()
Represents an Objective-C protocol declaration.
const ObjCAtCatchStmt * getCatchStmt(unsigned I) const
Retrieve a @catch statement.
Expr * Key
The key for the dictionary element.
SourceLocation getLocStart() const LLVM_READONLY
SourceLocation getLocEnd() const LLVM_READONLY
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
unsigned getLine() const
Return the presumed line number of this location.
An ordinary object is located at an address in memory.
Represents an ObjC class declaration.
SourceLocation getLocEnd() const LLVM_READONLY
propimpl_range property_impls() const
Represents a linkage specification.
detail::InMemoryDirectory::const_iterator I
PropertyAttributeKind getPropertyAttributes() const
SourceLocation getAtLoc() const
SourceRange getAtEndRange() const
ObjCPropertyImplDecl - Represents implementation declaration of a property in a class or category imp...
bool isThisDeclarationADefinition() const
Determine whether this particular declaration is also the definition.
ConditionalOperator - The ?: ternary operator.
SourceLocation getLocStart() const LLVM_READONLY
SourceLocation getLocEnd() const LLVM_READONLY
CompoundStmt - This represents a group of statements like { stmt stmt }.
QualType getParamType(unsigned i) const
Represents a prototype with parameter type info, e.g.
SourceLocation getLocEnd() const LLVM_READONLY
CastKind
CastKind - The kind of operation required for a conversion.
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.
SourceLocation getTypeSpecStartLoc() const
StorageClass getStorageClass() const
Returns the storage class as written in the source.
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee...
bool isFunctionPointerType() const
QualType getObjCInterfaceType(const ObjCInterfaceDecl *Decl, ObjCInterfaceDecl *PrevDecl=nullptr) const
getObjCInterfaceType - Return the unique reference to the type for the specified ObjC interface decl...
bool isRealFloatingType() const
Floating point categories.
const ObjCMethodDecl * getMethodDecl() const
SourceLocation getLocStart() const LLVM_READONLY
BlockDecl - This represents a block literal declaration, which is like an unnamed FunctionDecl...
QualType getPointeeType() const
ValueDecl - Represent the declaration of a variable (in which case it is an lvalue) a function (in wh...
Expr - This represents one expression.
StringRef getName() const
Return the actual identifier string.
bool isBeforeInTranslationUnit(SourceLocation LHS, SourceLocation RHS) const
Determines the order of 2 source locations in the translation unit.
ObjCIvarDecl * getPropertyIvarDecl() const
Expr * getBitWidth() const
SourceLocation getRParenLoc() const
BlockExpr - Adaptor class for mixing a BlockDecl with expressions.
TranslationUnitDecl * getTranslationUnitDecl() const
bool isObjCGCWeak() const
true when Type is objc's weak.
Expr * getUnderlyingExpr() const
ObjCDictionaryLiteral - AST node to represent objective-c dictionary literals; as in:"name" : NSUserN...
Represents Objective-C's @synchronized statement.
ObjCSelectorExpr used for @selector in Objective-C.
unsigned getExpansionLineNumber(SourceLocation Loc, bool *Invalid=nullptr) const
bool isWrittenInMainFile(SourceLocation Loc) const
Returns true if the spelling location for the given location is in the main file buffer.
Selector getSelector() const
unsigned getNumElements() const
getNumElements - Return number of elements of objective-c array literal.
Defines the clang::IdentifierInfo, clang::IdentifierTable, and clang::Selector interfaces.
ObjCIvarDecl * lookupInstanceVariable(IdentifierInfo *IVarName, ObjCInterfaceDecl *&ClassDeclared)
Expr * getElement(unsigned Index)
getExpr - Return the Expr at the specified index.
bool isInstanceMethod() const
bool isa(CodeGen::Address addr)
QualType getObjCIdType() const
Represents the Objective-CC id type.
An expression that sends a message to the given Objective-C object or class.
Represents an unpacked "presumed" location which can be presented to the user.
UnaryOperator - This represents the unary-expression's (except sizeof and alignof), the postinc/postdec operators from postfix-expression, and various extensions.
DeclarationName getDeclName() const
getDeclName - Get the actual, stored name of the declaration, which may be a special name...
The result type of a method or function.
CStyleCastExpr - An explicit cast in C (C99 6.5.4) or a C-style cast in C++ (C++ [expr.cast]), which uses the syntax (Type)expr.
RecordDecl * getDefinition() const
getDefinition - Returns the RecordDecl that actually defines this struct/union/class.
std::unique_ptr< ASTConsumer > CreateModernObjCRewriter(const std::string &InFile, std::unique_ptr< raw_ostream > OS, DiagnosticsEngine &Diags, const LangOptions &LOpts, bool SilenceRewriteMacroWarning, bool LineInfo)
Expr * getArg(unsigned Arg)
getArg - Return the specified argument.
const clang::PrintingPolicy & getPrintingPolicy() const
SourceLocation getAtLoc() const
SourceLocation getRightLoc() const
ObjCCategoryDecl * getCategoryDecl() const
param_iterator param_begin()
ArrayRef< ParmVarDecl * > parameters() const
Stmt * getBody(const FunctionDecl *&Definition) const
getBody - Retrieve the body (definition) of the function.
unsigned getTypeAlign(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in bits.
SelectorTable & Selectors
PseudoObjectExpr - An expression which accesses a pseudo-object l-value.
SourceLocation getLocStart() const LLVM_READONLY
const char * getFilename() const
Return the presumed filename of this location.
Encodes a location in the source.
enumerator_range enumerators() const
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of enums...
const TemplateArgument * iterator
SourceLocation getLocStart() const LLVM_READONLY
unsigned getBitWidthValue(const ASTContext &Ctx) const
static LLVM_READONLY bool isAlphanumeric(unsigned char c)
Return true if this character is an ASCII letter or digit: [a-zA-Z0-9].
Interfaces are the core concept in Objective-C for object oriented design.
bool isValid() const
Return true if this is a valid SourceLocation object.
TagDecl - Represents the declaration of a struct/union/class/enum.
static OMPLinearClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, OpenMPLinearClauseKind Modifier, SourceLocation ModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL, ArrayRef< Expr * > PL, ArrayRef< Expr * > IL, Expr *Step, Expr *CalcStep, Stmt *PreInit, Expr *PostUpdate)
Creates clause with a list of variables VL and a linear step Step.
TypeSourceInfo * getTrivialTypeSourceInfo(QualType T, SourceLocation Loc=SourceLocation()) const
Allocate a TypeSourceInfo where all locations have been initialized to a given location, which defaults to the empty location.
bool refersToEnclosingVariableOrCapture() const
Does this DeclRefExpr refer to an enclosing local or a captured variable?
DeclStmt - Adaptor class for mixing declarations with statements and expressions. ...
QualType withConst() const
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...
TypeSourceInfo * getClassReceiverTypeInfo() const
Returns a type-source information of a class message send, or NULL if the message is not a class mess...
SourceLocation getLocStart() const LLVM_READONLY
bool isIntegralType(const ASTContext &Ctx) const
Determine whether this type is an integral type.
ObjCCategoryDecl - Represents a category declaration.
const ObjCInterfaceDecl * getClassInterface() const
decl_iterator decl_begin()
ObjCProtocolExpr used for protocol expression in Objective-C.
std::string getAsString() const
Derive the full selector name (e.g.
Represents one property declaration in an Objective-C interface.
ImplicitCastExpr - Allows us to explicitly represent implicit type conversions, which have no direct ...
QualType getReturnType() const
SourceLocation getBegin() const
const T * castAs() const
Member-template castAs<specific type>.
FileID getMainFileID() const
Returns the FileID of the main source file.
bool isFileContext() const
SourceLocation getAtSynchronizedLoc() const
ObjCBoxedExpr - used for generalized expression boxing.
const BlockDecl * getBlockDecl() const
unsigned TypeAlias
Whether this template specialization type is a substituted type alias.
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
QualType getObjCInstanceType()
Retrieve the Objective-C "instancetype" type, if already known; otherwise, returns a NULL type;...
QualType getPointeeType() const
Expr * Value
The value of the dictionary element.
void getObjCEncodingForPropertyDecl(const ObjCPropertyDecl *PD, const Decl *Container, std::string &S) const
getObjCEncodingForPropertyDecl - Return the encoded type for this method declaration.
QualType getFunctionType(QualType ResultTy, ArrayRef< QualType > Args, const FunctionProtoType::ExtProtoInfo &EPI) const
Return a normal function type with a typed argument list.
QualType getObjCSelType() const
Retrieve the type that corresponds to the predefined Objective-C 'SEL' type.
decl_iterator - Iterates through the declarations stored within this context.
Expr * getInstanceReceiver()
Returns the object expression (receiver) for an instance message, or null for a message that is not a...
ObjCIvarDecl * getNextIvar()
Base class for declarations which introduce a typedef-name.
Expr * getResultExpr()
Return the result-bearing expression, or null if there is none.
An opaque identifier used by SourceManager which refers to a source file (MemoryBuffer) along with it...
instmeth_range instance_methods() const
ObjCCategoryDecl * FindCategoryDeclaration(IdentifierInfo *CategoryId) const
FindCategoryDeclaration - Finds category declaration in the list of categories for this class and ret...
SourceLocation getLParenLoc() const
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
unsigned getByteLength() const
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
SourceLocation getLocStart() const LLVM_READONLY
std::string getNameAsString() const
Get the name of the class associated with this interface.
ObjCMethodDecl * getInstanceMethod(Selector Sel, bool AllowHidden=false) const
QualType IgnoreParens() const
Returns the specified type after dropping any outer-level parentheses.
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
Selector getGetterName() const
U cast(CodeGen::Address addr)
int printf(__constant const char *st,...)
bool isThisDeclarationADefinition() const
isThisDeclarationADefinition - Returns whether this specific declaration of the function is also a de...
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
EnumDecl - Represents an enum.
Selector getSelector() const
ObjCMethodDecl * getArrayWithObjectsMethod() const
detail::InMemoryDirectory::const_iterator E
SourceLocation getEndOfDefinitionLoc() const
CanQualType getCanonicalType(QualType T) const
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
ObjCMethodDecl * getDictWithObjectsMethod() const
Expr * IgnoreParenImpCasts() LLVM_READONLY
IgnoreParenImpCasts - Ignore parentheses and implicit casts.
Defines the Diagnostic-related interfaces.
Represents a pointer to an Objective C object.
CanQualType ObjCBuiltinBoolTy
SourceLocation getRParenLoc() const
ObjCImplementationDecl - Represents a class definition - this is where method definitions are specifi...
ObjCMethodDecl * getGetterMethodDecl() const
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
SourceLocation getLeftLoc() const
const T * getAs() const
Member-template getAs<specific type>'.
const Stmt * getSubStmt() const
Represents Objective-C's collection statement.
CanQualType UnsignedLongTy
ObjCMethodDecl * getSetterMethodDecl() const
ObjCEncodeExpr, used for @encode in Objective-C.
Selector getSelector(unsigned NumArgs, IdentifierInfo **IIV)
Can create any sort of selector.
SourceLocation getAtTryLoc() const
Retrieve the location of the @ in the @try.
static CStyleCastExpr * Create(const ASTContext &Context, QualType T, ExprValueKind VK, CastKind K, Expr *Op, const CXXCastPath *BasePath, TypeSourceInfo *WrittenTy, SourceLocation L, SourceLocation R)
instprop_range instance_properties() const
bool isObjCQualifiedIdType() const
MutableArrayRef< ParmVarDecl * >::iterator param_iterator
DeclContext * getRedeclContext()
getRedeclContext - Retrieve the context in which an entity conflicts with other entities of the same ...
ObjCInterfaceDecl * getCanonicalDecl() override
Retrieves the canonical declaration of this Objective-C class.
Represents Objective-C's @finally statement.
uint64_t getCharWidth() const
Return the size of the character type, in bits.
const ObjCProtocolList & getReferencedProtocols() const
ObjCImplementationDecl * getImplementation() const
void addDecl(Decl *D)
Add the declaration D into this context.
ExprIterator arg_iterator
unsigned getNumArgs() const
Return the number of actual arguments in this message, not counting the receiver. ...
QualType getTagDeclType(const TagDecl *Decl) const
Return the unique reference to the type for the specified TagDecl (struct/union/class/enum) decl...
bool getObjCEncodingForMethodDecl(const ObjCMethodDecl *Decl, std::string &S, bool Extended=false) const
Emit the encoded type for the method declaration Decl into S.
unsigned getNumCatchStmts() const
Retrieve the number of @catch statements in this try-catch-finally block.
SourceLocation getRParenLoc() const
ObjCIvarRefExpr - A reference to an ObjC instance variable.
SourceManager & getSourceManager()
bool isDefaultConstructor() const
Whether this constructor is a default constructor (C++ [class.ctor]p5), which can be used to default-...
X
Add a minimal nested name specifier fixit hint to allow lookup of a tag name from an outer enclosing ...
ObjCPropertyDecl * getPropertyDecl() const
AccessControl getAccessControl() const
classmeth_range class_methods() const
const internal::VariadicDynCastAllOfMatcher< Stmt, CastExpr > castExpr
Matches any cast nodes of Clang's AST.
Rewriter - This is the main interface to the rewrite buffers.
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
bool isImplicitInterfaceDecl() const
isImplicitInterfaceDecl - check that this is an implicitly declared ObjCInterfaceDecl node...
ContinueStmt - This represents a continue.
bool isReadOnly() const
isReadOnly - Return true iff the property has a setter.
bool isObjCObjectPointerType() const
QualType getEncodedType() const
ObjCIvarDecl - Represents an ObjC instance variable.
bool isImplicit() const
Indicates whether the message send was implicitly generated by the implementation.
SourceLocation getLocEnd() const LLVM_READONLY
Represents Objective-C's @try ... @catch ... @finally statement.
const Expr * getThrowExpr() const
SourceLocation getLocation() const
StringLiteral - This represents a string literal expression, e.g.
Defines the clang::TargetInfo interface.
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
ObjCInterfaceDecl * getSuperClass() const
ObjCBoolLiteralExpr - Objective-C Boolean Literal.
SourceLocation getIvarRBraceLoc() const
const Stmt * getTryBody() const
Retrieve the @try body.
TranslationUnitDecl - The top declaration context.
const internal::VariadicDynCastAllOfMatcher< Decl, FieldDecl > fieldDecl
Matches field declarations.
A reference to a declared variable, function, enum, etc.
ExprValueKind getValueKind() const
getValueKind - The value kind that this expression produces.
QualType getDecltypeType(Expr *e, QualType UnderlyingType) const
C++11 decltype.
QualType getConstantArrayType(QualType EltTy, const llvm::APInt &ArySize, ArrayType::ArraySizeModifier ASM, unsigned IndexTypeQuals) const
Return the unique reference to the type for a constant array of the specified element type...
QualType getElementType() const
BreakStmt - This represents a break.
Expr * getSemanticExpr(unsigned index)
SourceLocation getLocForStartOfFile(FileID FID) const
Return the source location corresponding to the first byte of the specified file. ...
An l-value expression is a reference to an object with independent storage.
A trivial tuple used to represent a source range.
NamedDecl - This represents a decl with a name.
ObjCIvarDecl * all_declared_ivar_begin()
all_declared_ivar_begin - return first ivar declared in this class, its extensions and its implementa...
SourceLocation getLocStart() const LLVM_READONLY
SourceLocation getExpansionLoc(SourceLocation Loc) const
Given a SourceLocation object Loc, return the expansion location referenced by the ID...
SourceLocation getLocStart() const LLVM_READONLY
SourceLocation getLocEnd() const LLVM_READONLY
bool isConstQualified() const
Determine whether this type is const-qualified.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
const ObjCObjectPointerType * getAsObjCInterfacePointerType() const
ReceiverKind getReceiverKind() const
Determine the kind of receiver that this message is being sent to.
Represents Objective-C's @autoreleasepool Statement.
ObjCCategoryImplDecl - An object of this class encapsulates a category @implementation declaration...
Represents the canonical version of C arrays with a specified constant size.
This class handles loading and caching of source files into memory.
QualType getBaseElementType(const ArrayType *VAT) const
Return the innermost element type of an array type.
unsigned getNumElements() const
getNumElements - Return number of elements of objective-c dictionary literal.
bool isObjCQualifiedInterfaceType() const
bool BlockRequiresCopying(QualType Ty, const VarDecl *D)
Returns true iff we need copy/dispose helpers for the given type.
CanQualType UnsignedIntTy
bool isPointerType() const
PresumedLoc getPresumedLoc(SourceLocation Loc, bool UseLineDirectives=true) const
Returns the "presumed" location of a SourceLocation specifies.