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;
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;
140 SmallVector<ValueDecl *, 8> BlockByCopyDecls;
141 llvm::SmallPtrSet<ValueDecl *, 8> BlockByCopyDeclsPtrSet;
142 SmallVector<ValueDecl *, 8> BlockByRefDecls;
143 llvm::SmallPtrSet<ValueDecl *, 8> BlockByRefDeclsPtrSet;
144 llvm::DenseMap<ValueDecl *, unsigned> BlockByRefDeclNo;
145 llvm::SmallPtrSet<ValueDecl *, 8> ImportedBlockDecls;
146 llvm::SmallPtrSet<VarDecl *, 8> ImportedLocalExternalDecls;
148 llvm::DenseMap<BlockExpr *, std::string> RewrittenBlockExprs;
150 llvm::SmallPtrSet<ObjCIvarDecl *, 8> > ReferencedIvars;
154 llvm::DenseMap<const ObjCIvarDecl* , unsigned> IvarGroupNumber;
157 llvm::DenseMap<std::pair<const ObjCInterfaceDecl*, unsigned>,
QualType> GroupRecordType;
158 SmallVector<FunctionDecl*, 32> FunctionDefinitionsSeen;
163 llvm::DenseMap<Stmt *, Stmt *> ReplacedNodes;
167 bool SilenceRewriteMacroWarning;
168 bool GenerateLineInfo;
169 bool objc_impl_method;
171 bool DisableReplaceStmt;
172 class DisableReplaceStmtScope {
173 RewriteModernObjC &R;
177 DisableReplaceStmtScope(RewriteModernObjC &R)
178 : R(R), SavedValue(R.DisableReplaceStmt) {
179 R.DisableReplaceStmt =
true;
181 ~DisableReplaceStmtScope() {
182 R.DisableReplaceStmt = SavedValue;
188 llvm::DenseMap<ObjCMethodDecl*, std::string> MethodInternalNames;
193 if (!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);
241 void HandleTopLevelSingleDecl(
Decl *D);
242 void HandleDeclInMainFile(
Decl *D);
243 RewriteModernObjC(std::string inFile, raw_ostream *OS,
245 bool silenceMacroWarn,
bool LineInfo);
247 ~RewriteModernObjC()
override {}
249 void HandleTranslationUnit(
ASTContext &
C)
override;
251 void ReplaceStmt(
Stmt *Old,
Stmt *New) {
252 ReplaceStmtWithRange(Old, New, Old->getSourceRange());
256 assert(Old !=
nullptr && New !=
nullptr &&
"Expected non-null Stmt's");
258 Stmt *ReplacingStmt = ReplacedNodes[Old];
262 if (DisableReplaceStmt)
266 int Size = Rewrite.getRangeSize(SrcRange);
269 << Old->getSourceRange();
274 llvm::raw_string_ostream
S(SStr);
276 const std::string &Str =
S.str();
279 if (!Rewrite.ReplaceText(SrcRange.
getBegin(), Size, Str)) {
280 ReplacedNodes[Old] = New;
283 if (SilenceRewriteMacroWarning)
286 << Old->getSourceRange();
290 bool InsertAfter =
true) {
292 if (!Rewrite.InsertText(Loc, Str, InsertAfter) ||
293 SilenceRewriteMacroWarning)
302 if (!Rewrite.ReplaceText(Start, OrigLength, Str) ||
303 SilenceRewriteMacroWarning)
311 void RewriteInclude();
312 void RewriteLineDirective(
const Decl *D);
314 std::string &LineString);
316 void RewriteForwardClassDecl(
const SmallVectorImpl<Decl *> &DG);
318 const std::string &typedefString);
319 void RewriteImplementations();
324 void RewriteImplementationDecl(
Decl *Dcl);
327 void RewriteTypeIntoString(
QualType T, std::string &ResultStr,
329 void RewriteByRefString(std::string &ResultStr,
const std::string &Name,
334 void RewriteForwardProtocolDecl(
const SmallVectorImpl<Decl *> &DG);
338 void RewriteBlockPointerType(std::string& Str,
QualType Type);
339 void RewriteBlockPointerTypeVariable(std::string& Str,
ValueDecl *VD);
341 void RewriteObjCQualifiedInterfaceTypes(
Decl *Dcl);
342 void RewriteTypeOfDecl(
VarDecl *VD);
343 void RewriteObjCQualifiedInterfaceTypes(
Expr *E);
348 Stmt *RewriteFunctionBodyOrGlobalInitializer(
Stmt *
S);
369 void RewriteImplicitCastObjCExpr(
CastExpr *IE);
382 QualType SynthesizeBitfieldGroupStructType(
384 SmallVectorImpl<ObjCIvarDecl *> &IVars);
390 void RewriteBlockPointerDecl(
NamedDecl *VD);
391 void RewriteByRefVar(
VarDecl *VD,
bool firstDecl,
bool lastDecl);
401 bool &IsNamedDefinition);
410 void Initialize(
ASTContext &context)
override;
415 Expr **args,
unsigned nargs,
421 SmallVectorImpl<QualType> &ArgTypes,
422 SmallVectorImpl<Expr*> &MsgExprs,
429 void SynthCountByEnumWithState(std::string &buf);
430 void SynthMsgSendFunctionDecl();
431 void SynthMsgSendSuperFunctionDecl();
432 void SynthMsgSendStretFunctionDecl();
433 void SynthMsgSendFpretFunctionDecl();
434 void SynthMsgSendSuperStretFunctionDecl();
435 void SynthGetClassFunctionDecl();
436 void SynthGetMetaClassFunctionDecl();
437 void SynthGetSuperClassFunctionDecl();
438 void SynthSelGetUidFunctionDecl();
439 void SynthSuperConstructorFunctionDecl();
442 template<
typename MethodIterator>
443 void RewriteObjCMethodsMetaData(MethodIterator MethodBegin,
444 MethodIterator MethodEnd,
445 bool IsInstanceMethod,
451 void RewriteObjCProtocolListMetaData(
453 StringRef prefix, StringRef ClassName, std::string &
Result);
456 void RewriteClassSetupInitHook(std::string &
Result);
458 void RewriteMetaDataIntoBuffer(std::string &
Result);
459 void WriteImageInfo(std::string &
Result);
462 void RewriteCategorySetupInitHook(std::string &
Result);
470 std::string SynthesizeByrefCopyDestroyHelper(
VarDecl *VD,
int flag);
471 std::string SynthesizeBlockHelperFuncs(
BlockExpr *CE,
int i,
472 StringRef funcName, std::string Tag);
473 std::string SynthesizeBlockFunc(
BlockExpr *CE,
int i,
474 StringRef funcName, std::string Tag);
475 std::string SynthesizeBlockImpl(
BlockExpr *CE,
476 std::string Tag, std::string Desc);
477 std::string SynthesizeBlockDescriptor(std::string DescTag,
479 int i, StringRef funcName,
484 FunctionDecl *SynthBlockInitFunctionDecl(StringRef name);
486 const SmallVectorImpl<DeclRefExpr *> &InnerBlockDeclRefs);
490 void WarnAboutReturnGotoStmts(
Stmt *
S);
492 void InsertBlockLiteralsWithinFunction(
FunctionDecl *FD);
495 bool IsDeclStmtInForeachHeader(
DeclStmt *DS);
496 void CollectBlockDeclRefInfo(
BlockExpr *Exp);
497 void GetBlockDeclRefExprs(
Stmt *
S);
498 void GetInnerBlockDeclRefExprs(
Stmt *
S,
499 SmallVectorImpl<DeclRefExpr *> &InnerBlockDeclRefs,
500 llvm::SmallPtrSetImpl<const DeclContext *> &InnerContexts);
504 bool isTopLevelBlockPointerType(
QualType T) {
505 return isa<BlockPointerType>(T);
511 bool convertBlockPointerToFunctionPointer(
QualType &T) {
512 if (isTopLevelBlockPointerType(T)) {
520 bool convertObjCTypeToCStyleType(
QualType &T);
522 bool needToScanForQualifiers(
QualType T);
524 QualType getConstantStringStructType();
526 bool BufferContainsPPDirectives(
const char *startBuf,
const char *endBuf);
528 void convertToUnqualifiedObjCType(
QualType &T) {
549 if (!LangOpts.ObjC1 && !LangOpts.ObjC2)
559 if (isa<ObjCInterfaceType>(PT->getPointeeType()) ||
560 PT->getPointeeType()->isObjCQualifiedIdType())
565 bool PointerTypeTakesAnyBlockArguments(
QualType QT);
566 bool PointerTypeTakesAnyObjCQualifiedType(
QualType QT);
567 void GetExtentOfArgList(
const char *Name,
const char *&LParen,
568 const char *&RParen);
570 void QuoteDoublequotes(std::string &From, std::string &To) {
571 for (
unsigned i = 0; i < From.length(); i++) {
580 ArrayRef<QualType> args,
581 bool variadic =
false) {
597 bool ImplementationIsNonLazy(
const ObjCImplDecl *OD)
const {
614 void RewriteModernObjC::RewriteBlocksInFunctionProtoType(
QualType funcType,
617 = dyn_cast<FunctionProtoType>(funcType.
IgnoreParens())) {
618 for (
const auto &I : fproto->param_types())
619 if (isTopLevelBlockPointerType(I)) {
621 RewriteBlockPointerDecl(D);
627 void RewriteModernObjC::CheckFunctionPointerDecl(
QualType funcType,
NamedDecl *ND) {
629 if (PT && PointerTypeTakesAnyBlockArguments(funcType))
633 static bool IsHeaderFile(
const std::string &Filename) {
634 std::string::size_type DotPos = Filename.rfind(
'.');
636 if (DotPos == std::string::npos) {
641 std::string Ext = std::string(Filename.begin()+DotPos+1, Filename.end());
644 return Ext ==
"h" || Ext ==
"hh" || Ext ==
"H";
647 RewriteModernObjC::RewriteModernObjC(std::string inFile, raw_ostream* OS,
649 bool silenceMacroWarn,
651 : Diags(D), LangOpts(LOpts), InFileName(inFile), OutFile(OS),
652 SilenceRewriteMacroWarning(silenceMacroWarn), GenerateLineInfo(LineInfo) {
653 IsHeader = IsHeaderFile(inFile);
655 "rewriting sub-expression within a macro (may not be correct)");
659 "rewriting block literal declared in global scope is not implemented");
661 TryFinallyContainsReturnDiag = Diags.getCustomDiagID(
663 "rewriter doesn't support user-specified control flow semantics "
664 "for @try/@finally (code may not execute properly)");
669 const LangOptions &LOpts,
bool SilenceRewriteMacroWarning,
bool LineInfo) {
670 return llvm::make_unique<RewriteModernObjC>(
671 InFile, OS, Diags, LOpts, SilenceRewriteMacroWarning, LineInfo);
674 void RewriteModernObjC::InitializeCommon(
ASTContext &context) {
678 MsgSendFunctionDecl =
nullptr;
679 MsgSendSuperFunctionDecl =
nullptr;
680 MsgSendStretFunctionDecl =
nullptr;
681 MsgSendSuperStretFunctionDecl =
nullptr;
682 MsgSendFpretFunctionDecl =
nullptr;
683 GetClassFunctionDecl =
nullptr;
684 GetMetaClassFunctionDecl =
nullptr;
685 GetSuperClassFunctionDecl =
nullptr;
686 SelGetUidFunctionDecl =
nullptr;
687 CFStringFunctionDecl =
nullptr;
688 ConstantStringClassReference =
nullptr;
689 NSStringRecord =
nullptr;
690 CurMethodDef =
nullptr;
691 CurFunctionDef =
nullptr;
692 GlobalVarDecl =
nullptr;
693 GlobalConstructionExp =
nullptr;
694 SuperStructDecl =
nullptr;
695 ProtocolTypeDecl =
nullptr;
696 ConstantStringDecl =
nullptr;
698 SuperConstructorFunctionDecl =
nullptr;
699 NumObjCStringLiterals = 0;
700 PropParentMap =
nullptr;
701 CurrentBody =
nullptr;
702 DisableReplaceStmt =
false;
703 objc_impl_method =
false;
707 const llvm::MemoryBuffer *MainBuf =
SM->
getBuffer(MainFileID);
708 MainFileStart = MainBuf->getBufferStart();
709 MainFileEnd = MainBuf->getBufferEnd();
718 void RewriteModernObjC::HandleTopLevelSingleDecl(
Decl *D) {
719 if (Diags.hasErrorOccurred())
733 RewriteFunctionDecl(FD);
734 }
else if (
VarDecl *FVD = dyn_cast<VarDecl>(D)) {
736 if (FVD->getName() ==
"_NSConstantStringClassReference") {
737 ConstantStringClassReference = FVD;
741 RewriteCategoryDecl(CD);
743 if (PD->isThisDeclarationADefinition())
744 RewriteProtocolDecl(PD);
752 DIEnd = LSD->decls_end();
755 if (!IFace->isThisDeclarationADefinition()) {
756 SmallVector<Decl *, 8> DG;
759 if (isa<ObjCInterfaceDecl>(*DI) &&
760 !cast<ObjCInterfaceDecl>(*DI)->isThisDeclarationADefinition() &&
761 StartLoc == (*DI)->getLocStart())
767 }
while (DI != DIEnd);
768 RewriteForwardClassDecl(DG);
773 ObjCInterfacesSeen.push_back(IFace);
780 if (!Proto->isThisDeclarationADefinition()) {
781 SmallVector<Decl *, 8> DG;
784 if (isa<ObjCProtocolDecl>(*DI) &&
785 !cast<ObjCProtocolDecl>(*DI)->isThisDeclarationADefinition() &&
786 StartLoc == (*DI)->getLocStart())
792 }
while (DI != DIEnd);
793 RewriteForwardProtocolDecl(DG);
798 HandleTopLevelSingleDecl(*DI);
804 return HandleDeclInMainFile(D);
811 void RewriteModernObjC::RewriteInclude() {
814 const char *MainBufStart = MainBuf.begin();
815 const char *MainBufEnd = MainBuf.end();
816 size_t ImportLen = strlen(
"import");
819 for (
const char *BufPtr = MainBufStart; BufPtr < MainBufEnd; ++BufPtr) {
820 if (*BufPtr ==
'#') {
821 if (++BufPtr == MainBufEnd)
823 while (*BufPtr ==
' ' || *BufPtr ==
'\t')
824 if (++BufPtr == MainBufEnd)
826 if (!strncmp(BufPtr,
"import", ImportLen)) {
830 ReplaceText(ImportLoc, ImportLen,
"include");
839 Result +=
"OBJC_IVAR_$_";
846 RewriteModernObjC::getIvarAccessString(
ObjCIvarDecl *D) {
850 std::string IvarOffsetName;
852 ObjCIvarBitfieldGroupOffset(D, IvarOffsetName);
854 WriteInternalIvarName(ClassDecl, D, IvarOffsetName);
857 std::string
S =
"(*(";
860 IvarT = GetGroupRecordTypeForObjCIvarBitfield(D);
862 if (!isa<TypedefType>(IvarT) && IvarT->
isRecordType()) {
871 CDecl = CatDecl->getClassInterface();
872 std::string RecName = CDecl->
getName();
878 unsigned UnsignedIntSize =
881 llvm::APInt(UnsignedIntSize, 0),
898 convertObjCTypeToCStyleType(IvarT);
905 S +=
"((char *)self + ";
929 static bool objcGetPropertyDefined =
false;
930 static bool objcSetPropertyDefined =
false;
935 InsertText(startLoc,
"// ");
937 assert((*startBuf ==
'@') &&
"bogus @synthesize location");
938 const char *semiBuf = strchr(startBuf,
';');
939 assert((*semiBuf ==
';') &&
"@synthesize: can't find ';'");
951 assert(IMD && OID &&
"Synthesized ivars must be attached to @implementation");
954 if (mustSynthesizeSetterGetterMethod(IMD, PD,
true )) {
955 bool GenGetProperty = !(Attributes & ObjCPropertyDecl::OBJC_PR_nonatomic) &&
956 (Attributes & (ObjCPropertyDecl::OBJC_PR_retain |
957 ObjCPropertyDecl::OBJC_PR_copy));
959 if (GenGetProperty && !objcGetPropertyDefined) {
960 objcGetPropertyDefined =
true;
962 Getr =
"\nextern \"C\" __declspec(dllimport) "
963 "id objc_getProperty(id, SEL, long, bool);\n";
970 if (GenGetProperty) {
983 for (
unsigned i = 0, e = FT->getNumParams(); i != e; ++i) {
985 std::string ParamStr =
989 if (FT->isVariadic()) {
990 if (FT->getNumParams())
999 Getr +=
"return (_TYPE)";
1000 Getr +=
"objc_getProperty(self, _cmd, ";
1001 RewriteIvarOffsetComputation(OID, Getr);
1005 Getr +=
"return " + getIvarAccessString(OID);
1007 InsertText(startGetterSetterLoc, Getr);
1011 !mustSynthesizeSetterGetterMethod(IMD, PD,
false ))
1016 bool GenSetProperty = Attributes & (ObjCPropertyDecl::OBJC_PR_retain |
1017 ObjCPropertyDecl::OBJC_PR_copy);
1018 if (GenSetProperty && !objcSetPropertyDefined) {
1019 objcSetPropertyDefined =
true;
1021 Setr =
"\nextern \"C\" __declspec(dllimport) "
1022 "void objc_setProperty (id, SEL, long, id, bool, bool);\n";
1030 if (GenSetProperty) {
1031 Setr +=
"objc_setProperty (self, _cmd, ";
1032 RewriteIvarOffsetComputation(OID, Setr);
1036 if (Attributes & ObjCPropertyDecl::OBJC_PR_nonatomic)
1040 if (Attributes & ObjCPropertyDecl::OBJC_PR_copy)
1046 Setr += getIvarAccessString(OID) +
" = ";
1050 InsertText(startGetterSetterLoc, Setr);
1054 std::string &typedefString) {
1055 typedefString +=
"\n#ifndef _REWRITER_typedef_";
1057 typedefString +=
"\n";
1058 typedefString +=
"#define _REWRITER_typedef_";
1060 typedefString +=
"\n";
1061 typedefString +=
"typedef struct objc_object ";
1064 typedefString +=
";\ntypedef struct {} _objc_exc_";
1066 typedefString +=
";\n#endif\n";
1069 void RewriteModernObjC::RewriteForwardClassEpilogue(
ObjCInterfaceDecl *ClassDecl,
1070 const std::string &typedefString) {
1073 const char *semiPtr = strchr(startBuf,
';');
1075 ReplaceText(startLoc, semiPtr-startBuf+1, typedefString);
1078 void RewriteModernObjC::RewriteForwardClassDecl(
DeclGroupRef D) {
1079 std::string typedefString;
1082 if (I == D.
begin()) {
1086 typedefString +=
"// @class ";
1088 typedefString +=
";";
1090 RewriteOneForwardClassDecl(ForwardDecl, typedefString);
1093 HandleTopLevelSingleDecl(*I);
1096 RewriteForwardClassEpilogue(cast<ObjCInterfaceDecl>(*I), typedefString);
1099 void RewriteModernObjC::RewriteForwardClassDecl(
1100 const SmallVectorImpl<Decl *> &D) {
1101 std::string typedefString;
1102 for (
unsigned i = 0; i < D.size(); i++) {
1105 typedefString +=
"// @class ";
1107 typedefString +=
";";
1109 RewriteOneForwardClassDecl(ForwardDecl, typedefString);
1111 RewriteForwardClassEpilogue(cast<ObjCInterfaceDecl>(D[0]), typedefString);
1114 void RewriteModernObjC::RewriteMethodDeclaration(
ObjCMethodDecl *Method) {
1124 InsertText(LocStart,
"#if 0\n");
1125 ReplaceText(LocEnd, 1,
";\n#endif\n");
1127 InsertText(LocStart,
"// ");
1134 ReplaceText(Loc, 0,
"// ");
1143 ReplaceText(LocStart, 1,
"/** ");
1147 ReplaceText(LocStart, 0,
"// ");
1154 RewriteMethodDeclaration(I);
1156 RewriteMethodDeclaration(I);
1160 strlen(
"@end"),
"/* @end */\n");
1168 ReplaceText(LocStart, 0,
"// ");
1171 RewriteMethodDeclaration(I);
1173 RewriteMethodDeclaration(I);
1179 ReplaceText(LocEnd, strlen(
"@end"),
"/* @end */\n");
1184 for (
const char *
p = startBuf;
p < endBuf;
p++) {
1185 if (*
p ==
'@' && !strncmp(
p+1,
"optional", strlen(
"optional"))) {
1187 ReplaceText(OptionalLoc, strlen(
"@optional"),
"/* @optional */");
1190 else if (*
p ==
'@' && !strncmp(
p+1,
"required", strlen(
"required"))) {
1192 ReplaceText(OptionalLoc, strlen(
"@required"),
"/* @required */");
1198 void RewriteModernObjC::RewriteForwardProtocolDecl(
DeclGroupRef D) {
1201 llvm_unreachable(
"Invalid SourceLocation");
1203 ReplaceText(LocStart, 0,
"// ");
1207 RewriteModernObjC::RewriteForwardProtocolDecl(
const SmallVectorImpl<Decl *> &DG) {
1210 llvm_unreachable(
"Invalid SourceLocation");
1212 ReplaceText(LocStart, 0,
"// ");
1219 llvm_unreachable(
"Invalid extern SourceLocation");
1221 ReplaceText(LocStart, 0,
"// ");
1227 llvm_unreachable(
"Invalid rbrace SourceLocation");
1228 ReplaceText(LocRBrace, 0,
"// ");
1231 void RewriteModernObjC::RewriteTypeIntoString(
QualType T, std::string &ResultStr,
1256 std::string &ResultStr) {
1259 ResultStr +=
"\nstatic ";
1260 RewriteTypeIntoString(OMD->
getReturnType(), ResultStr, FPRetType);
1264 std::string NameStr;
1282 int len = selString.size();
1283 for (
int i = 0; i < len; i++)
1284 if (selString[i] ==
':')
1286 NameStr += selString;
1289 MethodInternalNames[OMD] = NameStr;
1290 ResultStr += NameStr;
1299 if (!LangOpts.MicrosoftExt) {
1300 if (ObjCSynthesizedStructs.count(const_cast<ObjCInterfaceDecl*>(IDecl)))
1301 ResultStr +=
"struct ";
1311 ResultStr +=
" self, ";
1313 ResultStr +=
" _cmd";
1316 for (
const auto *PDecl : OMD->
params()) {
1318 if (PDecl->getType()->isObjCQualifiedIdType()) {
1325 (void)convertBlockPointerToFunctionPointer(QT);
1331 ResultStr +=
", ...";
1340 for (
unsigned i = 0, e = FT->getNumParams(); i != e; ++i) {
1341 if (i) ResultStr +=
", ";
1342 std::string ParamStr =
1344 ResultStr += ParamStr;
1346 if (FT->isVariadic()) {
1347 if (FT->getNumParams())
1357 void RewriteModernObjC::RewriteImplementationDecl(
Decl *OID) {
1371 InsertText(CID->getLocStart(),
"// ");
1373 for (
auto *OMD : IMD ? IMD->
instance_methods() : CID->instance_methods()) {
1374 std::string ResultStr;
1381 ReplaceText(LocStart, endBuf-startBuf, ResultStr);
1384 for (
auto *OMD : IMD ? IMD->
class_methods() : CID->class_methods()) {
1385 std::string ResultStr;
1392 ReplaceText(LocStart, endBuf-startBuf, ResultStr);
1394 for (
auto *I : IMD ? IMD->
property_impls() : CID->property_impls())
1395 RewritePropertyImplDecl(I, IMD, CID);
1397 InsertText(IMD ? IMD->
getLocEnd() : CID->getLocEnd(),
"// ");
1402 if (ObjCSynthesizedStructs.count(ClassDecl))
1406 while (SuperClass) {
1407 RewriteInterfaceDecl(SuperClass);
1410 std::string ResultStr;
1413 RewriteOneForwardClassDecl(ClassDecl, ResultStr);
1414 RewriteIvarOffsetSymbols(ClassDecl, ResultStr);
1416 RewriteObjCInternalStruct(ClassDecl, ResultStr);
1423 RewriteMethodDeclaration(I);
1425 RewriteMethodDeclaration(I);
1434 SourceRange OldRange = PseudoOp->getSourceRange();
1445 SmallVector<Expr*, 2> Args;
1447 DisableReplaceStmtScope
S(*
this);
1453 Base = cast<OpaqueValueExpr>(Base)->getSourceExpr();
1454 Base = cast<Expr>(RewriteFunctionBodyOrGlobalInitializer(Base));
1458 for (
unsigned i = 0; i < numArgs; i++) {
1460 if (isa<OpaqueValueExpr>(Arg))
1461 Arg = cast<OpaqueValueExpr>(Arg)->getSourceExpr();
1462 Arg = cast<Expr>(RewriteFunctionBodyOrGlobalInitializer(Arg));
1463 Args.push_back(Arg);
1468 SmallVector<SourceLocation, 1> SelLocs;
1473 case ObjCMessageExpr::Class:
1486 case ObjCMessageExpr::Instance:
1499 case ObjCMessageExpr::SuperClass:
1500 case ObjCMessageExpr::SuperInstance:
1516 Stmt *Replacement = SynthMessageExpr(NewMsg);
1517 ReplaceStmtWithRange(PseudoOp, Replacement, OldRange);
1522 SourceRange OldRange = PseudoOp->getSourceRange();
1531 Expr *Base =
nullptr;
1532 SmallVector<Expr*, 1> Args;
1534 DisableReplaceStmtScope
S(*
this);
1538 Base = cast<OpaqueValueExpr>(Base)->getSourceExpr();
1539 Base = cast<Expr>(RewriteFunctionBodyOrGlobalInitializer(Base));
1542 for (
unsigned i = 0; i < numArgs; i++) {
1544 if (isa<OpaqueValueExpr>(Arg))
1545 Arg = cast<OpaqueValueExpr>(Arg)->getSourceExpr();
1546 Arg = cast<Expr>(RewriteFunctionBodyOrGlobalInitializer(Arg));
1547 Args.push_back(Arg);
1552 SmallVector<SourceLocation, 1> SelLocs;
1556 case ObjCMessageExpr::Class:
1569 case ObjCMessageExpr::Instance:
1582 case ObjCMessageExpr::SuperClass:
1583 case ObjCMessageExpr::SuperInstance:
1599 Stmt *Replacement = SynthMessageExpr(NewMsg);
1600 ReplaceStmtWithRange(PseudoOp, Replacement, OldRange);
1613 void RewriteModernObjC::SynthCountByEnumWithState(std::string &buf) {
1614 buf +=
"((_WIN_NSUInteger (*) (id, SEL, struct __objcFastEnumerationState *, "
1615 "id *, _WIN_NSUInteger))(void *)objc_msgSend)";
1617 buf +=
"((id)l_collection,\n\t\t";
1618 buf +=
"sel_registerName(\"countByEnumeratingWithState:objects:count:\"),";
1620 buf +=
"&enumState, "
1621 "(id *)__rw_items, (_WIN_NSUInteger)16)";
1628 if (Stmts.empty() || !isa<ObjCForCollectionStmt>(Stmts.back()))
1634 buf =
"goto __break_label_";
1635 buf += utostr(ObjCBcLabelNo.back());
1636 ReplaceText(startLoc, strlen(
"break"), buf);
1641 void RewriteModernObjC::ConvertSourceLocationToLineDirective(
1643 std::string &LineString) {
1644 if (Loc.
isFileID() && GenerateLineInfo) {
1645 LineString +=
"\n#line ";
1647 LineString += utostr(PLoc.
getLine());
1648 LineString +=
" \"";
1649 LineString += Lexer::Stringify(PLoc.
getFilename());
1650 LineString +=
"\"\n";
1658 if (Stmts.empty() || !isa<ObjCForCollectionStmt>(Stmts.back()))
1664 buf =
"goto __continue_label_";
1665 buf += utostr(ObjCBcLabelNo.back());
1666 ReplaceText(startLoc, strlen(
"continue"), buf);
1705 assert(!Stmts.empty() &&
"ObjCForCollectionStmt - Statement stack empty");
1706 assert(isa<ObjCForCollectionStmt>(Stmts.back()) &&
1707 "ObjCForCollectionStmt Statement stack mismatch");
1708 assert(!ObjCBcLabelNo.empty() &&
1709 "ObjCForCollectionStmt - Label No stack empty");
1713 StringRef elementName;
1714 std::string elementTypeAsString;
1718 ConvertSourceLocationToLineDirective(ForEachLoc, buf);
1722 NamedDecl* D = cast<NamedDecl>(DS->getSingleDecl());
1723 QualType ElementType = cast<ValueDecl>(D)->getType();
1724 if (ElementType->isObjCQualifiedIdType() ||
1725 ElementType->isObjCQualifiedInterfaceType())
1727 elementTypeAsString =
"id";
1730 buf += elementTypeAsString;
1743 elementTypeAsString =
"id";
1749 buf +=
"struct __objcFastEnumerationState enumState = { 0 };\n\t";
1751 buf +=
"id __rw_items[16];\n\t";
1753 buf +=
"id l_collection = (id)";
1755 const char *startCollectionBuf = startBuf;
1756 startCollectionBuf += 3;
1757 startCollectionBuf = strchr(startCollectionBuf,
'(');
1758 startCollectionBuf++;
1760 while (*startCollectionBuf !=
' ' ||
1761 *(startCollectionBuf+1) !=
'i' || *(startCollectionBuf+2) !=
'n' ||
1762 (*(startCollectionBuf+3) !=
' ' &&
1763 *(startCollectionBuf+3) !=
'[' && *(startCollectionBuf+3) !=
'('))
1764 startCollectionBuf++;
1765 startCollectionBuf += 3;
1768 ReplaceText(startLoc, startCollectionBuf - startBuf, buf);
1786 buf +=
"_WIN_NSUInteger limit =\n\t\t";
1787 SynthCountByEnumWithState(buf);
1797 buf +=
"if (limit) {\n\t";
1798 buf +=
"unsigned long startMutations = *enumState.mutationsPtr;\n\t";
1799 buf +=
"do {\n\t\t";
1800 buf +=
"unsigned long counter = 0;\n\t\t";
1801 buf +=
"do {\n\t\t\t";
1802 buf +=
"if (startMutations != *enumState.mutationsPtr)\n\t\t\t\t";
1803 buf +=
"objc_enumerationMutation(l_collection);\n\t\t\t";
1806 buf += elementTypeAsString;
1807 buf +=
")enumState.itemsPtr[counter++];";
1809 ReplaceText(lparenLoc, 1, buf);
1823 buf +=
"__continue_label_";
1824 buf += utostr(ObjCBcLabelNo.back());
1827 buf +=
"} while (counter < limit);\n\t";
1828 buf +=
"} while ((limit = ";
1829 SynthCountByEnumWithState(buf);
1833 buf += elementTypeAsString;
1835 buf +=
"__break_label_";
1836 buf += utostr(ObjCBcLabelNo.back());
1839 buf +=
"else\n\t\t";
1842 buf += elementTypeAsString;
1848 if (isa<CompoundStmt>(S->
getBody())) {
1850 InsertText(endBodyLoc, buf);
1860 const char *semiBuf = strchr(stmtBuf,
';');
1861 assert(semiBuf &&
"Can't find ';'");
1863 InsertText(endBodyLoc, buf);
1866 ObjCBcLabelNo.pop_back();
1870 static void Write_RethrowObject(std::string &buf) {
1871 buf +=
"{ struct _FIN { _FIN(id reth) : rethrow(reth) {}\n";
1872 buf +=
"\t~_FIN() { if (rethrow) objc_exception_throw(rethrow); }\n";
1873 buf +=
"\tid rethrow;\n";
1874 buf +=
"\t} _fin_force_rethow(_rethrow);";
1888 assert((*startBuf ==
'@') &&
"bogus @synchronized location");
1892 ConvertSourceLocationToLineDirective(SynchLoc, buf);
1893 buf +=
"{ id _rethrow = 0; id _sync_obj = (id)";
1895 const char *lparenBuf = startBuf;
1896 while (*lparenBuf !=
'(') lparenBuf++;
1897 ReplaceText(startLoc, lparenBuf-startBuf+1, buf);
1899 buf =
"; objc_sync_enter(_sync_obj);\n";
1900 buf +=
"try {\n\tstruct _SYNC_EXIT { _SYNC_EXIT(id arg) : sync_exit(arg) {}";
1901 buf +=
"\n\t~_SYNC_EXIT() {objc_sync_exit(sync_exit);}";
1902 buf +=
"\n\tid sync_exit;";
1903 buf +=
"\n\t} _sync_exit(_sync_obj);\n";
1910 while (*RParenExprLocBuf !=
')') RParenExprLocBuf--;
1915 assert (*LBraceLocBuf ==
'{');
1916 ReplaceText(RParenExprLoc, (LBraceLocBuf -
SM->
getCharacterData(RParenExprLoc) + 1), buf);
1920 "bogus @synchronized block");
1922 buf =
"} catch (id e) {_rethrow = e;}\n";
1923 Write_RethrowObject(buf);
1927 ReplaceText(startRBraceLoc, 1, buf);
1932 void RewriteModernObjC::WarnAboutReturnGotoStmts(
Stmt *S)
1935 for (
Stmt *SubStmt : S->children())
1937 WarnAboutReturnGotoStmts(SubStmt);
1939 if (isa<ReturnStmt>(S) || isa<GotoStmt>(S)) {
1941 TryFinallyContainsReturnDiag);
1948 ReplaceText(startLoc, strlen(
"@autoreleasepool"),
"/* @autoreleasepool */");
1949 ReplaceText(S->
getSubStmt()->getLocStart(), 1,
1950 "{ __AtAutoreleasePool __autoreleasepool; ");
1960 ConvertSourceLocationToLineDirective(TryLocation, buf);
1964 buf +=
"{ id volatile _rethrow = 0;\n";
1966 buf +=
"{ id volatile _rethrow = 0;\ntry {\n";
1973 assert((*startBuf ==
'@') &&
"bogus @try location");
1975 ReplaceText(startLoc, 1, buf);
1978 ReplaceText(startLoc, 1,
"");
1985 bool AtRemoved =
false;
1993 ConvertSourceLocationToLineDirective(Catch->
getLocStart(), Result);
1996 assert((*startBuf ==
'@') &&
"bogus @catch location");
2004 ReplaceText(startLoc, rParenBuf-startBuf+1, Result);
2015 ReplaceText(lBraceLoc, 1, Result);
2022 ReplaceText(startLoc, 1,
"");
2030 ConvertSourceLocationToLineDirective(FinallyLoc, buf);
2031 buf +=
"catch (id e) {_rethrow = e;}\n";
2035 ConvertSourceLocationToLineDirective(FinallyLoc, buf);
2036 buf +=
"catch (id e) {_rethrow = e;}\n";
2040 ReplaceText(startFinalLoc, 8, buf);
2044 Write_RethrowObject(buf);
2045 ReplaceText(startFinalBodyLoc, 1, buf);
2048 ReplaceText(endFinalBodyLoc, 1,
"}\n}");
2064 assert((*startBuf ==
'@') &&
"bogus @throw location");
2069 buf =
"objc_exception_throw(";
2074 const char *wBuf = strchr(startBuf,
'w');
2075 assert((*wBuf ==
'w') &&
"@throw: can't find 'w'");
2076 ReplaceText(startLoc, wBuf-startBuf+1, buf);
2080 const char *semiBuf = strchr(endBuf,
';');
2081 assert((*semiBuf ==
';') &&
"@throw: can't find ';'");
2084 ReplaceText(semiLoc, 1,
");");
2090 std::string StrEncoding;
2092 Expr *Replacement = getStringLiteral(StrEncoding);
2093 ReplaceStmt(Exp, Replacement);
2101 if (!SelGetUidFunctionDecl)
2102 SynthSelGetUidFunctionDecl();
2103 assert(SelGetUidFunctionDecl &&
"Can't find sel_registerName() decl");
2105 SmallVector<Expr*, 8> SelExprs;
2107 CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl,
2108 &SelExprs[0], SelExprs.size());
2109 ReplaceStmt(Exp, SelExp);
2114 CallExpr *RewriteModernObjC::SynthesizeCallToFunctionDecl(
2139 static bool scanForProtocolRefs(
const char *startBuf,
const char *endBuf,
2140 const char *&startRef,
const char *&endRef) {
2141 while (startBuf < endBuf) {
2142 if (*startBuf ==
'<')
2143 startRef = startBuf;
2144 if (*startBuf ==
'>') {
2145 if (startRef && *startRef ==
'<') {
2156 static void scanToNextArgument(
const char *&argRef) {
2158 while (*argRef !=
')' && (*argRef !=
',' || angle > 0)) {
2161 else if (*argRef ==
'>')
2165 assert(angle == 0 &&
"scanToNextArgument - bad protocol type syntax");
2168 bool RewriteModernObjC::needToScanForQualifiers(
QualType T) {
2181 return needToScanForQualifiers(ElemTy);
2186 void RewriteModernObjC::RewriteObjCQualifiedInterfaceTypes(
Expr *E) {
2188 if (needToScanForQualifiers(Type)) {
2192 Loc = ECE->getLParenLoc();
2193 EndLoc = ECE->getRParenLoc();
2195 Loc = E->getLocStart();
2196 EndLoc = E->getLocEnd();
2204 const char *startRef =
nullptr, *endRef =
nullptr;
2205 if (scanForProtocolRefs(startBuf, endBuf, startRef, endRef)) {
2210 InsertText(LessLoc,
"/*");
2211 InsertText(GreaterLoc,
"*/");
2216 void RewriteModernObjC::RewriteObjCQualifiedInterfaceTypes(
Decl *Dcl) {
2220 if (
VarDecl *VD = dyn_cast<VarDecl>(Dcl)) {
2224 else if (
FunctionDecl *FD = dyn_cast<FunctionDecl>(Dcl)) {
2229 assert(funcType &&
"missing function type");
2235 else if (
FieldDecl *FD = dyn_cast<FieldDecl>(Dcl)) {
2240 Loc = TD->getLocation();
2241 Type = TD->getUnderlyingType();
2246 if (needToScanForQualifiers(Type)) {
2250 const char *startBuf = endBuf;
2251 while (*startBuf !=
';' && *startBuf !=
'<' && startBuf != MainFileStart)
2253 const char *startRef =
nullptr, *endRef =
nullptr;
2254 if (scanForProtocolRefs(startBuf, endBuf, startRef, endRef)) {
2259 InsertText(LessLoc,
"/*");
2260 InsertText(GreaterLoc,
"*/");
2267 const char *startFuncBuf = startBuf;
2272 const char *endBuf = startBuf;
2274 scanToNextArgument(endBuf);
2275 const char *startRef =
nullptr, *endRef =
nullptr;
2276 if (scanForProtocolRefs(startBuf, endBuf, startRef, endRef)) {
2283 InsertText(LessLoc,
"/*");
2284 InsertText(GreaterLoc,
"*/");
2286 startBuf = ++endBuf;
2291 while (*startBuf && *startBuf !=
')' && *startBuf !=
',')
2298 void RewriteModernObjC::RewriteTypeOfDecl(
VarDecl *ND) {
2300 const Type* TypePtr = QT->
getAs<Type>();
2301 if (!isa<TypeOfExprType>(TypePtr))
2303 while (isa<TypeOfExprType>(TypePtr)) {
2304 const TypeOfExprType *TypeOfExprTypePtr = cast<TypeOfExprType>(TypePtr);
2306 TypePtr = QT->
getAs<Type>();
2315 TypeAsString +=
" " + Name +
" = ";
2319 startLoc = ECE->getLParenLoc();
2321 startLoc = E->getLocStart();
2324 ReplaceText(DeclLoc, endBuf-startBuf-1, TypeAsString);
2330 ReplaceText(DeclLoc, endBuf-startBuf-1, TypeAsString);
2335 void RewriteModernObjC::SynthSelGetUidFunctionDecl() {
2337 SmallVector<QualType, 16> ArgTys;
2344 SelGetUidIdent, getFuncType,
2348 void RewriteModernObjC::RewriteFunctionDecl(
FunctionDecl *FD) {
2351 FD->
getName() ==
"sel_registerName") {
2352 SelGetUidFunctionDecl = FD;
2355 RewriteObjCQualifiedInterfaceTypes(FD);
2358 void RewriteModernObjC::RewriteBlockPointerType(std::string& Str,
QualType Type) {
2360 const char *argPtr = TypeString.c_str();
2361 if (!strchr(argPtr,
'^')) {
2366 Str += (*argPtr ==
'^' ?
'*' : *argPtr);
2372 void RewriteModernObjC::RewriteBlockPointerTypeVariable(std::string& Str,
2376 const char *argPtr = TypeString.c_str();
2401 void RewriteModernObjC::RewriteBlockLiteralFunctionDecl(
FunctionDecl *FD) {
2407 QualType Type = proto->getReturnType();
2412 unsigned numArgs = proto->getNumParams();
2413 for (
unsigned i = 0; i < numArgs; i++) {
2414 QualType ArgType = proto->getParamType(i);
2415 RewriteBlockPointerType(FdStr, ArgType);
2420 FdStr += (numArgs > 0) ?
", ...);\n" :
"...);\n";
2424 InsertText(FunLocStart, FdStr);
2428 void RewriteModernObjC::SynthSuperConstructorFunctionDecl() {
2429 if (SuperConstructorFunctionDecl)
2432 SmallVector<QualType, 16> ArgTys;
2434 assert(!argT.
isNull() &&
"Can't find 'id' type");
2435 ArgTys.push_back(argT);
2436 ArgTys.push_back(argT);
2442 msgSendIdent, msgSendType,
2447 void RewriteModernObjC::SynthMsgSendFunctionDecl() {
2449 SmallVector<QualType, 16> ArgTys;
2451 assert(!argT.
isNull() &&
"Can't find 'id' type");
2452 ArgTys.push_back(argT);
2454 assert(!argT.
isNull() &&
"Can't find 'SEL' type");
2455 ArgTys.push_back(argT);
2461 msgSendIdent, msgSendType,
nullptr,
2466 void RewriteModernObjC::SynthMsgSendSuperFunctionDecl() {
2468 SmallVector<QualType, 2> ArgTys;
2475 msgSendIdent, msgSendType,
2480 void RewriteModernObjC::SynthMsgSendStretFunctionDecl() {
2482 SmallVector<QualType, 16> ArgTys;
2484 assert(!argT.
isNull() &&
"Can't find 'id' type");
2485 ArgTys.push_back(argT);
2487 assert(!argT.
isNull() &&
"Can't find 'SEL' type");
2488 ArgTys.push_back(argT);
2494 msgSendIdent, msgSendType,
2500 void RewriteModernObjC::SynthMsgSendSuperStretFunctionDecl() {
2503 SmallVector<QualType, 2> ArgTys;
2511 msgSendType,
nullptr,
2516 void RewriteModernObjC::SynthMsgSendFpretFunctionDecl() {
2518 SmallVector<QualType, 16> ArgTys;
2520 assert(!argT.
isNull() &&
"Can't find 'id' type");
2521 ArgTys.push_back(argT);
2523 assert(!argT.
isNull() &&
"Can't find 'SEL' type");
2524 ArgTys.push_back(argT);
2530 msgSendIdent, msgSendType,
2535 void RewriteModernObjC::SynthGetClassFunctionDecl() {
2537 SmallVector<QualType, 16> ArgTys;
2544 getClassIdent, getClassType,
2549 void RewriteModernObjC::SynthGetSuperClassFunctionDecl() {
2552 SmallVector<QualType, 16> ArgTys;
2560 getClassType,
nullptr,
2565 void RewriteModernObjC::SynthGetMetaClassFunctionDecl() {
2567 SmallVector<QualType, 16> ArgTys;
2574 getClassIdent, getClassType,
2579 assert (Exp !=
nullptr &&
"Expected non-null ObjCStringLiteral");
2580 QualType strType = getConstantStringStructType();
2582 std::string S =
"__NSConstantStringImpl_";
2584 std::string tmpName = InFileName;
2586 for (i=0; i < tmpName.length(); i++) {
2587 char c = tmpName.at(i);
2594 S += utostr(NumObjCStringLiterals++);
2596 Preamble +=
"static __NSConstantStringImpl " +
S;
2597 Preamble +=
" __attribute__ ((section (\"__DATA, __cfstring\"))) = {__CFConstantStringClassReference,";
2598 Preamble +=
"0x000007c8,";
2600 std::string prettyBufS;
2601 llvm::raw_string_ostream prettyBuf(prettyBufS);
2603 Preamble += prettyBuf.str();
2619 ReplaceStmt(Exp, cast);
2629 llvm::APInt(IntSize, Exp->
getValue()),
2635 ReplaceStmt(Exp, PE);
2641 if (!SelGetUidFunctionDecl)
2642 SynthSelGetUidFunctionDecl();
2644 if (!MsgSendFunctionDecl)
2645 SynthMsgSendFunctionDecl();
2646 if (!GetClassFunctionDecl)
2647 SynthGetClassFunctionDecl();
2654 SmallVector<Expr*, 4> MsgExprs;
2655 SmallVector<Expr*, 4> ClsExprs;
2662 ClsExprs.push_back(getStringLiteral(clsName->
getName()));
2663 CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl,
2667 MsgExprs.push_back(Cls);
2671 SmallVector<Expr*, 4> SelExprs;
2674 CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl,
2675 &SelExprs[0], SelExprs.size(),
2677 MsgExprs.push_back(SelExp);
2687 subExpr = NoTypeInfoCStyleCastExpr(
Context, type, CK, subExpr);
2689 MsgExprs.push_back(subExpr);
2691 SmallVector<QualType, 4> ArgTypes;
2694 for (
const auto PI : BoxingMethod->
parameters())
2695 ArgTypes.push_back(PI->getType());
2711 getSimpleFunctionType(returnType, ArgTypes, BoxingMethod->
isVariadic());
2722 ReplaceStmt(Exp, CE);
2728 if (!SelGetUidFunctionDecl)
2729 SynthSelGetUidFunctionDecl();
2731 if (!MsgSendFunctionDecl)
2732 SynthMsgSendFunctionDecl();
2733 if (!GetClassFunctionDecl)
2734 SynthGetClassFunctionDecl();
2744 std::string NSArrayFName(
"__NSContainer_literal");
2745 FunctionDecl *NSArrayFD = SynthBlockInitFunctionDecl(NSArrayFName);
2750 SmallVector<Expr*, 16> InitExprs;
2752 unsigned UnsignedIntSize =
2755 llvm::APInt(UnsignedIntSize, NumElements),
2757 InitExprs.push_back(count);
2758 for (
unsigned i = 0; i < NumElements; i++)
2760 Expr *NSArrayCallExpr =
2775 NoTypeInfoCStyleCastExpr(
Context,
2781 SmallVector<Expr*, 32> MsgExprs;
2782 SmallVector<Expr*, 4> ClsExprs;
2790 ClsExprs.push_back(getStringLiteral(clsName->
getName()));
2791 CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl,
2795 MsgExprs.push_back(Cls);
2799 SmallVector<Expr*, 4> SelExprs;
2803 CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl,
2804 &SelExprs[0], SelExprs.size(),
2806 MsgExprs.push_back(SelExp);
2809 MsgExprs.push_back(ArrayLiteralObjects);
2813 llvm::APInt(UnsignedIntSize, NumElements),
2815 MsgExprs.push_back(cnt);
2818 SmallVector<QualType, 4> ArgTypes;
2821 for (
const auto *PI : ArrayMethod->
params())
2822 ArgTypes.push_back(PI->getType());
2838 getSimpleFunctionType(returnType, ArgTypes, ArrayMethod->
isVariadic());
2849 ReplaceStmt(Exp, CE);
2855 if (!SelGetUidFunctionDecl)
2856 SynthSelGetUidFunctionDecl();
2858 if (!MsgSendFunctionDecl)
2859 SynthMsgSendFunctionDecl();
2860 if (!GetClassFunctionDecl)
2861 SynthGetClassFunctionDecl();
2871 std::string NSDictFName(
"__NSContainer_literal");
2872 FunctionDecl *NSDictFD = SynthBlockInitFunctionDecl(NSDictFName);
2877 SmallVector<Expr*, 16> KeyExprs;
2878 SmallVector<Expr*, 16> ValueExprs;
2881 unsigned UnsignedIntSize =
2884 llvm::APInt(UnsignedIntSize, NumElements),
2886 KeyExprs.push_back(count);
2887 ValueExprs.push_back(count);
2888 for (
unsigned i = 0; i < NumElements; i++) {
2890 KeyExprs.push_back(Element.
Key);
2891 ValueExprs.push_back(Element.
Value);
2895 Expr *NSValueCallExpr =
2910 NoTypeInfoCStyleCastExpr(
Context,
2913 DictLiteralValueME);
2915 Expr *NSKeyCallExpr =
2924 NoTypeInfoCStyleCastExpr(
Context,
2932 SmallVector<Expr*, 32> MsgExprs;
2933 SmallVector<Expr*, 4> ClsExprs;
2941 ClsExprs.push_back(getStringLiteral(clsName->
getName()));
2942 CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl,
2946 MsgExprs.push_back(Cls);
2950 SmallVector<Expr*, 4> SelExprs;
2953 CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl,
2954 &SelExprs[0], SelExprs.size(),
2956 MsgExprs.push_back(SelExp);
2959 MsgExprs.push_back(DictValueObjects);
2962 MsgExprs.push_back(DictKeyObjects);
2966 llvm::APInt(UnsignedIntSize, NumElements),
2968 MsgExprs.push_back(cnt);
2971 SmallVector<QualType, 8> ArgTypes;
2974 for (
const auto *PI : DictMethod->
params()) {
2978 convertToUnqualifiedObjCType(PointeeTy);
2981 ArgTypes.push_back(T);
2998 getSimpleFunctionType(returnType, ArgTypes, DictMethod->
isVariadic());
3009 ReplaceStmt(Exp, CE);
3016 QualType RewriteModernObjC::getSuperStructType() {
3017 if (!SuperStructDecl) {
3029 for (
unsigned i = 0; i < 2; ++i) {
3033 FieldTypes[i],
nullptr,
3039 SuperStructDecl->completeDefinition();
3044 QualType RewriteModernObjC::getConstantStringStructType() {
3045 if (!ConstantStringDecl) {
3061 for (
unsigned i = 0; i < 4; ++i) {
3066 FieldTypes[i],
nullptr,
3072 ConstantStringDecl->completeDefinition();
3080 static SourceLocation getFunctionSourceLocation (RewriteModernObjC &R,
3090 R.RewriteBlockLiteralFunctionDecl(FD);
3094 void RewriteModernObjC::RewriteLineDirective(
const Decl *D) {
3098 if (Location.
isFileID() && GenerateLineInfo) {
3099 std::string LineString(
"\n#line ");
3101 LineString += utostr(PLoc.
getLine());
3102 LineString +=
" \"";
3103 LineString += Lexer::Stringify(PLoc.
getFilename());
3104 if (isa<ObjCMethodDecl>(D))
3106 else LineString +=
"\"\n";
3109 if (
const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
3118 InsertText(Location, LineString);
3132 Expr *RewriteModernObjC::SynthMsgSendStretCallExpr(
FunctionDecl *MsgSendStretFlavor,
3134 SmallVectorImpl<QualType> &ArgTypes,
3135 SmallVectorImpl<Expr*> &MsgExprs,
3138 QualType castType = getSimpleFunctionType(returnType, ArgTypes,
3144 static unsigned stretCount=0;
3145 std::string name =
"__Stret"; name += utostr(stretCount);
3147 "extern \"C\" void * __cdecl memset(void *_Dst, int _Val, size_t _Size);\n";
3148 str +=
"namespace {\n";
3149 str +=
"struct "; str += name;
3152 str +=
"(id receiver, SEL sel";
3153 for (
unsigned i = 2; i < ArgTypes.size(); i++) {
3154 std::string ArgName =
"arg"; ArgName += utostr(i);
3156 str +=
", "; str += ArgName;
3159 for (
unsigned i = ArgTypes.size(); i < MsgExprs.size(); i++) {
3160 std::string ArgName =
"arg"; ArgName += utostr(i);
3161 MsgExprs[i]->getType().getAsStringInternal(ArgName,
3163 str +=
", "; str += ArgName;
3167 str +=
"\t unsigned size = sizeof(";
3170 str +=
"\t if (size == 1 || size == 2 || size == 4 || size == 8)\n";
3173 str +=
")(void *)objc_msgSend)(receiver, sel";
3174 for (
unsigned i = 2; i < ArgTypes.size(); i++) {
3175 str +=
", arg"; str += utostr(i);
3178 for (
unsigned i = ArgTypes.size(); i < MsgExprs.size(); i++) {
3179 str +=
", arg"; str += utostr(i);
3183 str +=
"\t else if (receiver == 0)\n";
3184 str +=
"\t memset((void*)&s, 0, sizeof(s));\n";
3189 str +=
")(void *)objc_msgSend_stret)(receiver, sel";
3190 for (
unsigned i = 2; i < ArgTypes.size(); i++) {
3191 str +=
", arg"; str += utostr(i);
3194 for (
unsigned i = ArgTypes.size(); i < MsgExprs.size(); i++) {
3195 str +=
", arg"; str += utostr(i);
3203 str +=
"};\n};\n\n";
3206 FunLocStart = getFunctionSourceLocation(*
this, CurFunctionDef);
3208 assert(CurMethodDef &&
"SynthMsgSendStretCallExpr - CurMethodDef is null");
3209 FunLocStart = CurMethodDef->getLocStart();
3212 InsertText(FunLocStart, str);
3228 returnType,
nullptr,
3241 if (!SelGetUidFunctionDecl)
3242 SynthSelGetUidFunctionDecl();
3243 if (!MsgSendFunctionDecl)
3244 SynthMsgSendFunctionDecl();
3245 if (!MsgSendSuperFunctionDecl)
3246 SynthMsgSendSuperFunctionDecl();
3247 if (!MsgSendStretFunctionDecl)
3248 SynthMsgSendStretFunctionDecl();
3249 if (!MsgSendSuperStretFunctionDecl)
3250 SynthMsgSendSuperStretFunctionDecl();
3251 if (!MsgSendFpretFunctionDecl)
3252 SynthMsgSendFpretFunctionDecl();
3253 if (!GetClassFunctionDecl)
3254 SynthGetClassFunctionDecl();
3255 if (!GetSuperClassFunctionDecl)
3256 SynthGetSuperClassFunctionDecl();
3257 if (!GetMetaClassFunctionDecl)
3258 SynthGetMetaClassFunctionDecl();
3265 QualType resultType = mDecl->getReturnType();
3267 MsgSendStretFlavor = MsgSendStretFunctionDecl;
3269 MsgSendFlavor = MsgSendFpretFunctionDecl;
3273 SmallVector<Expr*, 8> MsgExprs;
3275 case ObjCMessageExpr::SuperClass: {
3276 MsgSendFlavor = MsgSendSuperFunctionDecl;
3277 if (MsgSendStretFlavor)
3278 MsgSendStretFlavor = MsgSendSuperStretFunctionDecl;
3279 assert(MsgSendFlavor &&
"MsgSendFlavor is NULL!");
3283 SmallVector<Expr*, 4> InitExprs;
3286 InitExprs.push_back(
3297 SmallVector<Expr*, 8> ClsExprs;
3300 CallExpr *Cls = SynthesizeCallToFunctionDecl(GetMetaClassFunctionDecl,
3306 ClsExprs.push_back(Cls);
3307 Cls = SynthesizeCallToFunctionDecl(GetSuperClassFunctionDecl,
3308 &ClsExprs[0], ClsExprs.size(),
3313 InitExprs.push_back(
3314 NoTypeInfoCStyleCastExpr(
Context,
3318 QualType superType = getSuperStructType();
3321 if (LangOpts.MicrosoftExt) {
3322 SynthSuperConstructorFunctionDecl();
3340 SuperRep = NoTypeInfoCStyleCastExpr(
Context,
3359 MsgExprs.push_back(SuperRep);
3363 case ObjCMessageExpr::Class: {
3364 SmallVector<Expr*, 8> ClsExprs;
3368 ClsExprs.push_back(getStringLiteral(clsName->
getName()));
3369 CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl,
3376 MsgExprs.push_back(ArgExpr);
3380 case ObjCMessageExpr::SuperInstance:{
3381 MsgSendFlavor = MsgSendSuperFunctionDecl;
3382 if (MsgSendStretFlavor)
3383 MsgSendStretFlavor = MsgSendSuperStretFunctionDecl;
3384 assert(MsgSendFlavor &&
"MsgSendFlavor is NULL!");
3386 SmallVector<Expr*, 4> InitExprs;
3388 InitExprs.push_back(
3398 SmallVector<Expr*, 8> ClsExprs;
3401 CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl,
3406 ClsExprs.push_back(Cls);
3407 Cls = SynthesizeCallToFunctionDecl(GetSuperClassFunctionDecl,
3408 &ClsExprs[0], ClsExprs.size(),
3413 InitExprs.push_back(
3418 QualType superType = getSuperStructType();
3421 if (LangOpts.MicrosoftExt) {
3422 SynthSuperConstructorFunctionDecl();
3425 false, superType, VK_LValue,
3439 SuperRep = NoTypeInfoCStyleCastExpr(
Context,
3453 MsgExprs.push_back(SuperRep);
3457 case ObjCMessageExpr::Instance: {
3462 recExpr = CE->getSubExpr();
3470 MsgExprs.push_back(recExpr);
3476 SmallVector<Expr*, 8> SelExprs;
3478 CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl,
3479 &SelExprs[0], SelExprs.size(),
3482 MsgExprs.push_back(SelExp);
3485 for (
unsigned i = 0; i < Exp->
getNumArgs(); i++) {
3491 if (needToScanForQualifiers(type))
3494 (void)convertBlockPointerToFunctionPointer(type);
3512 userExpr = NoTypeInfoCStyleCastExpr(
Context, type, CK, userExpr);
3515 else if (
CStyleCastExpr *CE = dyn_cast<CStyleCastExpr>(userExpr)) {
3516 if (CE->getType()->isObjCQualifiedIdType()) {
3517 while ((CE = dyn_cast<CStyleCastExpr>(userExpr)))
3518 userExpr = CE->getSubExpr();
3533 MsgExprs.push_back(userExpr);
3541 SmallVector<QualType, 8> ArgTypes;
3545 if (MsgSendFlavor == MsgSendSuperFunctionDecl)
3552 for (
const auto *PI : OMD->
params()) {
3557 (void)convertBlockPointerToFunctionPointer(t);
3558 ArgTypes.push_back(t);
3561 convertToUnqualifiedObjCType(returnType);
3562 (void)convertBlockPointerToFunctionPointer(returnType);
3577 cast = NoTypeInfoCStyleCastExpr(
Context,
3585 getSimpleFunctionType(returnType, ArgTypes, MD ? MD->isVariadic() :
true);
3596 Stmt *ReplacingStmt = CE;
3597 if (MsgSendStretFlavor) {
3603 Expr *STCE = SynthMsgSendStretCallExpr(MsgSendStretFlavor,
3607 ReplacingStmt = STCE;
3610 return ReplacingStmt;
3618 ReplaceStmt(Exp, ReplacingStmt);
3621 return ReplacingStmt;
3625 QualType RewriteModernObjC::getProtocolType() {
3626 if (!ProtocolTypeDecl) {
3642 std::string Name =
"_OBJC_PROTOCOL_REFERENCE_$_" +
3651 NoTypeInfoCStyleCastExpr(
3653 ReplaceStmt(Exp, castExpr);
3660 bool RewriteModernObjC::BufferContainsPPDirectives(
const char *startBuf,
3661 const char *endBuf) {
3662 while (startBuf < endBuf) {
3663 if (*startBuf ==
'#') {
3665 for (++startBuf; startBuf[0] ==
' ' || startBuf[0] ==
'\t'; ++startBuf)
3667 if (!strncmp(startBuf,
"if", strlen(
"if")) ||
3668 !strncmp(startBuf,
"ifdef", strlen(
"ifdef")) ||
3669 !strncmp(startBuf,
"ifndef", strlen(
"ifndef")) ||
3670 !strncmp(startBuf,
"define", strlen(
"define")) ||
3671 !strncmp(startBuf,
"undef", strlen(
"undef")) ||
3672 !strncmp(startBuf,
"else", strlen(
"else")) ||
3673 !strncmp(startBuf,
"elif", strlen(
"elif")) ||
3674 !strncmp(startBuf,
"endif", strlen(
"endif")) ||
3675 !strncmp(startBuf,
"pragma", strlen(
"pragma")) ||
3676 !strncmp(startBuf,
"include", strlen(
"include")) ||
3677 !strncmp(startBuf,
"import", strlen(
"import")) ||
3678 !strncmp(startBuf,
"include_next", strlen(
"include_next")))
3690 bool &IsNamedDefinition) {
3694 if (
RecordDecl *RD = dyn_cast<RecordDecl>(Tag)) {
3698 IsNamedDefinition =
true;
3703 if (
EnumDecl *ED = dyn_cast<EnumDecl>(Tag)) {
3704 if (!ED || !ED->getDeclName().getAsIdentifierInfo())
3706 IsNamedDefinition =
true;
3707 TagLocation = ED->getLocation();
3717 bool RewriteModernObjC::RewriteObjCFieldDeclType(
QualType &Type,
3718 std::string &Result) {
3719 if (isa<TypedefType>(Type)) {
3726 return RewriteObjCFieldDeclType(ElemTy, Result);
3732 Result +=
"\n\tstruct ";
3734 Result +=
"\n\tunion ";
3736 assert(
false &&
"class not allowed as an ivar type");
3739 if (GlobalDefinedTags.count(RD)) {
3745 for (
auto *FD : RD->
fields())
3746 RewriteObjCFieldDecl(FD, Result);
3754 Result +=
"\n\tenum ";
3756 if (GlobalDefinedTags.count(ED)) {
3764 Result +=
"\t"; Result += EC->getName(); Result +=
" = ";
3765 llvm::APSInt Val = EC->getInitVal();
3766 Result += Val.toString(10);
3775 convertObjCTypeToCStyleType(Type);
3783 std::string &Result) {
3787 bool EleboratedType = RewriteObjCFieldDeclType(Type, Result);
3788 if (!EleboratedType)
3799 llvm::APInt Dim = CAT->getSize();
3800 Result += utostr(Dim.getZExtValue());
3812 void RewriteModernObjC::RewriteLocallyDefinedNamedAggregates(
FieldDecl *fieldDecl,
3813 std::string &Result) {
3815 if (isa<TypedefType>(Type))
3831 if (GlobalDefinedTags.count(TD))
3834 bool IsNamedDefinition =
false;
3835 if (IsTagDefinedInsideClass(IDecl, TD, IsNamedDefinition)) {
3836 RewriteObjCFieldDeclType(Type, Result);
3839 if (IsNamedDefinition)
3840 GlobalDefinedTags.insert(TD);
3845 unsigned RewriteModernObjC::ObjCIvarBitfieldGroupNo(
ObjCIvarDecl *IV) {
3847 if (ObjCInterefaceHasBitfieldGroups.count(CDecl)) {
3848 return IvarGroupNumber[IV];
3850 unsigned GroupNo = 0;
3851 SmallVector<const ObjCIvarDecl *, 8> IVars;
3854 IVars.push_back(IVD);
3856 for (
unsigned i = 0, e = IVars.size(); i < e; i++)
3857 if (IVars[i]->isBitField()) {
3858 IvarGroupNumber[IVars[i++]] = ++GroupNo;
3859 while (i < e && IVars[i]->isBitField())
3860 IvarGroupNumber[IVars[i++]] = GroupNo;
3865 ObjCInterefaceHasBitfieldGroups.insert(CDecl);
3866 return IvarGroupNumber[IV];
3869 QualType RewriteModernObjC::SynthesizeBitfieldGroupStructType(
3871 SmallVectorImpl<ObjCIvarDecl *> &IVars) {
3872 std::string StructTagName;
3873 ObjCIvarBitfieldGroupType(IV, StructTagName);
3878 for (
unsigned i=0, e = IVars.size(); i < e; i++) {
3892 unsigned GroupNo = ObjCIvarBitfieldGroupNo(IV);
3893 std::pair<const ObjCInterfaceDecl*, unsigned> tuple = std::make_pair(CDecl, GroupNo);
3894 if (GroupRecordType.count(tuple))
3895 return GroupRecordType[tuple];
3897 SmallVector<ObjCIvarDecl *, 8> IVars;
3900 if (IVD->isBitField())
3901 IVars.push_back(const_cast<ObjCIvarDecl *>(IVD));
3903 if (!IVars.empty()) {
3904 unsigned GroupNo = ObjCIvarBitfieldGroupNo(IVars[0]);
3906 GroupRecordType[std::make_pair(CDecl, GroupNo)] =
3907 SynthesizeBitfieldGroupStructType(IVars[0], IVars);
3912 if (!IVars.empty()) {
3914 unsigned GroupNo = ObjCIvarBitfieldGroupNo(IVars[0]);
3915 GroupRecordType[std::make_pair(CDecl, GroupNo)] =
3916 SynthesizeBitfieldGroupStructType(IVars[0], IVars);
3918 QualType RetQT = GroupRecordType[tuple];
3919 assert(!RetQT.
isNull() &&
"GetGroupRecordTypeForObjCIvarBitfield struct type is NULL");
3926 void RewriteModernObjC::ObjCIvarBitfieldGroupDecl(
ObjCIvarDecl *IV,
3927 std::string &Result) {
3930 Result +=
"__GRBF_";
3931 unsigned GroupNo = ObjCIvarBitfieldGroupNo(IV);
3932 Result += utostr(GroupNo);
3939 void RewriteModernObjC::ObjCIvarBitfieldGroupType(
ObjCIvarDecl *IV,
3940 std::string &Result) {
3944 unsigned GroupNo = ObjCIvarBitfieldGroupNo(IV);
3945 Result += utostr(GroupNo);
3952 void RewriteModernObjC::ObjCIvarBitfieldGroupOffset(
ObjCIvarDecl *IV,
3953 std::string &Result) {
3954 Result +=
"OBJC_IVAR_$_";
3955 ObjCIvarBitfieldGroupDecl(IV, Result);
3958 #define SKIP_BITFIELDS(IX, ENDIX, VEC) { \
3959 while ((IX < ENDIX) && VEC[IX]->isBitField()) \
3968 std::string &Result) {
3969 assert(CDecl &&
"Class missing in SynthesizeObjCInternalStruct");
3970 assert(CDecl->
getName() !=
"" &&
3971 "Name missing in SynthesizeObjCInternalStruct");
3973 SmallVector<ObjCIvarDecl *, 8> IVars;
3976 IVars.push_back(IVD);
3987 (!RCDecl || !ObjCSynthesizedStructs.count(RCDecl))) {
3988 endBuf += Lexer::MeasureTokenLength(LocEnd, *
SM, LangOpts);
3989 ReplaceText(LocStart, endBuf-startBuf, Result);
3996 for (
unsigned i = 0, e = IVars.size(); i < e; i++)
3997 RewriteLocallyDefinedNamedAggregates(IVars[i], Result);
4001 for (
unsigned i = 0, e = IVars.size(); i < e; i++)
4002 if (IVars[i]->isBitField()) {
4004 QualType QT = GetGroupRecordTypeForObjCIvarBitfield(IV);
4005 RewriteObjCFieldDeclType(QT, Result);
4008 SKIP_BITFIELDS(i , e, IVars);
4011 Result +=
"\nstruct ";
4013 Result +=
"_IMPL {\n";
4015 if (RCDecl && ObjCSynthesizedStructs.count(RCDecl)) {
4016 Result +=
"\tstruct "; Result += RCDecl->getNameAsString();
4017 Result +=
"_IMPL "; Result += RCDecl->getNameAsString();
4018 Result +=
"_IVARS;\n";
4021 for (
unsigned i = 0, e = IVars.size(); i < e; i++) {
4022 if (IVars[i]->isBitField()) {
4024 Result +=
"\tstruct ";
4025 ObjCIvarBitfieldGroupType(IV, Result); Result +=
" ";
4026 ObjCIvarBitfieldGroupDecl(IV, Result); Result +=
";\n";
4028 SKIP_BITFIELDS(i , e, IVars);
4031 RewriteObjCFieldDecl(IVars[i], Result);
4035 endBuf += Lexer::MeasureTokenLength(LocEnd, *
SM, LangOpts);
4036 ReplaceText(LocStart, endBuf-startBuf, Result);
4038 if (!ObjCSynthesizedStructs.insert(CDecl).second)
4039 llvm_unreachable(
"struct already synthesize- RewriteObjCInternalStruct");
4045 std::string &Result) {
4048 llvm::SmallPtrSet<ObjCIvarDecl *, 8> Ivars = ReferencedIvars[CDecl];
4055 unsigned GroupNo = 0;
4057 GroupNo = ObjCIvarBitfieldGroupNo(IvarDecl);
4058 if (GroupSymbolOutput.count(std::make_pair(IDecl, GroupNo)))
4062 if (LangOpts.MicrosoftExt)
4063 Result +=
"__declspec(allocate(\".objc_ivar$B\")) ";
4064 Result +=
"extern \"C\" ";
4065 if (LangOpts.MicrosoftExt &&
4068 Result +=
"__declspec(dllimport) ";
4070 Result +=
"unsigned long ";
4072 ObjCIvarBitfieldGroupOffset(IvarDecl, Result);
4073 GroupSymbolOutput.insert(std::make_pair(IDecl, GroupNo));
4076 WriteInternalIvarName(CDecl, IvarDecl, Result);
4089 void RewriteModernObjC::RewriteImplementations() {
4090 int ClsDefCount = ClassImplementation.size();
4091 int CatDefCount = CategoryImplementation.size();
4094 for (
int i = 0; i < ClsDefCount; i++) {
4099 "Legacy implicit interface rewriting not supported in moder abi");
4100 RewriteImplementationDecl(OIMP);
4103 for (
int i = 0; i < CatDefCount; i++) {
4108 "Legacy implicit interface rewriting not supported in moder abi");
4109 RewriteImplementationDecl(CIMP);
4113 void RewriteModernObjC::RewriteByRefString(std::string &ResultStr,
4114 const std::string &Name,
4116 assert(BlockByRefDeclNo.count(VD) &&
4117 "RewriteByRefString: ByRef decl missing");
4119 ResultStr +=
"struct ";
4120 ResultStr +=
"__Block_byref_" + Name +
4121 "_" + utostr(BlockByRefDeclNo[VD]) ;
4124 static bool HasLocalVariableExternalStorage(
ValueDecl *VD) {
4125 if (
VarDecl *Var = dyn_cast<VarDecl>(VD))
4126 return (Var->isFunctionOrMethodVarDecl() && !Var->hasLocalStorage());
4130 std::string RewriteModernObjC::SynthesizeBlockFunc(
BlockExpr *CE,
int i,
4135 std::string StructRef =
"struct " + Tag;
4138 ConvertSourceLocationToLineDirective(BlockLoc, S);
4141 funcName.str() +
"_block_func_" + utostr(i);
4145 if (isa<FunctionNoProtoType>(AFT)) {
4148 S +=
"(" + StructRef +
" *__cself)";
4150 S +=
"(" + StructRef +
" *__cself)";
4153 assert(FT &&
"SynthesizeBlockFunc: No function proto");
4156 S += StructRef +
" *__cself, ";
4157 std::string ParamStr;
4161 ParamStr = (*AI)->getNameAsString();
4163 (void)convertBlockPointerToFunctionPointer(QT);
4177 for (SmallVectorImpl<ValueDecl *>::iterator I = BlockByRefDecls.begin(),
4178 E = BlockByRefDecls.end(); I != E; ++I) {
4180 std::string Name = (*I)->getNameAsString();
4181 std::string TypeString;
4182 RewriteByRefString(TypeString, Name, (*I));
4184 Name = TypeString + Name;
4185 S += Name +
" = __cself->" + (*I)->getNameAsString() +
"; // bound by ref\n";
4188 for (SmallVectorImpl<ValueDecl *>::iterator I = BlockByCopyDecls.begin(),
4189 E = BlockByCopyDecls.end(); I != E; ++I) {
4201 if (isTopLevelBlockPointerType((*I)->getType())) {
4202 RewriteBlockPointerTypeVariable(S, (*I));
4204 RewriteBlockPointerType(S, (*I)->getType());
4206 S +=
"__cself->" + (*I)->getNameAsString() +
"; // bound by copy\n";
4209 std::string Name = (*I)->getNameAsString();
4211 if (HasLocalVariableExternalStorage(*I))
4214 S += Name +
" = __cself->" +
4215 (*I)->getNameAsString() +
"; // bound by copy\n";
4218 std::string RewrittenStr = RewrittenBlockExprs[CE];
4219 const char *cstr = RewrittenStr.c_str();
4220 while (*cstr++ !=
'{') ;
4226 std::string RewriteModernObjC::SynthesizeBlockHelperFuncs(
BlockExpr *CE,
int i,
4229 std::string StructRef =
"struct " + Tag;
4230 std::string S =
"static void __";
4233 S +=
"_block_copy_" + utostr(i);
4234 S +=
"(" + StructRef;
4235 S +=
"*dst, " + StructRef;
4237 for (
ValueDecl *VD : ImportedBlockDecls) {
4238 S +=
"_Block_object_assign((void*)&dst->";
4240 S +=
", (void*)src->";
4242 if (BlockByRefDeclsPtrSet.count(VD))
4251 S +=
"\nstatic void __";
4253 S +=
"_block_dispose_" + utostr(i);
4254 S +=
"(" + StructRef;
4256 for (
ValueDecl *VD : ImportedBlockDecls) {
4257 S +=
"_Block_object_dispose((void*)src->";
4259 if (BlockByRefDeclsPtrSet.count(VD))
4270 std::string RewriteModernObjC::SynthesizeBlockImpl(
BlockExpr *CE, std::string Tag,
4272 std::string S =
"\nstruct " + Tag;
4273 std::string Constructor =
" " + Tag;
4275 S +=
" {\n struct __block_impl impl;\n";
4276 S +=
" struct " + Desc;
4279 Constructor +=
"(void *fp, ";
4280 Constructor +=
"struct " + Desc;
4281 Constructor +=
" *desc";
4283 if (BlockDeclRefs.size()) {
4285 for (SmallVectorImpl<ValueDecl *>::iterator I = BlockByCopyDecls.begin(),
4286 E = BlockByCopyDecls.end(); I != E; ++I) {
4288 std::string FieldName = (*I)->getNameAsString();
4289 std::string ArgName =
"_" + FieldName;
4300 if (isTopLevelBlockPointerType((*I)->getType())) {
4301 S +=
"struct __block_impl *";
4302 Constructor +=
", void *" + ArgName;
4305 if (HasLocalVariableExternalStorage(*I))
4309 Constructor +=
", " + ArgName;
4311 S += FieldName +
";\n";
4314 for (SmallVectorImpl<ValueDecl *>::iterator I = BlockByRefDecls.begin(),
4315 E = BlockByRefDecls.end(); I != E; ++I) {
4317 std::string FieldName = (*I)->getNameAsString();
4318 std::string ArgName =
"_" + FieldName;
4320 std::string TypeString;
4321 RewriteByRefString(TypeString, FieldName, (*I));
4323 FieldName = TypeString + FieldName;
4324 ArgName = TypeString + ArgName;
4325 Constructor +=
", " + ArgName;
4327 S += FieldName +
"; // by ref\n";
4330 Constructor +=
", int flags=0)";
4332 bool firsTime =
true;
4333 for (SmallVectorImpl<ValueDecl *>::iterator I = BlockByCopyDecls.begin(),
4334 E = BlockByCopyDecls.end(); I != E; ++I) {
4335 std::string Name = (*I)->getNameAsString();
4337 Constructor +=
" : ";
4341 Constructor +=
", ";
4342 if (isTopLevelBlockPointerType((*I)->getType()))
4343 Constructor += Name +
"((struct __block_impl *)_" + Name +
")";
4345 Constructor += Name +
"(_" + Name +
")";
4348 for (SmallVectorImpl<ValueDecl *>::iterator I = BlockByRefDecls.begin(),
4349 E = BlockByRefDecls.end(); I != E; ++I) {
4350 std::string Name = (*I)->getNameAsString();
4352 Constructor +=
" : ";
4356 Constructor +=
", ";
4357 Constructor += Name +
"(_" + Name +
"->__forwarding)";
4360 Constructor +=
" {\n";
4362 Constructor +=
" impl.isa = &_NSConcreteGlobalBlock;\n";
4364 Constructor +=
" impl.isa = &_NSConcreteStackBlock;\n";
4365 Constructor +=
" impl.Flags = flags;\n impl.FuncPtr = fp;\n";
4367 Constructor +=
" Desc = desc;\n";
4370 Constructor +=
", int flags=0) {\n";
4372 Constructor +=
" impl.isa = &_NSConcreteGlobalBlock;\n";
4374 Constructor +=
" impl.isa = &_NSConcreteStackBlock;\n";
4375 Constructor +=
" impl.Flags = flags;\n impl.FuncPtr = fp;\n";
4376 Constructor +=
" Desc = desc;\n";
4379 Constructor +=
"}\n";
4385 std::string RewriteModernObjC::SynthesizeBlockDescriptor(std::string DescTag,
4386 std::string ImplTag,
int i,
4389 std::string S =
"\nstatic struct " + DescTag;
4391 S +=
" {\n size_t reserved;\n";
4392 S +=
" size_t Block_size;\n";
4394 S +=
" void (*copy)(struct ";
4395 S += ImplTag; S +=
"*, struct ";
4396 S += ImplTag; S +=
"*);\n";
4398 S +=
" void (*dispose)(struct ";
4399 S += ImplTag; S +=
"*);\n";
4403 S += DescTag +
"_DATA = { 0, sizeof(struct ";
4406 S +=
", __" + FunName.str() +
"_block_copy_" + utostr(i);
4407 S +=
", __" + FunName.str() +
"_block_dispose_" + utostr(i);
4413 void RewriteModernObjC::SynthesizeBlockLiterals(
SourceLocation FunLocStart,
4414 StringRef FunName) {
4415 bool RewriteSC = (GlobalVarDecl &&
4417 GlobalVarDecl->getStorageClass() ==
SC_Static &&
4418 GlobalVarDecl->getType().getCVRQualifiers());
4420 std::string SC(
" void __");
4421 SC += GlobalVarDecl->getNameAsString();
4423 InsertText(FunLocStart, SC);
4427 for (
unsigned i = 0, count=0; i < Blocks.size(); i++) {
4428 CollectBlockDeclRefInfo(Blocks[i]);
4431 for (
int j = 0; j < InnerDeclRefsCount[i]; j++) {
4434 BlockDeclRefs.push_back(Exp);
4435 if (!VD->
hasAttr<BlocksAttr>()) {
4436 if (!BlockByCopyDeclsPtrSet.count(VD)) {
4437 BlockByCopyDeclsPtrSet.insert(VD);
4438 BlockByCopyDecls.push_back(VD);
4443 if (!BlockByRefDeclsPtrSet.count(VD)) {
4444 BlockByRefDeclsPtrSet.insert(VD);
4445 BlockByRefDecls.push_back(VD);
4452 ImportedBlockDecls.insert(VD);
4455 std::string ImplTag =
"__" + FunName.str() +
"_block_impl_" + utostr(i);
4456 std::string DescTag =
"__" + FunName.str() +
"_block_desc_" + utostr(i);
4458 std::string CI = SynthesizeBlockImpl(Blocks[i], ImplTag, DescTag);
4460 InsertText(FunLocStart, CI);
4462 std::string CF = SynthesizeBlockFunc(Blocks[i], i, FunName, ImplTag);
4464 InsertText(FunLocStart, CF);
4466 if (ImportedBlockDecls.size()) {
4467 std::string HF = SynthesizeBlockHelperFuncs(Blocks[i], i, FunName, ImplTag);
4468 InsertText(FunLocStart, HF);
4470 std::string BD = SynthesizeBlockDescriptor(DescTag, ImplTag, i, FunName,
4471 ImportedBlockDecls.size() > 0);
4472 InsertText(FunLocStart, BD);
4474 BlockDeclRefs.clear();
4475 BlockByRefDecls.clear();
4476 BlockByRefDeclsPtrSet.clear();
4477 BlockByCopyDecls.clear();
4478 BlockByCopyDeclsPtrSet.clear();
4479 ImportedBlockDecls.clear();
4485 if (GlobalVarDecl->getStorageClass() ==
SC_Static)
4487 if (GlobalVarDecl->getType().isConstQualified())
4489 if (GlobalVarDecl->getType().isVolatileQualified())
4491 if (GlobalVarDecl->getType().isRestrictQualified())
4493 InsertText(FunLocStart, SC);
4495 if (GlobalConstructionExp) {
4499 std::string Tag =
"__";
4501 Tag +=
"_block_impl_";
4502 Tag += utostr(Blocks.size()-1);
4503 std::string globalBuf =
"static ";
4504 globalBuf += Tag; globalBuf +=
" ";
4507 llvm::raw_string_ostream constructorExprBuf(SStr);
4508 GlobalConstructionExp->printPretty(constructorExprBuf,
nullptr,
4510 globalBuf += constructorExprBuf.str();
4512 InsertText(FunLocStart, globalBuf);
4513 GlobalConstructionExp =
nullptr;
4517 InnerDeclRefsCount.clear();
4518 InnerDeclRefs.clear();
4519 RewrittenBlockExprs.clear();
4522 void RewriteModernObjC::InsertBlockLiteralsWithinFunction(
FunctionDecl *FD) {
4524 (!Blocks.empty()) ? getFunctionSourceLocation(*
this, FD)
4526 StringRef FuncName = FD->
getName();
4528 SynthesizeBlockLiterals(FunLocStart, FuncName);
4531 static void BuildUniqueMethodName(std::string &Name,
4537 std::string::size_type loc = 0;
4538 while ((loc = Name.find(
":", loc)) != std::string::npos)
4539 Name.replace(loc, 1,
"_");
4542 void RewriteModernObjC::InsertBlockLiteralsWithinMethod(
ObjCMethodDecl *MD) {
4546 std::string FuncName;
4547 BuildUniqueMethodName(FuncName, MD);
4548 SynthesizeBlockLiterals(FunLocStart, FuncName);
4551 void RewriteModernObjC::GetBlockDeclRefExprs(
Stmt *S) {
4552 for (
Stmt *SubStmt : S->children())
4554 if (
BlockExpr *CBE = dyn_cast<BlockExpr>(SubStmt))
4555 GetBlockDeclRefExprs(CBE->getBody());
4557 GetBlockDeclRefExprs(SubStmt);
4562 HasLocalVariableExternalStorage(DRE->
getDecl()))
4564 BlockDeclRefs.push_back(DRE);
4569 void RewriteModernObjC::GetInnerBlockDeclRefExprs(
Stmt *S,
4570 SmallVectorImpl<DeclRefExpr *> &InnerBlockDeclRefs,
4571 llvm::SmallPtrSetImpl<const DeclContext *> &InnerContexts) {
4572 for (
Stmt *SubStmt : S->children())
4574 if (
BlockExpr *CBE = dyn_cast<BlockExpr>(SubStmt)) {
4575 InnerContexts.insert(cast<DeclContext>(CBE->getBlockDecl()));
4576 GetInnerBlockDeclRefExprs(CBE->getBody(),
4581 GetInnerBlockDeclRefExprs(SubStmt, InnerBlockDeclRefs, InnerContexts);
4584 if (
DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(S)) {
4586 HasLocalVariableExternalStorage(DRE->
getDecl())) {
4588 InnerBlockDeclRefs.push_back(DRE);
4590 if (Var->isFunctionOrMethodVarDecl())
4591 ImportedLocalExternalDecls.insert(Var);
4601 bool RewriteModernObjC::convertObjCTypeToCStyleType(
QualType &T) {
4603 convertBlockPointerToFunctionPointer(T);
4609 T = convertFunctionTypeOfBlocks(FT);
4615 convertToUnqualifiedObjCType(T);
4627 SmallVector<QualType, 8> ArgTypes;
4629 bool modified = convertObjCTypeToCStyleType(Res);
4635 if (convertObjCTypeToCStyleType(t))
4637 ArgTypes.push_back(t);
4642 FuncType = getSimpleFunctionType(Res, ArgTypes);
4647 Stmt *RewriteModernObjC::SynthesizeBlockCall(
CallExpr *Exp,
const Expr *BlockExp) {
4651 if (
const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(BlockExp)) {
4653 }
else if (
const MemberExpr *MExpr = dyn_cast<MemberExpr>(BlockExp)) {
4656 else if (
const ParenExpr *PRE = dyn_cast<ParenExpr>(BlockExp)) {
4657 return SynthesizeBlockCall(Exp, PRE->getSubExpr());
4659 else if (
const ImplicitCastExpr *IEXPR = dyn_cast<ImplicitCastExpr>(BlockExp))
4662 dyn_cast<ConditionalOperator>(BlockExp)) {
4663 Expr *LHSExp = CEXPR->getLHS();
4664 Stmt *LHSStmt = SynthesizeBlockCall(Exp, LHSExp);
4665 Expr *RHSExp = CEXPR->getRHS();
4666 Stmt *RHSStmt = SynthesizeBlockCall(Exp, RHSExp);
4667 Expr *CONDExp = CEXPR->getCond();
4674 }
else if (
const ObjCIvarRefExpr *IRE = dyn_cast<ObjCIvarRefExpr>(BlockExp)) {
4677 = dyn_cast<PseudoObjectExpr>(BlockExp)) {
4680 assert(1 &&
"RewriteBlockClass: Bad type");
4682 assert(CPT &&
"RewriteBlockClass: Bad type");
4684 assert(FT &&
"RewriteBlockClass: Bad type");
4694 SmallVector<QualType, 8> ArgTypes;
4697 ArgTypes.push_back(PtrBlock);
4702 if (!convertBlockPointerToFunctionPointer(t))
4703 convertToUnqualifiedObjCType(t);
4704 ArgTypes.push_back(t);
4708 QualType PtrToFuncCastType = getSimpleFunctionType(Exp->
getType(), ArgTypes);
4714 const_cast<Expr*>(BlockExp));
4730 CastExpr *FunkCast = NoTypeInfoCStyleCastExpr(
Context, PtrToFuncCastType,
4734 SmallVector<Expr*, 8> BlkExprs;
4736 BlkExprs.push_back(BlkCast);
4739 E = Exp->
arg_end(); I != E; ++I) {
4740 BlkExprs.push_back(*I);
4761 Stmt *RewriteModernObjC::RewriteBlockDeclRefExpr(
DeclRefExpr *DeclRefExp) {
4766 HasLocalVariableExternalStorage(DeclRefExp->
getDecl());
4778 StringRef Name = VD->
getName();
4792 ReplaceStmt(DeclRefExp, PE);
4799 Stmt *RewriteModernObjC::RewriteLocalVariableExternalStorage(
DeclRefExpr *DRE) {
4801 if (
VarDecl *Var = dyn_cast<VarDecl>(VD))
4802 if (!ImportedLocalExternalDecls.count(Var))
4810 ReplaceStmt(DRE, PE);
4822 if (!Rewriter::isRewritable(LocStart) || !Rewriter::isRewritable(LocEnd))
4828 const Type* TypePtr = QT->
getAs<Type>();
4829 if (isa<TypeOfExprType>(TypePtr)) {
4830 const TypeOfExprType *TypeOfExprTypePtr = cast<TypeOfExprType>(TypePtr);
4832 std::string TypeAsString =
"(";
4833 RewriteBlockPointerType(TypeAsString, QT);
4834 TypeAsString +=
")";
4835 ReplaceText(LocStart, endBuf-startBuf+1, TypeAsString);
4839 const char *argPtr = startBuf;
4841 while (*argPtr++ && (argPtr < endBuf)) {
4846 ReplaceText(LocStart, 1,
"*");
4853 void RewriteModernObjC::RewriteImplicitCastObjCExpr(
CastExpr *IC) {
4860 (void)convertBlockPointerToFunctionPointer(QT);
4862 std::string Str =
"(";
4865 InsertText(IC->
getSubExpr()->getLocStart(), &Str[0], Str.size());
4870 void RewriteModernObjC::RewriteBlockPointerFunctionArgs(
FunctionDecl *FD) {
4872 unsigned parenCount = 0;
4876 const char *startArgList = strchr(startBuf,
'(');
4878 assert((*startArgList ==
'(') &&
"Rewriter fuzzy parser confused");
4883 assert((DeclLoc.
isValid()) &&
"Invalid DeclLoc");
4885 const char *argPtr = startArgList;
4887 while (*argPtr++ && parenCount) {
4892 ReplaceText(DeclLoc, 1,
"*");
4905 bool RewriteModernObjC::PointerTypeTakesAnyBlockArguments(
QualType QT) {
4912 assert(BPT &&
"BlockPointerTypeTakeAnyBlockArguments(): not a block pointer type");
4917 if (isTopLevelBlockPointerType(I))
4923 bool RewriteModernObjC::PointerTypeTakesAnyObjCQualifiedType(
QualType QT) {
4930 assert(BPT &&
"BlockPointerTypeTakeAnyBlockArguments(): not a block pointer type");
4935 if (I->isObjCQualifiedIdType())
4937 if (I->isObjCObjectPointerType() &&
4938 I->getPointeeType()->isObjCQualifiedInterfaceType())
4946 void RewriteModernObjC::GetExtentOfArgList(
const char *Name,
const char *&LParen,
4947 const char *&RParen) {
4948 const char *argPtr = strchr(Name,
'(');
4949 assert((*argPtr ==
'(') &&
"Rewriter fuzzy parser confused");
4953 unsigned parenCount = 1;
4955 while (*argPtr && parenCount) {
4957 case '(': parenCount++;
break;
4958 case ')': parenCount--;
break;
4961 if (parenCount) argPtr++;
4963 assert((*argPtr ==
')') &&
"Rewriter fuzzy parser confused");
4967 void RewriteModernObjC::RewriteBlockPointerDecl(
NamedDecl *ND) {
4969 RewriteBlockPointerFunctionArgs(FD);
4975 if (
VarDecl *VD = dyn_cast<VarDecl>(ND))
4978 DeclT = TDD->getUnderlyingType();
4979 else if (
FieldDecl *FD = dyn_cast<FieldDecl>(ND))
4982 llvm_unreachable(
"RewriteBlockPointerDecl(): Decl type not yet handled");
4985 const char *endBuf = startBuf;
4987 while (*startBuf !=
'^' && *startBuf !=
';' && startBuf != MainFileStart)
4991 unsigned OrigLength=0;
4994 if (*startBuf ==
'^') {
5000 while (*startBuf !=
')') {
5008 if (PointerTypeTakesAnyBlockArguments(DeclT) ||
5009 PointerTypeTakesAnyObjCQualifiedType(DeclT)) {
5014 const char *argListBegin, *argListEnd;
5015 GetExtentOfArgList(startBuf, argListBegin, argListEnd);
5016 while (argListBegin < argListEnd) {
5017 if (*argListBegin ==
'^')
5019 else if (*argListBegin ==
'<') {
5021 buf += *argListBegin++;
5023 while (*argListBegin !=
'>') {
5024 buf += *argListBegin++;
5027 buf += *argListBegin;
5031 buf += *argListBegin;
5038 ReplaceText(Start, OrigLength, buf);
5064 std::string RewriteModernObjC::SynthesizeByrefCopyDestroyHelper(
VarDecl *VD,
5067 if (CopyDestroyCache.count(flag))
5069 CopyDestroyCache.insert(flag);
5070 S =
"static void __Block_byref_id_object_copy_";
5072 S +=
"(void *dst, void *src) {\n";
5078 unsigned VoidPtrSize =
5082 S +=
" _Block_object_assign((char*)dst + ";
5083 S += utostr(offset);
5084 S +=
", *(void * *) ((char*)src + ";
5085 S += utostr(offset);
5090 S +=
"static void __Block_byref_id_object_dispose_";
5092 S +=
"(void *src) {\n";
5093 S +=
" _Block_object_dispose(*(void * *) ((char*)src + ";
5094 S += utostr(offset);
5119 void RewriteModernObjC::RewriteByRefVar(
VarDecl *ND,
bool firstDecl,
5133 std::string ByrefType;
5134 RewriteByRefString(ByrefType, Name, ND,
true);
5135 ByrefType +=
" {\n";
5136 ByrefType +=
" void *__isa;\n";
5137 RewriteByRefString(ByrefType, Name, ND);
5138 ByrefType +=
" *__forwarding;\n";
5139 ByrefType +=
" int __flags;\n";
5140 ByrefType +=
" int __size;\n";
5145 if (HasCopyAndDispose) {
5146 ByrefType +=
" void (*__Block_byref_id_object_copy)(void*, void*);\n";
5147 ByrefType +=
" void (*__Block_byref_id_object_dispose)(void*);\n";
5151 (void)convertBlockPointerToFunctionPointer(T);
5154 ByrefType +=
" " + Name +
";\n";
5155 ByrefType +=
"};\n";
5159 FunLocStart = getFunctionSourceLocation(*
this, CurFunctionDef);
5161 assert(CurMethodDef &&
"RewriteByRefVar - CurMethodDef is null");
5162 FunLocStart = CurMethodDef->getLocStart();
5164 InsertText(FunLocStart, ByrefType);
5170 if (HasCopyAndDispose) {
5178 std::string HF = SynthesizeByrefCopyDestroyHelper(ND, flag);
5186 bool hasInit = (ND->
getInit() !=
nullptr);
5197 if (HasCopyAndDispose)
5201 RewriteByRefString(ByrefType, Name, ND);
5202 std::string ForwardingCastType(
"(");
5203 ForwardingCastType += ByrefType +
" *)";
5204 ByrefType +=
" " + Name +
" = {(void*)";
5205 ByrefType += utostr(isa);
5206 ByrefType +=
"," + ForwardingCastType +
"&" + Name +
", ";
5207 ByrefType += utostr(flags);
5209 ByrefType +=
"sizeof(";
5210 RewriteByRefString(ByrefType, Name, ND);
5212 if (HasCopyAndDispose) {
5213 ByrefType +=
", __Block_byref_id_object_copy_";
5214 ByrefType += utostr(flag);
5215 ByrefType +=
", __Block_byref_id_object_dispose_";
5216 ByrefType += utostr(flag);
5225 const char *commaBuf = startDeclBuf;
5226 while (*commaBuf !=
',')
5228 assert((*commaBuf ==
',') &&
"RewriteByRefVar: can't find ','");
5230 startBuf = commaBuf;
5234 ByrefType +=
"};\n";
5235 unsigned nameSize = Name.size();
5240 ReplaceText(DeclLoc, endBuf-startBuf+nameSize, ByrefType);
5247 startLoc = ECE->getLParenLoc();
5249 startLoc = E->getLocStart();
5252 ReplaceText(DeclLoc, endBuf-startBuf, ByrefType);
5254 const char separator = lastDecl ?
';' :
',';
5256 const char *separatorBuf = strchr(startInitializerBuf, separator);
5257 assert((*separatorBuf == separator) &&
5258 "RewriteByRefVar: can't find ';' or ','");
5262 InsertText(separatorLoc, lastDecl ?
"}" :
"};\n");
5267 void RewriteModernObjC::CollectBlockDeclRefInfo(
BlockExpr *Exp) {
5269 GetBlockDeclRefExprs(Exp->
getBody());
5270 if (BlockDeclRefs.size()) {
5272 for (
unsigned i = 0; i < BlockDeclRefs.size(); i++)
5273 if (!BlockDeclRefs[i]->getDecl()->hasAttr<BlocksAttr>()) {
5274 if (!BlockByCopyDeclsPtrSet.count(BlockDeclRefs[i]->getDecl())) {
5275 BlockByCopyDeclsPtrSet.insert(BlockDeclRefs[i]->getDecl());
5276 BlockByCopyDecls.push_back(BlockDeclRefs[i]->getDecl());
5280 for (
unsigned i = 0; i < BlockDeclRefs.size(); i++)
5281 if (BlockDeclRefs[i]->getDecl()->hasAttr<BlocksAttr>()) {
5282 if (!BlockByRefDeclsPtrSet.count(BlockDeclRefs[i]->getDecl())) {
5283 BlockByRefDeclsPtrSet.insert(BlockDeclRefs[i]->getDecl());
5284 BlockByRefDecls.push_back(BlockDeclRefs[i]->getDecl());
5288 for (
unsigned i = 0; i < BlockDeclRefs.size(); i++)
5289 if (BlockDeclRefs[i]->getDecl()->hasAttr<BlocksAttr>() ||
5290 BlockDeclRefs[i]->getType()->isObjCObjectPointerType() ||
5291 BlockDeclRefs[i]->getType()->isBlockPointerType())
5292 ImportedBlockDecls.insert(BlockDeclRefs[i]->getDecl());
5296 FunctionDecl *RewriteModernObjC::SynthBlockInitFunctionDecl(StringRef name) {
5305 const SmallVectorImpl<DeclRefExpr *> &InnerBlockDeclRefs) {
5309 Blocks.push_back(Exp);
5311 CollectBlockDeclRefInfo(Exp);
5314 int countOfInnerDecls = 0;
5315 if (!InnerBlockDeclRefs.empty()) {
5316 for (
unsigned i = 0; i < InnerBlockDeclRefs.size(); i++) {
5319 if (!VD->
hasAttr<BlocksAttr>() && !BlockByCopyDeclsPtrSet.count(VD)) {
5323 InnerDeclRefs.push_back(Exp); countOfInnerDecls++;
5324 BlockDeclRefs.push_back(Exp);
5325 BlockByCopyDeclsPtrSet.insert(VD);
5326 BlockByCopyDecls.push_back(VD);
5328 if (VD->
hasAttr<BlocksAttr>() && !BlockByRefDeclsPtrSet.count(VD)) {
5329 InnerDeclRefs.push_back(Exp); countOfInnerDecls++;
5330 BlockDeclRefs.push_back(Exp);
5331 BlockByRefDeclsPtrSet.insert(VD);
5332 BlockByRefDecls.push_back(VD);
5336 for (
unsigned i = 0; i < InnerBlockDeclRefs.size(); i++)
5337 if (InnerBlockDeclRefs[i]->getDecl()->hasAttr<BlocksAttr>() ||
5338 InnerBlockDeclRefs[i]->getType()->isObjCObjectPointerType() ||
5339 InnerBlockDeclRefs[i]->getType()->isBlockPointerType())
5340 ImportedBlockDecls.insert(InnerBlockDeclRefs[i]->getDecl());
5342 InnerDeclRefsCount.push_back(countOfInnerDecls);
5344 std::string FuncName;
5348 else if (CurMethodDef)
5349 BuildUniqueMethodName(FuncName, CurMethodDef);
5350 else if (GlobalVarDecl)
5351 FuncName = std::string(GlobalVarDecl->getNameAsString());
5353 bool GlobalBlockExpr =
5356 if (GlobalBlockExpr && !GlobalVarDecl) {
5357 Diags.Report(block->
getLocation(), GlobalBlockRewriteFailedDiag);
5358 GlobalBlockExpr =
false;
5361 std::string BlockNumber = utostr(Blocks.size()-1);
5363 std::string Func =
"__" + FuncName +
"_block_func_" + BlockNumber;
5366 QualType BFT = convertFunctionTypeOfBlocks(Exp->getFunctionType());
5375 if (GlobalBlockExpr)
5379 Tag += FuncName +
"_block_impl_" + BlockNumber;
5381 FD = SynthBlockInitFunctionDecl(Tag);
5385 SmallVector<Expr*, 4> InitExprs;
5388 FD = SynthBlockInitFunctionDecl(Func);
5393 InitExprs.push_back(castExpr);
5396 std::string DescData =
"__" + FuncName +
"_block_desc_" + BlockNumber +
"_DATA";
5412 InitExprs.push_back(DescRefExpr);
5415 if (BlockDeclRefs.size()) {
5418 for (SmallVectorImpl<ValueDecl *>::iterator I = BlockByCopyDecls.begin(),
5419 E = BlockByCopyDecls.end(); I != E; ++I) {
5420 if (isObjCType((*I)->getType())) {
5422 FD = SynthBlockInitFunctionDecl((*I)->getName());
5425 if (HasLocalVariableExternalStorage(*I)) {
5431 }
else if (isTopLevelBlockPointerType((*I)->getType())) {
5432 FD = SynthBlockInitFunctionDecl((*I)->getName());
5438 FD = SynthBlockInitFunctionDecl((*I)->getName());
5441 if (HasLocalVariableExternalStorage(*I)) {
5449 InitExprs.push_back(Exp);
5452 for (SmallVectorImpl<ValueDecl *>::iterator I = BlockByRefDecls.begin(),
5453 E = BlockByRefDecls.end(); I != E; ++I) {
5456 std::string RecName;
5457 RewriteByRefString(RecName, Name, ND,
true);
5459 +
sizeof(
"struct"));
5463 assert(RD &&
"SynthBlockInitExpr(): Can't find RecordDecl");
5466 FD = SynthBlockInitFunctionDecl((*I)->getName());
5469 bool isNestedCapturedVar =
false;
5471 for (
const auto &CI : block->
captures()) {
5472 const VarDecl *variable = CI.getVariable();
5473 if (variable == ND && CI.isNested()) {
5474 assert (CI.isByRef() &&
5475 "SynthBlockInitExpr - captured block variable is not byref");
5476 isNestedCapturedVar =
true;
5482 if (!isNestedCapturedVar)
5487 InitExprs.push_back(Exp);
5490 if (ImportedBlockDecls.size()) {
5497 InitExprs.push_back(FlagExp);
5502 if (GlobalBlockExpr) {
5503 assert (!GlobalConstructionExp &&
5504 "SynthBlockInitExpr - GlobalConstructionExp must be null");
5505 GlobalConstructionExp = NewRep;
5518 BlockDeclRefs.clear();
5519 BlockByRefDecls.clear();
5520 BlockByRefDeclsPtrSet.clear();
5521 BlockByCopyDecls.clear();
5522 BlockByCopyDeclsPtrSet.clear();
5523 ImportedBlockDecls.clear();
5527 bool RewriteModernObjC::IsDeclStmtInForeachHeader(
DeclStmt *DS) {
5529 dyn_cast<ObjCForCollectionStmt>(Stmts.back()))
5530 return CS->getElement() == DS;
5538 Stmt *RewriteModernObjC::RewriteFunctionBodyOrGlobalInitializer(
Stmt *S) {
5539 if (isa<SwitchStmt>(S) || isa<WhileStmt>(S) ||
5540 isa<DoStmt>(S) || isa<ForStmt>(S))
5542 else if (isa<ObjCForCollectionStmt>(S)) {
5544 ObjCBcLabelNo.push_back(++BcLabelCount);
5551 return RewritePropertyOrImplicitSetter(PseudoOp);
5553 return RewritePropertyOrImplicitGetter(PseudoOp);
5555 }
else if (
ObjCIvarRefExpr *IvarRefExpr = dyn_cast<ObjCIvarRefExpr>(S)) {
5556 return RewriteObjCIvarRefExpr(IvarRefExpr);
5558 else if (isa<OpaqueValueExpr>(S))
5559 S = cast<OpaqueValueExpr>(
S)->getSourceExpr();
5564 for (
Stmt *&childStmt : S->children())
5566 Stmt *newStmt = RewriteFunctionBodyOrGlobalInitializer(childStmt);
5568 childStmt = newStmt;
5572 if (
BlockExpr *BE = dyn_cast<BlockExpr>(S)) {
5573 SmallVector<DeclRefExpr *, 8> InnerBlockDeclRefs;
5574 llvm::SmallPtrSet<const DeclContext *, 8> InnerContexts;
5575 InnerContexts.insert(BE->getBlockDecl());
5576 ImportedLocalExternalDecls.clear();
5577 GetInnerBlockDeclRefExprs(BE->getBody(),
5578 InnerBlockDeclRefs, InnerContexts);
5580 Stmt *SaveCurrentBody = CurrentBody;
5581 CurrentBody = BE->getBody();
5582 PropParentMap =
nullptr;
5588 bool saveDisableReplaceStmt = DisableReplaceStmt;
5589 DisableReplaceStmt =
false;
5590 RewriteFunctionBodyOrGlobalInitializer(BE->getBody());
5591 DisableReplaceStmt = saveDisableReplaceStmt;
5592 CurrentBody = SaveCurrentBody;
5593 PropParentMap =
nullptr;
5594 ImportedLocalExternalDecls.clear();
5596 std::string Str = Rewrite.getRewrittenText(BE->getSourceRange());
5597 RewrittenBlockExprs[BE] = Str;
5599 Stmt *blockTranscribed = SynthBlockInitExpr(BE, InnerBlockDeclRefs);
5602 ReplaceStmt(S, blockTranscribed);
5603 return blockTranscribed;
5607 return RewriteAtEncode(AtEncode);
5610 return RewriteAtSelector(AtSelector);
5613 return RewriteObjCStringLiteral(AtString);
5616 return RewriteObjCBoolLiteralExpr(BoolLitExpr);
5619 return RewriteObjCBoxedExpr(BoxedExpr);
5622 return RewriteObjCArrayLiteralExpr(ArrayLitExpr);
5625 dyn_cast<ObjCDictionaryLiteral>(S))
5626 return RewriteObjCDictionaryLiteralExpr(DictionaryLitExpr);
5637 std::string messString;
5638 messString +=
"// ";
5639 messString.append(startBuf, endBuf-startBuf+1);
5648 return RewriteMessageExpr(MessExpr);
5652 dyn_cast<ObjCAutoreleasePoolStmt>(S)) {
5653 return RewriteObjCAutoreleasePoolStmt(StmtAutoRelease);
5657 return RewriteObjCTryStmt(StmtTry);
5660 return RewriteObjCSynchronizedStmt(StmtTry);
5663 return RewriteObjCThrowStmt(StmtThrow);
5666 return RewriteObjCProtocolExpr(ProtocolExp);
5669 dyn_cast<ObjCForCollectionStmt>(S))
5670 return RewriteObjCForCollectionStmt(StmtForCollection,
5673 dyn_cast<BreakStmt>(S))
5674 return RewriteBreakStmt(StmtBreakStmt);
5676 dyn_cast<ContinueStmt>(S))
5677 return RewriteContinueStmt(StmtContinueStmt);
5681 if (
DeclStmt *DS = dyn_cast<DeclStmt>(S)) {
5691 if (Stmts.empty() || !IsDeclStmtInForeachHeader(DS))
5692 RewriteObjCQualifiedInterfaceTypes(*DS->
decl_begin());
5698 if (
ValueDecl *ND = dyn_cast<ValueDecl>(SD)) {
5699 if (isTopLevelBlockPointerType(ND->
getType()))
5700 RewriteBlockPointerDecl(ND);
5702 CheckFunctionPointerDecl(ND->
getType(), ND);
5703 if (
VarDecl *VD = dyn_cast<VarDecl>(SD)) {
5704 if (VD->
hasAttr<BlocksAttr>()) {
5705 static unsigned uniqueByrefDeclCount = 0;
5706 assert(!BlockByRefDeclNo.count(ND) &&
5707 "RewriteFunctionBodyOrGlobalInitializer: Duplicate byref decl");
5708 BlockByRefDeclNo[ND] = uniqueByrefDeclCount++;
5709 RewriteByRefVar(VD, (DI == DS->
decl_begin()), ((DI+1) == DE));
5712 RewriteTypeOfDecl(VD);
5716 if (isTopLevelBlockPointerType(TD->getUnderlyingType()))
5717 RewriteBlockPointerDecl(TD);
5718 else if (TD->getUnderlyingType()->isFunctionPointerType())
5719 CheckFunctionPointerDecl(TD->getUnderlyingType(), TD);
5725 RewriteObjCQualifiedInterfaceTypes(CE);
5727 if (isa<SwitchStmt>(S) || isa<WhileStmt>(
S) ||
5728 isa<DoStmt>(S) || isa<ForStmt>(
S)) {
5729 assert(!Stmts.empty() &&
"Statement stack is empty");
5730 assert ((isa<SwitchStmt>(Stmts.back()) || isa<WhileStmt>(Stmts.back()) ||
5731 isa<DoStmt>(Stmts.back()) || isa<ForStmt>(Stmts.back()))
5732 &&
"Statement stack mismatch");
5736 if (
DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(S)) {
5738 if (VD->
hasAttr<BlocksAttr>())
5739 return RewriteBlockDeclRefExpr(DRE);
5740 if (HasLocalVariableExternalStorage(VD))
5741 return RewriteLocalVariableExternalStorage(DRE);
5744 if (
CallExpr *CE = dyn_cast<CallExpr>(S)) {
5747 ReplaceStmt(S, BlockCall);
5752 RewriteCastExpr(CE);
5755 RewriteImplicitCastObjCExpr(ICE);
5765 llvm::raw_string_ostream Buf(SStr);
5766 Replacement->printPretty(Buf);
5767 const std::string &Str = Buf.str();
5769 printf(
"CAST = %s\n", &Str[0]);
5770 InsertText(ICE->
getSubExpr()->getLocStart(), &Str[0], Str.size());
5779 void RewriteModernObjC::RewriteRecordBody(
RecordDecl *RD) {
5780 for (
auto *FD : RD->
fields()) {
5781 if (isTopLevelBlockPointerType(FD->
getType()))
5782 RewriteBlockPointerDecl(FD);
5785 RewriteObjCQualifiedInterfaceTypes(FD);
5791 void RewriteModernObjC::HandleDeclInMainFile(
Decl *D) {
5793 case Decl::Function: {
5801 RewriteBlocksInFunctionProtoType(FD->
getType(), FD);
5808 CurFunctionDef = FD;
5811 cast_or_null<CompoundStmt>(RewriteFunctionBodyOrGlobalInitializer(Body));
5813 CurrentBody =
nullptr;
5814 if (PropParentMap) {
5815 delete PropParentMap;
5816 PropParentMap =
nullptr;
5820 InsertBlockLiteralsWithinFunction(FD);
5821 RewriteLineDirective(D);
5822 CurFunctionDef =
nullptr;
5826 case Decl::ObjCMethod: {
5832 cast_or_null<CompoundStmt>(RewriteFunctionBodyOrGlobalInitializer(Body));
5834 CurrentBody =
nullptr;
5835 if (PropParentMap) {
5836 delete PropParentMap;
5837 PropParentMap =
nullptr;
5839 InsertBlockLiteralsWithinMethod(MD);
5840 RewriteLineDirective(D);
5841 CurMethodDef =
nullptr;
5845 case Decl::ObjCImplementation: {
5847 ClassImplementation.push_back(CI);
5850 case Decl::ObjCCategoryImpl: {
5852 CategoryImplementation.push_back(CI);
5856 VarDecl *VD = cast<VarDecl>(D);
5857 RewriteObjCQualifiedInterfaceTypes(VD);
5858 if (isTopLevelBlockPointerType(VD->
getType()))
5859 RewriteBlockPointerDecl(VD);
5861 CheckFunctionPointerDecl(VD->
getType(), VD);
5864 RewriteCastExpr(CE);
5870 RewriteRecordBody(RD);
5875 RewriteFunctionBodyOrGlobalInitializer(VD->
getInit());
5876 CurrentBody =
nullptr;
5877 if (PropParentMap) {
5878 delete PropParentMap;
5879 PropParentMap =
nullptr;
5882 GlobalVarDecl =
nullptr;
5886 RewriteCastExpr(CE);
5891 case Decl::TypeAlias:
5892 case Decl::Typedef: {
5894 if (isTopLevelBlockPointerType(TD->getUnderlyingType()))
5895 RewriteBlockPointerDecl(TD);
5896 else if (TD->getUnderlyingType()->isFunctionPointerType())
5897 CheckFunctionPointerDecl(TD->getUnderlyingType(), TD);
5899 RewriteObjCQualifiedInterfaceTypes(TD);
5903 case Decl::CXXRecord:
5904 case Decl::Record: {
5907 RewriteRecordBody(RD);
5921 std::string &Result) {
5924 Result +=
"static ";
5925 Result +=
"struct _protocol_t *";
5926 Result +=
"_OBJC_PROTOCOL_REFERENCE_$_";
5933 void RewriteModernObjC::HandleTranslationUnit(
ASTContext &
C) {
5934 if (Diags.hasErrorOccurred())
5939 for (
unsigned i = 0, e = FunctionDefinitionsSeen.size(); i < e; i++) {
5944 HandleTopLevelSingleDecl(FDecl);
5950 RewriteObjCProtocolMetaData(ProtDecl, Preamble);
5951 Write_ProtocolExprReferencedMetadata(Context, ProtDecl, Preamble);
5956 if (ClassImplementation.size() || CategoryImplementation.size())
5957 RewriteImplementations();
5959 for (
unsigned i = 0, e = ObjCInterfacesSeen.size(); i < e; i++) {
5965 RewriteInterfaceDecl(CDecl);
5971 Rewrite.getRewriteBufferFor(MainFileID)) {
5973 *OutFile << std::string(RewriteBuf->begin(), RewriteBuf->end());
5975 llvm::errs() <<
"No changes\n";
5978 if (ClassImplementation.size() || CategoryImplementation.size() ||
5979 ProtocolExprDecls.size()) {
5981 std::string ResultStr;
5982 RewriteMetaDataIntoBuffer(ResultStr);
5984 *OutFile << ResultStr;
5988 std::string ResultStr;
5989 WriteImageInfo(ResultStr);
5990 *OutFile << ResultStr;
5995 void RewriteModernObjC::Initialize(
ASTContext &context) {
5996 InitializeCommon(context);
5998 Preamble +=
"#ifndef __OBJC2__\n";
5999 Preamble +=
"#define __OBJC2__\n";
6000 Preamble +=
"#endif\n";
6005 Preamble =
"#pragma once\n";
6006 Preamble +=
"struct objc_selector; struct objc_class;\n";
6007 Preamble +=
"struct __rw_objc_super { \n\tstruct objc_object *object; ";
6008 Preamble +=
"\n\tstruct objc_object *superClass; ";
6010 Preamble +=
"\n\t__rw_objc_super(struct objc_object *o, struct objc_object *s) ";
6011 Preamble +=
": object(o), superClass(s) {} ";
6012 Preamble +=
"\n};\n";
6014 if (LangOpts.MicrosoftExt) {
6017 Preamble +=
"\n#pragma section(\".objc_classlist$B\", long, read, write)\n";
6018 Preamble +=
"#pragma section(\".objc_catlist$B\", long, read, write)\n";
6019 Preamble +=
"#pragma section(\".objc_imageinfo$B\", long, read, write)\n";
6020 Preamble +=
"#pragma section(\".objc_nlclslist$B\", long, read, write)\n";
6021 Preamble +=
"#pragma section(\".objc_nlcatlist$B\", long, read, write)\n";
6023 Preamble +=
"#pragma section(\".cat_cls_meth$B\", long, read, write)\n";
6024 Preamble +=
"#pragma section(\".inst_meth$B\", long, read, write)\n";
6025 Preamble +=
"#pragma section(\".cls_meth$B\", long, read, write)\n";
6026 Preamble +=
"#pragma section(\".objc_ivar$B\", long, read, write)\n";
6030 Preamble +=
"#pragma section(\".objc_selrefs$B\", long, read, write)\n";
6031 Preamble +=
"#pragma section(\".objc_classrefs$B\", long, read, write)\n";
6032 Preamble +=
"#pragma section(\".objc_superrefs$B\", long, read, write)\n";
6035 Preamble +=
"#ifndef _REWRITER_typedef_Protocol\n";
6036 Preamble +=
"typedef struct objc_object Protocol;\n";
6037 Preamble +=
"#define _REWRITER_typedef_Protocol\n";
6038 Preamble +=
"#endif\n";
6039 if (LangOpts.MicrosoftExt) {
6040 Preamble +=
"#define __OBJC_RW_DLLIMPORT extern \"C\" __declspec(dllimport)\n";
6041 Preamble +=
"#define __OBJC_RW_STATICIMPORT extern \"C\"\n";
6044 Preamble +=
"#define __OBJC_RW_DLLIMPORT extern\n";
6046 Preamble +=
"__OBJC_RW_DLLIMPORT void objc_msgSend(void);\n";
6047 Preamble +=
"__OBJC_RW_DLLIMPORT void objc_msgSendSuper(void);\n";
6048 Preamble +=
"__OBJC_RW_DLLIMPORT void objc_msgSend_stret(void);\n";
6049 Preamble +=
"__OBJC_RW_DLLIMPORT void objc_msgSendSuper_stret(void);\n";
6050 Preamble +=
"__OBJC_RW_DLLIMPORT void objc_msgSend_fpret(void);\n";
6052 Preamble +=
"__OBJC_RW_DLLIMPORT struct objc_class *objc_getClass";
6053 Preamble +=
"(const char *);\n";
6054 Preamble +=
"__OBJC_RW_DLLIMPORT struct objc_class *class_getSuperclass";
6055 Preamble +=
"(struct objc_class *);\n";
6056 Preamble +=
"__OBJC_RW_DLLIMPORT struct objc_class *objc_getMetaClass";
6057 Preamble +=
"(const char *);\n";
6058 Preamble +=
"__OBJC_RW_DLLIMPORT void objc_exception_throw( struct objc_object *);\n";
6060 Preamble +=
"__OBJC_RW_DLLIMPORT int objc_sync_enter( struct objc_object *);\n";
6061 Preamble +=
"__OBJC_RW_DLLIMPORT int objc_sync_exit( struct objc_object *);\n";
6062 Preamble +=
"__OBJC_RW_DLLIMPORT Protocol *objc_getProtocol(const char *);\n";
6063 Preamble +=
"#ifdef _WIN64\n";
6064 Preamble +=
"typedef unsigned long long _WIN_NSUInteger;\n";
6065 Preamble +=
"#else\n";
6066 Preamble +=
"typedef unsigned int _WIN_NSUInteger;\n";
6067 Preamble +=
"#endif\n";
6068 Preamble +=
"#ifndef __FASTENUMERATIONSTATE\n";
6069 Preamble +=
"struct __objcFastEnumerationState {\n\t";
6070 Preamble +=
"unsigned long state;\n\t";
6071 Preamble +=
"void **itemsPtr;\n\t";
6072 Preamble +=
"unsigned long *mutationsPtr;\n\t";
6073 Preamble +=
"unsigned long extra[5];\n};\n";
6074 Preamble +=
"__OBJC_RW_DLLIMPORT void objc_enumerationMutation(struct objc_object *);\n";
6075 Preamble +=
"#define __FASTENUMERATIONSTATE\n";
6076 Preamble +=
"#endif\n";
6077 Preamble +=
"#ifndef __NSCONSTANTSTRINGIMPL\n";
6078 Preamble +=
"struct __NSConstantStringImpl {\n";
6079 Preamble +=
" int *isa;\n";
6080 Preamble +=
" int flags;\n";
6081 Preamble +=
" char *str;\n";
6082 Preamble +=
"#if _WIN64\n";
6083 Preamble +=
" long long length;\n";
6084 Preamble +=
"#else\n";
6085 Preamble +=
" long length;\n";
6086 Preamble +=
"#endif\n";
6088 Preamble +=
"#ifdef CF_EXPORT_CONSTANT_STRING\n";
6089 Preamble +=
"extern \"C\" __declspec(dllexport) int __CFConstantStringClassReference[];\n";
6090 Preamble +=
"#else\n";
6091 Preamble +=
"__OBJC_RW_DLLIMPORT int __CFConstantStringClassReference[];\n";
6092 Preamble +=
"#endif\n";
6093 Preamble +=
"#define __NSCONSTANTSTRINGIMPL\n";
6094 Preamble +=
"#endif\n";
6096 Preamble +=
"#ifndef BLOCK_IMPL\n";
6097 Preamble +=
"#define BLOCK_IMPL\n";
6098 Preamble +=
"struct __block_impl {\n";
6099 Preamble +=
" void *isa;\n";
6100 Preamble +=
" int Flags;\n";
6101 Preamble +=
" int Reserved;\n";
6102 Preamble +=
" void *FuncPtr;\n";
6104 Preamble +=
"// Runtime copy/destroy helper functions (from Block_private.h)\n";
6105 Preamble +=
"#ifdef __OBJC_EXPORT_BLOCKS\n";
6106 Preamble +=
"extern \"C\" __declspec(dllexport) "
6107 "void _Block_object_assign(void *, const void *, const int);\n";
6108 Preamble +=
"extern \"C\" __declspec(dllexport) void _Block_object_dispose(const void *, const int);\n";
6109 Preamble +=
"extern \"C\" __declspec(dllexport) void *_NSConcreteGlobalBlock[32];\n";
6110 Preamble +=
"extern \"C\" __declspec(dllexport) void *_NSConcreteStackBlock[32];\n";
6111 Preamble +=
"#else\n";
6112 Preamble +=
"__OBJC_RW_DLLIMPORT void _Block_object_assign(void *, const void *, const int);\n";
6113 Preamble +=
"__OBJC_RW_DLLIMPORT void _Block_object_dispose(const void *, const int);\n";
6114 Preamble +=
"__OBJC_RW_DLLIMPORT void *_NSConcreteGlobalBlock[32];\n";
6115 Preamble +=
"__OBJC_RW_DLLIMPORT void *_NSConcreteStackBlock[32];\n";
6116 Preamble +=
"#endif\n";
6117 Preamble +=
"#endif\n";
6118 if (LangOpts.MicrosoftExt) {
6119 Preamble +=
"#undef __OBJC_RW_DLLIMPORT\n";
6120 Preamble +=
"#undef __OBJC_RW_STATICIMPORT\n";
6121 Preamble +=
"#ifndef KEEP_ATTRIBUTES\n";
6122 Preamble +=
"#define __attribute__(X)\n";
6123 Preamble +=
"#endif\n";
6124 Preamble +=
"#ifndef __weak\n";
6125 Preamble +=
"#define __weak\n";
6126 Preamble +=
"#endif\n";
6127 Preamble +=
"#ifndef __block\n";
6128 Preamble +=
"#define __block\n";
6129 Preamble +=
"#endif\n";
6132 Preamble +=
"#define __block\n";
6133 Preamble +=
"#define __weak\n";
6137 Preamble +=
"\n#include <stdarg.h>\n";
6138 Preamble +=
"struct __NSContainer_literal {\n";
6139 Preamble +=
" void * *arr;\n";
6140 Preamble +=
" __NSContainer_literal (unsigned int count, ...) {\n";
6141 Preamble +=
"\tva_list marker;\n";
6142 Preamble +=
"\tva_start(marker, count);\n";
6143 Preamble +=
"\tarr = new void *[count];\n";
6144 Preamble +=
"\tfor (unsigned i = 0; i < count; i++)\n";
6145 Preamble +=
"\t arr[i] = va_arg(marker, void *);\n";
6146 Preamble +=
"\tva_end( marker );\n";
6147 Preamble +=
" };\n";
6148 Preamble +=
" ~__NSContainer_literal() {\n";
6149 Preamble +=
"\tdelete[] arr;\n";
6154 Preamble +=
"extern \"C\" __declspec(dllimport) void * objc_autoreleasePoolPush(void);\n";
6155 Preamble +=
"extern \"C\" __declspec(dllimport) void objc_autoreleasePoolPop(void *);\n\n";
6156 Preamble +=
"struct __AtAutoreleasePool {\n";
6157 Preamble +=
" __AtAutoreleasePool() {atautoreleasepoolobj = objc_autoreleasePoolPush();}\n";
6158 Preamble +=
" ~__AtAutoreleasePool() {objc_autoreleasePoolPop(atautoreleasepoolobj);}\n";
6159 Preamble +=
" void * atautoreleasepoolobj;\n";
6164 Preamble +=
"\n#define __OFFSETOFIVAR__(TYPE, MEMBER) ((long long) &((TYPE *)0)->MEMBER)\n";
6169 void RewriteModernObjC::RewriteIvarOffsetComputation(
ObjCIvarDecl *ivar,
6170 std::string &Result) {
6171 Result +=
"__OFFSETOFIVAR__(struct ";
6173 if (LangOpts.MicrosoftExt)
6177 ObjCIvarBitfieldGroupDecl(ivar, Result);
6285 static void WriteModernMetadataDeclarations(
ASTContext *Context, std::string &Result) {
6286 static bool meta_data_declared =
false;
6287 if (meta_data_declared)
6290 Result +=
"\nstruct _prop_t {\n";
6291 Result +=
"\tconst char *name;\n";
6292 Result +=
"\tconst char *attributes;\n";
6295 Result +=
"\nstruct _protocol_t;\n";
6297 Result +=
"\nstruct _objc_method {\n";
6298 Result +=
"\tstruct objc_selector * _cmd;\n";
6299 Result +=
"\tconst char *method_type;\n";
6300 Result +=
"\tvoid *_imp;\n";
6303 Result +=
"\nstruct _protocol_t {\n";
6304 Result +=
"\tvoid * isa; // NULL\n";
6305 Result +=
"\tconst char *protocol_name;\n";
6306 Result +=
"\tconst struct _protocol_list_t * protocol_list; // super protocols\n";
6307 Result +=
"\tconst struct method_list_t *instance_methods;\n";
6308 Result +=
"\tconst struct method_list_t *class_methods;\n";
6309 Result +=
"\tconst struct method_list_t *optionalInstanceMethods;\n";
6310 Result +=
"\tconst struct method_list_t *optionalClassMethods;\n";
6311 Result +=
"\tconst struct _prop_list_t * properties;\n";
6312 Result +=
"\tconst unsigned int size; // sizeof(struct _protocol_t)\n";
6313 Result +=
"\tconst unsigned int flags; // = 0\n";
6314 Result +=
"\tconst char ** extendedMethodTypes;\n";
6317 Result +=
"\nstruct _ivar_t {\n";
6318 Result +=
"\tunsigned long int *offset; // pointer to ivar offset location\n";
6319 Result +=
"\tconst char *name;\n";
6320 Result +=
"\tconst char *type;\n";
6321 Result +=
"\tunsigned int alignment;\n";
6322 Result +=
"\tunsigned int size;\n";
6325 Result +=
"\nstruct _class_ro_t {\n";
6326 Result +=
"\tunsigned int flags;\n";
6327 Result +=
"\tunsigned int instanceStart;\n";
6328 Result +=
"\tunsigned int instanceSize;\n";
6330 if (Triple.getArch() == llvm::Triple::x86_64)
6331 Result +=
"\tunsigned int reserved;\n";
6332 Result +=
"\tconst unsigned char *ivarLayout;\n";
6333 Result +=
"\tconst char *name;\n";
6334 Result +=
"\tconst struct _method_list_t *baseMethods;\n";
6335 Result +=
"\tconst struct _objc_protocol_list *baseProtocols;\n";
6336 Result +=
"\tconst struct _ivar_list_t *ivars;\n";
6337 Result +=
"\tconst unsigned char *weakIvarLayout;\n";
6338 Result +=
"\tconst struct _prop_list_t *properties;\n";
6341 Result +=
"\nstruct _class_t {\n";
6342 Result +=
"\tstruct _class_t *isa;\n";
6343 Result +=
"\tstruct _class_t *superclass;\n";
6344 Result +=
"\tvoid *cache;\n";
6345 Result +=
"\tvoid *vtable;\n";
6346 Result +=
"\tstruct _class_ro_t *ro;\n";
6349 Result +=
"\nstruct _category_t {\n";
6350 Result +=
"\tconst char *name;\n";
6351 Result +=
"\tstruct _class_t *cls;\n";
6352 Result +=
"\tconst struct _method_list_t *instance_methods;\n";
6353 Result +=
"\tconst struct _method_list_t *class_methods;\n";
6354 Result +=
"\tconst struct _protocol_list_t *protocols;\n";
6355 Result +=
"\tconst struct _prop_list_t *properties;\n";
6358 Result +=
"extern \"C\" __declspec(dllimport) struct objc_cache _objc_empty_cache;\n";
6359 Result +=
"#pragma warning(disable:4273)\n";
6360 meta_data_declared =
true;
6363 static void Write_protocol_list_t_TypeDecl(std::string &Result,
6364 long super_protocol_count) {
6365 Result +=
"struct /*_protocol_list_t*/"; Result +=
" {\n";
6366 Result +=
"\tlong protocol_count; // Note, this is 32/64 bit\n";
6367 Result +=
"\tstruct _protocol_t *super_protocols[";
6368 Result += utostr(super_protocol_count); Result +=
"];\n";
6372 static void Write_method_list_t_TypeDecl(std::string &Result,
6373 unsigned int method_count) {
6374 Result +=
"struct /*_method_list_t*/"; Result +=
" {\n";
6375 Result +=
"\tunsigned int entsize; // sizeof(struct _objc_method)\n";
6376 Result +=
"\tunsigned int method_count;\n";
6377 Result +=
"\tstruct _objc_method method_list[";
6378 Result += utostr(method_count); Result +=
"];\n";
6382 static void Write__prop_list_t_TypeDecl(std::string &Result,
6383 unsigned int property_count) {
6384 Result +=
"struct /*_prop_list_t*/"; Result +=
" {\n";
6385 Result +=
"\tunsigned int entsize; // sizeof(struct _prop_t)\n";
6386 Result +=
"\tunsigned int count_of_properties;\n";
6387 Result +=
"\tstruct _prop_t prop_list[";
6388 Result += utostr(property_count); Result +=
"];\n";
6392 static void Write__ivar_list_t_TypeDecl(std::string &Result,
6393 unsigned int ivar_count) {
6394 Result +=
"struct /*_ivar_list_t*/"; Result +=
" {\n";
6395 Result +=
"\tunsigned int entsize; // sizeof(struct _prop_t)\n";
6396 Result +=
"\tunsigned int count;\n";
6397 Result +=
"\tstruct _ivar_t ivar_list[";
6398 Result += utostr(ivar_count); Result +=
"];\n";
6402 static void Write_protocol_list_initializer(
ASTContext *Context, std::string &Result,
6403 ArrayRef<ObjCProtocolDecl *> SuperProtocols,
6405 StringRef ProtocolName) {
6406 if (SuperProtocols.size() > 0) {
6407 Result +=
"\nstatic ";
6408 Write_protocol_list_t_TypeDecl(Result, SuperProtocols.size());
6409 Result +=
" "; Result += VarName;
6410 Result += ProtocolName;
6411 Result +=
" __attribute__ ((used, section (\"__DATA,__objc_const\"))) = {\n";
6412 Result +=
"\t"; Result += utostr(SuperProtocols.size()); Result +=
",\n";
6413 for (
unsigned i = 0, e = SuperProtocols.size(); i < e; i++) {
6415 Result +=
"\t&"; Result +=
"_OBJC_PROTOCOL_";
6425 static void Write_method_list_t_initializer(RewriteModernObjC &RewriteObj,
6427 ArrayRef<ObjCMethodDecl *> Methods,
6429 StringRef TopLevelDeclName,
6431 if (Methods.size() > 0) {
6432 Result +=
"\nstatic ";
6433 Write_method_list_t_TypeDecl(Result, Methods.size());
6434 Result +=
" "; Result += VarName;
6435 Result += TopLevelDeclName;
6436 Result +=
" __attribute__ ((used, section (\"__DATA,__objc_const\"))) = {\n";
6437 Result +=
"\t"; Result +=
"sizeof(_objc_method)"; Result +=
",\n";
6438 Result +=
"\t"; Result += utostr(Methods.size()); Result +=
",\n";
6439 for (
unsigned i = 0, e = Methods.size(); i < e; i++) {
6442 Result +=
"\t{{(struct objc_selector *)\"";
6444 Result +=
"\t{(struct objc_selector *)\"";
6445 Result += (MD)->getSelector().getAsString(); Result +=
"\"";
6447 std::string MethodTypeString;
6449 Result +=
"\""; Result += MethodTypeString; Result +=
"\"";
6454 Result +=
"(void *)";
6455 Result += RewriteObj.MethodInternalNames[MD];
6466 static void Write_prop_list_t_initializer(RewriteModernObjC &RewriteObj,
6468 ArrayRef<ObjCPropertyDecl *> Properties,
6469 const Decl *Container,
6471 StringRef ProtocolName) {
6472 if (Properties.size() > 0) {
6473 Result +=
"\nstatic ";
6474 Write__prop_list_t_TypeDecl(Result, Properties.size());
6475 Result +=
" "; Result += VarName;
6476 Result += ProtocolName;
6477 Result +=
" __attribute__ ((used, section (\"__DATA,__objc_const\"))) = {\n";
6478 Result +=
"\t"; Result +=
"sizeof(_prop_t)"; Result +=
",\n";
6479 Result +=
"\t"; Result += utostr(Properties.size()); Result +=
",\n";
6480 for (
unsigned i = 0, e = Properties.size(); i < e; i++) {
6486 Result += PropDecl->
getName(); Result +=
"\",";
6487 std::string PropertyTypeString, QuotePropertyTypeString;
6489 RewriteObj.QuoteDoublequotes(PropertyTypeString, QuotePropertyTypeString);
6490 Result +=
"\""; Result += QuotePropertyTypeString; Result +=
"\"";
6501 enum MetaDataDlags {
6505 OBJC2_CLS_HIDDEN = 0x10,
6506 CLS_EXCEPTION = 0x20,
6509 CLS_HAS_IVAR_RELEASER = 0x40,
6511 CLS_COMPILED_BY_ARC = 0x80
6514 static void Write__class_ro_t_initializer(
ASTContext *Context, std::string &Result,
6516 const std::string &InstanceStart,
6517 const std::string &InstanceSize,
6518 ArrayRef<ObjCMethodDecl *>baseMethods,
6519 ArrayRef<ObjCProtocolDecl *>baseProtocols,
6520 ArrayRef<ObjCIvarDecl *>ivars,
6521 ArrayRef<ObjCPropertyDecl *>Properties,
6523 StringRef ClassName) {
6524 Result +=
"\nstatic struct _class_ro_t ";
6525 Result += VarName; Result += ClassName;
6526 Result +=
" __attribute__ ((used, section (\"__DATA,__objc_const\"))) = {\n";
6528 Result += llvm::utostr(flags); Result +=
", ";
6529 Result += InstanceStart; Result +=
", ";
6530 Result += InstanceSize; Result +=
", \n";
6533 if (Triple.getArch() == llvm::Triple::x86_64)
6535 Result +=
"(unsigned int)0, \n\t";
6537 Result +=
"0, \n\t";
6538 Result +=
"\""; Result += ClassName; Result +=
"\",\n\t";
6539 bool metaclass = ((flags & CLS_META) != 0);
6540 if (baseMethods.size() > 0) {
6541 Result +=
"(const struct _method_list_t *)&";
6543 Result +=
"_OBJC_$_CLASS_METHODS_";
6545 Result +=
"_OBJC_$_INSTANCE_METHODS_";
6546 Result += ClassName;
6550 Result +=
"0, \n\t";
6552 if (!metaclass && baseProtocols.size() > 0) {
6553 Result +=
"(const struct _objc_protocol_list *)&";
6554 Result +=
"_OBJC_CLASS_PROTOCOLS_$_"; Result += ClassName;
6558 Result +=
"0, \n\t";
6560 if (!metaclass && ivars.size() > 0) {
6561 Result +=
"(const struct _ivar_list_t *)&";
6562 Result +=
"_OBJC_$_INSTANCE_VARIABLES_"; Result += ClassName;
6566 Result +=
"0, \n\t";
6569 Result +=
"0, \n\t";
6570 if (!metaclass && Properties.size() > 0) {
6571 Result +=
"(const struct _prop_list_t *)&";
6572 Result +=
"_OBJC_$_PROP_LIST_"; Result += ClassName;
6581 static void Write_class_t(
ASTContext *Context, std::string &Result,
6595 if (metaclass && rootClass) {
6598 Result +=
"extern \"C\" ";
6600 Result +=
"__declspec(dllexport) ";
6602 Result +=
"__declspec(dllimport) ";
6604 Result +=
"struct _class_t OBJC_CLASS_$_";
6612 Result +=
"extern \"C\" ";
6614 Result +=
"__declspec(dllexport) ";
6616 Result +=
"__declspec(dllimport) ";
6618 Result +=
"struct _class_t ";
6623 if (metaclass && RootClass != SuperClass) {
6624 Result +=
"extern \"C\" ";
6626 Result +=
"__declspec(dllexport) ";
6628 Result +=
"__declspec(dllimport) ";
6630 Result +=
"struct _class_t ";
6637 Result +=
"\nextern \"C\" __declspec(dllexport) struct _class_t ";
6639 Result +=
" __attribute__ ((used, section (\"__DATA,__objc_data\"))) = {\n";
6643 Result +=
"0, // &"; Result += VarName;
6646 Result +=
"0, // &"; Result += VarName;
6651 Result +=
"0, // &"; Result += VarName;
6659 Result +=
"0, // &OBJC_METACLASS_$_";
6663 Result +=
"0, // &"; Result += VarName;
6670 Result +=
"0, // (void *)&_objc_empty_cache,\n\t";
6671 Result +=
"0, // unused, was (void *)&_objc_empty_vtable,\n\t";
6673 Result +=
"&_OBJC_METACLASS_RO_$_";
6675 Result +=
"&_OBJC_CLASS_RO_$_";
6677 Result +=
",\n};\n";
6687 Result +=
"static void OBJC_CLASS_SETUP_$_";
6689 Result +=
"(void ) {\n";
6691 Result +=
".isa = "; Result +=
"&OBJC_METACLASS_$_";
6695 Result +=
".superclass = ";
6697 Result +=
"&OBJC_CLASS_$_";
6699 Result +=
"&OBJC_METACLASS_$_";
6704 Result +=
".cache = "; Result +=
"&_objc_empty_cache"; Result +=
";\n";
6707 Result +=
".isa = "; Result +=
"&OBJC_METACLASS_$_";
6712 Result +=
".superclass = "; Result +=
"&OBJC_CLASS_$_";
6717 Result +=
".cache = "; Result +=
"&_objc_empty_cache"; Result +=
";\n";
6721 static void Write_category_t(RewriteModernObjC &RewriteObj,
ASTContext *Context,
6722 std::string &Result,
6725 ArrayRef<ObjCMethodDecl *> InstanceMethods,
6726 ArrayRef<ObjCMethodDecl *> ClassMethods,
6727 ArrayRef<ObjCProtocolDecl *> RefedProtocols,
6728 ArrayRef<ObjCPropertyDecl *> ClassProperties) {
6729 StringRef CatName = CatDecl->
getName();
6730 StringRef ClassName = ClassDecl->
getName();
6734 Result +=
"extern \"C\" ";
6736 Result +=
"__declspec(dllexport) ";
6738 Result +=
"__declspec(dllimport) ";
6740 Result +=
"struct _class_t ";
6741 Result +=
"OBJC_CLASS_$_"; Result += ClassName;
6744 Result +=
"\nstatic struct _category_t ";
6745 Result +=
"_OBJC_$_CATEGORY_";
6746 Result += ClassName; Result +=
"_$_"; Result += CatName;
6747 Result +=
" __attribute__ ((used, section (\"__DATA,__objc_const\"))) = \n";
6749 Result +=
"\t\""; Result += ClassName; Result +=
"\",\n";
6750 Result +=
"\t0, // &"; Result +=
"OBJC_CLASS_$_"; Result += ClassName;
6752 if (InstanceMethods.size() > 0) {
6753 Result +=
"\t(const struct _method_list_t *)&";
6754 Result +=
"_OBJC_$_CATEGORY_INSTANCE_METHODS_";
6755 Result += ClassName; Result +=
"_$_"; Result += CatName;
6761 if (ClassMethods.size() > 0) {
6762 Result +=
"\t(const struct _method_list_t *)&";
6763 Result +=
"_OBJC_$_CATEGORY_CLASS_METHODS_";
6764 Result += ClassName; Result +=
"_$_"; Result += CatName;
6770 if (RefedProtocols.size() > 0) {
6771 Result +=
"\t(const struct _protocol_list_t *)&";
6772 Result +=
"_OBJC_CATEGORY_PROTOCOLS_$_";
6773 Result += ClassName; Result +=
"_$_"; Result += CatName;
6779 if (ClassProperties.size() > 0) {
6780 Result +=
"\t(const struct _prop_list_t *)&"; Result +=
"_OBJC_$_PROP_LIST_";
6781 Result += ClassName; Result +=
"_$_"; Result += CatName;
6790 Result +=
"static void OBJC_CATEGORY_SETUP_$_";
6794 Result +=
"(void ) {\n";
6795 Result +=
"\t_OBJC_$_CATEGORY_";
6799 Result +=
".cls = "; Result +=
"&OBJC_CLASS_$_"; Result += ClassName;
6803 static void Write__extendedMethodTypes_initializer(RewriteModernObjC &RewriteObj,
6805 ArrayRef<ObjCMethodDecl *> Methods,
6807 StringRef ProtocolName) {
6808 if (Methods.size() == 0)
6811 Result +=
"\nstatic const char *";
6812 Result += VarName; Result += ProtocolName;
6813 Result +=
" [] __attribute__ ((used, section (\"__DATA,__objc_const\"))) = \n";
6815 for (
unsigned i = 0, e = Methods.size(); i < e; i++) {
6817 std::string MethodTypeString, QuoteMethodTypeString;
6819 RewriteObj.QuoteDoublequotes(MethodTypeString, QuoteMethodTypeString);
6820 Result +=
"\t\""; Result += QuoteMethodTypeString; Result +=
"\"";
6829 static void Write_IvarOffsetVar(RewriteModernObjC &RewriteObj,
6831 std::string &Result,
6832 ArrayRef<ObjCIvarDecl *> Ivars,
6846 for (
unsigned i =0, e = Ivars.size(); i < e; i++) {
6849 Result +=
"__declspec(allocate(\".objc_ivar$B\")) ";
6854 Result +=
"extern \"C\" unsigned long int ";
6856 Result +=
"extern \"C\" __declspec(dllexport) unsigned long int ";
6857 if (Ivars[i]->isBitField())
6858 RewriteObj.ObjCIvarBitfieldGroupOffset(IvarDecl, Result);
6860 WriteInternalIvarName(CDecl, IvarDecl, Result);
6861 Result +=
" __attribute__ ((used, section (\"__DATA,__objc_ivar\")))";
6863 RewriteObj.RewriteIvarOffsetComputation(IvarDecl, Result);
6865 if (Ivars[i]->isBitField()) {
6867 SKIP_BITFIELDS(i , e, Ivars);
6872 static void Write__ivar_list_t_initializer(RewriteModernObjC &RewriteObj,
6874 ArrayRef<ObjCIvarDecl *> OriginalIvars,
6877 if (OriginalIvars.size() > 0) {
6878 Write_IvarOffsetVar(RewriteObj, Context, Result, OriginalIvars, CDecl);
6879 SmallVector<ObjCIvarDecl *, 8> Ivars;
6883 for (
unsigned i = 0, e = OriginalIvars.size(); i < e; i++) {
6884 if (OriginalIvars[i]->isBitField()) {
6885 Ivars.push_back(OriginalIvars[i]);
6887 SKIP_BITFIELDS(i , e, OriginalIvars);
6890 Ivars.push_back(OriginalIvars[i]);
6893 Result +=
"\nstatic ";
6894 Write__ivar_list_t_TypeDecl(Result, Ivars.size());
6895 Result +=
" "; Result += VarName;
6897 Result +=
" __attribute__ ((used, section (\"__DATA,__objc_const\"))) = {\n";
6898 Result +=
"\t"; Result +=
"sizeof(_ivar_t)"; Result +=
",\n";
6899 Result +=
"\t"; Result += utostr(Ivars.size()); Result +=
",\n";
6900 for (
unsigned i =0, e = Ivars.size(); i < e; i++) {
6906 Result +=
"(unsigned long int *)&";
6907 if (Ivars[i]->isBitField())
6908 RewriteObj.ObjCIvarBitfieldGroupOffset(IvarDecl, Result);
6910 WriteInternalIvarName(CDecl, IvarDecl, Result);
6914 if (Ivars[i]->isBitField())
6915 RewriteObj.ObjCIvarBitfieldGroupDecl(Ivars[i], Result);
6917 Result += IvarDecl->
getName();
6922 IVQT = RewriteObj.GetGroupRecordTypeForObjCIvarBitfield(IvarDecl);
6924 std::string IvarTypeString, QuoteIvarTypeString;
6927 RewriteObj.QuoteDoublequotes(IvarTypeString, QuoteIvarTypeString);
6928 Result +=
"\""; Result += QuoteIvarTypeString; Result +=
"\", ";
6933 Align = llvm::Log2_32(Align);
6934 Result += llvm::utostr(Align); Result +=
", ";
6947 void RewriteModernObjC::RewriteObjCProtocolMetaData(
ObjCProtocolDecl *PDecl,
6948 std::string &Result) {
6953 WriteModernMetadataDeclarations(Context, Result);
6960 RewriteObjCProtocolMetaData(I, Result);
6963 std::vector<ObjCMethodDecl *> InstanceMethods, ClassMethods;
6964 std::vector<ObjCMethodDecl *> OptInstanceMethods, OptClassMethods;
6967 OptInstanceMethods.push_back(MD);
6969 InstanceMethods.push_back(MD);
6975 OptClassMethods.push_back(MD);
6977 ClassMethods.push_back(MD);
6980 std::vector<ObjCMethodDecl *> AllMethods;
6981 for (
unsigned i = 0, e = InstanceMethods.size(); i < e; i++)
6982 AllMethods.push_back(InstanceMethods[i]);
6983 for (
unsigned i = 0, e = ClassMethods.size(); i < e; i++)
6984 AllMethods.push_back(ClassMethods[i]);
6985 for (
unsigned i = 0, e = OptInstanceMethods.size(); i < e; i++)
6986 AllMethods.push_back(OptInstanceMethods[i]);
6987 for (
unsigned i = 0, e = OptClassMethods.size(); i < e; i++)
6988 AllMethods.push_back(OptClassMethods[i]);
6990 Write__extendedMethodTypes_initializer(*
this, Context, Result,
6992 "_OBJC_PROTOCOL_METHOD_TYPES_",
6995 SmallVector<ObjCProtocolDecl *, 8> SuperProtocols(PDecl->
protocols());
6996 Write_protocol_list_initializer(Context, Result, SuperProtocols,
6997 "_OBJC_PROTOCOL_REFS_",
7000 Write_method_list_t_initializer(*
this, Context, Result, InstanceMethods,
7001 "_OBJC_PROTOCOL_INSTANCE_METHODS_",
7004 Write_method_list_t_initializer(*
this, Context, Result, ClassMethods,
7005 "_OBJC_PROTOCOL_CLASS_METHODS_",
7008 Write_method_list_t_initializer(*
this, Context, Result, OptInstanceMethods,
7009 "_OBJC_PROTOCOL_OPT_INSTANCE_METHODS_",
7012 Write_method_list_t_initializer(*
this, Context, Result, OptClassMethods,
7013 "_OBJC_PROTOCOL_OPT_CLASS_METHODS_",
7017 SmallVector<ObjCPropertyDecl *, 8> ProtocolProperties(PDecl->
properties());
7018 Write_prop_list_t_initializer(*
this, Context, Result, ProtocolProperties,
7020 "_OBJC_PROTOCOL_PROPERTIES_",
7025 if (LangOpts.MicrosoftExt)
7026 Result +=
"static ";
7027 Result +=
"struct _protocol_t _OBJC_PROTOCOL_";
7029 Result +=
" __attribute__ ((used, section (\"__DATA,__datacoal_nt,coalesced\"))) = {\n";
7031 Result +=
"\t\""; Result += PDecl->
getNameAsString(); Result +=
"\",\n";
7032 if (SuperProtocols.size() > 0) {
7033 Result +=
"\t(const struct _protocol_list_t *)&"; Result +=
"_OBJC_PROTOCOL_REFS_";
7038 if (InstanceMethods.size() > 0) {
7039 Result +=
"\t(const struct method_list_t *)&_OBJC_PROTOCOL_INSTANCE_METHODS_";
7045 if (ClassMethods.size() > 0) {
7046 Result +=
"\t(const struct method_list_t *)&_OBJC_PROTOCOL_CLASS_METHODS_";
7052 if (OptInstanceMethods.size() > 0) {
7053 Result +=
"\t(const struct method_list_t *)&_OBJC_PROTOCOL_OPT_INSTANCE_METHODS_";
7059 if (OptClassMethods.size() > 0) {
7060 Result +=
"\t(const struct method_list_t *)&_OBJC_PROTOCOL_OPT_CLASS_METHODS_";
7066 if (ProtocolProperties.size() > 0) {
7067 Result +=
"\t(const struct _prop_list_t *)&_OBJC_PROTOCOL_PROPERTIES_";
7073 Result +=
"\t"; Result +=
"sizeof(_protocol_t)"; Result +=
",\n";
7076 if (AllMethods.size() > 0) {
7077 Result +=
"\t(const char **)&"; Result +=
"_OBJC_PROTOCOL_METHOD_TYPES_";
7082 Result +=
"\t0\n};\n";
7084 if (LangOpts.MicrosoftExt)
7085 Result +=
"static ";
7086 Result +=
"struct _protocol_t *";
7087 Result +=
"_OBJC_LABEL_PROTOCOL_$_"; Result += PDecl->
getNameAsString();
7093 llvm_unreachable(
"protocol already synthesized");
7097 void RewriteModernObjC::RewriteObjCProtocolListMetaData(
7099 StringRef prefix, StringRef ClassName,
7100 std::string &Result) {
7101 if (Protocols.
empty())
return;
7103 for (
unsigned i = 0; i != Protocols.
size(); i++)
7104 RewriteObjCProtocolMetaData(Protocols[i], Result);
7114 if (LangOpts.MicrosoftExt)
7115 Result +=
"__declspec(allocate(\".cat_cls_meth$B\")) ";
7116 Result +=
"static struct {\n";
7117 Result +=
"\tstruct _objc_protocol_list *next;\n";
7118 Result +=
"\tint protocol_count;\n";
7119 Result +=
"\tstruct _objc_protocol *class_protocols[";
7120 Result += utostr(Protocols.
size());
7121 Result +=
"];\n} _OBJC_";
7123 Result +=
"_PROTOCOLS_";
7124 Result += ClassName;
7125 Result +=
" __attribute__ ((used, section (\"__OBJC, __cat_cls_meth\")))= "
7127 Result += utostr(Protocols.
size());
7130 Result +=
"\t,{&_OBJC_PROTOCOL_";
7131 Result += Protocols[0]->getNameAsString();
7134 for (
unsigned i = 1; i != Protocols.
size(); i++) {
7135 Result +=
"\t ,&_OBJC_PROTOCOL_";
7136 Result += Protocols[i]->getNameAsString();
7139 Result +=
"\t }\n};\n";
7147 if (OID->
hasAttr<ObjCExceptionAttr>())
7155 std::string &Result) {
7161 "Legacy implicit interface rewriting not supported in moder abi");
7163 WriteModernMetadataDeclarations(Context, Result);
7164 SmallVector<ObjCIvarDecl *, 8> IVars;
7169 if (!IVD->getDeclName())
7171 IVars.push_back(IVD);
7174 Write__ivar_list_t_initializer(*
this, Context, Result, IVars,
7175 "_OBJC_$_INSTANCE_VARIABLES_",
7179 SmallVector<ObjCMethodDecl *, 32> InstanceMethods(IDecl->
instance_methods());
7184 if (Prop->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic)
7186 if (!Prop->getPropertyIvarDecl())
7192 if (mustSynthesizeSetterGetterMethod(IDecl, PD,
true ))
7193 InstanceMethods.push_back(Getter);
7197 if (mustSynthesizeSetterGetterMethod(IDecl, PD,
false ))
7198 InstanceMethods.push_back(Setter);
7201 Write_method_list_t_initializer(*
this, Context, Result, InstanceMethods,
7202 "_OBJC_$_INSTANCE_METHODS_",
7205 SmallVector<ObjCMethodDecl *, 32> ClassMethods(IDecl->
class_methods());
7207 Write_method_list_t_initializer(*
this, Context, Result, ClassMethods,
7208 "_OBJC_$_CLASS_METHODS_",
7213 std::vector<ObjCProtocolDecl *> RefedProtocols;
7216 E = Protocols.
end();
7218 RefedProtocols.push_back(*I);
7221 RewriteObjCProtocolMetaData(*I, Result);
7224 Write_protocol_list_initializer(Context, Result,
7226 "_OBJC_CLASS_PROTOCOLS_$_",
7230 SmallVector<ObjCPropertyDecl *, 8> ClassProperties(CDecl->
properties());
7231 Write_prop_list_t_initializer(*
this, Context, Result, ClassProperties,
7233 "_OBJC_$_PROP_LIST_",
7238 uint32_t flags = CLS_META;
7239 std::string InstanceSize;
7240 std::string InstanceStart;
7245 flags |= OBJC2_CLS_HIDDEN;
7250 InstanceSize =
"sizeof(struct _class_t)";
7251 InstanceStart = InstanceSize;
7252 Write__class_ro_t_initializer(Context, Result, flags,
7253 InstanceStart, InstanceSize,
7258 "_OBJC_METACLASS_RO_$_",
7264 flags |= OBJC2_CLS_HIDDEN;
7267 flags |= CLS_EXCEPTION;
7273 InstanceSize.clear();
7274 InstanceStart.clear();
7275 if (!ObjCSynthesizedStructs.count(CDecl)) {
7277 InstanceStart =
"0";
7280 InstanceSize =
"sizeof(struct ";
7282 InstanceSize +=
"_IMPL)";
7286 RewriteIvarOffsetComputation(IVD, InstanceStart);
7289 InstanceStart = InstanceSize;
7291 Write__class_ro_t_initializer(Context, Result, flags,
7292 InstanceStart, InstanceSize,
7297 "_OBJC_CLASS_RO_$_",
7300 Write_class_t(Context, Result,
7301 "OBJC_METACLASS_$_",
7304 Write_class_t(Context, Result,
7308 if (ImplementationIsNonLazy(IDecl))
7309 DefinedNonLazyClasses.push_back(CDecl);
7313 void RewriteModernObjC::RewriteClassSetupInitHook(std::string &Result) {
7314 int ClsDefCount = ClassImplementation.size();
7317 Result +=
"#pragma section(\".objc_inithooks$B\", long, read, write)\n";
7318 Result +=
"__declspec(allocate(\".objc_inithooks$B\")) ";
7319 Result +=
"static void *OBJC_CLASS_SETUP[] = {\n";
7320 for (
int i = 0; i < ClsDefCount; i++) {
7323 Result +=
"\t(void *)&OBJC_CLASS_SETUP_$_";
7324 Result += CDecl->
getName(); Result +=
",\n";
7329 void RewriteModernObjC::RewriteMetaDataIntoBuffer(std::string &Result) {
7330 int ClsDefCount = ClassImplementation.size();
7331 int CatDefCount = CategoryImplementation.size();
7334 for (
int i = 0; i < ClsDefCount; i++)
7335 RewriteObjCClassMetaData(ClassImplementation[i], Result);
7337 RewriteClassSetupInitHook(Result);
7340 for (
int i = 0; i < CatDefCount; i++)
7341 RewriteObjCCategoryImplDecl(CategoryImplementation[i], Result);
7343 RewriteCategorySetupInitHook(Result);
7345 if (ClsDefCount > 0) {
7346 if (LangOpts.MicrosoftExt)
7347 Result +=
"__declspec(allocate(\".objc_classlist$B\")) ";
7348 Result +=
"static struct _class_t *L_OBJC_LABEL_CLASS_$ [";
7349 Result += llvm::utostr(ClsDefCount); Result +=
"]";
7351 " __attribute__((used, section (\"__DATA, __objc_classlist,"
7352 "regular,no_dead_strip\")))= {\n";
7353 for (
int i = 0; i < ClsDefCount; i++) {
7354 Result +=
"\t&OBJC_CLASS_$_";
7355 Result += ClassImplementation[i]->getNameAsString();
7360 if (!DefinedNonLazyClasses.empty()) {
7361 if (LangOpts.MicrosoftExt)
7362 Result +=
"__declspec(allocate(\".objc_nlclslist$B\")) \n";
7363 Result +=
"static struct _class_t *_OBJC_LABEL_NONLAZY_CLASS_$[] = {\n\t";
7364 for (
unsigned i = 0, e = DefinedNonLazyClasses.size(); i < e; i++) {
7365 Result +=
"\t&OBJC_CLASS_$_"; Result += DefinedNonLazyClasses[i]->getNameAsString();
7372 if (CatDefCount > 0) {
7373 if (LangOpts.MicrosoftExt)
7374 Result +=
"__declspec(allocate(\".objc_catlist$B\")) ";
7375 Result +=
"static struct _category_t *L_OBJC_LABEL_CATEGORY_$ [";
7376 Result += llvm::utostr(CatDefCount); Result +=
"]";
7378 " __attribute__((used, section (\"__DATA, __objc_catlist,"
7379 "regular,no_dead_strip\")))= {\n";
7380 for (
int i = 0; i < CatDefCount; i++) {
7381 Result +=
"\t&_OBJC_$_CATEGORY_";
7383 CategoryImplementation[i]->getClassInterface()->getNameAsString();
7385 Result += CategoryImplementation[i]->getNameAsString();
7391 if (!DefinedNonLazyCategories.empty()) {
7392 if (LangOpts.MicrosoftExt)
7393 Result +=
"__declspec(allocate(\".objc_nlcatlist$B\")) \n";
7394 Result +=
"static struct _category_t *_OBJC_LABEL_NONLAZY_CATEGORY_$[] = {\n\t";
7395 for (
unsigned i = 0, e = DefinedNonLazyCategories.size(); i < e; i++) {
7396 Result +=
"\t&_OBJC_$_CATEGORY_";
7398 DefinedNonLazyCategories[i]->getClassInterface()->getNameAsString();
7400 Result += DefinedNonLazyCategories[i]->getNameAsString();
7407 void RewriteModernObjC::WriteImageInfo(std::string &Result) {
7408 if (LangOpts.MicrosoftExt)
7409 Result +=
"__declspec(allocate(\".objc_imageinfo$B\")) \n";
7411 Result +=
"static struct IMAGE_INFO { unsigned version; unsigned flag; } ";
7413 Result +=
"_OBJC_IMAGE_INFO = { 0, 2 };\n";
7419 std::string &Result) {
7420 WriteModernMetadataDeclarations(Context, Result);
7427 FullCategoryName +=
"_$_";
7431 SmallVector<ObjCMethodDecl *, 32> InstanceMethods(IDecl->
instance_methods());
7436 if (Prop->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic)
7438 if (!Prop->getPropertyIvarDecl())
7444 InstanceMethods.push_back(Getter);
7448 InstanceMethods.push_back(Setter);
7451 Write_method_list_t_initializer(*
this, Context, Result, InstanceMethods,
7452 "_OBJC_$_CATEGORY_INSTANCE_METHODS_",
7453 FullCategoryName,
true);
7455 SmallVector<ObjCMethodDecl *, 32> ClassMethods(IDecl->
class_methods());
7457 Write_method_list_t_initializer(*
this, Context, Result, ClassMethods,
7458 "_OBJC_$_CATEGORY_CLASS_METHODS_",
7459 FullCategoryName,
true);
7463 SmallVector<ObjCProtocolDecl *, 8> RefedProtocols(CDecl->
protocols());
7467 RewriteObjCProtocolMetaData(I, Result);
7469 Write_protocol_list_initializer(Context, Result,
7471 "_OBJC_CATEGORY_PROTOCOLS_$_",
7475 SmallVector<ObjCPropertyDecl *, 8> ClassProperties(CDecl->
properties());
7476 Write_prop_list_t_initializer(*
this, Context, Result, ClassProperties,
7478 "_OBJC_$_PROP_LIST_",
7481 Write_category_t(*
this, Context, Result,
7490 if (ImplementationIsNonLazy(IDecl))
7491 DefinedNonLazyCategories.push_back(CDecl);
7495 void RewriteModernObjC::RewriteCategorySetupInitHook(std::string &Result) {
7496 int CatDefCount = CategoryImplementation.size();
7499 Result +=
"#pragma section(\".objc_inithooks$B\", long, read, write)\n";
7500 Result +=
"__declspec(allocate(\".objc_inithooks$B\")) ";
7501 Result +=
"static void *OBJC_CATEGORY_SETUP[] = {\n";
7502 for (
int i = 0; i < CatDefCount; i++) {
7506 Result +=
"\t(void *)&OBJC_CATEGORY_SETUP_$_";
7507 Result += ClassDecl->
getName();
7517 template<
typename MethodIterator>
7518 void RewriteModernObjC::RewriteObjCMethodsMetaData(MethodIterator MethodBegin,
7519 MethodIterator MethodEnd,
7520 bool IsInstanceMethod,
7522 StringRef ClassName,
7523 std::string &Result) {
7524 if (MethodBegin == MethodEnd)
return;
7526 if (!objc_impl_method) {
7533 Result +=
"\nstruct _objc_method {\n";
7534 Result +=
"\tSEL _cmd;\n";
7535 Result +=
"\tchar *method_types;\n";
7536 Result +=
"\tvoid *_imp;\n";
7539 objc_impl_method =
true;
7550 unsigned NumMethods = std::distance(MethodBegin, MethodEnd);
7552 if (LangOpts.MicrosoftExt) {
7553 if (IsInstanceMethod)
7554 Result +=
"__declspec(allocate(\".inst_meth$B\")) ";
7556 Result +=
"__declspec(allocate(\".cls_meth$B\")) ";
7558 Result +=
"static struct {\n";
7559 Result +=
"\tstruct _objc_method_list *next_method;\n";
7560 Result +=
"\tint method_count;\n";
7561 Result +=
"\tstruct _objc_method method_list[";
7562 Result += utostr(NumMethods);
7563 Result +=
"];\n} _OBJC_";
7565 Result += IsInstanceMethod ?
"INSTANCE" :
"CLASS";
7566 Result +=
"_METHODS_";
7567 Result += ClassName;
7568 Result +=
" __attribute__ ((used, section (\"__OBJC, __";
7569 Result += IsInstanceMethod ?
"inst" :
"cls";
7570 Result +=
"_meth\")))= ";
7571 Result +=
"{\n\t0, " + utostr(NumMethods) +
"\n";
7573 Result +=
"\t,{{(SEL)\"";
7574 Result += (*MethodBegin)->getSelector().getAsString().c_str();
7575 std::string MethodTypeString;
7578 Result += MethodTypeString;
7579 Result +=
"\", (void *)";
7580 Result += MethodInternalNames[*MethodBegin];
7582 for (++MethodBegin; MethodBegin != MethodEnd; ++MethodBegin) {
7583 Result +=
"\t ,{(SEL)\"";
7584 Result += (*MethodBegin)->getSelector().getAsString().c_str();
7585 std::string MethodTypeString;
7588 Result += MethodTypeString;
7589 Result +=
"\", (void *)";
7590 Result += MethodInternalNames[*MethodBegin];
7593 Result +=
"\t }\n};\n";
7602 DisableReplaceStmtScope
S(*
this);
7603 BaseExpr = cast<Expr>(RewriteFunctionBodyOrGlobalInitializer(BaseExpr));
7609 Expr *Replacement = IV;
7614 assert(iFaceDecl &&
"RewriteObjCIvarRefExpr - iFaceDecl is null");
7619 assert(clsDeclared &&
"RewriteObjCIvarRefExpr(): Can't find class");
7622 std::string IvarOffsetName;
7624 ObjCIvarBitfieldGroupOffset(D, IvarOffsetName);
7626 WriteInternalIvarName(clsDeclared, D, IvarOffsetName);
7628 ReferencedIvars[clsDeclared].insert(D);
7631 CastExpr *castExpr = NoTypeInfoCStyleCastExpr(Context,
7652 IvarT = GetGroupRecordTypeForObjCIvarBitfield(D);
7654 if (!isa<TypedefType>(IvarT) && IvarT->
isRecordType()) {
7664 std::string RecName = CDecl->
getName();
7670 unsigned UnsignedIntSize =
7673 llvm::APInt(UnsignedIntSize, 0),
7675 Zero = NoTypeInfoCStyleCastExpr(Context, PtrStructIMPL,
CK_BitCast, Zero);
7690 convertObjCTypeToCStyleType(IvarT);
7693 castExpr = NoTypeInfoCStyleCastExpr(Context,
7700 VK_LValue, OK_Ordinary,
7723 ReplaceStmtWithRange(IV, Replacement, OldRange);
SourceLocation getEnd() const
const Expr * getBase() const
ObjCInterfaceDecl * getDecl() const
getDecl - Get the declaration of this interface.
CastKind getCastKind() const
StringRef getName() const
protocol_range protocols() const
Expr * getSyntacticForm()
Smart pointer class that efficiently represents Objective-C method names.
SourceLocation getLocStart() const LLVM_READONLY
const ObjCAtFinallyStmt * getFinallyStmt() const
Retrieve the @finally statement, if any.
ImplementationControl getImplementationControl() const
ObjCInterfaceDecl * getClassInterface()
ObjCInterfaceDecl * getClassInterface()
bool isBitField() const
Determines whether this field is a bitfield.
QualType getClassReceiver() const
Returns the type of a class message send, or NULL if the message is not a class message.
IdentifierInfo * getIdentifier() const
CanQual< T > getUnqualifiedType() const
Retrieve the unqualified form of this type.
std::unique_ptr< ASTConsumer > CreateModernObjCRewriter(const std::string &InFile, raw_ostream *OS, DiagnosticsEngine &Diags, const LangOptions &LOpts, bool SilenceRewriteMacroWarning, bool LineInfo)
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
void getSelectorLocs(SmallVectorImpl< SourceLocation > &SelLocs) const
std::string getAsString() const
FullSourceLoc getFullLoc(SourceLocation Loc) const
IdentifierInfo * getAsIdentifierInfo() const
SourceLocation getLocStart() const LLVM_READONLY
bool isObjCQualifiedClassType() const
Represents Objective-C's @throw statement.
SourceLocation getLocStart() const LLVM_READONLY
const Expr * getInit() const
Represents a call to a C++ constructor.
virtual void completeDefinition()
static bool hasObjCExceptionAttribute(ASTContext &Context, const ObjCInterfaceDecl *OID)
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)
protocol_range protocols() const
SourceLocation getLocStart() const LLVM_READONLY
SourceLocation getLocEnd() const LLVM_READONLY
Represents a C++ constructor within a class.
ObjCDictionaryElement getKeyValueElement(unsigned Index) const
SourceLocation getIvarRBraceLoc() const
ExtProtoInfo - 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.
Expr * IgnoreImplicit() LLVM_READONLY
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
ParmVarDecl - Represents a parameter to a function.
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
SourceLocation getLocStart() const LLVM_READONLY
QualType withConst() const
Retrieves a version of this type with const applied. Note that this does not always yield a canonical...
unsigned getNumParams() const
Kind getPropertyImplementation() const
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.
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...
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.
bool isCompleteDefinition() const
StringLiteral * getString()
const Stmt * getBody() const
ObjCMethodDecl * getClassMethod(Selector Sel, bool AllowHidden=false) const
bool ReplaceText(SourceLocation Start, unsigned OrigLength, StringRef NewStr)
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
QualType getTypeDeclType(const TypeDecl *Decl, const TypeDecl *PrevDecl=nullptr) const
Return the unique reference to the type for the specified type declaration.
bool hasBraces() const
Determines whether this linkage specification had braces in its syntactic form.
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.
QualType getCallResultType(ASTContext &Context) const
Determine the type of an expression that calls a function of this type.
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.
const LangOptions & getLangOpts() const
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
TypeOfExprType (GCC extension).
A builtin binary operation expression such as "x + y" or "x <= y".
Selector getSelector() const
Selector getSetterName() const
bool isOverloadedOperator() const
static OMPLinearClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL, ArrayRef< Expr * > IL, Expr *Step, Expr *CalcStep)
Creates clause with a list of variables VL and a linear step Step.
std::string getNameAsString() const
ObjCProtocolDecl * getDefinition()
Retrieve the definition of this protocol, if any.
bool isVariadic() const
Whether this function is variadic.
const Stmt * getCatchBody() const
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.
PropertyAttributeKind getPropertyAttributes() const
SourceLocation getAtLoc() const
SourceRange getAtEndRange() const
bool isThisDeclarationADefinition() const
Determine whether this particular declaration is also the definition.
SourceLocation getLocStart() const LLVM_READONLY
SourceLocation getLocEnd() const LLVM_READONLY
QualType getParamType(unsigned i) const
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
ID
Defines the set of possible language-specific address spaces.
StorageClass getStorageClass() const
Returns the storage class as written in the source. For the computed linkage of symbol, see getLinkage.
QualType getPointeeType() const
bool isFunctionPointerType() const
QualType getObjCInterfaceType(const ObjCInterfaceDecl *Decl, ObjCInterfaceDecl *PrevDecl=nullptr) const
bool isRealFloatingType() const
Floating point categories.
const ObjCMethodDecl * getMethodDecl() const
SourceLocation getLocStart() const LLVM_READONLY
QualType getPointeeType() const
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
TranslationUnitDecl * getTranslationUnitDecl() const
bool isObjCGCWeak() const
isObjCGCWeak true when Type is objc's weak.
Expr * getUnderlyingExpr() const
DeclContext * getDeclContext()
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
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.
DeclarationName getDeclName() const
The result type of a method or function.
RecordDecl * getDefinition() const
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
SourceLocation getLocStart() const LLVM_READONLY
unsigned getTypeAlign(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in bits.
SourceLocation getExternLoc() const
SelectorTable & Selectors
SourceLocation getLocStart() const LLVM_READONLY
const char * getFilename() const
Return the presumed filename of this location.
Encodes a location in the source. The SourceManager can decode this to get at the full include stack...
enumerator_range enumerators() const
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
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].
bool isValid() const
Return true if this is a valid SourceLocation object.
TagDecl - Represents the declaration of a struct/union/class/enum.
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?
QualType withConst() const
bool InsertText(SourceLocation Loc, StringRef Str, bool InsertAfter=true, bool indentNewLines=false)
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
const ObjCInterfaceDecl * getClassInterface() const
decl_iterator decl_begin()
std::string getAsString() const
Derive the full selector name (e.g. "foo:bar:") and return it as an std::string.
Represents one property declaration in an Objective-C interface.
QualType getReturnType() const
SourceLocation getBegin() const
FileID getMainFileID() const
Returns the FileID of the main source file.
bool isFileContext() const
SourceLocation getAtSynchronizedLoc() const
const BlockDecl * getBlockDecl() const
SourceLocation getExprLoc() const LLVM_READONLY
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
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.
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
SourceLocation getLParenLoc() const
unsigned getByteLength() const
prop_range properties() 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
static __inline__ uint32_t volatile uint32_t * p
QualType IgnoreParens() const
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
Selector getGetterName() const
bool isThisDeclarationADefinition() const
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
Selector getSelector() const
ObjCMethodDecl * getArrayWithObjectsMethod() const
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
Defines the Diagnostic-related interfaces.
CanQualType ObjCBuiltinBoolTy
SourceLocation getRParenLoc() const
ObjCMethodDecl * getGetterMethodDecl() const
SourceLocation getLeftLoc() const
const Stmt * getSubStmt() const
Represents Objective-C's collection statement.
CanQualType UnsignedLongTy
ObjCMethodDecl * getSetterMethodDecl() const
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)
bool isObjCQualifiedIdType() const
DeclContext * getRedeclContext()
SourceLocation getRBraceLoc() const
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.
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
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.
bool isImplicitInterfaceDecl() const
bool isReadOnly() const
isReadOnly - Return true iff the property has a setter.
bool isObjCObjectPointerType() const
QualType getEncodedType() const
bool isImplicit() const
Indicates whether the message send was implicitly generated by the implementation. If false, it was written explicitly in the source code.
SourceLocation getLocEnd() const LLVM_READONLY
Represents Objective-C's @try ... @catch ... @finally statement.
const Expr * getThrowExpr() const
SourceLocation getLocation() const
Defines the clang::TargetInfo interface.
ObjCInterfaceDecl * getSuperClass() const
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. [C99 6.5.1p2].
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
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.
SourceLocation getLocation() const
ObjCIvarDecl * all_declared_ivar_begin()
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
isNull - 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.
bool isIntegralType(ASTContext &Ctx) const
Determine whether this type is an integral type.
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
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.