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 ArrayRef<Expr *> Args,
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;
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,
2109 ReplaceStmt(Exp, SelExp);
2115 RewriteModernObjC::SynthesizeCallToFunctionDecl(
FunctionDecl *FD,
2116 ArrayRef<Expr *> Args,
2140 static bool scanForProtocolRefs(
const char *startBuf,
const char *endBuf,
2141 const char *&startRef,
const char *&endRef) {
2142 while (startBuf < endBuf) {
2143 if (*startBuf ==
'<')
2144 startRef = startBuf;
2145 if (*startBuf ==
'>') {
2146 if (startRef && *startRef ==
'<') {
2157 static void scanToNextArgument(
const char *&argRef) {
2159 while (*argRef !=
')' && (*argRef !=
',' || angle > 0)) {
2162 else if (*argRef ==
'>')
2166 assert(angle == 0 &&
"scanToNextArgument - bad protocol type syntax");
2169 bool RewriteModernObjC::needToScanForQualifiers(
QualType T) {
2182 return needToScanForQualifiers(ElemTy);
2187 void RewriteModernObjC::RewriteObjCQualifiedInterfaceTypes(
Expr *E) {
2189 if (needToScanForQualifiers(Type)) {
2193 Loc = ECE->getLParenLoc();
2194 EndLoc = ECE->getRParenLoc();
2196 Loc = E->getLocStart();
2197 EndLoc = E->getLocEnd();
2205 const char *startRef =
nullptr, *endRef =
nullptr;
2206 if (scanForProtocolRefs(startBuf, endBuf, startRef, endRef)) {
2211 InsertText(LessLoc,
"/*");
2212 InsertText(GreaterLoc,
"*/");
2217 void RewriteModernObjC::RewriteObjCQualifiedInterfaceTypes(
Decl *Dcl) {
2221 if (
VarDecl *VD = dyn_cast<VarDecl>(Dcl)) {
2225 else if (
FunctionDecl *FD = dyn_cast<FunctionDecl>(Dcl)) {
2230 assert(funcType &&
"missing function type");
2236 else if (
FieldDecl *FD = dyn_cast<FieldDecl>(Dcl)) {
2241 Loc = TD->getLocation();
2242 Type = TD->getUnderlyingType();
2247 if (needToScanForQualifiers(Type)) {
2251 const char *startBuf = endBuf;
2252 while (*startBuf !=
';' && *startBuf !=
'<' && startBuf != MainFileStart)
2254 const char *startRef =
nullptr, *endRef =
nullptr;
2255 if (scanForProtocolRefs(startBuf, endBuf, startRef, endRef)) {
2260 InsertText(LessLoc,
"/*");
2261 InsertText(GreaterLoc,
"*/");
2268 const char *startFuncBuf = startBuf;
2273 const char *endBuf = startBuf;
2275 scanToNextArgument(endBuf);
2276 const char *startRef =
nullptr, *endRef =
nullptr;
2277 if (scanForProtocolRefs(startBuf, endBuf, startRef, endRef)) {
2284 InsertText(LessLoc,
"/*");
2285 InsertText(GreaterLoc,
"*/");
2287 startBuf = ++endBuf;
2292 while (*startBuf && *startBuf !=
')' && *startBuf !=
',')
2299 void RewriteModernObjC::RewriteTypeOfDecl(
VarDecl *ND) {
2301 const Type* TypePtr = QT->
getAs<Type>();
2302 if (!isa<TypeOfExprType>(TypePtr))
2304 while (isa<TypeOfExprType>(TypePtr)) {
2305 const TypeOfExprType *TypeOfExprTypePtr = cast<TypeOfExprType>(TypePtr);
2307 TypePtr = QT->
getAs<Type>();
2316 TypeAsString +=
" " + Name +
" = ";
2320 startLoc = ECE->getLParenLoc();
2322 startLoc = E->getLocStart();
2325 ReplaceText(DeclLoc, endBuf-startBuf-1, TypeAsString);
2331 ReplaceText(DeclLoc, endBuf-startBuf-1, TypeAsString);
2336 void RewriteModernObjC::SynthSelGetUidFunctionDecl() {
2338 SmallVector<QualType, 16> ArgTys;
2345 SelGetUidIdent, getFuncType,
2349 void RewriteModernObjC::RewriteFunctionDecl(
FunctionDecl *FD) {
2352 FD->
getName() ==
"sel_registerName") {
2353 SelGetUidFunctionDecl = FD;
2356 RewriteObjCQualifiedInterfaceTypes(FD);
2359 void RewriteModernObjC::RewriteBlockPointerType(std::string& Str,
QualType Type) {
2361 const char *argPtr = TypeString.c_str();
2362 if (!strchr(argPtr,
'^')) {
2367 Str += (*argPtr ==
'^' ?
'*' : *argPtr);
2373 void RewriteModernObjC::RewriteBlockPointerTypeVariable(std::string& Str,
2377 const char *argPtr = TypeString.c_str();
2402 void RewriteModernObjC::RewriteBlockLiteralFunctionDecl(
FunctionDecl *FD) {
2408 QualType Type = proto->getReturnType();
2413 unsigned numArgs = proto->getNumParams();
2414 for (
unsigned i = 0; i < numArgs; i++) {
2415 QualType ArgType = proto->getParamType(i);
2416 RewriteBlockPointerType(FdStr, ArgType);
2421 FdStr += (numArgs > 0) ?
", ...);\n" :
"...);\n";
2425 InsertText(FunLocStart, FdStr);
2429 void RewriteModernObjC::SynthSuperConstructorFunctionDecl() {
2430 if (SuperConstructorFunctionDecl)
2433 SmallVector<QualType, 16> ArgTys;
2435 assert(!argT.
isNull() &&
"Can't find 'id' type");
2436 ArgTys.push_back(argT);
2437 ArgTys.push_back(argT);
2443 msgSendIdent, msgSendType,
2448 void RewriteModernObjC::SynthMsgSendFunctionDecl() {
2450 SmallVector<QualType, 16> ArgTys;
2452 assert(!argT.
isNull() &&
"Can't find 'id' type");
2453 ArgTys.push_back(argT);
2455 assert(!argT.
isNull() &&
"Can't find 'SEL' type");
2456 ArgTys.push_back(argT);
2462 msgSendIdent, msgSendType,
nullptr,
2467 void RewriteModernObjC::SynthMsgSendSuperFunctionDecl() {
2469 SmallVector<QualType, 2> ArgTys;
2476 msgSendIdent, msgSendType,
2481 void RewriteModernObjC::SynthMsgSendStretFunctionDecl() {
2483 SmallVector<QualType, 16> ArgTys;
2485 assert(!argT.
isNull() &&
"Can't find 'id' type");
2486 ArgTys.push_back(argT);
2488 assert(!argT.
isNull() &&
"Can't find 'SEL' type");
2489 ArgTys.push_back(argT);
2495 msgSendIdent, msgSendType,
2501 void RewriteModernObjC::SynthMsgSendSuperStretFunctionDecl() {
2504 SmallVector<QualType, 2> ArgTys;
2512 msgSendType,
nullptr,
2517 void RewriteModernObjC::SynthMsgSendFpretFunctionDecl() {
2519 SmallVector<QualType, 16> ArgTys;
2521 assert(!argT.
isNull() &&
"Can't find 'id' type");
2522 ArgTys.push_back(argT);
2524 assert(!argT.
isNull() &&
"Can't find 'SEL' type");
2525 ArgTys.push_back(argT);
2531 msgSendIdent, msgSendType,
2536 void RewriteModernObjC::SynthGetClassFunctionDecl() {
2538 SmallVector<QualType, 16> ArgTys;
2545 getClassIdent, getClassType,
2550 void RewriteModernObjC::SynthGetSuperClassFunctionDecl() {
2553 SmallVector<QualType, 16> ArgTys;
2561 getClassType,
nullptr,
2566 void RewriteModernObjC::SynthGetMetaClassFunctionDecl() {
2568 SmallVector<QualType, 16> ArgTys;
2575 getClassIdent, getClassType,
2580 assert (Exp !=
nullptr &&
"Expected non-null ObjCStringLiteral");
2581 QualType strType = getConstantStringStructType();
2583 std::string S =
"__NSConstantStringImpl_";
2585 std::string tmpName = InFileName;
2587 for (i=0; i < tmpName.length(); i++) {
2588 char c = tmpName.at(i);
2595 S += utostr(NumObjCStringLiterals++);
2597 Preamble +=
"static __NSConstantStringImpl " +
S;
2598 Preamble +=
" __attribute__ ((section (\"__DATA, __cfstring\"))) = {__CFConstantStringClassReference,";
2599 Preamble +=
"0x000007c8,";
2601 std::string prettyBufS;
2602 llvm::raw_string_ostream prettyBuf(prettyBufS);
2604 Preamble += prettyBuf.str();
2620 ReplaceStmt(Exp, cast);
2630 llvm::APInt(IntSize, Exp->
getValue()),
2636 ReplaceStmt(Exp, PE);
2642 if (!SelGetUidFunctionDecl)
2643 SynthSelGetUidFunctionDecl();
2645 if (!MsgSendFunctionDecl)
2646 SynthMsgSendFunctionDecl();
2647 if (!GetClassFunctionDecl)
2648 SynthGetClassFunctionDecl();
2655 SmallVector<Expr*, 4> MsgExprs;
2656 SmallVector<Expr*, 4> ClsExprs;
2663 ClsExprs.push_back(getStringLiteral(clsName->
getName()));
2664 CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl, ClsExprs,
2666 MsgExprs.push_back(Cls);
2670 SmallVector<Expr*, 4> SelExprs;
2673 CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl,
2674 SelExprs, StartLoc, EndLoc);
2675 MsgExprs.push_back(SelExp);
2685 subExpr = NoTypeInfoCStyleCastExpr(
Context, type, CK, subExpr);
2687 MsgExprs.push_back(subExpr);
2689 SmallVector<QualType, 4> ArgTypes;
2692 for (
const auto PI : BoxingMethod->
parameters())
2693 ArgTypes.push_back(PI->getType());
2709 getSimpleFunctionType(returnType, ArgTypes, BoxingMethod->
isVariadic());
2720 ReplaceStmt(Exp, CE);
2726 if (!SelGetUidFunctionDecl)
2727 SynthSelGetUidFunctionDecl();
2729 if (!MsgSendFunctionDecl)
2730 SynthMsgSendFunctionDecl();
2731 if (!GetClassFunctionDecl)
2732 SynthGetClassFunctionDecl();
2742 std::string NSArrayFName(
"__NSContainer_literal");
2743 FunctionDecl *NSArrayFD = SynthBlockInitFunctionDecl(NSArrayFName);
2748 SmallVector<Expr*, 16> InitExprs;
2750 unsigned UnsignedIntSize =
2753 llvm::APInt(UnsignedIntSize, NumElements),
2755 InitExprs.push_back(count);
2756 for (
unsigned i = 0; i < NumElements; i++)
2758 Expr *NSArrayCallExpr =
2773 NoTypeInfoCStyleCastExpr(
Context,
2779 SmallVector<Expr*, 32> MsgExprs;
2780 SmallVector<Expr*, 4> ClsExprs;
2788 ClsExprs.push_back(getStringLiteral(clsName->
getName()));
2789 CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl, ClsExprs,
2791 MsgExprs.push_back(Cls);
2795 SmallVector<Expr*, 4> SelExprs;
2799 CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl,
2800 SelExprs, StartLoc, EndLoc);
2801 MsgExprs.push_back(SelExp);
2804 MsgExprs.push_back(ArrayLiteralObjects);
2808 llvm::APInt(UnsignedIntSize, NumElements),
2810 MsgExprs.push_back(cnt);
2813 SmallVector<QualType, 4> ArgTypes;
2816 for (
const auto *PI : ArrayMethod->
params())
2817 ArgTypes.push_back(PI->getType());
2833 getSimpleFunctionType(returnType, ArgTypes, ArrayMethod->
isVariadic());
2844 ReplaceStmt(Exp, CE);
2850 if (!SelGetUidFunctionDecl)
2851 SynthSelGetUidFunctionDecl();
2853 if (!MsgSendFunctionDecl)
2854 SynthMsgSendFunctionDecl();
2855 if (!GetClassFunctionDecl)
2856 SynthGetClassFunctionDecl();
2866 std::string NSDictFName(
"__NSContainer_literal");
2867 FunctionDecl *NSDictFD = SynthBlockInitFunctionDecl(NSDictFName);
2872 SmallVector<Expr*, 16> KeyExprs;
2873 SmallVector<Expr*, 16> ValueExprs;
2876 unsigned UnsignedIntSize =
2879 llvm::APInt(UnsignedIntSize, NumElements),
2881 KeyExprs.push_back(count);
2882 ValueExprs.push_back(count);
2883 for (
unsigned i = 0; i < NumElements; i++) {
2885 KeyExprs.push_back(Element.
Key);
2886 ValueExprs.push_back(Element.
Value);
2890 Expr *NSValueCallExpr =
2905 NoTypeInfoCStyleCastExpr(
Context,
2908 DictLiteralValueME);
2910 Expr *NSKeyCallExpr =
2919 NoTypeInfoCStyleCastExpr(
Context,
2927 SmallVector<Expr*, 32> MsgExprs;
2928 SmallVector<Expr*, 4> ClsExprs;
2936 ClsExprs.push_back(getStringLiteral(clsName->
getName()));
2937 CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl, ClsExprs,
2939 MsgExprs.push_back(Cls);
2943 SmallVector<Expr*, 4> SelExprs;
2946 CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl,
2947 SelExprs, StartLoc, EndLoc);
2948 MsgExprs.push_back(SelExp);
2951 MsgExprs.push_back(DictValueObjects);
2954 MsgExprs.push_back(DictKeyObjects);
2958 llvm::APInt(UnsignedIntSize, NumElements),
2960 MsgExprs.push_back(cnt);
2963 SmallVector<QualType, 8> ArgTypes;
2966 for (
const auto *PI : DictMethod->
params()) {
2970 convertToUnqualifiedObjCType(PointeeTy);
2973 ArgTypes.push_back(T);
2990 getSimpleFunctionType(returnType, ArgTypes, DictMethod->
isVariadic());
3001 ReplaceStmt(Exp, CE);
3008 QualType RewriteModernObjC::getSuperStructType() {
3009 if (!SuperStructDecl) {
3021 for (
unsigned i = 0; i < 2; ++i) {
3025 FieldTypes[i],
nullptr,
3031 SuperStructDecl->completeDefinition();
3036 QualType RewriteModernObjC::getConstantStringStructType() {
3037 if (!ConstantStringDecl) {
3053 for (
unsigned i = 0; i < 4; ++i) {
3058 FieldTypes[i],
nullptr,
3064 ConstantStringDecl->completeDefinition();
3072 static SourceLocation getFunctionSourceLocation (RewriteModernObjC &R,
3082 R.RewriteBlockLiteralFunctionDecl(FD);
3086 void RewriteModernObjC::RewriteLineDirective(
const Decl *D) {
3090 if (Location.
isFileID() && GenerateLineInfo) {
3091 std::string LineString(
"\n#line ");
3093 LineString += utostr(PLoc.
getLine());
3094 LineString +=
" \"";
3095 LineString += Lexer::Stringify(PLoc.
getFilename());
3096 if (isa<ObjCMethodDecl>(D))
3098 else LineString +=
"\"\n";
3101 if (
const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
3110 InsertText(Location, LineString);
3124 Expr *RewriteModernObjC::SynthMsgSendStretCallExpr(
FunctionDecl *MsgSendStretFlavor,
3126 SmallVectorImpl<QualType> &ArgTypes,
3127 SmallVectorImpl<Expr*> &MsgExprs,
3130 QualType castType = getSimpleFunctionType(returnType, ArgTypes,
3136 static unsigned stretCount=0;
3137 std::string name =
"__Stret"; name += utostr(stretCount);
3139 "extern \"C\" void * __cdecl memset(void *_Dst, int _Val, size_t _Size);\n";
3140 str +=
"namespace {\n";
3141 str +=
"struct "; str += name;
3144 str +=
"(id receiver, SEL sel";
3145 for (
unsigned i = 2; i < ArgTypes.size(); i++) {
3146 std::string ArgName =
"arg"; ArgName += utostr(i);
3148 str +=
", "; str += ArgName;
3151 for (
unsigned i = ArgTypes.size(); i < MsgExprs.size(); i++) {
3152 std::string ArgName =
"arg"; ArgName += utostr(i);
3153 MsgExprs[i]->getType().getAsStringInternal(ArgName,
3155 str +=
", "; str += ArgName;
3159 str +=
"\t unsigned size = sizeof(";
3162 str +=
"\t if (size == 1 || size == 2 || size == 4 || size == 8)\n";
3165 str +=
")(void *)objc_msgSend)(receiver, sel";
3166 for (
unsigned i = 2; i < ArgTypes.size(); i++) {
3167 str +=
", arg"; str += utostr(i);
3170 for (
unsigned i = ArgTypes.size(); i < MsgExprs.size(); i++) {
3171 str +=
", arg"; str += utostr(i);
3175 str +=
"\t else if (receiver == 0)\n";
3176 str +=
"\t memset((void*)&s, 0, sizeof(s));\n";
3181 str +=
")(void *)objc_msgSend_stret)(receiver, sel";
3182 for (
unsigned i = 2; i < ArgTypes.size(); i++) {
3183 str +=
", arg"; str += utostr(i);
3186 for (
unsigned i = ArgTypes.size(); i < MsgExprs.size(); i++) {
3187 str +=
", arg"; str += utostr(i);
3195 str +=
"};\n};\n\n";
3198 FunLocStart = getFunctionSourceLocation(*
this, CurFunctionDef);
3200 assert(CurMethodDef &&
"SynthMsgSendStretCallExpr - CurMethodDef is null");
3201 FunLocStart = CurMethodDef->getLocStart();
3204 InsertText(FunLocStart, str);
3220 returnType,
nullptr,
3233 if (!SelGetUidFunctionDecl)
3234 SynthSelGetUidFunctionDecl();
3235 if (!MsgSendFunctionDecl)
3236 SynthMsgSendFunctionDecl();
3237 if (!MsgSendSuperFunctionDecl)
3238 SynthMsgSendSuperFunctionDecl();
3239 if (!MsgSendStretFunctionDecl)
3240 SynthMsgSendStretFunctionDecl();
3241 if (!MsgSendSuperStretFunctionDecl)
3242 SynthMsgSendSuperStretFunctionDecl();
3243 if (!MsgSendFpretFunctionDecl)
3244 SynthMsgSendFpretFunctionDecl();
3245 if (!GetClassFunctionDecl)
3246 SynthGetClassFunctionDecl();
3247 if (!GetSuperClassFunctionDecl)
3248 SynthGetSuperClassFunctionDecl();
3249 if (!GetMetaClassFunctionDecl)
3250 SynthGetMetaClassFunctionDecl();
3257 QualType resultType = mDecl->getReturnType();
3259 MsgSendStretFlavor = MsgSendStretFunctionDecl;
3261 MsgSendFlavor = MsgSendFpretFunctionDecl;
3265 SmallVector<Expr*, 8> MsgExprs;
3267 case ObjCMessageExpr::SuperClass: {
3268 MsgSendFlavor = MsgSendSuperFunctionDecl;
3269 if (MsgSendStretFlavor)
3270 MsgSendStretFlavor = MsgSendSuperStretFunctionDecl;
3271 assert(MsgSendFlavor &&
"MsgSendFlavor is NULL!");
3275 SmallVector<Expr*, 4> InitExprs;
3278 InitExprs.push_back(
3289 SmallVector<Expr*, 8> ClsExprs;
3292 CallExpr *Cls = SynthesizeCallToFunctionDecl(GetMetaClassFunctionDecl,
3293 ClsExprs, StartLoc, EndLoc);
3295 ClsExprs.push_back(Cls);
3296 Cls = SynthesizeCallToFunctionDecl(GetSuperClassFunctionDecl, ClsExprs,
3301 InitExprs.push_back(
3302 NoTypeInfoCStyleCastExpr(
Context,
3306 QualType superType = getSuperStructType();
3309 if (LangOpts.MicrosoftExt) {
3310 SynthSuperConstructorFunctionDecl();
3328 SuperRep = NoTypeInfoCStyleCastExpr(
Context,
3347 MsgExprs.push_back(SuperRep);
3351 case ObjCMessageExpr::Class: {
3352 SmallVector<Expr*, 8> ClsExprs;
3356 ClsExprs.push_back(getStringLiteral(clsName->
getName()));
3357 CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl, ClsExprs,
3362 MsgExprs.push_back(ArgExpr);
3366 case ObjCMessageExpr::SuperInstance:{
3367 MsgSendFlavor = MsgSendSuperFunctionDecl;
3368 if (MsgSendStretFlavor)
3369 MsgSendStretFlavor = MsgSendSuperStretFunctionDecl;
3370 assert(MsgSendFlavor &&
"MsgSendFlavor is NULL!");
3372 SmallVector<Expr*, 4> InitExprs;
3374 InitExprs.push_back(
3384 SmallVector<Expr*, 8> ClsExprs;
3387 CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl, ClsExprs,
3390 ClsExprs.push_back(Cls);
3391 Cls = SynthesizeCallToFunctionDecl(GetSuperClassFunctionDecl, ClsExprs,
3396 InitExprs.push_back(
3401 QualType superType = getSuperStructType();
3404 if (LangOpts.MicrosoftExt) {
3405 SynthSuperConstructorFunctionDecl();
3408 false, superType, VK_LValue,
3422 SuperRep = NoTypeInfoCStyleCastExpr(
Context,
3436 MsgExprs.push_back(SuperRep);
3440 case ObjCMessageExpr::Instance: {
3445 recExpr = CE->getSubExpr();
3453 MsgExprs.push_back(recExpr);
3459 SmallVector<Expr*, 8> SelExprs;
3461 CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl,
3462 SelExprs, StartLoc, EndLoc);
3463 MsgExprs.push_back(SelExp);
3466 for (
unsigned i = 0; i < Exp->
getNumArgs(); i++) {
3472 if (needToScanForQualifiers(type))
3475 (void)convertBlockPointerToFunctionPointer(type);
3493 userExpr = NoTypeInfoCStyleCastExpr(
Context, type, CK, userExpr);
3496 else if (
CStyleCastExpr *CE = dyn_cast<CStyleCastExpr>(userExpr)) {
3497 if (CE->getType()->isObjCQualifiedIdType()) {
3498 while ((CE = dyn_cast<CStyleCastExpr>(userExpr)))
3499 userExpr = CE->getSubExpr();
3514 MsgExprs.push_back(userExpr);
3522 SmallVector<QualType, 8> ArgTypes;
3526 if (MsgSendFlavor == MsgSendSuperFunctionDecl)
3533 for (
const auto *PI : OMD->
params()) {
3538 (void)convertBlockPointerToFunctionPointer(t);
3539 ArgTypes.push_back(t);
3542 convertToUnqualifiedObjCType(returnType);
3543 (void)convertBlockPointerToFunctionPointer(returnType);
3558 cast = NoTypeInfoCStyleCastExpr(
Context,
3566 getSimpleFunctionType(returnType, ArgTypes, MD ? MD->isVariadic() :
true);
3577 Stmt *ReplacingStmt = CE;
3578 if (MsgSendStretFlavor) {
3584 Expr *STCE = SynthMsgSendStretCallExpr(MsgSendStretFlavor,
3588 ReplacingStmt = STCE;
3591 return ReplacingStmt;
3599 ReplaceStmt(Exp, ReplacingStmt);
3602 return ReplacingStmt;
3606 QualType RewriteModernObjC::getProtocolType() {
3607 if (!ProtocolTypeDecl) {
3623 std::string Name =
"_OBJC_PROTOCOL_REFERENCE_$_" +
3632 NoTypeInfoCStyleCastExpr(
3634 ReplaceStmt(Exp, castExpr);
3641 bool RewriteModernObjC::BufferContainsPPDirectives(
const char *startBuf,
3642 const char *endBuf) {
3643 while (startBuf < endBuf) {
3644 if (*startBuf ==
'#') {
3646 for (++startBuf; startBuf[0] ==
' ' || startBuf[0] ==
'\t'; ++startBuf)
3648 if (!strncmp(startBuf,
"if", strlen(
"if")) ||
3649 !strncmp(startBuf,
"ifdef", strlen(
"ifdef")) ||
3650 !strncmp(startBuf,
"ifndef", strlen(
"ifndef")) ||
3651 !strncmp(startBuf,
"define", strlen(
"define")) ||
3652 !strncmp(startBuf,
"undef", strlen(
"undef")) ||
3653 !strncmp(startBuf,
"else", strlen(
"else")) ||
3654 !strncmp(startBuf,
"elif", strlen(
"elif")) ||
3655 !strncmp(startBuf,
"endif", strlen(
"endif")) ||
3656 !strncmp(startBuf,
"pragma", strlen(
"pragma")) ||
3657 !strncmp(startBuf,
"include", strlen(
"include")) ||
3658 !strncmp(startBuf,
"import", strlen(
"import")) ||
3659 !strncmp(startBuf,
"include_next", strlen(
"include_next")))
3671 bool &IsNamedDefinition) {
3675 if (
RecordDecl *RD = dyn_cast<RecordDecl>(Tag)) {
3679 IsNamedDefinition =
true;
3684 if (
EnumDecl *ED = dyn_cast<EnumDecl>(Tag)) {
3685 if (!ED || !ED->getDeclName().getAsIdentifierInfo())
3687 IsNamedDefinition =
true;
3688 TagLocation = ED->getLocation();
3698 bool RewriteModernObjC::RewriteObjCFieldDeclType(
QualType &Type,
3699 std::string &Result) {
3700 if (isa<TypedefType>(Type)) {
3707 return RewriteObjCFieldDeclType(ElemTy, Result);
3713 Result +=
"\n\tstruct ";
3715 Result +=
"\n\tunion ";
3717 assert(
false &&
"class not allowed as an ivar type");
3720 if (GlobalDefinedTags.count(RD)) {
3726 for (
auto *FD : RD->
fields())
3727 RewriteObjCFieldDecl(FD, Result);
3735 Result +=
"\n\tenum ";
3737 if (GlobalDefinedTags.count(ED)) {
3745 Result +=
"\t"; Result += EC->getName(); Result +=
" = ";
3746 llvm::APSInt Val = EC->getInitVal();
3747 Result += Val.toString(10);
3756 convertObjCTypeToCStyleType(Type);
3764 std::string &Result) {
3768 bool EleboratedType = RewriteObjCFieldDeclType(Type, Result);
3769 if (!EleboratedType)
3780 llvm::APInt Dim = CAT->getSize();
3781 Result += utostr(Dim.getZExtValue());
3793 void RewriteModernObjC::RewriteLocallyDefinedNamedAggregates(
FieldDecl *fieldDecl,
3794 std::string &Result) {
3796 if (isa<TypedefType>(Type))
3812 if (GlobalDefinedTags.count(TD))
3815 bool IsNamedDefinition =
false;
3816 if (IsTagDefinedInsideClass(IDecl, TD, IsNamedDefinition)) {
3817 RewriteObjCFieldDeclType(Type, Result);
3820 if (IsNamedDefinition)
3821 GlobalDefinedTags.insert(TD);
3826 unsigned RewriteModernObjC::ObjCIvarBitfieldGroupNo(
ObjCIvarDecl *IV) {
3828 if (ObjCInterefaceHasBitfieldGroups.count(CDecl)) {
3829 return IvarGroupNumber[IV];
3831 unsigned GroupNo = 0;
3832 SmallVector<const ObjCIvarDecl *, 8> IVars;
3835 IVars.push_back(IVD);
3837 for (
unsigned i = 0, e = IVars.size(); i < e; i++)
3838 if (IVars[i]->isBitField()) {
3839 IvarGroupNumber[IVars[i++]] = ++GroupNo;
3840 while (i < e && IVars[i]->isBitField())
3841 IvarGroupNumber[IVars[i++]] = GroupNo;
3846 ObjCInterefaceHasBitfieldGroups.insert(CDecl);
3847 return IvarGroupNumber[IV];
3850 QualType RewriteModernObjC::SynthesizeBitfieldGroupStructType(
3852 SmallVectorImpl<ObjCIvarDecl *> &IVars) {
3853 std::string StructTagName;
3854 ObjCIvarBitfieldGroupType(IV, StructTagName);
3859 for (
unsigned i=0, e = IVars.size(); i < e; i++) {
3873 unsigned GroupNo = ObjCIvarBitfieldGroupNo(IV);
3874 std::pair<const ObjCInterfaceDecl*, unsigned> tuple = std::make_pair(CDecl, GroupNo);
3875 if (GroupRecordType.count(tuple))
3876 return GroupRecordType[tuple];
3878 SmallVector<ObjCIvarDecl *, 8> IVars;
3881 if (IVD->isBitField())
3882 IVars.push_back(const_cast<ObjCIvarDecl *>(IVD));
3884 if (!IVars.empty()) {
3885 unsigned GroupNo = ObjCIvarBitfieldGroupNo(IVars[0]);
3887 GroupRecordType[std::make_pair(CDecl, GroupNo)] =
3888 SynthesizeBitfieldGroupStructType(IVars[0], IVars);
3893 if (!IVars.empty()) {
3895 unsigned GroupNo = ObjCIvarBitfieldGroupNo(IVars[0]);
3896 GroupRecordType[std::make_pair(CDecl, GroupNo)] =
3897 SynthesizeBitfieldGroupStructType(IVars[0], IVars);
3899 QualType RetQT = GroupRecordType[tuple];
3900 assert(!RetQT.
isNull() &&
"GetGroupRecordTypeForObjCIvarBitfield struct type is NULL");
3907 void RewriteModernObjC::ObjCIvarBitfieldGroupDecl(
ObjCIvarDecl *IV,
3908 std::string &Result) {
3911 Result +=
"__GRBF_";
3912 unsigned GroupNo = ObjCIvarBitfieldGroupNo(IV);
3913 Result += utostr(GroupNo);
3920 void RewriteModernObjC::ObjCIvarBitfieldGroupType(
ObjCIvarDecl *IV,
3921 std::string &Result) {
3925 unsigned GroupNo = ObjCIvarBitfieldGroupNo(IV);
3926 Result += utostr(GroupNo);
3933 void RewriteModernObjC::ObjCIvarBitfieldGroupOffset(
ObjCIvarDecl *IV,
3934 std::string &Result) {
3935 Result +=
"OBJC_IVAR_$_";
3936 ObjCIvarBitfieldGroupDecl(IV, Result);
3939 #define SKIP_BITFIELDS(IX, ENDIX, VEC) { \
3940 while ((IX < ENDIX) && VEC[IX]->isBitField()) \
3949 std::string &Result) {
3950 assert(CDecl &&
"Class missing in SynthesizeObjCInternalStruct");
3951 assert(CDecl->
getName() !=
"" &&
3952 "Name missing in SynthesizeObjCInternalStruct");
3954 SmallVector<ObjCIvarDecl *, 8> IVars;
3957 IVars.push_back(IVD);
3968 (!RCDecl || !ObjCSynthesizedStructs.count(RCDecl))) {
3969 endBuf += Lexer::MeasureTokenLength(LocEnd, *
SM, LangOpts);
3970 ReplaceText(LocStart, endBuf-startBuf, Result);
3977 for (
unsigned i = 0, e = IVars.size(); i < e; i++)
3978 RewriteLocallyDefinedNamedAggregates(IVars[i], Result);
3982 for (
unsigned i = 0, e = IVars.size(); i < e; i++)
3983 if (IVars[i]->isBitField()) {
3985 QualType QT = GetGroupRecordTypeForObjCIvarBitfield(IV);
3986 RewriteObjCFieldDeclType(QT, Result);
3989 SKIP_BITFIELDS(i , e, IVars);
3992 Result +=
"\nstruct ";
3994 Result +=
"_IMPL {\n";
3996 if (RCDecl && ObjCSynthesizedStructs.count(RCDecl)) {
3997 Result +=
"\tstruct "; Result += RCDecl->getNameAsString();
3998 Result +=
"_IMPL "; Result += RCDecl->getNameAsString();
3999 Result +=
"_IVARS;\n";
4002 for (
unsigned i = 0, e = IVars.size(); i < e; i++) {
4003 if (IVars[i]->isBitField()) {
4005 Result +=
"\tstruct ";
4006 ObjCIvarBitfieldGroupType(IV, Result); Result +=
" ";
4007 ObjCIvarBitfieldGroupDecl(IV, Result); Result +=
";\n";
4009 SKIP_BITFIELDS(i , e, IVars);
4012 RewriteObjCFieldDecl(IVars[i], Result);
4016 endBuf += Lexer::MeasureTokenLength(LocEnd, *
SM, LangOpts);
4017 ReplaceText(LocStart, endBuf-startBuf, Result);
4019 if (!ObjCSynthesizedStructs.insert(CDecl).second)
4020 llvm_unreachable(
"struct already synthesize- RewriteObjCInternalStruct");
4026 std::string &Result) {
4029 llvm::SmallPtrSet<ObjCIvarDecl *, 8> Ivars = ReferencedIvars[CDecl];
4036 unsigned GroupNo = 0;
4038 GroupNo = ObjCIvarBitfieldGroupNo(IvarDecl);
4039 if (GroupSymbolOutput.count(std::make_pair(IDecl, GroupNo)))
4043 if (LangOpts.MicrosoftExt)
4044 Result +=
"__declspec(allocate(\".objc_ivar$B\")) ";
4045 Result +=
"extern \"C\" ";
4046 if (LangOpts.MicrosoftExt &&
4049 Result +=
"__declspec(dllimport) ";
4051 Result +=
"unsigned long ";
4053 ObjCIvarBitfieldGroupOffset(IvarDecl, Result);
4054 GroupSymbolOutput.insert(std::make_pair(IDecl, GroupNo));
4057 WriteInternalIvarName(CDecl, IvarDecl, Result);
4070 void RewriteModernObjC::RewriteImplementations() {
4071 int ClsDefCount = ClassImplementation.size();
4072 int CatDefCount = CategoryImplementation.size();
4075 for (
int i = 0; i < ClsDefCount; i++) {
4080 "Legacy implicit interface rewriting not supported in moder abi");
4081 RewriteImplementationDecl(OIMP);
4084 for (
int i = 0; i < CatDefCount; i++) {
4089 "Legacy implicit interface rewriting not supported in moder abi");
4090 RewriteImplementationDecl(CIMP);
4094 void RewriteModernObjC::RewriteByRefString(std::string &ResultStr,
4095 const std::string &Name,
4097 assert(BlockByRefDeclNo.count(VD) &&
4098 "RewriteByRefString: ByRef decl missing");
4100 ResultStr +=
"struct ";
4101 ResultStr +=
"__Block_byref_" + Name +
4102 "_" + utostr(BlockByRefDeclNo[VD]) ;
4105 static bool HasLocalVariableExternalStorage(
ValueDecl *VD) {
4106 if (
VarDecl *Var = dyn_cast<VarDecl>(VD))
4107 return (Var->isFunctionOrMethodVarDecl() && !Var->hasLocalStorage());
4111 std::string RewriteModernObjC::SynthesizeBlockFunc(
BlockExpr *CE,
int i,
4116 std::string StructRef =
"struct " + Tag;
4119 ConvertSourceLocationToLineDirective(BlockLoc, S);
4122 funcName.str() +
"_block_func_" + utostr(i);
4126 if (isa<FunctionNoProtoType>(AFT)) {
4129 S +=
"(" + StructRef +
" *__cself)";
4131 S +=
"(" + StructRef +
" *__cself)";
4134 assert(FT &&
"SynthesizeBlockFunc: No function proto");
4137 S += StructRef +
" *__cself, ";
4138 std::string ParamStr;
4142 ParamStr = (*AI)->getNameAsString();
4144 (void)convertBlockPointerToFunctionPointer(QT);
4159 E = BlockByRefDecls.end(); I !=
E; ++
I) {
4161 std::string Name = (*I)->getNameAsString();
4162 std::string TypeString;
4163 RewriteByRefString(TypeString, Name, (*I));
4165 Name = TypeString +
Name;
4166 S += Name +
" = __cself->" + (*I)->getNameAsString() +
"; // bound by ref\n";
4170 E = BlockByCopyDecls.end(); I !=
E; ++
I) {
4182 if (isTopLevelBlockPointerType((*I)->getType())) {
4183 RewriteBlockPointerTypeVariable(S, (*I));
4185 RewriteBlockPointerType(S, (*I)->getType());
4187 S +=
"__cself->" + (*I)->getNameAsString() +
"; // bound by copy\n";
4190 std::string Name = (*I)->getNameAsString();
4192 if (HasLocalVariableExternalStorage(*I))
4195 S += Name +
" = __cself->" +
4196 (*I)->getNameAsString() +
"; // bound by copy\n";
4199 std::string RewrittenStr = RewrittenBlockExprs[CE];
4200 const char *cstr = RewrittenStr.c_str();
4201 while (*cstr++ !=
'{') ;
4207 std::string RewriteModernObjC::SynthesizeBlockHelperFuncs(
BlockExpr *CE,
int i,
4210 std::string StructRef =
"struct " + Tag;
4211 std::string S =
"static void __";
4214 S +=
"_block_copy_" + utostr(i);
4215 S +=
"(" + StructRef;
4216 S +=
"*dst, " + StructRef;
4218 for (
ValueDecl *VD : ImportedBlockDecls) {
4219 S +=
"_Block_object_assign((void*)&dst->";
4221 S +=
", (void*)src->";
4223 if (BlockByRefDeclsPtrSet.count(VD))
4232 S +=
"\nstatic void __";
4234 S +=
"_block_dispose_" + utostr(i);
4235 S +=
"(" + StructRef;
4237 for (
ValueDecl *VD : ImportedBlockDecls) {
4238 S +=
"_Block_object_dispose((void*)src->";
4240 if (BlockByRefDeclsPtrSet.count(VD))
4251 std::string RewriteModernObjC::SynthesizeBlockImpl(
BlockExpr *CE, std::string Tag,
4253 std::string S =
"\nstruct " + Tag;
4254 std::string Constructor =
" " + Tag;
4256 S +=
" {\n struct __block_impl impl;\n";
4257 S +=
" struct " + Desc;
4260 Constructor +=
"(void *fp, ";
4261 Constructor +=
"struct " + Desc;
4262 Constructor +=
" *desc";
4264 if (BlockDeclRefs.size()) {
4267 E = BlockByCopyDecls.end(); I !=
E; ++
I) {
4269 std::string FieldName = (*I)->getNameAsString();
4270 std::string ArgName =
"_" + FieldName;
4281 if (isTopLevelBlockPointerType((*I)->getType())) {
4282 S +=
"struct __block_impl *";
4283 Constructor +=
", void *" + ArgName;
4286 if (HasLocalVariableExternalStorage(*I))
4290 Constructor +=
", " + ArgName;
4292 S += FieldName +
";\n";
4296 E = BlockByRefDecls.end(); I !=
E; ++
I) {
4298 std::string FieldName = (*I)->getNameAsString();
4299 std::string ArgName =
"_" + FieldName;
4301 std::string TypeString;
4302 RewriteByRefString(TypeString, FieldName, (*I));
4304 FieldName = TypeString + FieldName;
4305 ArgName = TypeString + ArgName;
4306 Constructor +=
", " + ArgName;
4308 S += FieldName +
"; // by ref\n";
4311 Constructor +=
", int flags=0)";
4313 bool firsTime =
true;
4315 E = BlockByCopyDecls.end(); I !=
E; ++
I) {
4316 std::string Name = (*I)->getNameAsString();
4318 Constructor +=
" : ";
4322 Constructor +=
", ";
4323 if (isTopLevelBlockPointerType((*I)->getType()))
4324 Constructor += Name +
"((struct __block_impl *)_" + Name +
")";
4326 Constructor += Name +
"(_" + Name +
")";
4330 E = BlockByRefDecls.end(); I !=
E; ++
I) {
4331 std::string Name = (*I)->getNameAsString();
4333 Constructor +=
" : ";
4337 Constructor +=
", ";
4338 Constructor += Name +
"(_" + Name +
"->__forwarding)";
4341 Constructor +=
" {\n";
4343 Constructor +=
" impl.isa = &_NSConcreteGlobalBlock;\n";
4345 Constructor +=
" impl.isa = &_NSConcreteStackBlock;\n";
4346 Constructor +=
" impl.Flags = flags;\n impl.FuncPtr = fp;\n";
4348 Constructor +=
" Desc = desc;\n";
4351 Constructor +=
", int flags=0) {\n";
4353 Constructor +=
" impl.isa = &_NSConcreteGlobalBlock;\n";
4355 Constructor +=
" impl.isa = &_NSConcreteStackBlock;\n";
4356 Constructor +=
" impl.Flags = flags;\n impl.FuncPtr = fp;\n";
4357 Constructor +=
" Desc = desc;\n";
4360 Constructor +=
"}\n";
4366 std::string RewriteModernObjC::SynthesizeBlockDescriptor(std::string DescTag,
4367 std::string ImplTag,
int i,
4370 std::string S =
"\nstatic struct " + DescTag;
4372 S +=
" {\n size_t reserved;\n";
4373 S +=
" size_t Block_size;\n";
4375 S +=
" void (*copy)(struct ";
4376 S += ImplTag; S +=
"*, struct ";
4377 S += ImplTag; S +=
"*);\n";
4379 S +=
" void (*dispose)(struct ";
4380 S += ImplTag; S +=
"*);\n";
4384 S += DescTag +
"_DATA = { 0, sizeof(struct ";
4387 S +=
", __" + FunName.str() +
"_block_copy_" + utostr(i);
4388 S +=
", __" + FunName.str() +
"_block_dispose_" + utostr(i);
4394 void RewriteModernObjC::SynthesizeBlockLiterals(
SourceLocation FunLocStart,
4395 StringRef FunName) {
4396 bool RewriteSC = (GlobalVarDecl &&
4398 GlobalVarDecl->getStorageClass() ==
SC_Static &&
4399 GlobalVarDecl->getType().getCVRQualifiers());
4401 std::string SC(
" void __");
4402 SC += GlobalVarDecl->getNameAsString();
4404 InsertText(FunLocStart, SC);
4408 for (
unsigned i = 0, count=0; i < Blocks.size(); i++) {
4409 CollectBlockDeclRefInfo(Blocks[i]);
4412 for (
int j = 0; j < InnerDeclRefsCount[i]; j++) {
4415 BlockDeclRefs.push_back(Exp);
4416 if (!VD->
hasAttr<BlocksAttr>()) {
4417 if (!BlockByCopyDeclsPtrSet.count(VD)) {
4418 BlockByCopyDeclsPtrSet.insert(VD);
4419 BlockByCopyDecls.push_back(VD);
4424 if (!BlockByRefDeclsPtrSet.count(VD)) {
4425 BlockByRefDeclsPtrSet.insert(VD);
4426 BlockByRefDecls.push_back(VD);
4433 ImportedBlockDecls.insert(VD);
4436 std::string ImplTag =
"__" + FunName.str() +
"_block_impl_" + utostr(i);
4437 std::string DescTag =
"__" + FunName.str() +
"_block_desc_" + utostr(i);
4439 std::string CI = SynthesizeBlockImpl(Blocks[i], ImplTag, DescTag);
4441 InsertText(FunLocStart, CI);
4443 std::string CF = SynthesizeBlockFunc(Blocks[i], i, FunName, ImplTag);
4445 InsertText(FunLocStart, CF);
4447 if (ImportedBlockDecls.size()) {
4448 std::string HF = SynthesizeBlockHelperFuncs(Blocks[i], i, FunName, ImplTag);
4449 InsertText(FunLocStart, HF);
4451 std::string BD = SynthesizeBlockDescriptor(DescTag, ImplTag, i, FunName,
4452 ImportedBlockDecls.size() > 0);
4453 InsertText(FunLocStart, BD);
4455 BlockDeclRefs.clear();
4456 BlockByRefDecls.clear();
4457 BlockByRefDeclsPtrSet.clear();
4458 BlockByCopyDecls.clear();
4459 BlockByCopyDeclsPtrSet.clear();
4460 ImportedBlockDecls.clear();
4466 if (GlobalVarDecl->getStorageClass() ==
SC_Static)
4468 if (GlobalVarDecl->getType().isConstQualified())
4470 if (GlobalVarDecl->getType().isVolatileQualified())
4472 if (GlobalVarDecl->getType().isRestrictQualified())
4474 InsertText(FunLocStart, SC);
4476 if (GlobalConstructionExp) {
4480 std::string Tag =
"__";
4482 Tag +=
"_block_impl_";
4483 Tag += utostr(Blocks.size()-1);
4484 std::string globalBuf =
"static ";
4485 globalBuf += Tag; globalBuf +=
" ";
4488 llvm::raw_string_ostream constructorExprBuf(SStr);
4489 GlobalConstructionExp->printPretty(constructorExprBuf,
nullptr,
4491 globalBuf += constructorExprBuf.str();
4493 InsertText(FunLocStart, globalBuf);
4494 GlobalConstructionExp =
nullptr;
4498 InnerDeclRefsCount.clear();
4499 InnerDeclRefs.clear();
4500 RewrittenBlockExprs.clear();
4503 void RewriteModernObjC::InsertBlockLiteralsWithinFunction(
FunctionDecl *FD) {
4505 (!Blocks.empty()) ? getFunctionSourceLocation(*
this, FD)
4507 StringRef FuncName = FD->
getName();
4509 SynthesizeBlockLiterals(FunLocStart, FuncName);
4512 static void BuildUniqueMethodName(std::string &Name,
4518 std::string::size_type loc = 0;
4519 while ((loc = Name.find(
":", loc)) != std::string::npos)
4520 Name.replace(loc, 1,
"_");
4523 void RewriteModernObjC::InsertBlockLiteralsWithinMethod(
ObjCMethodDecl *MD) {
4527 std::string FuncName;
4528 BuildUniqueMethodName(FuncName, MD);
4529 SynthesizeBlockLiterals(FunLocStart, FuncName);
4532 void RewriteModernObjC::GetBlockDeclRefExprs(
Stmt *S) {
4533 for (
Stmt *SubStmt : S->children())
4535 if (
BlockExpr *CBE = dyn_cast<BlockExpr>(SubStmt))
4536 GetBlockDeclRefExprs(CBE->getBody());
4538 GetBlockDeclRefExprs(SubStmt);
4543 HasLocalVariableExternalStorage(DRE->
getDecl()))
4545 BlockDeclRefs.push_back(DRE);
4550 void RewriteModernObjC::GetInnerBlockDeclRefExprs(
Stmt *S,
4551 SmallVectorImpl<DeclRefExpr *> &InnerBlockDeclRefs,
4552 llvm::SmallPtrSetImpl<const DeclContext *> &InnerContexts) {
4553 for (
Stmt *SubStmt : S->children())
4555 if (
BlockExpr *CBE = dyn_cast<BlockExpr>(SubStmt)) {
4556 InnerContexts.insert(cast<DeclContext>(CBE->getBlockDecl()));
4557 GetInnerBlockDeclRefExprs(CBE->getBody(),
4562 GetInnerBlockDeclRefExprs(SubStmt, InnerBlockDeclRefs, InnerContexts);
4565 if (
DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(S)) {
4567 HasLocalVariableExternalStorage(DRE->
getDecl())) {
4569 InnerBlockDeclRefs.push_back(DRE);
4571 if (Var->isFunctionOrMethodVarDecl())
4572 ImportedLocalExternalDecls.insert(Var);
4582 bool RewriteModernObjC::convertObjCTypeToCStyleType(
QualType &T) {
4584 convertBlockPointerToFunctionPointer(T);
4590 T = convertFunctionTypeOfBlocks(FT);
4596 convertToUnqualifiedObjCType(T);
4608 SmallVector<QualType, 8> ArgTypes;
4610 bool modified = convertObjCTypeToCStyleType(Res);
4616 if (convertObjCTypeToCStyleType(t))
4618 ArgTypes.push_back(t);
4623 FuncType = getSimpleFunctionType(Res, ArgTypes);
4628 Stmt *RewriteModernObjC::SynthesizeBlockCall(
CallExpr *Exp,
const Expr *BlockExp) {
4632 if (
const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(BlockExp)) {
4634 }
else if (
const MemberExpr *MExpr = dyn_cast<MemberExpr>(BlockExp)) {
4637 else if (
const ParenExpr *PRE = dyn_cast<ParenExpr>(BlockExp)) {
4638 return SynthesizeBlockCall(Exp, PRE->getSubExpr());
4640 else if (
const ImplicitCastExpr *IEXPR = dyn_cast<ImplicitCastExpr>(BlockExp))
4643 dyn_cast<ConditionalOperator>(BlockExp)) {
4644 Expr *LHSExp = CEXPR->getLHS();
4645 Stmt *LHSStmt = SynthesizeBlockCall(Exp, LHSExp);
4646 Expr *RHSExp = CEXPR->getRHS();
4647 Stmt *RHSStmt = SynthesizeBlockCall(Exp, RHSExp);
4648 Expr *CONDExp = CEXPR->getCond();
4655 }
else if (
const ObjCIvarRefExpr *IRE = dyn_cast<ObjCIvarRefExpr>(BlockExp)) {
4658 = dyn_cast<PseudoObjectExpr>(BlockExp)) {
4661 assert(1 &&
"RewriteBlockClass: Bad type");
4663 assert(CPT &&
"RewriteBlockClass: Bad type");
4665 assert(FT &&
"RewriteBlockClass: Bad type");
4675 SmallVector<QualType, 8> ArgTypes;
4678 ArgTypes.push_back(PtrBlock);
4683 if (!convertBlockPointerToFunctionPointer(t))
4684 convertToUnqualifiedObjCType(t);
4685 ArgTypes.push_back(t);
4689 QualType PtrToFuncCastType = getSimpleFunctionType(Exp->
getType(), ArgTypes);
4695 const_cast<Expr*>(BlockExp));
4711 CastExpr *FunkCast = NoTypeInfoCStyleCastExpr(
Context, PtrToFuncCastType,
4715 SmallVector<Expr*, 8> BlkExprs;
4717 BlkExprs.push_back(BlkCast);
4721 BlkExprs.push_back(*I);
4742 Stmt *RewriteModernObjC::RewriteBlockDeclRefExpr(
DeclRefExpr *DeclRefExp) {
4747 HasLocalVariableExternalStorage(DeclRefExp->
getDecl());
4759 StringRef Name = VD->
getName();
4773 ReplaceStmt(DeclRefExp, PE);
4780 Stmt *RewriteModernObjC::RewriteLocalVariableExternalStorage(
DeclRefExpr *DRE) {
4782 if (
VarDecl *Var = dyn_cast<VarDecl>(VD))
4783 if (!ImportedLocalExternalDecls.count(Var))
4791 ReplaceStmt(DRE, PE);
4803 if (!Rewriter::isRewritable(LocStart) || !Rewriter::isRewritable(LocEnd))
4809 const Type* TypePtr = QT->
getAs<Type>();
4810 if (isa<TypeOfExprType>(TypePtr)) {
4811 const TypeOfExprType *TypeOfExprTypePtr = cast<TypeOfExprType>(TypePtr);
4813 std::string TypeAsString =
"(";
4814 RewriteBlockPointerType(TypeAsString, QT);
4815 TypeAsString +=
")";
4816 ReplaceText(LocStart, endBuf-startBuf+1, TypeAsString);
4820 const char *argPtr = startBuf;
4822 while (*argPtr++ && (argPtr < endBuf)) {
4827 ReplaceText(LocStart, 1,
"*");
4834 void RewriteModernObjC::RewriteImplicitCastObjCExpr(
CastExpr *IC) {
4841 (void)convertBlockPointerToFunctionPointer(QT);
4843 std::string Str =
"(";
4846 InsertText(IC->
getSubExpr()->getLocStart(), Str);
4851 void RewriteModernObjC::RewriteBlockPointerFunctionArgs(
FunctionDecl *FD) {
4853 unsigned parenCount = 0;
4857 const char *startArgList = strchr(startBuf,
'(');
4859 assert((*startArgList ==
'(') &&
"Rewriter fuzzy parser confused");
4864 assert((DeclLoc.
isValid()) &&
"Invalid DeclLoc");
4866 const char *argPtr = startArgList;
4868 while (*argPtr++ && parenCount) {
4873 ReplaceText(DeclLoc, 1,
"*");
4886 bool RewriteModernObjC::PointerTypeTakesAnyBlockArguments(
QualType QT) {
4893 assert(BPT &&
"BlockPointerTypeTakeAnyBlockArguments(): not a block pointer type");
4898 if (isTopLevelBlockPointerType(I))
4904 bool RewriteModernObjC::PointerTypeTakesAnyObjCQualifiedType(
QualType QT) {
4911 assert(BPT &&
"BlockPointerTypeTakeAnyBlockArguments(): not a block pointer type");
4916 if (I->isObjCQualifiedIdType())
4918 if (I->isObjCObjectPointerType() &&
4919 I->getPointeeType()->isObjCQualifiedInterfaceType())
4927 void RewriteModernObjC::GetExtentOfArgList(
const char *Name,
const char *&LParen,
4928 const char *&RParen) {
4929 const char *argPtr = strchr(Name,
'(');
4930 assert((*argPtr ==
'(') &&
"Rewriter fuzzy parser confused");
4934 unsigned parenCount = 1;
4936 while (*argPtr && parenCount) {
4938 case '(': parenCount++;
break;
4939 case ')': parenCount--;
break;
4942 if (parenCount) argPtr++;
4944 assert((*argPtr ==
')') &&
"Rewriter fuzzy parser confused");
4948 void RewriteModernObjC::RewriteBlockPointerDecl(
NamedDecl *ND) {
4950 RewriteBlockPointerFunctionArgs(FD);
4956 if (
VarDecl *VD = dyn_cast<VarDecl>(ND))
4959 DeclT = TDD->getUnderlyingType();
4960 else if (
FieldDecl *FD = dyn_cast<FieldDecl>(ND))
4963 llvm_unreachable(
"RewriteBlockPointerDecl(): Decl type not yet handled");
4966 const char *endBuf = startBuf;
4968 while (*startBuf !=
'^' && *startBuf !=
';' && startBuf != MainFileStart)
4972 unsigned OrigLength=0;
4975 if (*startBuf ==
'^') {
4981 while (*startBuf !=
')') {
4989 if (PointerTypeTakesAnyBlockArguments(DeclT) ||
4990 PointerTypeTakesAnyObjCQualifiedType(DeclT)) {
4995 const char *argListBegin, *argListEnd;
4996 GetExtentOfArgList(startBuf, argListBegin, argListEnd);
4997 while (argListBegin < argListEnd) {
4998 if (*argListBegin ==
'^')
5000 else if (*argListBegin ==
'<') {
5002 buf += *argListBegin++;
5004 while (*argListBegin !=
'>') {
5005 buf += *argListBegin++;
5008 buf += *argListBegin;
5012 buf += *argListBegin;
5019 ReplaceText(Start, OrigLength, buf);
5045 std::string RewriteModernObjC::SynthesizeByrefCopyDestroyHelper(
VarDecl *VD,
5048 if (CopyDestroyCache.count(flag))
5050 CopyDestroyCache.insert(flag);
5051 S =
"static void __Block_byref_id_object_copy_";
5053 S +=
"(void *dst, void *src) {\n";
5059 unsigned VoidPtrSize =
5063 S +=
" _Block_object_assign((char*)dst + ";
5064 S += utostr(offset);
5065 S +=
", *(void * *) ((char*)src + ";
5066 S += utostr(offset);
5071 S +=
"static void __Block_byref_id_object_dispose_";
5073 S +=
"(void *src) {\n";
5074 S +=
" _Block_object_dispose(*(void * *) ((char*)src + ";
5075 S += utostr(offset);
5100 void RewriteModernObjC::RewriteByRefVar(
VarDecl *ND,
bool firstDecl,
5114 std::string ByrefType;
5115 RewriteByRefString(ByrefType, Name, ND,
true);
5116 ByrefType +=
" {\n";
5117 ByrefType +=
" void *__isa;\n";
5118 RewriteByRefString(ByrefType, Name, ND);
5119 ByrefType +=
" *__forwarding;\n";
5120 ByrefType +=
" int __flags;\n";
5121 ByrefType +=
" int __size;\n";
5126 if (HasCopyAndDispose) {
5127 ByrefType +=
" void (*__Block_byref_id_object_copy)(void*, void*);\n";
5128 ByrefType +=
" void (*__Block_byref_id_object_dispose)(void*);\n";
5132 (void)convertBlockPointerToFunctionPointer(T);
5135 ByrefType +=
" " + Name +
";\n";
5136 ByrefType +=
"};\n";
5140 FunLocStart = getFunctionSourceLocation(*
this, CurFunctionDef);
5142 assert(CurMethodDef &&
"RewriteByRefVar - CurMethodDef is null");
5143 FunLocStart = CurMethodDef->getLocStart();
5145 InsertText(FunLocStart, ByrefType);
5151 if (HasCopyAndDispose) {
5159 std::string HF = SynthesizeByrefCopyDestroyHelper(ND, flag);
5167 bool hasInit = (ND->
getInit() !=
nullptr);
5178 if (HasCopyAndDispose)
5182 RewriteByRefString(ByrefType, Name, ND);
5183 std::string ForwardingCastType(
"(");
5184 ForwardingCastType += ByrefType +
" *)";
5185 ByrefType +=
" " + Name +
" = {(void*)";
5186 ByrefType += utostr(isa);
5187 ByrefType +=
"," + ForwardingCastType +
"&" + Name +
", ";
5188 ByrefType += utostr(flags);
5190 ByrefType +=
"sizeof(";
5191 RewriteByRefString(ByrefType, Name, ND);
5193 if (HasCopyAndDispose) {
5194 ByrefType +=
", __Block_byref_id_object_copy_";
5195 ByrefType += utostr(flag);
5196 ByrefType +=
", __Block_byref_id_object_dispose_";
5197 ByrefType += utostr(flag);
5206 const char *commaBuf = startDeclBuf;
5207 while (*commaBuf !=
',')
5209 assert((*commaBuf ==
',') &&
"RewriteByRefVar: can't find ','");
5211 startBuf = commaBuf;
5215 ByrefType +=
"};\n";
5216 unsigned nameSize = Name.size();
5221 ReplaceText(DeclLoc, endBuf-startBuf+nameSize, ByrefType);
5228 startLoc = ECE->getLParenLoc();
5230 startLoc = E->getLocStart();
5233 ReplaceText(DeclLoc, endBuf-startBuf, ByrefType);
5235 const char separator = lastDecl ?
';' :
',';
5237 const char *separatorBuf = strchr(startInitializerBuf, separator);
5238 assert((*separatorBuf == separator) &&
5239 "RewriteByRefVar: can't find ';' or ','");
5243 InsertText(separatorLoc, lastDecl ?
"}" :
"};\n");
5248 void RewriteModernObjC::CollectBlockDeclRefInfo(
BlockExpr *Exp) {
5250 GetBlockDeclRefExprs(Exp->
getBody());
5251 if (BlockDeclRefs.size()) {
5253 for (
unsigned i = 0; i < BlockDeclRefs.size(); i++)
5254 if (!BlockDeclRefs[i]->getDecl()->hasAttr<BlocksAttr>()) {
5255 if (!BlockByCopyDeclsPtrSet.count(BlockDeclRefs[i]->getDecl())) {
5256 BlockByCopyDeclsPtrSet.insert(BlockDeclRefs[i]->getDecl());
5257 BlockByCopyDecls.push_back(BlockDeclRefs[i]->getDecl());
5261 for (
unsigned i = 0; i < BlockDeclRefs.size(); i++)
5262 if (BlockDeclRefs[i]->getDecl()->hasAttr<BlocksAttr>()) {
5263 if (!BlockByRefDeclsPtrSet.count(BlockDeclRefs[i]->getDecl())) {
5264 BlockByRefDeclsPtrSet.insert(BlockDeclRefs[i]->getDecl());
5265 BlockByRefDecls.push_back(BlockDeclRefs[i]->getDecl());
5269 for (
unsigned i = 0; i < BlockDeclRefs.size(); i++)
5270 if (BlockDeclRefs[i]->getDecl()->hasAttr<BlocksAttr>() ||
5271 BlockDeclRefs[i]->getType()->isObjCObjectPointerType() ||
5272 BlockDeclRefs[i]->getType()->isBlockPointerType())
5273 ImportedBlockDecls.insert(BlockDeclRefs[i]->getDecl());
5277 FunctionDecl *RewriteModernObjC::SynthBlockInitFunctionDecl(StringRef name) {
5286 const SmallVectorImpl<DeclRefExpr *> &InnerBlockDeclRefs) {
5290 Blocks.push_back(Exp);
5292 CollectBlockDeclRefInfo(Exp);
5295 int countOfInnerDecls = 0;
5296 if (!InnerBlockDeclRefs.empty()) {
5297 for (
unsigned i = 0; i < InnerBlockDeclRefs.size(); i++) {
5300 if (!VD->
hasAttr<BlocksAttr>() && !BlockByCopyDeclsPtrSet.count(VD)) {
5304 InnerDeclRefs.push_back(Exp); countOfInnerDecls++;
5305 BlockDeclRefs.push_back(Exp);
5306 BlockByCopyDeclsPtrSet.insert(VD);
5307 BlockByCopyDecls.push_back(VD);
5309 if (VD->
hasAttr<BlocksAttr>() && !BlockByRefDeclsPtrSet.count(VD)) {
5310 InnerDeclRefs.push_back(Exp); countOfInnerDecls++;
5311 BlockDeclRefs.push_back(Exp);
5312 BlockByRefDeclsPtrSet.insert(VD);
5313 BlockByRefDecls.push_back(VD);
5317 for (
unsigned i = 0; i < InnerBlockDeclRefs.size(); i++)
5318 if (InnerBlockDeclRefs[i]->getDecl()->hasAttr<BlocksAttr>() ||
5319 InnerBlockDeclRefs[i]->getType()->isObjCObjectPointerType() ||
5320 InnerBlockDeclRefs[i]->getType()->isBlockPointerType())
5321 ImportedBlockDecls.insert(InnerBlockDeclRefs[i]->getDecl());
5323 InnerDeclRefsCount.push_back(countOfInnerDecls);
5325 std::string FuncName;
5329 else if (CurMethodDef)
5330 BuildUniqueMethodName(FuncName, CurMethodDef);
5331 else if (GlobalVarDecl)
5332 FuncName = std::string(GlobalVarDecl->getNameAsString());
5334 bool GlobalBlockExpr =
5337 if (GlobalBlockExpr && !GlobalVarDecl) {
5338 Diags.Report(block->
getLocation(), GlobalBlockRewriteFailedDiag);
5339 GlobalBlockExpr =
false;
5342 std::string BlockNumber = utostr(Blocks.size()-1);
5344 std::string Func =
"__" + FuncName +
"_block_func_" + BlockNumber;
5347 QualType BFT = convertFunctionTypeOfBlocks(Exp->getFunctionType());
5356 if (GlobalBlockExpr)
5360 Tag += FuncName +
"_block_impl_" + BlockNumber;
5362 FD = SynthBlockInitFunctionDecl(Tag);
5366 SmallVector<Expr*, 4> InitExprs;
5369 FD = SynthBlockInitFunctionDecl(Func);
5374 InitExprs.push_back(castExpr);
5377 std::string DescData =
"__" + FuncName +
"_block_desc_" + BlockNumber +
"_DATA";
5393 InitExprs.push_back(DescRefExpr);
5396 if (BlockDeclRefs.size()) {
5400 E = BlockByCopyDecls.end(); I !=
E; ++
I) {
5401 if (isObjCType((*I)->getType())) {
5403 FD = SynthBlockInitFunctionDecl((*I)->getName());
5406 if (HasLocalVariableExternalStorage(*I)) {
5412 }
else if (isTopLevelBlockPointerType((*I)->getType())) {
5413 FD = SynthBlockInitFunctionDecl((*I)->getName());
5419 FD = SynthBlockInitFunctionDecl((*I)->getName());
5422 if (HasLocalVariableExternalStorage(*I)) {
5430 InitExprs.push_back(Exp);
5434 E = BlockByRefDecls.end(); I !=
E; ++
I) {
5437 std::string RecName;
5438 RewriteByRefString(RecName, Name, ND,
true);
5440 +
sizeof(
"struct"));
5444 assert(RD &&
"SynthBlockInitExpr(): Can't find RecordDecl");
5447 FD = SynthBlockInitFunctionDecl((*I)->getName());
5450 bool isNestedCapturedVar =
false;
5452 for (
const auto &CI : block->
captures()) {
5453 const VarDecl *variable = CI.getVariable();
5454 if (variable == ND && CI.isNested()) {
5455 assert (CI.isByRef() &&
5456 "SynthBlockInitExpr - captured block variable is not byref");
5457 isNestedCapturedVar =
true;
5463 if (!isNestedCapturedVar)
5468 InitExprs.push_back(Exp);
5471 if (ImportedBlockDecls.size()) {
5478 InitExprs.push_back(FlagExp);
5483 if (GlobalBlockExpr) {
5484 assert (!GlobalConstructionExp &&
5485 "SynthBlockInitExpr - GlobalConstructionExp must be null");
5486 GlobalConstructionExp = NewRep;
5499 BlockDeclRefs.clear();
5500 BlockByRefDecls.clear();
5501 BlockByRefDeclsPtrSet.clear();
5502 BlockByCopyDecls.clear();
5503 BlockByCopyDeclsPtrSet.clear();
5504 ImportedBlockDecls.clear();
5508 bool RewriteModernObjC::IsDeclStmtInForeachHeader(
DeclStmt *DS) {
5510 dyn_cast<ObjCForCollectionStmt>(Stmts.back()))
5511 return CS->getElement() == DS;
5519 Stmt *RewriteModernObjC::RewriteFunctionBodyOrGlobalInitializer(
Stmt *S) {
5520 if (isa<SwitchStmt>(S) || isa<WhileStmt>(S) ||
5521 isa<DoStmt>(S) || isa<ForStmt>(S))
5523 else if (isa<ObjCForCollectionStmt>(S)) {
5525 ObjCBcLabelNo.push_back(++BcLabelCount);
5532 return RewritePropertyOrImplicitSetter(PseudoOp);
5534 return RewritePropertyOrImplicitGetter(PseudoOp);
5536 }
else if (
ObjCIvarRefExpr *IvarRefExpr = dyn_cast<ObjCIvarRefExpr>(S)) {
5537 return RewriteObjCIvarRefExpr(IvarRefExpr);
5539 else if (isa<OpaqueValueExpr>(S))
5540 S = cast<OpaqueValueExpr>(
S)->getSourceExpr();
5545 for (
Stmt *&childStmt : S->children())
5547 Stmt *newStmt = RewriteFunctionBodyOrGlobalInitializer(childStmt);
5549 childStmt = newStmt;
5553 if (
BlockExpr *BE = dyn_cast<BlockExpr>(S)) {
5554 SmallVector<DeclRefExpr *, 8> InnerBlockDeclRefs;
5555 llvm::SmallPtrSet<const DeclContext *, 8> InnerContexts;
5556 InnerContexts.insert(BE->getBlockDecl());
5557 ImportedLocalExternalDecls.clear();
5558 GetInnerBlockDeclRefExprs(BE->getBody(),
5559 InnerBlockDeclRefs, InnerContexts);
5561 Stmt *SaveCurrentBody = CurrentBody;
5562 CurrentBody = BE->getBody();
5563 PropParentMap =
nullptr;
5569 bool saveDisableReplaceStmt = DisableReplaceStmt;
5570 DisableReplaceStmt =
false;
5571 RewriteFunctionBodyOrGlobalInitializer(BE->getBody());
5572 DisableReplaceStmt = saveDisableReplaceStmt;
5573 CurrentBody = SaveCurrentBody;
5574 PropParentMap =
nullptr;
5575 ImportedLocalExternalDecls.clear();
5577 std::string Str = Rewrite.getRewrittenText(BE->getSourceRange());
5578 RewrittenBlockExprs[BE] = Str;
5580 Stmt *blockTranscribed = SynthBlockInitExpr(BE, InnerBlockDeclRefs);
5583 ReplaceStmt(S, blockTranscribed);
5584 return blockTranscribed;
5588 return RewriteAtEncode(AtEncode);
5591 return RewriteAtSelector(AtSelector);
5594 return RewriteObjCStringLiteral(AtString);
5597 return RewriteObjCBoolLiteralExpr(BoolLitExpr);
5600 return RewriteObjCBoxedExpr(BoxedExpr);
5603 return RewriteObjCArrayLiteralExpr(ArrayLitExpr);
5606 dyn_cast<ObjCDictionaryLiteral>(S))
5607 return RewriteObjCDictionaryLiteralExpr(DictionaryLitExpr);
5618 std::string messString;
5619 messString +=
"// ";
5620 messString.append(startBuf, endBuf-startBuf+1);
5629 return RewriteMessageExpr(MessExpr);
5633 dyn_cast<ObjCAutoreleasePoolStmt>(S)) {
5634 return RewriteObjCAutoreleasePoolStmt(StmtAutoRelease);
5638 return RewriteObjCTryStmt(StmtTry);
5641 return RewriteObjCSynchronizedStmt(StmtTry);
5644 return RewriteObjCThrowStmt(StmtThrow);
5647 return RewriteObjCProtocolExpr(ProtocolExp);
5650 dyn_cast<ObjCForCollectionStmt>(S))
5651 return RewriteObjCForCollectionStmt(StmtForCollection,
5654 dyn_cast<BreakStmt>(S))
5655 return RewriteBreakStmt(StmtBreakStmt);
5657 dyn_cast<ContinueStmt>(S))
5658 return RewriteContinueStmt(StmtContinueStmt);
5662 if (
DeclStmt *DS = dyn_cast<DeclStmt>(S)) {
5672 if (Stmts.empty() || !IsDeclStmtInForeachHeader(DS))
5673 RewriteObjCQualifiedInterfaceTypes(*DS->
decl_begin());
5679 if (
ValueDecl *ND = dyn_cast<ValueDecl>(SD)) {
5680 if (isTopLevelBlockPointerType(ND->
getType()))
5681 RewriteBlockPointerDecl(ND);
5683 CheckFunctionPointerDecl(ND->
getType(), ND);
5684 if (
VarDecl *VD = dyn_cast<VarDecl>(SD)) {
5685 if (VD->
hasAttr<BlocksAttr>()) {
5686 static unsigned uniqueByrefDeclCount = 0;
5687 assert(!BlockByRefDeclNo.count(ND) &&
5688 "RewriteFunctionBodyOrGlobalInitializer: Duplicate byref decl");
5689 BlockByRefDeclNo[ND] = uniqueByrefDeclCount++;
5690 RewriteByRefVar(VD, (DI == DS->
decl_begin()), ((DI+1) == DE));
5693 RewriteTypeOfDecl(VD);
5697 if (isTopLevelBlockPointerType(TD->getUnderlyingType()))
5698 RewriteBlockPointerDecl(TD);
5699 else if (TD->getUnderlyingType()->isFunctionPointerType())
5700 CheckFunctionPointerDecl(TD->getUnderlyingType(), TD);
5706 RewriteObjCQualifiedInterfaceTypes(CE);
5708 if (isa<SwitchStmt>(S) || isa<WhileStmt>(
S) ||
5709 isa<DoStmt>(S) || isa<ForStmt>(
S)) {
5710 assert(!Stmts.empty() &&
"Statement stack is empty");
5711 assert ((isa<SwitchStmt>(Stmts.back()) || isa<WhileStmt>(Stmts.back()) ||
5712 isa<DoStmt>(Stmts.back()) || isa<ForStmt>(Stmts.back()))
5713 &&
"Statement stack mismatch");
5717 if (
DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(S)) {
5719 if (VD->
hasAttr<BlocksAttr>())
5720 return RewriteBlockDeclRefExpr(DRE);
5721 if (HasLocalVariableExternalStorage(VD))
5722 return RewriteLocalVariableExternalStorage(DRE);
5725 if (
CallExpr *CE = dyn_cast<CallExpr>(S)) {
5728 ReplaceStmt(S, BlockCall);
5733 RewriteCastExpr(CE);
5736 RewriteImplicitCastObjCExpr(ICE);
5746 llvm::raw_string_ostream Buf(SStr);
5747 Replacement->printPretty(Buf);
5748 const std::string &Str = Buf.str();
5750 printf(
"CAST = %s\n", &Str[0]);
5751 InsertText(ICE->
getSubExpr()->getLocStart(), Str);
5760 void RewriteModernObjC::RewriteRecordBody(
RecordDecl *RD) {
5761 for (
auto *FD : RD->
fields()) {
5762 if (isTopLevelBlockPointerType(FD->
getType()))
5763 RewriteBlockPointerDecl(FD);
5766 RewriteObjCQualifiedInterfaceTypes(FD);
5772 void RewriteModernObjC::HandleDeclInMainFile(
Decl *D) {
5774 case Decl::Function: {
5782 RewriteBlocksInFunctionProtoType(FD->
getType(), FD);
5789 CurFunctionDef = FD;
5792 cast_or_null<CompoundStmt>(RewriteFunctionBodyOrGlobalInitializer(Body));
5794 CurrentBody =
nullptr;
5795 if (PropParentMap) {
5796 delete PropParentMap;
5797 PropParentMap =
nullptr;
5801 InsertBlockLiteralsWithinFunction(FD);
5802 RewriteLineDirective(D);
5803 CurFunctionDef =
nullptr;
5807 case Decl::ObjCMethod: {
5813 cast_or_null<CompoundStmt>(RewriteFunctionBodyOrGlobalInitializer(Body));
5815 CurrentBody =
nullptr;
5816 if (PropParentMap) {
5817 delete PropParentMap;
5818 PropParentMap =
nullptr;
5820 InsertBlockLiteralsWithinMethod(MD);
5821 RewriteLineDirective(D);
5822 CurMethodDef =
nullptr;
5826 case Decl::ObjCImplementation: {
5828 ClassImplementation.push_back(CI);
5831 case Decl::ObjCCategoryImpl: {
5833 CategoryImplementation.push_back(CI);
5837 VarDecl *VD = cast<VarDecl>(D);
5838 RewriteObjCQualifiedInterfaceTypes(VD);
5839 if (isTopLevelBlockPointerType(VD->
getType()))
5840 RewriteBlockPointerDecl(VD);
5842 CheckFunctionPointerDecl(VD->
getType(), VD);
5845 RewriteCastExpr(CE);
5851 RewriteRecordBody(RD);
5856 RewriteFunctionBodyOrGlobalInitializer(VD->
getInit());
5857 CurrentBody =
nullptr;
5858 if (PropParentMap) {
5859 delete PropParentMap;
5860 PropParentMap =
nullptr;
5863 GlobalVarDecl =
nullptr;
5867 RewriteCastExpr(CE);
5873 case Decl::Typedef: {
5875 if (isTopLevelBlockPointerType(TD->getUnderlyingType()))
5876 RewriteBlockPointerDecl(TD);
5877 else if (TD->getUnderlyingType()->isFunctionPointerType())
5878 CheckFunctionPointerDecl(TD->getUnderlyingType(), TD);
5880 RewriteObjCQualifiedInterfaceTypes(TD);
5884 case Decl::CXXRecord:
5885 case Decl::Record: {
5888 RewriteRecordBody(RD);
5902 std::string &Result) {
5905 Result +=
"static ";
5906 Result +=
"struct _protocol_t *";
5907 Result +=
"_OBJC_PROTOCOL_REFERENCE_$_";
5914 void RewriteModernObjC::HandleTranslationUnit(
ASTContext &
C) {
5915 if (Diags.hasErrorOccurred())
5920 for (
unsigned i = 0, e = FunctionDefinitionsSeen.size(); i < e; i++) {
5925 HandleTopLevelSingleDecl(FDecl);
5931 RewriteObjCProtocolMetaData(ProtDecl, Preamble);
5932 Write_ProtocolExprReferencedMetadata(Context, ProtDecl, Preamble);
5937 if (ClassImplementation.size() || CategoryImplementation.size())
5938 RewriteImplementations();
5940 for (
unsigned i = 0, e = ObjCInterfacesSeen.size(); i < e; i++) {
5946 RewriteInterfaceDecl(CDecl);
5952 Rewrite.getRewriteBufferFor(MainFileID)) {
5954 *OutFile << std::string(RewriteBuf->begin(), RewriteBuf->end());
5956 llvm::errs() <<
"No changes\n";
5959 if (ClassImplementation.size() || CategoryImplementation.size() ||
5960 ProtocolExprDecls.size()) {
5962 std::string ResultStr;
5963 RewriteMetaDataIntoBuffer(ResultStr);
5965 *OutFile << ResultStr;
5969 std::string ResultStr;
5970 WriteImageInfo(ResultStr);
5971 *OutFile << ResultStr;
5976 void RewriteModernObjC::Initialize(
ASTContext &context) {
5977 InitializeCommon(context);
5979 Preamble +=
"#ifndef __OBJC2__\n";
5980 Preamble +=
"#define __OBJC2__\n";
5981 Preamble +=
"#endif\n";
5986 Preamble =
"#pragma once\n";
5987 Preamble +=
"struct objc_selector; struct objc_class;\n";
5988 Preamble +=
"struct __rw_objc_super { \n\tstruct objc_object *object; ";
5989 Preamble +=
"\n\tstruct objc_object *superClass; ";
5991 Preamble +=
"\n\t__rw_objc_super(struct objc_object *o, struct objc_object *s) ";
5992 Preamble +=
": object(o), superClass(s) {} ";
5993 Preamble +=
"\n};\n";
5995 if (LangOpts.MicrosoftExt) {
5998 Preamble +=
"\n#pragma section(\".objc_classlist$B\", long, read, write)\n";
5999 Preamble +=
"#pragma section(\".objc_catlist$B\", long, read, write)\n";
6000 Preamble +=
"#pragma section(\".objc_imageinfo$B\", long, read, write)\n";
6001 Preamble +=
"#pragma section(\".objc_nlclslist$B\", long, read, write)\n";
6002 Preamble +=
"#pragma section(\".objc_nlcatlist$B\", long, read, write)\n";
6004 Preamble +=
"#pragma section(\".cat_cls_meth$B\", long, read, write)\n";
6005 Preamble +=
"#pragma section(\".inst_meth$B\", long, read, write)\n";
6006 Preamble +=
"#pragma section(\".cls_meth$B\", long, read, write)\n";
6007 Preamble +=
"#pragma section(\".objc_ivar$B\", long, read, write)\n";
6011 Preamble +=
"#pragma section(\".objc_selrefs$B\", long, read, write)\n";
6012 Preamble +=
"#pragma section(\".objc_classrefs$B\", long, read, write)\n";
6013 Preamble +=
"#pragma section(\".objc_superrefs$B\", long, read, write)\n";
6016 Preamble +=
"#ifndef _REWRITER_typedef_Protocol\n";
6017 Preamble +=
"typedef struct objc_object Protocol;\n";
6018 Preamble +=
"#define _REWRITER_typedef_Protocol\n";
6019 Preamble +=
"#endif\n";
6020 if (LangOpts.MicrosoftExt) {
6021 Preamble +=
"#define __OBJC_RW_DLLIMPORT extern \"C\" __declspec(dllimport)\n";
6022 Preamble +=
"#define __OBJC_RW_STATICIMPORT extern \"C\"\n";
6025 Preamble +=
"#define __OBJC_RW_DLLIMPORT extern\n";
6027 Preamble +=
"__OBJC_RW_DLLIMPORT void objc_msgSend(void);\n";
6028 Preamble +=
"__OBJC_RW_DLLIMPORT void objc_msgSendSuper(void);\n";
6029 Preamble +=
"__OBJC_RW_DLLIMPORT void objc_msgSend_stret(void);\n";
6030 Preamble +=
"__OBJC_RW_DLLIMPORT void objc_msgSendSuper_stret(void);\n";
6031 Preamble +=
"__OBJC_RW_DLLIMPORT void objc_msgSend_fpret(void);\n";
6033 Preamble +=
"__OBJC_RW_DLLIMPORT struct objc_class *objc_getClass";
6034 Preamble +=
"(const char *);\n";
6035 Preamble +=
"__OBJC_RW_DLLIMPORT struct objc_class *class_getSuperclass";
6036 Preamble +=
"(struct objc_class *);\n";
6037 Preamble +=
"__OBJC_RW_DLLIMPORT struct objc_class *objc_getMetaClass";
6038 Preamble +=
"(const char *);\n";
6039 Preamble +=
"__OBJC_RW_DLLIMPORT void objc_exception_throw( struct objc_object *);\n";
6041 Preamble +=
"__OBJC_RW_DLLIMPORT int objc_sync_enter( struct objc_object *);\n";
6042 Preamble +=
"__OBJC_RW_DLLIMPORT int objc_sync_exit( struct objc_object *);\n";
6043 Preamble +=
"__OBJC_RW_DLLIMPORT Protocol *objc_getProtocol(const char *);\n";
6044 Preamble +=
"#ifdef _WIN64\n";
6045 Preamble +=
"typedef unsigned long long _WIN_NSUInteger;\n";
6046 Preamble +=
"#else\n";
6047 Preamble +=
"typedef unsigned int _WIN_NSUInteger;\n";
6048 Preamble +=
"#endif\n";
6049 Preamble +=
"#ifndef __FASTENUMERATIONSTATE\n";
6050 Preamble +=
"struct __objcFastEnumerationState {\n\t";
6051 Preamble +=
"unsigned long state;\n\t";
6052 Preamble +=
"void **itemsPtr;\n\t";
6053 Preamble +=
"unsigned long *mutationsPtr;\n\t";
6054 Preamble +=
"unsigned long extra[5];\n};\n";
6055 Preamble +=
"__OBJC_RW_DLLIMPORT void objc_enumerationMutation(struct objc_object *);\n";
6056 Preamble +=
"#define __FASTENUMERATIONSTATE\n";
6057 Preamble +=
"#endif\n";
6058 Preamble +=
"#ifndef __NSCONSTANTSTRINGIMPL\n";
6059 Preamble +=
"struct __NSConstantStringImpl {\n";
6060 Preamble +=
" int *isa;\n";
6061 Preamble +=
" int flags;\n";
6062 Preamble +=
" char *str;\n";
6063 Preamble +=
"#if _WIN64\n";
6064 Preamble +=
" long long length;\n";
6065 Preamble +=
"#else\n";
6066 Preamble +=
" long length;\n";
6067 Preamble +=
"#endif\n";
6069 Preamble +=
"#ifdef CF_EXPORT_CONSTANT_STRING\n";
6070 Preamble +=
"extern \"C\" __declspec(dllexport) int __CFConstantStringClassReference[];\n";
6071 Preamble +=
"#else\n";
6072 Preamble +=
"__OBJC_RW_DLLIMPORT int __CFConstantStringClassReference[];\n";
6073 Preamble +=
"#endif\n";
6074 Preamble +=
"#define __NSCONSTANTSTRINGIMPL\n";
6075 Preamble +=
"#endif\n";
6077 Preamble +=
"#ifndef BLOCK_IMPL\n";
6078 Preamble +=
"#define BLOCK_IMPL\n";
6079 Preamble +=
"struct __block_impl {\n";
6080 Preamble +=
" void *isa;\n";
6081 Preamble +=
" int Flags;\n";
6082 Preamble +=
" int Reserved;\n";
6083 Preamble +=
" void *FuncPtr;\n";
6085 Preamble +=
"// Runtime copy/destroy helper functions (from Block_private.h)\n";
6086 Preamble +=
"#ifdef __OBJC_EXPORT_BLOCKS\n";
6087 Preamble +=
"extern \"C\" __declspec(dllexport) "
6088 "void _Block_object_assign(void *, const void *, const int);\n";
6089 Preamble +=
"extern \"C\" __declspec(dllexport) void _Block_object_dispose(const void *, const int);\n";
6090 Preamble +=
"extern \"C\" __declspec(dllexport) void *_NSConcreteGlobalBlock[32];\n";
6091 Preamble +=
"extern \"C\" __declspec(dllexport) void *_NSConcreteStackBlock[32];\n";
6092 Preamble +=
"#else\n";
6093 Preamble +=
"__OBJC_RW_DLLIMPORT void _Block_object_assign(void *, const void *, const int);\n";
6094 Preamble +=
"__OBJC_RW_DLLIMPORT void _Block_object_dispose(const void *, const int);\n";
6095 Preamble +=
"__OBJC_RW_DLLIMPORT void *_NSConcreteGlobalBlock[32];\n";
6096 Preamble +=
"__OBJC_RW_DLLIMPORT void *_NSConcreteStackBlock[32];\n";
6097 Preamble +=
"#endif\n";
6098 Preamble +=
"#endif\n";
6099 if (LangOpts.MicrosoftExt) {
6100 Preamble +=
"#undef __OBJC_RW_DLLIMPORT\n";
6101 Preamble +=
"#undef __OBJC_RW_STATICIMPORT\n";
6102 Preamble +=
"#ifndef KEEP_ATTRIBUTES\n";
6103 Preamble +=
"#define __attribute__(X)\n";
6104 Preamble +=
"#endif\n";
6105 Preamble +=
"#ifndef __weak\n";
6106 Preamble +=
"#define __weak\n";
6107 Preamble +=
"#endif\n";
6108 Preamble +=
"#ifndef __block\n";
6109 Preamble +=
"#define __block\n";
6110 Preamble +=
"#endif\n";
6113 Preamble +=
"#define __block\n";
6114 Preamble +=
"#define __weak\n";
6118 Preamble +=
"\n#include <stdarg.h>\n";
6119 Preamble +=
"struct __NSContainer_literal {\n";
6120 Preamble +=
" void * *arr;\n";
6121 Preamble +=
" __NSContainer_literal (unsigned int count, ...) {\n";
6122 Preamble +=
"\tva_list marker;\n";
6123 Preamble +=
"\tva_start(marker, count);\n";
6124 Preamble +=
"\tarr = new void *[count];\n";
6125 Preamble +=
"\tfor (unsigned i = 0; i < count; i++)\n";
6126 Preamble +=
"\t arr[i] = va_arg(marker, void *);\n";
6127 Preamble +=
"\tva_end( marker );\n";
6128 Preamble +=
" };\n";
6129 Preamble +=
" ~__NSContainer_literal() {\n";
6130 Preamble +=
"\tdelete[] arr;\n";
6135 Preamble +=
"extern \"C\" __declspec(dllimport) void * objc_autoreleasePoolPush(void);\n";
6136 Preamble +=
"extern \"C\" __declspec(dllimport) void objc_autoreleasePoolPop(void *);\n\n";
6137 Preamble +=
"struct __AtAutoreleasePool {\n";
6138 Preamble +=
" __AtAutoreleasePool() {atautoreleasepoolobj = objc_autoreleasePoolPush();}\n";
6139 Preamble +=
" ~__AtAutoreleasePool() {objc_autoreleasePoolPop(atautoreleasepoolobj);}\n";
6140 Preamble +=
" void * atautoreleasepoolobj;\n";
6145 Preamble +=
"\n#define __OFFSETOFIVAR__(TYPE, MEMBER) ((long long) &((TYPE *)0)->MEMBER)\n";
6150 void RewriteModernObjC::RewriteIvarOffsetComputation(
ObjCIvarDecl *ivar,
6151 std::string &Result) {
6152 Result +=
"__OFFSETOFIVAR__(struct ";
6154 if (LangOpts.MicrosoftExt)
6158 ObjCIvarBitfieldGroupDecl(ivar, Result);
6266 static void WriteModernMetadataDeclarations(
ASTContext *Context, std::string &Result) {
6267 static bool meta_data_declared =
false;
6268 if (meta_data_declared)
6271 Result +=
"\nstruct _prop_t {\n";
6272 Result +=
"\tconst char *name;\n";
6273 Result +=
"\tconst char *attributes;\n";
6276 Result +=
"\nstruct _protocol_t;\n";
6278 Result +=
"\nstruct _objc_method {\n";
6279 Result +=
"\tstruct objc_selector * _cmd;\n";
6280 Result +=
"\tconst char *method_type;\n";
6281 Result +=
"\tvoid *_imp;\n";
6284 Result +=
"\nstruct _protocol_t {\n";
6285 Result +=
"\tvoid * isa; // NULL\n";
6286 Result +=
"\tconst char *protocol_name;\n";
6287 Result +=
"\tconst struct _protocol_list_t * protocol_list; // super protocols\n";
6288 Result +=
"\tconst struct method_list_t *instance_methods;\n";
6289 Result +=
"\tconst struct method_list_t *class_methods;\n";
6290 Result +=
"\tconst struct method_list_t *optionalInstanceMethods;\n";
6291 Result +=
"\tconst struct method_list_t *optionalClassMethods;\n";
6292 Result +=
"\tconst struct _prop_list_t * properties;\n";
6293 Result +=
"\tconst unsigned int size; // sizeof(struct _protocol_t)\n";
6294 Result +=
"\tconst unsigned int flags; // = 0\n";
6295 Result +=
"\tconst char ** extendedMethodTypes;\n";
6298 Result +=
"\nstruct _ivar_t {\n";
6299 Result +=
"\tunsigned long int *offset; // pointer to ivar offset location\n";
6300 Result +=
"\tconst char *name;\n";
6301 Result +=
"\tconst char *type;\n";
6302 Result +=
"\tunsigned int alignment;\n";
6303 Result +=
"\tunsigned int size;\n";
6306 Result +=
"\nstruct _class_ro_t {\n";
6307 Result +=
"\tunsigned int flags;\n";
6308 Result +=
"\tunsigned int instanceStart;\n";
6309 Result +=
"\tunsigned int instanceSize;\n";
6311 if (Triple.getArch() == llvm::Triple::x86_64)
6312 Result +=
"\tunsigned int reserved;\n";
6313 Result +=
"\tconst unsigned char *ivarLayout;\n";
6314 Result +=
"\tconst char *name;\n";
6315 Result +=
"\tconst struct _method_list_t *baseMethods;\n";
6316 Result +=
"\tconst struct _objc_protocol_list *baseProtocols;\n";
6317 Result +=
"\tconst struct _ivar_list_t *ivars;\n";
6318 Result +=
"\tconst unsigned char *weakIvarLayout;\n";
6319 Result +=
"\tconst struct _prop_list_t *properties;\n";
6322 Result +=
"\nstruct _class_t {\n";
6323 Result +=
"\tstruct _class_t *isa;\n";
6324 Result +=
"\tstruct _class_t *superclass;\n";
6325 Result +=
"\tvoid *cache;\n";
6326 Result +=
"\tvoid *vtable;\n";
6327 Result +=
"\tstruct _class_ro_t *ro;\n";
6330 Result +=
"\nstruct _category_t {\n";
6331 Result +=
"\tconst char *name;\n";
6332 Result +=
"\tstruct _class_t *cls;\n";
6333 Result +=
"\tconst struct _method_list_t *instance_methods;\n";
6334 Result +=
"\tconst struct _method_list_t *class_methods;\n";
6335 Result +=
"\tconst struct _protocol_list_t *protocols;\n";
6336 Result +=
"\tconst struct _prop_list_t *properties;\n";
6339 Result +=
"extern \"C\" __declspec(dllimport) struct objc_cache _objc_empty_cache;\n";
6340 Result +=
"#pragma warning(disable:4273)\n";
6341 meta_data_declared =
true;
6344 static void Write_protocol_list_t_TypeDecl(std::string &Result,
6345 long super_protocol_count) {
6346 Result +=
"struct /*_protocol_list_t*/"; Result +=
" {\n";
6347 Result +=
"\tlong protocol_count; // Note, this is 32/64 bit\n";
6348 Result +=
"\tstruct _protocol_t *super_protocols[";
6349 Result += utostr(super_protocol_count); Result +=
"];\n";
6353 static void Write_method_list_t_TypeDecl(std::string &Result,
6354 unsigned int method_count) {
6355 Result +=
"struct /*_method_list_t*/"; Result +=
" {\n";
6356 Result +=
"\tunsigned int entsize; // sizeof(struct _objc_method)\n";
6357 Result +=
"\tunsigned int method_count;\n";
6358 Result +=
"\tstruct _objc_method method_list[";
6359 Result += utostr(method_count); Result +=
"];\n";
6363 static void Write__prop_list_t_TypeDecl(std::string &Result,
6364 unsigned int property_count) {
6365 Result +=
"struct /*_prop_list_t*/"; Result +=
" {\n";
6366 Result +=
"\tunsigned int entsize; // sizeof(struct _prop_t)\n";
6367 Result +=
"\tunsigned int count_of_properties;\n";
6368 Result +=
"\tstruct _prop_t prop_list[";
6369 Result += utostr(property_count); Result +=
"];\n";
6373 static void Write__ivar_list_t_TypeDecl(std::string &Result,
6374 unsigned int ivar_count) {
6375 Result +=
"struct /*_ivar_list_t*/"; Result +=
" {\n";
6376 Result +=
"\tunsigned int entsize; // sizeof(struct _prop_t)\n";
6377 Result +=
"\tunsigned int count;\n";
6378 Result +=
"\tstruct _ivar_t ivar_list[";
6379 Result += utostr(ivar_count); Result +=
"];\n";
6383 static void Write_protocol_list_initializer(
ASTContext *Context, std::string &Result,
6384 ArrayRef<ObjCProtocolDecl *> SuperProtocols,
6386 StringRef ProtocolName) {
6387 if (SuperProtocols.size() > 0) {
6388 Result +=
"\nstatic ";
6389 Write_protocol_list_t_TypeDecl(Result, SuperProtocols.size());
6390 Result +=
" "; Result += VarName;
6391 Result += ProtocolName;
6392 Result +=
" __attribute__ ((used, section (\"__DATA,__objc_const\"))) = {\n";
6393 Result +=
"\t"; Result += utostr(SuperProtocols.size()); Result +=
",\n";
6394 for (
unsigned i = 0, e = SuperProtocols.size(); i < e; i++) {
6396 Result +=
"\t&"; Result +=
"_OBJC_PROTOCOL_";
6406 static void Write_method_list_t_initializer(RewriteModernObjC &RewriteObj,
6408 ArrayRef<ObjCMethodDecl *> Methods,
6410 StringRef TopLevelDeclName,
6412 if (Methods.size() > 0) {
6413 Result +=
"\nstatic ";
6414 Write_method_list_t_TypeDecl(Result, Methods.size());
6415 Result +=
" "; Result += VarName;
6416 Result += TopLevelDeclName;
6417 Result +=
" __attribute__ ((used, section (\"__DATA,__objc_const\"))) = {\n";
6418 Result +=
"\t"; Result +=
"sizeof(_objc_method)"; Result +=
",\n";
6419 Result +=
"\t"; Result += utostr(Methods.size()); Result +=
",\n";
6420 for (
unsigned i = 0, e = Methods.size(); i < e; i++) {
6423 Result +=
"\t{{(struct objc_selector *)\"";
6425 Result +=
"\t{(struct objc_selector *)\"";
6426 Result += (MD)->getSelector().getAsString(); Result +=
"\"";
6428 std::string MethodTypeString;
6430 Result +=
"\""; Result += MethodTypeString; Result +=
"\"";
6435 Result +=
"(void *)";
6436 Result += RewriteObj.MethodInternalNames[MD];
6447 static void Write_prop_list_t_initializer(RewriteModernObjC &RewriteObj,
6449 ArrayRef<ObjCPropertyDecl *> Properties,
6450 const Decl *Container,
6452 StringRef ProtocolName) {
6453 if (Properties.size() > 0) {
6454 Result +=
"\nstatic ";
6455 Write__prop_list_t_TypeDecl(Result, Properties.size());
6456 Result +=
" "; Result += VarName;
6457 Result += ProtocolName;
6458 Result +=
" __attribute__ ((used, section (\"__DATA,__objc_const\"))) = {\n";
6459 Result +=
"\t"; Result +=
"sizeof(_prop_t)"; Result +=
",\n";
6460 Result +=
"\t"; Result += utostr(Properties.size()); Result +=
",\n";
6461 for (
unsigned i = 0, e = Properties.size(); i < e; i++) {
6467 Result += PropDecl->
getName(); Result +=
"\",";
6468 std::string PropertyTypeString, QuotePropertyTypeString;
6470 RewriteObj.QuoteDoublequotes(PropertyTypeString, QuotePropertyTypeString);
6471 Result +=
"\""; Result += QuotePropertyTypeString; Result +=
"\"";
6482 enum MetaDataDlags {
6486 OBJC2_CLS_HIDDEN = 0x10,
6487 CLS_EXCEPTION = 0x20,
6490 CLS_HAS_IVAR_RELEASER = 0x40,
6492 CLS_COMPILED_BY_ARC = 0x80
6495 static void Write__class_ro_t_initializer(
ASTContext *Context, std::string &Result,
6497 const std::string &InstanceStart,
6498 const std::string &InstanceSize,
6499 ArrayRef<ObjCMethodDecl *>baseMethods,
6500 ArrayRef<ObjCProtocolDecl *>baseProtocols,
6501 ArrayRef<ObjCIvarDecl *>ivars,
6502 ArrayRef<ObjCPropertyDecl *>Properties,
6504 StringRef ClassName) {
6505 Result +=
"\nstatic struct _class_ro_t ";
6506 Result += VarName; Result += ClassName;
6507 Result +=
" __attribute__ ((used, section (\"__DATA,__objc_const\"))) = {\n";
6509 Result += llvm::utostr(flags); Result +=
", ";
6510 Result += InstanceStart; Result +=
", ";
6511 Result += InstanceSize; Result +=
", \n";
6514 if (Triple.getArch() == llvm::Triple::x86_64)
6516 Result +=
"(unsigned int)0, \n\t";
6518 Result +=
"0, \n\t";
6519 Result +=
"\""; Result += ClassName; Result +=
"\",\n\t";
6520 bool metaclass = ((flags & CLS_META) != 0);
6521 if (baseMethods.size() > 0) {
6522 Result +=
"(const struct _method_list_t *)&";
6524 Result +=
"_OBJC_$_CLASS_METHODS_";
6526 Result +=
"_OBJC_$_INSTANCE_METHODS_";
6527 Result += ClassName;
6531 Result +=
"0, \n\t";
6533 if (!metaclass && baseProtocols.size() > 0) {
6534 Result +=
"(const struct _objc_protocol_list *)&";
6535 Result +=
"_OBJC_CLASS_PROTOCOLS_$_"; Result += ClassName;
6539 Result +=
"0, \n\t";
6541 if (!metaclass && ivars.size() > 0) {
6542 Result +=
"(const struct _ivar_list_t *)&";
6543 Result +=
"_OBJC_$_INSTANCE_VARIABLES_"; Result += ClassName;
6547 Result +=
"0, \n\t";
6550 Result +=
"0, \n\t";
6551 if (!metaclass && Properties.size() > 0) {
6552 Result +=
"(const struct _prop_list_t *)&";
6553 Result +=
"_OBJC_$_PROP_LIST_"; Result += ClassName;
6562 static void Write_class_t(
ASTContext *Context, std::string &Result,
6576 if (metaclass && rootClass) {
6579 Result +=
"extern \"C\" ";
6581 Result +=
"__declspec(dllexport) ";
6583 Result +=
"__declspec(dllimport) ";
6585 Result +=
"struct _class_t OBJC_CLASS_$_";
6593 Result +=
"extern \"C\" ";
6595 Result +=
"__declspec(dllexport) ";
6597 Result +=
"__declspec(dllimport) ";
6599 Result +=
"struct _class_t ";
6604 if (metaclass && RootClass != SuperClass) {
6605 Result +=
"extern \"C\" ";
6607 Result +=
"__declspec(dllexport) ";
6609 Result +=
"__declspec(dllimport) ";
6611 Result +=
"struct _class_t ";
6618 Result +=
"\nextern \"C\" __declspec(dllexport) struct _class_t ";
6620 Result +=
" __attribute__ ((used, section (\"__DATA,__objc_data\"))) = {\n";
6624 Result +=
"0, // &"; Result += VarName;
6627 Result +=
"0, // &"; Result += VarName;
6632 Result +=
"0, // &"; Result += VarName;
6640 Result +=
"0, // &OBJC_METACLASS_$_";
6644 Result +=
"0, // &"; Result += VarName;
6651 Result +=
"0, // (void *)&_objc_empty_cache,\n\t";
6652 Result +=
"0, // unused, was (void *)&_objc_empty_vtable,\n\t";
6654 Result +=
"&_OBJC_METACLASS_RO_$_";
6656 Result +=
"&_OBJC_CLASS_RO_$_";
6658 Result +=
",\n};\n";
6668 Result +=
"static void OBJC_CLASS_SETUP_$_";
6670 Result +=
"(void ) {\n";
6672 Result +=
".isa = "; Result +=
"&OBJC_METACLASS_$_";
6676 Result +=
".superclass = ";
6678 Result +=
"&OBJC_CLASS_$_";
6680 Result +=
"&OBJC_METACLASS_$_";
6685 Result +=
".cache = "; Result +=
"&_objc_empty_cache"; Result +=
";\n";
6688 Result +=
".isa = "; Result +=
"&OBJC_METACLASS_$_";
6693 Result +=
".superclass = "; Result +=
"&OBJC_CLASS_$_";
6698 Result +=
".cache = "; Result +=
"&_objc_empty_cache"; Result +=
";\n";
6702 static void Write_category_t(RewriteModernObjC &RewriteObj,
ASTContext *Context,
6703 std::string &Result,
6706 ArrayRef<ObjCMethodDecl *> InstanceMethods,
6707 ArrayRef<ObjCMethodDecl *> ClassMethods,
6708 ArrayRef<ObjCProtocolDecl *> RefedProtocols,
6709 ArrayRef<ObjCPropertyDecl *> ClassProperties) {
6710 StringRef CatName = CatDecl->
getName();
6711 StringRef ClassName = ClassDecl->
getName();
6715 Result +=
"extern \"C\" ";
6717 Result +=
"__declspec(dllexport) ";
6719 Result +=
"__declspec(dllimport) ";
6721 Result +=
"struct _class_t ";
6722 Result +=
"OBJC_CLASS_$_"; Result += ClassName;
6725 Result +=
"\nstatic struct _category_t ";
6726 Result +=
"_OBJC_$_CATEGORY_";
6727 Result += ClassName; Result +=
"_$_"; Result += CatName;
6728 Result +=
" __attribute__ ((used, section (\"__DATA,__objc_const\"))) = \n";
6730 Result +=
"\t\""; Result += ClassName; Result +=
"\",\n";
6731 Result +=
"\t0, // &"; Result +=
"OBJC_CLASS_$_"; Result += ClassName;
6733 if (InstanceMethods.size() > 0) {
6734 Result +=
"\t(const struct _method_list_t *)&";
6735 Result +=
"_OBJC_$_CATEGORY_INSTANCE_METHODS_";
6736 Result += ClassName; Result +=
"_$_"; Result += CatName;
6742 if (ClassMethods.size() > 0) {
6743 Result +=
"\t(const struct _method_list_t *)&";
6744 Result +=
"_OBJC_$_CATEGORY_CLASS_METHODS_";
6745 Result += ClassName; Result +=
"_$_"; Result += CatName;
6751 if (RefedProtocols.size() > 0) {
6752 Result +=
"\t(const struct _protocol_list_t *)&";
6753 Result +=
"_OBJC_CATEGORY_PROTOCOLS_$_";
6754 Result += ClassName; Result +=
"_$_"; Result += CatName;
6760 if (ClassProperties.size() > 0) {
6761 Result +=
"\t(const struct _prop_list_t *)&"; Result +=
"_OBJC_$_PROP_LIST_";
6762 Result += ClassName; Result +=
"_$_"; Result += CatName;
6771 Result +=
"static void OBJC_CATEGORY_SETUP_$_";
6775 Result +=
"(void ) {\n";
6776 Result +=
"\t_OBJC_$_CATEGORY_";
6780 Result +=
".cls = "; Result +=
"&OBJC_CLASS_$_"; Result += ClassName;
6784 static void Write__extendedMethodTypes_initializer(RewriteModernObjC &RewriteObj,
6786 ArrayRef<ObjCMethodDecl *> Methods,
6788 StringRef ProtocolName) {
6789 if (Methods.size() == 0)
6792 Result +=
"\nstatic const char *";
6793 Result += VarName; Result += ProtocolName;
6794 Result +=
" [] __attribute__ ((used, section (\"__DATA,__objc_const\"))) = \n";
6796 for (
unsigned i = 0, e = Methods.size(); i < e; i++) {
6798 std::string MethodTypeString, QuoteMethodTypeString;
6800 RewriteObj.QuoteDoublequotes(MethodTypeString, QuoteMethodTypeString);
6801 Result +=
"\t\""; Result += QuoteMethodTypeString; Result +=
"\"";
6810 static void Write_IvarOffsetVar(RewriteModernObjC &RewriteObj,
6812 std::string &Result,
6813 ArrayRef<ObjCIvarDecl *> Ivars,
6827 for (
unsigned i =0, e = Ivars.size(); i < e; i++) {
6830 Result +=
"__declspec(allocate(\".objc_ivar$B\")) ";
6835 Result +=
"extern \"C\" unsigned long int ";
6837 Result +=
"extern \"C\" __declspec(dllexport) unsigned long int ";
6838 if (Ivars[i]->isBitField())
6839 RewriteObj.ObjCIvarBitfieldGroupOffset(IvarDecl, Result);
6841 WriteInternalIvarName(CDecl, IvarDecl, Result);
6842 Result +=
" __attribute__ ((used, section (\"__DATA,__objc_ivar\")))";
6844 RewriteObj.RewriteIvarOffsetComputation(IvarDecl, Result);
6846 if (Ivars[i]->isBitField()) {
6848 SKIP_BITFIELDS(i , e, Ivars);
6853 static void Write__ivar_list_t_initializer(RewriteModernObjC &RewriteObj,
6855 ArrayRef<ObjCIvarDecl *> OriginalIvars,
6858 if (OriginalIvars.size() > 0) {
6859 Write_IvarOffsetVar(RewriteObj, Context, Result, OriginalIvars, CDecl);
6860 SmallVector<ObjCIvarDecl *, 8> Ivars;
6864 for (
unsigned i = 0, e = OriginalIvars.size(); i < e; i++) {
6865 if (OriginalIvars[i]->isBitField()) {
6866 Ivars.push_back(OriginalIvars[i]);
6868 SKIP_BITFIELDS(i , e, OriginalIvars);
6871 Ivars.push_back(OriginalIvars[i]);
6874 Result +=
"\nstatic ";
6875 Write__ivar_list_t_TypeDecl(Result, Ivars.size());
6876 Result +=
" "; Result += VarName;
6878 Result +=
" __attribute__ ((used, section (\"__DATA,__objc_const\"))) = {\n";
6879 Result +=
"\t"; Result +=
"sizeof(_ivar_t)"; Result +=
",\n";
6880 Result +=
"\t"; Result += utostr(Ivars.size()); Result +=
",\n";
6881 for (
unsigned i =0, e = Ivars.size(); i < e; i++) {
6887 Result +=
"(unsigned long int *)&";
6888 if (Ivars[i]->isBitField())
6889 RewriteObj.ObjCIvarBitfieldGroupOffset(IvarDecl, Result);
6891 WriteInternalIvarName(CDecl, IvarDecl, Result);
6895 if (Ivars[i]->isBitField())
6896 RewriteObj.ObjCIvarBitfieldGroupDecl(Ivars[i], Result);
6898 Result += IvarDecl->
getName();
6903 IVQT = RewriteObj.GetGroupRecordTypeForObjCIvarBitfield(IvarDecl);
6905 std::string IvarTypeString, QuoteIvarTypeString;
6908 RewriteObj.QuoteDoublequotes(IvarTypeString, QuoteIvarTypeString);
6909 Result +=
"\""; Result += QuoteIvarTypeString; Result +=
"\", ";
6914 Align = llvm::Log2_32(Align);
6915 Result += llvm::utostr(Align); Result +=
", ";
6928 void RewriteModernObjC::RewriteObjCProtocolMetaData(
ObjCProtocolDecl *PDecl,
6929 std::string &Result) {
6934 WriteModernMetadataDeclarations(Context, Result);
6941 RewriteObjCProtocolMetaData(I, Result);
6944 std::vector<ObjCMethodDecl *> InstanceMethods, ClassMethods;
6945 std::vector<ObjCMethodDecl *> OptInstanceMethods, OptClassMethods;
6948 OptInstanceMethods.push_back(MD);
6950 InstanceMethods.push_back(MD);
6956 OptClassMethods.push_back(MD);
6958 ClassMethods.push_back(MD);
6961 std::vector<ObjCMethodDecl *> AllMethods;
6962 for (
unsigned i = 0, e = InstanceMethods.size(); i < e; i++)
6963 AllMethods.push_back(InstanceMethods[i]);
6964 for (
unsigned i = 0, e = ClassMethods.size(); i < e; i++)
6965 AllMethods.push_back(ClassMethods[i]);
6966 for (
unsigned i = 0, e = OptInstanceMethods.size(); i < e; i++)
6967 AllMethods.push_back(OptInstanceMethods[i]);
6968 for (
unsigned i = 0, e = OptClassMethods.size(); i < e; i++)
6969 AllMethods.push_back(OptClassMethods[i]);
6971 Write__extendedMethodTypes_initializer(*
this, Context, Result,
6973 "_OBJC_PROTOCOL_METHOD_TYPES_",
6976 SmallVector<ObjCProtocolDecl *, 8> SuperProtocols(PDecl->
protocols());
6977 Write_protocol_list_initializer(Context, Result, SuperProtocols,
6978 "_OBJC_PROTOCOL_REFS_",
6981 Write_method_list_t_initializer(*
this, Context, Result, InstanceMethods,
6982 "_OBJC_PROTOCOL_INSTANCE_METHODS_",
6985 Write_method_list_t_initializer(*
this, Context, Result, ClassMethods,
6986 "_OBJC_PROTOCOL_CLASS_METHODS_",
6989 Write_method_list_t_initializer(*
this, Context, Result, OptInstanceMethods,
6990 "_OBJC_PROTOCOL_OPT_INSTANCE_METHODS_",
6993 Write_method_list_t_initializer(*
this, Context, Result, OptClassMethods,
6994 "_OBJC_PROTOCOL_OPT_CLASS_METHODS_",
6998 SmallVector<ObjCPropertyDecl *, 8> ProtocolProperties(PDecl->
properties());
6999 Write_prop_list_t_initializer(*
this, Context, Result, ProtocolProperties,
7001 "_OBJC_PROTOCOL_PROPERTIES_",
7006 if (LangOpts.MicrosoftExt)
7007 Result +=
"static ";
7008 Result +=
"struct _protocol_t _OBJC_PROTOCOL_";
7010 Result +=
" __attribute__ ((used, section (\"__DATA,__datacoal_nt,coalesced\"))) = {\n";
7012 Result +=
"\t\""; Result += PDecl->
getNameAsString(); Result +=
"\",\n";
7013 if (SuperProtocols.size() > 0) {
7014 Result +=
"\t(const struct _protocol_list_t *)&"; Result +=
"_OBJC_PROTOCOL_REFS_";
7019 if (InstanceMethods.size() > 0) {
7020 Result +=
"\t(const struct method_list_t *)&_OBJC_PROTOCOL_INSTANCE_METHODS_";
7026 if (ClassMethods.size() > 0) {
7027 Result +=
"\t(const struct method_list_t *)&_OBJC_PROTOCOL_CLASS_METHODS_";
7033 if (OptInstanceMethods.size() > 0) {
7034 Result +=
"\t(const struct method_list_t *)&_OBJC_PROTOCOL_OPT_INSTANCE_METHODS_";
7040 if (OptClassMethods.size() > 0) {
7041 Result +=
"\t(const struct method_list_t *)&_OBJC_PROTOCOL_OPT_CLASS_METHODS_";
7047 if (ProtocolProperties.size() > 0) {
7048 Result +=
"\t(const struct _prop_list_t *)&_OBJC_PROTOCOL_PROPERTIES_";
7054 Result +=
"\t"; Result +=
"sizeof(_protocol_t)"; Result +=
",\n";
7057 if (AllMethods.size() > 0) {
7058 Result +=
"\t(const char **)&"; Result +=
"_OBJC_PROTOCOL_METHOD_TYPES_";
7063 Result +=
"\t0\n};\n";
7065 if (LangOpts.MicrosoftExt)
7066 Result +=
"static ";
7067 Result +=
"struct _protocol_t *";
7068 Result +=
"_OBJC_LABEL_PROTOCOL_$_"; Result += PDecl->
getNameAsString();
7074 llvm_unreachable(
"protocol already synthesized");
7078 void RewriteModernObjC::RewriteObjCProtocolListMetaData(
7080 StringRef prefix, StringRef ClassName,
7081 std::string &Result) {
7082 if (Protocols.
empty())
return;
7084 for (
unsigned i = 0; i != Protocols.
size(); i++)
7085 RewriteObjCProtocolMetaData(Protocols[i], Result);
7095 if (LangOpts.MicrosoftExt)
7096 Result +=
"__declspec(allocate(\".cat_cls_meth$B\")) ";
7097 Result +=
"static struct {\n";
7098 Result +=
"\tstruct _objc_protocol_list *next;\n";
7099 Result +=
"\tint protocol_count;\n";
7100 Result +=
"\tstruct _objc_protocol *class_protocols[";
7101 Result += utostr(Protocols.
size());
7102 Result +=
"];\n} _OBJC_";
7104 Result +=
"_PROTOCOLS_";
7105 Result += ClassName;
7106 Result +=
" __attribute__ ((used, section (\"__OBJC, __cat_cls_meth\")))= "
7108 Result += utostr(Protocols.
size());
7111 Result +=
"\t,{&_OBJC_PROTOCOL_";
7112 Result += Protocols[0]->getNameAsString();
7115 for (
unsigned i = 1; i != Protocols.
size(); i++) {
7116 Result +=
"\t ,&_OBJC_PROTOCOL_";
7117 Result += Protocols[i]->getNameAsString();
7120 Result +=
"\t }\n};\n";
7128 if (OID->
hasAttr<ObjCExceptionAttr>())
7136 std::string &Result) {
7142 "Legacy implicit interface rewriting not supported in moder abi");
7144 WriteModernMetadataDeclarations(Context, Result);
7145 SmallVector<ObjCIvarDecl *, 8> IVars;
7150 if (!IVD->getDeclName())
7152 IVars.push_back(IVD);
7155 Write__ivar_list_t_initializer(*
this, Context, Result, IVars,
7156 "_OBJC_$_INSTANCE_VARIABLES_",
7160 SmallVector<ObjCMethodDecl *, 32> InstanceMethods(IDecl->
instance_methods());
7165 if (Prop->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic)
7167 if (!Prop->getPropertyIvarDecl())
7173 if (mustSynthesizeSetterGetterMethod(IDecl, PD,
true ))
7174 InstanceMethods.push_back(Getter);
7178 if (mustSynthesizeSetterGetterMethod(IDecl, PD,
false ))
7179 InstanceMethods.push_back(Setter);
7182 Write_method_list_t_initializer(*
this, Context, Result, InstanceMethods,
7183 "_OBJC_$_INSTANCE_METHODS_",
7186 SmallVector<ObjCMethodDecl *, 32> ClassMethods(IDecl->
class_methods());
7188 Write_method_list_t_initializer(*
this, Context, Result, ClassMethods,
7189 "_OBJC_$_CLASS_METHODS_",
7194 std::vector<ObjCProtocolDecl *> RefedProtocols;
7197 E = Protocols.
end();
7199 RefedProtocols.push_back(*I);
7202 RewriteObjCProtocolMetaData(*I, Result);
7205 Write_protocol_list_initializer(Context, Result,
7207 "_OBJC_CLASS_PROTOCOLS_$_",
7211 SmallVector<ObjCPropertyDecl *, 8> ClassProperties(CDecl->
properties());
7212 Write_prop_list_t_initializer(*
this, Context, Result, ClassProperties,
7214 "_OBJC_$_PROP_LIST_",
7219 uint32_t flags = CLS_META;
7220 std::string InstanceSize;
7221 std::string InstanceStart;
7226 flags |= OBJC2_CLS_HIDDEN;
7231 InstanceSize =
"sizeof(struct _class_t)";
7232 InstanceStart = InstanceSize;
7233 Write__class_ro_t_initializer(Context, Result, flags,
7234 InstanceStart, InstanceSize,
7239 "_OBJC_METACLASS_RO_$_",
7245 flags |= OBJC2_CLS_HIDDEN;
7248 flags |= CLS_EXCEPTION;
7254 InstanceSize.clear();
7255 InstanceStart.clear();
7256 if (!ObjCSynthesizedStructs.count(CDecl)) {
7258 InstanceStart =
"0";
7261 InstanceSize =
"sizeof(struct ";
7263 InstanceSize +=
"_IMPL)";
7267 RewriteIvarOffsetComputation(IVD, InstanceStart);
7270 InstanceStart = InstanceSize;
7272 Write__class_ro_t_initializer(Context, Result, flags,
7273 InstanceStart, InstanceSize,
7278 "_OBJC_CLASS_RO_$_",
7281 Write_class_t(Context, Result,
7282 "OBJC_METACLASS_$_",
7285 Write_class_t(Context, Result,
7289 if (ImplementationIsNonLazy(IDecl))
7290 DefinedNonLazyClasses.push_back(CDecl);
7294 void RewriteModernObjC::RewriteClassSetupInitHook(std::string &Result) {
7295 int ClsDefCount = ClassImplementation.size();
7298 Result +=
"#pragma section(\".objc_inithooks$B\", long, read, write)\n";
7299 Result +=
"__declspec(allocate(\".objc_inithooks$B\")) ";
7300 Result +=
"static void *OBJC_CLASS_SETUP[] = {\n";
7301 for (
int i = 0; i < ClsDefCount; i++) {
7304 Result +=
"\t(void *)&OBJC_CLASS_SETUP_$_";
7305 Result += CDecl->
getName(); Result +=
",\n";
7310 void RewriteModernObjC::RewriteMetaDataIntoBuffer(std::string &Result) {
7311 int ClsDefCount = ClassImplementation.size();
7312 int CatDefCount = CategoryImplementation.size();
7315 for (
int i = 0; i < ClsDefCount; i++)
7316 RewriteObjCClassMetaData(ClassImplementation[i], Result);
7318 RewriteClassSetupInitHook(Result);
7321 for (
int i = 0; i < CatDefCount; i++)
7322 RewriteObjCCategoryImplDecl(CategoryImplementation[i], Result);
7324 RewriteCategorySetupInitHook(Result);
7326 if (ClsDefCount > 0) {
7327 if (LangOpts.MicrosoftExt)
7328 Result +=
"__declspec(allocate(\".objc_classlist$B\")) ";
7329 Result +=
"static struct _class_t *L_OBJC_LABEL_CLASS_$ [";
7330 Result += llvm::utostr(ClsDefCount); Result +=
"]";
7332 " __attribute__((used, section (\"__DATA, __objc_classlist,"
7333 "regular,no_dead_strip\")))= {\n";
7334 for (
int i = 0; i < ClsDefCount; i++) {
7335 Result +=
"\t&OBJC_CLASS_$_";
7336 Result += ClassImplementation[i]->getNameAsString();
7341 if (!DefinedNonLazyClasses.empty()) {
7342 if (LangOpts.MicrosoftExt)
7343 Result +=
"__declspec(allocate(\".objc_nlclslist$B\")) \n";
7344 Result +=
"static struct _class_t *_OBJC_LABEL_NONLAZY_CLASS_$[] = {\n\t";
7345 for (
unsigned i = 0, e = DefinedNonLazyClasses.size(); i < e; i++) {
7346 Result +=
"\t&OBJC_CLASS_$_"; Result += DefinedNonLazyClasses[i]->getNameAsString();
7353 if (CatDefCount > 0) {
7354 if (LangOpts.MicrosoftExt)
7355 Result +=
"__declspec(allocate(\".objc_catlist$B\")) ";
7356 Result +=
"static struct _category_t *L_OBJC_LABEL_CATEGORY_$ [";
7357 Result += llvm::utostr(CatDefCount); Result +=
"]";
7359 " __attribute__((used, section (\"__DATA, __objc_catlist,"
7360 "regular,no_dead_strip\")))= {\n";
7361 for (
int i = 0; i < CatDefCount; i++) {
7362 Result +=
"\t&_OBJC_$_CATEGORY_";
7364 CategoryImplementation[i]->getClassInterface()->getNameAsString();
7366 Result += CategoryImplementation[i]->getNameAsString();
7372 if (!DefinedNonLazyCategories.empty()) {
7373 if (LangOpts.MicrosoftExt)
7374 Result +=
"__declspec(allocate(\".objc_nlcatlist$B\")) \n";
7375 Result +=
"static struct _category_t *_OBJC_LABEL_NONLAZY_CATEGORY_$[] = {\n\t";
7376 for (
unsigned i = 0, e = DefinedNonLazyCategories.size(); i < e; i++) {
7377 Result +=
"\t&_OBJC_$_CATEGORY_";
7379 DefinedNonLazyCategories[i]->getClassInterface()->getNameAsString();
7381 Result += DefinedNonLazyCategories[i]->getNameAsString();
7388 void RewriteModernObjC::WriteImageInfo(std::string &Result) {
7389 if (LangOpts.MicrosoftExt)
7390 Result +=
"__declspec(allocate(\".objc_imageinfo$B\")) \n";
7392 Result +=
"static struct IMAGE_INFO { unsigned version; unsigned flag; } ";
7394 Result +=
"_OBJC_IMAGE_INFO = { 0, 2 };\n";
7400 std::string &Result) {
7401 WriteModernMetadataDeclarations(Context, Result);
7408 FullCategoryName +=
"_$_";
7412 SmallVector<ObjCMethodDecl *, 32> InstanceMethods(IDecl->
instance_methods());
7417 if (Prop->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic)
7419 if (!Prop->getPropertyIvarDecl())
7425 InstanceMethods.push_back(Getter);
7429 InstanceMethods.push_back(Setter);
7432 Write_method_list_t_initializer(*
this, Context, Result, InstanceMethods,
7433 "_OBJC_$_CATEGORY_INSTANCE_METHODS_",
7434 FullCategoryName,
true);
7436 SmallVector<ObjCMethodDecl *, 32> ClassMethods(IDecl->
class_methods());
7438 Write_method_list_t_initializer(*
this, Context, Result, ClassMethods,
7439 "_OBJC_$_CATEGORY_CLASS_METHODS_",
7440 FullCategoryName,
true);
7444 SmallVector<ObjCProtocolDecl *, 8> RefedProtocols(CDecl->
protocols());
7448 RewriteObjCProtocolMetaData(I, Result);
7450 Write_protocol_list_initializer(Context, Result,
7452 "_OBJC_CATEGORY_PROTOCOLS_$_",
7456 SmallVector<ObjCPropertyDecl *, 8> ClassProperties(CDecl->
properties());
7457 Write_prop_list_t_initializer(*
this, Context, Result, ClassProperties,
7459 "_OBJC_$_PROP_LIST_",
7462 Write_category_t(*
this, Context, Result,
7471 if (ImplementationIsNonLazy(IDecl))
7472 DefinedNonLazyCategories.push_back(CDecl);
7476 void RewriteModernObjC::RewriteCategorySetupInitHook(std::string &Result) {
7477 int CatDefCount = CategoryImplementation.size();
7480 Result +=
"#pragma section(\".objc_inithooks$B\", long, read, write)\n";
7481 Result +=
"__declspec(allocate(\".objc_inithooks$B\")) ";
7482 Result +=
"static void *OBJC_CATEGORY_SETUP[] = {\n";
7483 for (
int i = 0; i < CatDefCount; i++) {
7487 Result +=
"\t(void *)&OBJC_CATEGORY_SETUP_$_";
7488 Result += ClassDecl->
getName();
7498 template<
typename MethodIterator>
7499 void RewriteModernObjC::RewriteObjCMethodsMetaData(MethodIterator MethodBegin,
7500 MethodIterator MethodEnd,
7501 bool IsInstanceMethod,
7503 StringRef ClassName,
7504 std::string &Result) {
7505 if (MethodBegin == MethodEnd)
return;
7507 if (!objc_impl_method) {
7514 Result +=
"\nstruct _objc_method {\n";
7515 Result +=
"\tSEL _cmd;\n";
7516 Result +=
"\tchar *method_types;\n";
7517 Result +=
"\tvoid *_imp;\n";
7520 objc_impl_method =
true;
7531 unsigned NumMethods = std::distance(MethodBegin, MethodEnd);
7533 if (LangOpts.MicrosoftExt) {
7534 if (IsInstanceMethod)
7535 Result +=
"__declspec(allocate(\".inst_meth$B\")) ";
7537 Result +=
"__declspec(allocate(\".cls_meth$B\")) ";
7539 Result +=
"static struct {\n";
7540 Result +=
"\tstruct _objc_method_list *next_method;\n";
7541 Result +=
"\tint method_count;\n";
7542 Result +=
"\tstruct _objc_method method_list[";
7543 Result += utostr(NumMethods);
7544 Result +=
"];\n} _OBJC_";
7546 Result += IsInstanceMethod ?
"INSTANCE" :
"CLASS";
7547 Result +=
"_METHODS_";
7548 Result += ClassName;
7549 Result +=
" __attribute__ ((used, section (\"__OBJC, __";
7550 Result += IsInstanceMethod ?
"inst" :
"cls";
7551 Result +=
"_meth\")))= ";
7552 Result +=
"{\n\t0, " + utostr(NumMethods) +
"\n";
7554 Result +=
"\t,{{(SEL)\"";
7555 Result += (*MethodBegin)->getSelector().getAsString().c_str();
7556 std::string MethodTypeString;
7559 Result += MethodTypeString;
7560 Result +=
"\", (void *)";
7561 Result += MethodInternalNames[*MethodBegin];
7563 for (++MethodBegin; MethodBegin != MethodEnd; ++MethodBegin) {
7564 Result +=
"\t ,{(SEL)\"";
7565 Result += (*MethodBegin)->getSelector().getAsString().c_str();
7566 std::string MethodTypeString;
7569 Result += MethodTypeString;
7570 Result +=
"\", (void *)";
7571 Result += MethodInternalNames[*MethodBegin];
7574 Result +=
"\t }\n};\n";
7583 DisableReplaceStmtScope
S(*
this);
7584 BaseExpr = cast<Expr>(RewriteFunctionBodyOrGlobalInitializer(BaseExpr));
7590 Expr *Replacement = IV;
7595 assert(iFaceDecl &&
"RewriteObjCIvarRefExpr - iFaceDecl is null");
7600 assert(clsDeclared &&
"RewriteObjCIvarRefExpr(): Can't find class");
7603 std::string IvarOffsetName;
7605 ObjCIvarBitfieldGroupOffset(D, IvarOffsetName);
7607 WriteInternalIvarName(clsDeclared, D, IvarOffsetName);
7609 ReferencedIvars[clsDeclared].insert(D);
7612 CastExpr *castExpr = NoTypeInfoCStyleCastExpr(Context,
7633 IvarT = GetGroupRecordTypeForObjCIvarBitfield(D);
7635 if (!isa<TypedefType>(IvarT) && IvarT->
isRecordType()) {
7645 std::string RecName = CDecl->
getName();
7651 unsigned UnsignedIntSize =
7654 llvm::APInt(UnsignedIntSize, 0),
7656 Zero = NoTypeInfoCStyleCastExpr(Context, PtrStructIMPL,
CK_BitCast, Zero);
7671 convertObjCTypeToCStyleType(IvarT);
7674 castExpr = NoTypeInfoCStyleCastExpr(Context,
7681 VK_LValue, OK_Ordinary,
7704 ReplaceStmtWithRange(IV, Replacement, OldRange);
SourceLocation getEnd() const
const Expr * getBase() const
ObjCInterfaceDecl * getDecl() const
Get the declaration of this interface.
CastKind getCastKind() const
FunctionDecl - An instance of this class is created to represent a function declaration or definition...
StringRef getName() const
getName - Get the name of identifier for this declaration as a StringRef.
protocol_range protocols() const
Expr * getSyntacticForm()
Return the syntactic form of this expression, i.e.
Smart pointer class that efficiently represents Objective-C method names.
SourceLocation getLocStart() const LLVM_READONLY
PointerType - C99 6.7.5.1 - Pointer Declarators.
const ObjCAtFinallyStmt * getFinallyStmt() const
Retrieve the @finally statement, if any.
A (possibly-)qualified type.
ImplementationControl getImplementationControl() const
ObjCInterfaceDecl * getClassInterface()
ObjCInterfaceDecl * getClassInterface()
bool isBitField() const
Determines whether this field is a bitfield.
ASTConsumer - This is an abstract interface that should be implemented by clients that read ASTs...
QualType getClassReceiver() const
Returns the type of a class message send, or NULL if the message is not a class message.
IdentifierInfo * getIdentifier() const
getIdentifier - Get the identifier that names this declaration, if there is one.
CanQual< T > getUnqualifiedType() const
Retrieve the unqualified form of this type.
std::unique_ptr< ASTConsumer > CreateModernObjCRewriter(const std::string &InFile, raw_ostream *OS, DiagnosticsEngine &Diags, const LangOptions &LOpts, bool SilenceRewriteMacroWarning, bool LineInfo)
FunctionType - C99 6.7.5.3 - Function Declarators.
bool isMain() const
Determines whether this function is "main", which is the entry point into an executable program...
bool isThisDeclarationADefinition() const
Determine whether this particular declaration of this class is actually also a definition.
Defines the SourceManager interface.
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
SourceLocation getForLoc() const
bool isRecordType() const
Decl - This represents one declaration (or definition), e.g.
SourceLocation getLocEnd() const LLVM_READONLY
const char * getCharacterData(SourceLocation SL, bool *Invalid=nullptr) const
Return a pointer to the start of the specified location in the appropriate spelling MemoryBuffer...
param_iterator param_end()
llvm::MemoryBuffer * getBuffer(FileID FID, SourceLocation Loc, bool *Invalid=nullptr) const
Return the buffer for the specified FileID.
bool isEnumeralType() const
ParenExpr - This represents a parethesized expression, e.g.
void getSelectorLocs(SmallVectorImpl< SourceLocation > &SelLocs) const
std::string getAsString() const
FullSourceLoc getFullLoc(SourceLocation Loc) const
IdentifierInfo * getAsIdentifierInfo() const
getAsIdentifierInfo - Retrieve the IdentifierInfo * stored in this declaration name, or NULL if this declaration name isn't a simple identifier.
The base class of the type hierarchy.
SourceLocation getLocStart() const LLVM_READONLY
bool isObjCQualifiedClassType() const
Represents Objective-C's @throw statement.
SourceLocation getLocStart() const LLVM_READONLY
Represents an array type, per C99 6.7.5.2 - Array Declarators.
const Expr * getInit() const
Represents a call to a C++ constructor.
virtual void completeDefinition()
completeDefinition - Notes that the definition of this type is now complete.
static bool hasObjCExceptionAttribute(ASTContext &Context, const ObjCInterfaceDecl *OID)
hasObjCExceptionAttribute - Return true if this class or any super class has the objc_exception attri...
bool isBooleanType() const
A container of type source information.
bool isBlockPointerType() const
static StringLiteral * Create(const ASTContext &C, StringRef Str, StringKind Kind, bool Pascal, QualType Ty, const SourceLocation *Loc, unsigned NumStrs)
This is the "fully general" constructor that allows representation of strings formed from multiple co...
protocol_range protocols() const
SourceLocation getLocStart() const LLVM_READONLY
SourceLocation getLocEnd() const LLVM_READONLY
Represents a C++ constructor within a class.
ObjCDictionaryElement getKeyValueElement(unsigned Index) const
VarDecl - An instance of this class is created to represent a variable declaration or definition...
Objects with "hidden" visibility are not seen by the dynamic linker.
CompoundLiteralExpr - [C99 6.5.2.5].
SourceLocation getIvarRBraceLoc() const
Extra information about a function prototype.
SourceLocation getLocStart() const LLVM_READONLY
QualType getObjCClassType() const
Represents the Objective-C Class type.
const FunctionProtoType * getFunctionType() const
getFunctionType - Return the underlying function type for this block.
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
ObjCMethodDecl - Represents an instance or class method declaration.
RewriteBuffer - As code is rewritten, SourceBuffer's from the original input with modifications get a...
Expr * IgnoreImplicit() LLVM_READONLY
IgnoreImplicit - Skip past any implicit AST nodes which might surround this expression.
Visibility getVisibility() const
Determines the visibility of this entity.
Describes how types, statements, expressions, and declarations should be printed. ...
void getAsStringInternal(std::string &Str, const PrintingPolicy &Policy) const
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
getIdentifier - Get the identifier that names the category interface associated with this implementat...
SourceLocation getLocStart() const LLVM_READONLY
QualType withConst() const
Retrieves a version of this type with const applied.
unsigned getNumParams() const
Kind getPropertyImplementation() const
RecordDecl - Represents a struct/union/class.
bool isExternC() const
Determines whether this function is a function with external, C linkage.
ObjCProtocolDecl * getCanonicalDecl() override
Retrieves the canonical declaration of this Objective-C protocol.
One of these records is kept for each identifier that is lexed.
ObjCProtocolDecl * getProtocol() const
An element in an Objective-C dictionary literal.
const ObjCInterfaceDecl * getContainingInterface() const
Return the class interface that this ivar is logically contained in; this is either the interface whe...
class LLVM_ALIGNAS(8) DependentTemplateSpecializationType const IdentifierInfo * Name
Represents a template specialization type whose template cannot be resolved, e.g. ...
Represents a class type in Objective C.
StringRef getBufferData(FileID FID, bool *Invalid=nullptr) const
Return a StringRef to the source buffer data for the specified FileID.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
unsigned getNumSemanticExprs() const
std::string getNameAsString() const
Get the name of the class associated with this interface.
FieldDecl - An instance of this class is created by Sema::ActOnField to represent a member of a struc...
bool isCompleteDefinition() const
isCompleteDefinition - Return true if this decl has its body fully specified.
StringLiteral * getString()
const Stmt * getBody() const
ObjCMethodDecl * getClassMethod(Selector Sel, bool AllowHidden=false) const
bool ReplaceText(SourceLocation Start, unsigned OrigLength, StringRef NewStr)
ReplaceText - This method replaces a range of characters in the input buffer with a new string...
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
ObjCArrayLiteral - used for objective-c array containers; as in: @["Hello", NSApp, [NSNumber numberWithInt:42]];.
QualType getTypeDeclType(const TypeDecl *Decl, const TypeDecl *PrevDecl=nullptr) const
Return the unique reference to the type for the specified type declaration.
bool hasBraces() const
Determines whether this linkage specification had braces in its syntactic form.
CK_IntegralToPointer - Integral to pointer.
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.
CK_IntegralToBoolean - Integral to boolean.
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.
ObjCContainerDecl - Represents a container for method declarations.
const LangOptions & getLangOpts() const
bool isImplicit() const
isImplicit - Indicates whether the declaration was implicitly generated by the implementation.
CharUnits - This is an opaque type for sizes expressed in character units.
QualType getReturnType() const
QualType getSuperType() const
Retrieve the type referred to by 'super'.
field_range fields() const
Concrete class used by the front-end to report problems and issues.
const ArrayType * getAsArrayType(QualType T) const
Type Query functions.
Represents a typeof (or typeof) expression (a GCC extension).
TypeDecl - Represents a declaration of a type.
A builtin binary operation expression such as "x + y" or "x <= y".
Selector getSelector() const
Selector getSetterName() const
bool isOverloadedOperator() const
isOverloadedOperator - Whether this function declaration represents an C++ overloaded operator...
std::string getNameAsString() const
getNameAsString - Get a human-readable name for the declaration, even if it is one of the special kin...
ObjCStringLiteral, used for Objective-C string literals i.e.
ObjCProtocolDecl * getDefinition()
Retrieve the definition of this protocol, if any.
bool isVariadic() const
Whether this function is variadic.
const Stmt * getCatchBody() const
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
CompoundStmt * getCompoundBody()
Represents an Objective-C protocol declaration.
const ObjCAtCatchStmt * getCatchStmt(unsigned I) const
Retrieve a @catch statement.
Expr * Key
The key for the dictionary element.
SourceLocation getLocStart() const LLVM_READONLY
SourceLocation getLocEnd() const LLVM_READONLY
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
unsigned getLine() const
Return the presumed line number of this location.
An ordinary object is located at an address in memory.
Represents an ObjC class declaration.
SourceLocation getLocEnd() const LLVM_READONLY
propimpl_range property_impls() const
Represents a linkage specification.
detail::InMemoryDirectory::const_iterator I
PropertyAttributeKind getPropertyAttributes() const
SourceLocation getAtLoc() const
CK_AnyPointerToBlockPointerCast - Casting any non-block pointer to a block pointer.
SourceRange getAtEndRange() const
ObjCPropertyImplDecl - Represents implementation declaration of a property in a class or category imp...
bool isThisDeclarationADefinition() const
Determine whether this particular declaration is also the definition.
ConditionalOperator - The ?: ternary operator.
SourceLocation getLocStart() const LLVM_READONLY
SourceLocation getLocEnd() const LLVM_READONLY
CompoundStmt - This represents a group of statements like { stmt stmt }.
QualType getParamType(unsigned i) const
Represents a prototype with parameter type info, e.g.
SourceLocation getLocEnd() const LLVM_READONLY
CastKind
CastKind - The kind of operation required for a conversion.
void getObjCEncodingForType(QualType T, std::string &S, const FieldDecl *Field=nullptr, QualType *NotEncodedT=nullptr) const
Emit the Objective-CC type encoding for the given type T into S.
SourceLocation getTypeSpecStartLoc() const
ID
Defines the set of possible language-specific address spaces.
CK_FunctionToPointerDecay - Function to pointer decay.
StorageClass getStorageClass() const
Returns the storage class as written in the source.
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee...
bool isFunctionPointerType() const
QualType getObjCInterfaceType(const ObjCInterfaceDecl *Decl, ObjCInterfaceDecl *PrevDecl=nullptr) const
getObjCInterfaceType - Return the unique reference to the type for the specified ObjC interface decl...
bool isRealFloatingType() const
Floating point categories.
const ObjCMethodDecl * getMethodDecl() const
SourceLocation getLocStart() const LLVM_READONLY
BlockDecl - This represents a block literal declaration, which is like an unnamed FunctionDecl...
QualType getPointeeType() const
ValueDecl - Represent the declaration of a variable (in which case it is an lvalue) a function (in wh...
Expr - This represents one expression.
StringRef getName() const
Return the actual identifier string.
CK_BitCast - A conversion which causes a bit pattern of one type to be reinterpreted as a bit pattern...
bool isBeforeInTranslationUnit(SourceLocation LHS, SourceLocation RHS) const
Determines the order of 2 source locations in the translation unit.
ObjCIvarDecl * getPropertyIvarDecl() const
Expr * getBitWidth() const
SourceLocation getRParenLoc() const
BlockExpr - Adaptor class for mixing a BlockDecl with expressions.
TranslationUnitDecl * getTranslationUnitDecl() const
bool isObjCGCWeak() const
true when Type is objc's weak.
Expr * getUnderlyingExpr() const
ObjCDictionaryLiteral - AST node to represent objective-c dictionary literals; as in:"name" : NSUserN...
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
bool isa(CodeGen::Address addr)
QualType getObjCIdType() const
Represents the Objective-CC id type.
An expression that sends a message to the given Objective-C object or class.
Represents an unpacked "presumed" location which can be presented to the user.
static OMPLinearClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, OpenMPLinearClauseKind Modifier, SourceLocation ModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL, ArrayRef< Expr * > PL, ArrayRef< Expr * > IL, Expr *Step, Expr *CalcStep)
Creates clause with a list of variables VL and a linear step Step.
UnaryOperator - This represents the unary-expression's (except sizeof and alignof), the postinc/postdec operators from postfix-expression, and various extensions.
DeclarationName getDeclName() const
getDeclName - Get the actual, stored name of the declaration, which may be a special name...
The result type of a method or function.
CStyleCastExpr - An explicit cast in C (C99 6.5.4) or a C-style cast in C++ (C++ [expr.cast]), which uses the syntax (Type)expr.
RecordDecl * getDefinition() const
getDefinition - Returns the RecordDecl that actually defines this struct/union/class.
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
CK_CPointerToObjCPointerCast - Casting a C pointer kind to an Objective-C pointer.
Stmt * getBody(const FunctionDecl *&Definition) const
getBody - Retrieve the body (definition) of the function.
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
PseudoObjectExpr - An expression which accesses a pseudo-object l-value.
SourceLocation getLocStart() const LLVM_READONLY
const char * getFilename() const
Return the presumed filename of this location.
Encodes a location in the source.
enumerator_range enumerators() const
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of enums...
const TemplateArgument * iterator
SourceLocation getLocStart() const LLVM_READONLY
unsigned getBitWidthValue(const ASTContext &Ctx) const
static LLVM_READONLY bool isAlphanumeric(unsigned char c)
Return true if this character is an ASCII letter or digit: [a-zA-Z0-9].
Interfaces are the core concept in Objective-C for object oriented design.
bool isValid() const
Return true if this is a valid SourceLocation object.
TagDecl - Represents the declaration of a struct/union/class/enum.
TypeSourceInfo * getTrivialTypeSourceInfo(QualType T, SourceLocation Loc=SourceLocation()) const
Allocate a TypeSourceInfo where all locations have been initialized to a given location, which defaults to the empty location.
bool refersToEnclosingVariableOrCapture() const
Does this DeclRefExpr refer to an enclosing local or a captured variable?
DeclStmt - Adaptor class for mixing declarations with statements and expressions. ...
QualType withConst() const
bool InsertText(SourceLocation Loc, StringRef Str, bool InsertAfter=true, bool indentNewLines=false)
InsertText - Insert the specified string at the specified location in the original buffer...
TypeSourceInfo * getClassReceiverTypeInfo() const
Returns a type-source information of a class message send, or NULL if the message is not a class mess...
SourceLocation getLocStart() const LLVM_READONLY
ObjCCategoryDecl - Represents a category declaration.
const ObjCInterfaceDecl * getClassInterface() const
decl_iterator decl_begin()
ObjCProtocolExpr used for protocol expression in Objective-C.
std::string getAsString() const
Derive the full selector name (e.g.
Represents one property declaration in an Objective-C interface.
ImplicitCastExpr - Allows us to explicitly represent implicit type conversions, which have no direct ...
QualType getReturnType() const
SourceLocation getBegin() const
const T * castAs() const
Member-template castAs<specific type>.
FileID getMainFileID() const
Returns the FileID of the main source file.
bool isFileContext() const
SourceLocation getAtSynchronizedLoc() const
ObjCBoxedExpr - used for generalized expression boxing.
const BlockDecl * getBlockDecl() const
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
QualType getObjCInstanceType()
Retrieve the Objective-C "instancetype" type, if already known; otherwise, returns a NULL type;...
QualType getPointeeType() const
Expr * Value
The value of the dictionary element.
void getObjCEncodingForPropertyDecl(const ObjCPropertyDecl *PD, const Decl *Container, std::string &S) const
getObjCEncodingForPropertyDecl - Return the encoded type for this method declaration.
QualType getFunctionType(QualType ResultTy, ArrayRef< QualType > Args, const FunctionProtoType::ExtProtoInfo &EPI) const
Return a normal function type with a typed argument list.
QualType getObjCSelType() const
Retrieve the type that corresponds to the predefined Objective-C 'SEL' type.
decl_iterator - Iterates through the declarations stored within this context.
Expr * getInstanceReceiver()
Returns the object expression (receiver) for an instance message, or null for a message that is not a...
ObjCIvarDecl * getNextIvar()
Base class for declarations which introduce a typedef-name.
Expr * getResultExpr()
Return the result-bearing expression, or null if there is none.
An opaque identifier used by SourceManager which refers to a source file (MemoryBuffer) along with it...
instmeth_range instance_methods() const
ObjCCategoryDecl * FindCategoryDeclaration(IdentifierInfo *CategoryId) const
FindCategoryDeclaration - Finds category declaration in the list of categories for this class and ret...
SourceLocation getLParenLoc() const
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
unsigned getByteLength() const
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
Returns the specified type after dropping any outer-level parentheses.
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
Selector getGetterName() const
U cast(CodeGen::Address addr)
bool isThisDeclarationADefinition() const
isThisDeclarationADefinition - Returns whether this specific declaration of the function is also a de...
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
EnumDecl - Represents an enum.
Selector getSelector() const
ObjCMethodDecl * getArrayWithObjectsMethod() const
CK_BlockPointerToObjCPointerCast - Casting a block pointer to an ObjC pointer.
detail::InMemoryDirectory::const_iterator E
SourceLocation getEndOfDefinitionLoc() const
CanQualType getCanonicalType(QualType T) const
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
ObjCMethodDecl * getDictWithObjectsMethod() const
Expr * IgnoreParenImpCasts() LLVM_READONLY
IgnoreParenImpCasts - Ignore parentheses and implicit casts.
Defines the Diagnostic-related interfaces.
Represents a pointer to an Objective C object.
CanQualType ObjCBuiltinBoolTy
SourceLocation getRParenLoc() const
ObjCImplementationDecl - Represents a class definition - this is where method definitions are specifi...
ObjCMethodDecl * getGetterMethodDecl() const
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
SourceLocation getLeftLoc() const
bool TypeAlias
Whether this template specialization type is a substituted type alias.
const T * getAs() const
Member-template getAs<specific type>'.
const Stmt * getSubStmt() const
Represents Objective-C's collection statement.
CanQualType UnsignedLongTy
ObjCMethodDecl * getSetterMethodDecl() const
ObjCEncodeExpr, used for @encode in Objective-C.
Selector getSelector(unsigned NumArgs, IdentifierInfo **IIV)
Can create any sort of selector.
SourceLocation getAtTryLoc() const
Retrieve the location of the @ in the @try.
static CStyleCastExpr * Create(const ASTContext &Context, QualType T, ExprValueKind VK, CastKind K, Expr *Op, const CXXCastPath *BasePath, TypeSourceInfo *WrittenTy, SourceLocation L, SourceLocation R)
bool isObjCQualifiedIdType() const
DeclContext * getRedeclContext()
getRedeclContext - Retrieve the context in which an entity conflicts with other entities of the same ...
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.
ExprIterator arg_iterator
unsigned getNumArgs() const
Return the number of actual arguments in this message, not counting the receiver. ...
QualType getTagDeclType(const TagDecl *Decl) const
Return the unique reference to the type for the specified TagDecl (struct/union/class/enum) decl...
bool getObjCEncodingForMethodDecl(const ObjCMethodDecl *Decl, std::string &S, bool Extended=false) const
Emit the encoded type for the method declaration Decl into S.
unsigned getNumCatchStmts() const
Retrieve the number of @catch statements in this try-catch-finally block.
SourceLocation getRParenLoc() const
ObjCIvarRefExpr - A reference to an ObjC instance variable.
SourceManager & getSourceManager()
bool isDefaultConstructor() const
Whether this constructor is a default constructor (C++ [class.ctor]p5), which can be used to default-...
X
Add a minimal nested name specifier fixit hint to allow lookup of a tag name from an outer enclosing ...
ObjCPropertyDecl * getPropertyDecl() const
AccessControl getAccessControl() const
classmeth_range class_methods() const
const internal::VariadicDynCastAllOfMatcher< Stmt, CastExpr > castExpr
Matches any cast nodes of Clang's AST.
Rewriter - This is the main interface to the rewrite buffers.
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
bool isImplicitInterfaceDecl() const
isImplicitInterfaceDecl - check that this is an implicitly declared ObjCInterfaceDecl node...
ContinueStmt - This represents a continue.
bool isReadOnly() const
isReadOnly - Return true iff the property has a setter.
bool isObjCObjectPointerType() const
QualType getEncodedType() const
ObjCIvarDecl - Represents an ObjC instance variable.
bool isImplicit() const
Indicates whether the message send was implicitly generated by the implementation.
SourceLocation getLocEnd() const LLVM_READONLY
Represents Objective-C's @try ... @catch ... @finally statement.
const Expr * getThrowExpr() const
SourceLocation getLocation() const
StringLiteral - This represents a string literal expression, e.g.
Defines the clang::TargetInfo interface.
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
ObjCInterfaceDecl * getSuperClass() const
ObjCBoolLiteralExpr - Objective-C Boolean Literal.
SourceLocation getIvarRBraceLoc() const
const Stmt * getTryBody() const
Retrieve the @try body.
TranslationUnitDecl - The top declaration context.
const internal::VariadicDynCastAllOfMatcher< Decl, FieldDecl > fieldDecl
Matches field declarations.
A reference to a declared variable, function, enum, etc.
ExprValueKind getValueKind() const
getValueKind - The value kind that this expression produces.
QualType getDecltypeType(Expr *e, QualType UnderlyingType) const
C++11 decltype.
QualType getConstantArrayType(QualType EltTy, const llvm::APInt &ArySize, ArrayType::ArraySizeModifier ASM, unsigned IndexTypeQuals) const
Return the unique reference to the type for a constant array of the specified element type...
QualType getElementType() const
BreakStmt - This represents a break.
Expr * getSemanticExpr(unsigned index)
SourceLocation getLocForStartOfFile(FileID FID) const
Return the source location corresponding to the first byte of the specified file. ...
An l-value expression is a reference to an object with independent storage.
A trivial tuple used to represent a source range.
SourceLocation getLocation() const
NamedDecl - This represents a decl with a name.
ObjCIvarDecl * all_declared_ivar_begin()
all_declared_ivar_begin - return first ivar declared in this class, its extensions and its implementa...
SourceLocation getLocStart() const LLVM_READONLY
SourceLocation getExpansionLoc(SourceLocation Loc) const
Given a SourceLocation object Loc, return the expansion location referenced by the ID...
SourceLocation getLocStart() const LLVM_READONLY
SourceLocation getLocEnd() const LLVM_READONLY
bool isConstQualified() const
Determine whether this type is const-qualified.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
const ObjCObjectPointerType * getAsObjCInterfacePointerType() const
ReceiverKind getReceiverKind() const
Determine the kind of receiver that this message is being sent to.
Represents Objective-C's @autoreleasepool Statement.
ObjCCategoryImplDecl - An object of this class encapsulates a category @implementation declaration...
Represents the canonical version of C arrays with a specified constant size.
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
getNumElements - Return number of elements of objective-c dictionary literal.
bool isObjCQualifiedInterfaceType() const
bool BlockRequiresCopying(QualType Ty, const VarDecl *D)
Returns true iff we need copy/dispose helpers for the given type.
CanQualType UnsignedIntTy
bool isPointerType() const
PresumedLoc getPresumedLoc(SourceLocation Loc, bool UseLineDirectives=true) const
Returns the "presumed" location of a SourceLocation specifies.