23 #include "clang/Config/config.h" 26 #include "llvm/ADT/DenseSet.h" 27 #include "llvm/ADT/SmallPtrSet.h" 28 #include "llvm/ADT/StringExtras.h" 29 #include "llvm/Support/MemoryBuffer.h" 30 #include "llvm/Support/raw_ostream.h" 33 #if CLANG_ENABLE_OBJC_REWRITER 35 using namespace clang;
56 BLOCK_NEEDS_FREE = (1 << 24),
59 BLOCK_IS_GC = (1 << 27),
61 BLOCK_HAS_DESCRIPTOR = (1 << 29)
71 const char *MainFileStart, *MainFileEnd;
74 std::string InFileName;
75 std::unique_ptr<raw_ostream> OutFile;
80 Expr *GlobalConstructionExp;
81 unsigned RewriteFailedDiag;
82 unsigned GlobalBlockRewriteFailedDiag;
84 unsigned NumObjCStringLiterals;
85 VarDecl *ConstantStringClassReference;
91 unsigned TryFinallyContainsReturnDiag;
113 llvm::SmallPtrSet<ObjCInterfaceDecl*, 8> ObjCSynthesizedStructs;
114 llvm::SmallPtrSet<ObjCProtocolDecl*, 8> ObjCSynthesizedProtocols;
115 llvm::SmallPtrSet<ObjCInterfaceDecl*, 8> ObjCWrittenInterfaces;
116 llvm::SmallPtrSet<TagDecl*, 32> GlobalDefinedTags;
127 llvm::SmallPtrSet<ObjCProtocolDecl *, 32> ProtocolExprDecls;
140 llvm::SmallPtrSet<ValueDecl *, 8> BlockByCopyDeclsPtrSet;
142 llvm::SmallPtrSet<ValueDecl *, 8> BlockByRefDeclsPtrSet;
143 llvm::DenseMap<ValueDecl *, unsigned> BlockByRefDeclNo;
144 llvm::SmallPtrSet<ValueDecl *, 8> ImportedBlockDecls;
145 llvm::SmallPtrSet<VarDecl *, 8> ImportedLocalExternalDecls;
147 llvm::DenseMap<BlockExpr *, std::string> RewrittenBlockExprs;
153 llvm::DenseMap<const ObjCIvarDecl* , unsigned> IvarGroupNumber;
156 llvm::DenseMap<std::pair<const ObjCInterfaceDecl*, unsigned>,
QualType> GroupRecordType;
162 llvm::DenseMap<Stmt *, Stmt *> ReplacedNodes;
166 bool SilenceRewriteMacroWarning;
167 bool GenerateLineInfo;
168 bool objc_impl_method;
170 bool DisableReplaceStmt;
171 class DisableReplaceStmtScope {
172 RewriteModernObjC &R;
176 DisableReplaceStmtScope(RewriteModernObjC &R)
177 : R(R), SavedValue(R.DisableReplaceStmt) {
178 R.DisableReplaceStmt =
true;
180 ~DisableReplaceStmtScope() {
181 R.DisableReplaceStmt = SavedValue;
187 llvm::DenseMap<ObjCMethodDecl*, std::string> MethodInternalNames;
192 if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(*I)) {
193 if (!
Class->isThisDeclarationADefinition()) {
194 RewriteForwardClassDecl(D);
198 ObjCInterfacesSeen.push_back(Class);
204 if (!Proto->isThisDeclarationADefinition()) {
205 RewriteForwardProtocolDecl(D);
215 if (FDecl->isThisDeclarationADefinition() &&
217 !FDecl->isTopLevelDeclInObjCContainer()) {
218 FunctionDefinitionsSeen.push_back(FDecl);
222 HandleTopLevelSingleDecl(*I);
227 void HandleTopLevelDeclInObjCContainer(
DeclGroupRef D)
override {
230 if (isTopLevelBlockPointerType(TD->getUnderlyingType()))
231 RewriteBlockPointerDecl(TD);
232 else if (TD->getUnderlyingType()->isFunctionPointerType())
233 CheckFunctionPointerDecl(TD->getUnderlyingType(), TD);
235 RewriteObjCQualifiedInterfaceTypes(TD);
240 void HandleTopLevelSingleDecl(
Decl *D);
241 void HandleDeclInMainFile(
Decl *D);
242 RewriteModernObjC(std::string inFile, std::unique_ptr<raw_ostream> OS,
244 bool silenceMacroWarn,
bool LineInfo);
246 ~RewriteModernObjC()
override {}
248 void HandleTranslationUnit(
ASTContext &
C)
override;
250 void ReplaceStmt(
Stmt *Old,
Stmt *New) {
255 assert(Old !=
nullptr && New !=
nullptr &&
"Expected non-null Stmt's");
257 Stmt *ReplacingStmt = ReplacedNodes[Old];
261 if (DisableReplaceStmt)
273 llvm::raw_string_ostream S(SStr);
275 const std::string &Str = S.str();
279 ReplacedNodes[Old] = New;
282 if (SilenceRewriteMacroWarning)
289 bool InsertAfter =
true) {
291 if (!Rewrite.
InsertText(Loc, Str, InsertAfter) ||
292 SilenceRewriteMacroWarning)
301 if (!Rewrite.
ReplaceText(Start, OrigLength, Str) ||
302 SilenceRewriteMacroWarning)
310 void RewriteInclude();
311 void RewriteLineDirective(
const Decl *D);
313 std::string &LineString);
316 void RewriteForwardClassEpilogue(ObjCInterfaceDecl *ClassDecl,
317 const std::string &typedefString);
318 void RewriteImplementations();
322 void RewriteInterfaceDecl(ObjCInterfaceDecl *Dcl);
323 void RewriteImplementationDecl(
Decl *Dcl);
324 void RewriteObjCMethodDecl(
const ObjCInterfaceDecl *IDecl,
326 void RewriteTypeIntoString(
QualType T, std::string &ResultStr,
328 void RewriteByRefString(std::string &ResultStr,
const std::string &Name,
337 void RewriteBlockPointerType(std::string& Str,
QualType Type);
338 void RewriteBlockPointerTypeVariable(std::string& Str,
ValueDecl *VD);
340 void RewriteObjCQualifiedInterfaceTypes(
Decl *Dcl);
341 void RewriteTypeOfDecl(
VarDecl *VD);
342 void RewriteObjCQualifiedInterfaceTypes(
Expr *E);
347 Stmt *RewriteFunctionBodyOrGlobalInitializer(
Stmt *S);
368 void RewriteImplicitCastObjCExpr(
CastExpr *IE);
380 QualType SynthesizeBitfieldGroupStructType(
388 void RewriteBlockPointerDecl(
NamedDecl *VD);
389 void RewriteByRefVar(
VarDecl *VD,
bool firstDecl,
bool lastDecl);
394 void RewriteObjCInternalStruct(ObjCInterfaceDecl *CDecl,
399 bool &IsNamedDefinition);
405 void RewriteIvarOffsetSymbols(ObjCInterfaceDecl *CDecl,
408 void Initialize(
ASTContext &context)
override;
427 void SynthCountByEnumWithState(std::string &buf);
428 void SynthMsgSendFunctionDecl();
429 void SynthMsgSendSuperFunctionDecl();
430 void SynthMsgSendStretFunctionDecl();
431 void SynthMsgSendFpretFunctionDecl();
432 void SynthMsgSendSuperStretFunctionDecl();
433 void SynthGetClassFunctionDecl();
434 void SynthGetMetaClassFunctionDecl();
435 void SynthGetSuperClassFunctionDecl();
436 void SynthSelGetUidFunctionDecl();
437 void SynthSuperConstructorFunctionDecl();
440 template<
typename MethodIterator>
441 void RewriteObjCMethodsMetaData(MethodIterator MethodBegin,
442 MethodIterator MethodEnd,
443 bool IsInstanceMethod,
451 void RewriteClassSetupInitHook(std::string &
Result);
453 void RewriteMetaDataIntoBuffer(std::string &
Result);
454 void WriteImageInfo(std::string &
Result);
457 void RewriteCategorySetupInitHook(std::string &
Result);
465 std::string SynthesizeByrefCopyDestroyHelper(
VarDecl *VD,
int flag);
466 std::string SynthesizeBlockHelperFuncs(
BlockExpr *CE,
int i,
467 StringRef funcName, std::string Tag);
468 std::string SynthesizeBlockFunc(
BlockExpr *CE,
int i,
469 StringRef funcName, std::string Tag);
470 std::string SynthesizeBlockImpl(
BlockExpr *CE,
471 std::string Tag, std::string Desc);
472 std::string SynthesizeBlockDescriptor(std::string DescTag,
474 int i, StringRef funcName,
485 void WarnAboutReturnGotoStmts(
Stmt *S);
487 void InsertBlockLiteralsWithinFunction(
FunctionDecl *FD);
490 bool IsDeclStmtInForeachHeader(
DeclStmt *DS);
491 void CollectBlockDeclRefInfo(
BlockExpr *Exp);
492 void GetBlockDeclRefExprs(
Stmt *S);
493 void GetInnerBlockDeclRefExprs(
Stmt *S,
495 llvm::SmallPtrSetImpl<const DeclContext *> &InnerContexts);
499 bool isTopLevelBlockPointerType(
QualType T) {
500 return isa<BlockPointerType>(T);
506 bool convertBlockPointerToFunctionPointer(
QualType &T) {
507 if (isTopLevelBlockPointerType(T)) {
515 bool convertObjCTypeToCStyleType(
QualType &T);
517 bool needToScanForQualifiers(
QualType T);
519 QualType getConstantStringStructType();
522 void convertToUnqualifiedObjCType(
QualType &T) {
553 if (isa<ObjCInterfaceType>(PT->getPointeeType()) ||
554 PT->getPointeeType()->isObjCQualifiedIdType())
560 bool PointerTypeTakesAnyBlockArguments(
QualType QT);
561 bool PointerTypeTakesAnyObjCQualifiedType(
QualType QT);
562 void GetExtentOfArgList(
const char *Name,
const char *&LParen,
563 const char *&RParen);
565 void QuoteDoublequotes(std::string &From, std::string &To) {
566 for (
unsigned i = 0;
i < From.length();
i++) {
576 bool variadic =
false) {
592 bool ImplementationIsNonLazy(
const ObjCImplDecl *OD)
const {
608 void RewriteModernObjC::RewriteBlocksInFunctionProtoType(
QualType funcType,
611 = dyn_cast<FunctionProtoType>(funcType.
IgnoreParens())) {
612 for (
const auto &I : fproto->param_types())
613 if (isTopLevelBlockPointerType(I)) {
615 RewriteBlockPointerDecl(D);
621 void RewriteModernObjC::CheckFunctionPointerDecl(
QualType funcType,
NamedDecl *ND) {
623 if (PT && PointerTypeTakesAnyBlockArguments(funcType))
628 std::string::size_type DotPos = Filename.rfind(
'.');
630 if (DotPos == std::string::npos) {
635 std::string Ext = std::string(Filename.begin()+DotPos+1, Filename.end());
638 return Ext ==
"h" || Ext ==
"hh" || Ext ==
"H";
641 RewriteModernObjC::RewriteModernObjC(std::string inFile,
642 std::unique_ptr<raw_ostream> OS,
645 bool silenceMacroWarn,
bool LineInfo)
646 : Diags(D), LangOpts(LOpts), InFileName(inFile), OutFile(std::move(OS)),
647 SilenceRewriteMacroWarning(silenceMacroWarn), GenerateLineInfo(LineInfo) {
650 "rewriting sub-expression within a macro (may not be correct)");
654 "rewriting block literal declared in global scope is not implemented");
658 "rewriter doesn't support user-specified control flow semantics " 659 "for @try/@finally (code may not execute properly)");
663 const std::string &InFile, std::unique_ptr<raw_ostream> OS,
665 bool SilenceRewriteMacroWarning,
bool LineInfo) {
666 return llvm::make_unique<RewriteModernObjC>(InFile, std::move(OS), Diags,
667 LOpts, SilenceRewriteMacroWarning,
671 void RewriteModernObjC::InitializeCommon(
ASTContext &context) {
675 MsgSendFunctionDecl =
nullptr;
676 MsgSendSuperFunctionDecl =
nullptr;
677 MsgSendStretFunctionDecl =
nullptr;
678 MsgSendSuperStretFunctionDecl =
nullptr;
679 MsgSendFpretFunctionDecl =
nullptr;
680 GetClassFunctionDecl =
nullptr;
681 GetMetaClassFunctionDecl =
nullptr;
682 GetSuperClassFunctionDecl =
nullptr;
683 SelGetUidFunctionDecl =
nullptr;
684 CFStringFunctionDecl =
nullptr;
685 ConstantStringClassReference =
nullptr;
686 NSStringRecord =
nullptr;
687 CurMethodDef =
nullptr;
688 CurFunctionDef =
nullptr;
689 GlobalVarDecl =
nullptr;
690 GlobalConstructionExp =
nullptr;
691 SuperStructDecl =
nullptr;
692 ProtocolTypeDecl =
nullptr;
693 ConstantStringDecl =
nullptr;
695 SuperConstructorFunctionDecl =
nullptr;
696 NumObjCStringLiterals = 0;
697 PropParentMap =
nullptr;
698 CurrentBody =
nullptr;
699 DisableReplaceStmt =
false;
700 objc_impl_method =
false;
704 const llvm::MemoryBuffer *MainBuf = SM->
getBuffer(MainFileID);
705 MainFileStart = MainBuf->getBufferStart();
706 MainFileEnd = MainBuf->getBufferEnd();
715 void RewriteModernObjC::HandleTopLevelSingleDecl(
Decl *D) {
730 RewriteFunctionDecl(FD);
731 }
else if (
VarDecl *FVD = dyn_cast<VarDecl>(D)) {
733 if (FVD->getName() ==
"_NSConstantStringClassReference") {
734 ConstantStringClassReference = FVD;
738 RewriteCategoryDecl(CD);
740 if (PD->isThisDeclarationADefinition())
741 RewriteProtocolDecl(PD);
745 DIEnd = LSD->decls_end();
747 if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>((*DI))) {
748 if (!IFace->isThisDeclarationADefinition()) {
752 if (isa<ObjCInterfaceDecl>(*DI) &&
753 !cast<ObjCInterfaceDecl>(*DI)->isThisDeclarationADefinition() &&
754 StartLoc == (*DI)->getBeginLoc())
760 }
while (DI != DIEnd);
761 RewriteForwardClassDecl(DG);
766 ObjCInterfacesSeen.push_back(IFace);
773 if (!Proto->isThisDeclarationADefinition()) {
777 if (isa<ObjCProtocolDecl>(*DI) &&
778 !cast<ObjCProtocolDecl>(*DI)->isThisDeclarationADefinition() &&
779 StartLoc == (*DI)->getBeginLoc())
785 }
while (DI != DIEnd);
786 RewriteForwardProtocolDecl(DG);
791 HandleTopLevelSingleDecl(*DI);
797 return HandleDeclInMainFile(D);
804 void RewriteModernObjC::RewriteInclude() {
807 const char *MainBufStart = MainBuf.begin();
808 const char *MainBufEnd = MainBuf.end();
809 size_t ImportLen = strlen(
"import");
812 for (
const char *BufPtr = MainBufStart; BufPtr < MainBufEnd; ++BufPtr) {
813 if (*BufPtr ==
'#') {
814 if (++BufPtr == MainBufEnd)
816 while (*BufPtr ==
' ' || *BufPtr ==
'\t')
817 if (++BufPtr == MainBufEnd)
819 if (!strncmp(BufPtr,
"import", ImportLen)) {
823 ReplaceText(ImportLoc, ImportLen,
"include");
832 Result +=
"OBJC_IVAR_$_";
843 std::string IvarOffsetName;
845 ObjCIvarBitfieldGroupOffset(D, IvarOffsetName);
849 std::string S =
"(*(";
852 IvarT = GetGroupRecordTypeForObjCIvarBitfield(D);
854 if (!isa<TypedefType>(IvarT) && IvarT->
isRecordType()) {
863 CDecl = CatDecl->getClassInterface();
864 std::string RecName = CDecl->
getName();
870 unsigned UnsignedIntSize =
873 llvm::APInt(UnsignedIntSize, 0),
875 Zero = NoTypeInfoCStyleCastExpr(Context, PtrStructIMPL, CK_BitCast, Zero);
889 convertObjCTypeToCStyleType(IvarT);
896 S +=
"((char *)self + ";
903 ReferencedIvars[
const_cast<ObjCInterfaceDecl *
>(ClassDecl)].insert(D);
920 static bool objcGetPropertyDefined =
false;
921 static bool objcSetPropertyDefined =
false;
926 InsertText(startLoc,
"// ");
928 assert((*startBuf ==
'@') &&
"bogus @synthesize location");
929 const char *semiBuf = strchr(startBuf,
';');
930 assert((*semiBuf ==
';') &&
"@synthesize: can't find ';'");
941 assert(IMD && OID &&
"Synthesized ivars must be attached to @implementation");
949 if (GenGetProperty && !objcGetPropertyDefined) {
950 objcGetPropertyDefined =
true;
952 Getr =
"\nextern \"C\" __declspec(dllimport) " 953 "id objc_getProperty(id, SEL, long, bool);\n";
960 if (GenGetProperty) {
973 for (
unsigned i = 0, e = FT->getNumParams();
i != e; ++
i) {
975 std::string ParamStr =
979 if (FT->isVariadic()) {
980 if (FT->getNumParams())
989 Getr +=
"return (_TYPE)";
990 Getr +=
"objc_getProperty(self, _cmd, ";
991 RewriteIvarOffsetComputation(OID, Getr);
997 InsertText(startGetterSetterLoc, Getr);
1008 if (GenSetProperty && !objcSetPropertyDefined) {
1009 objcSetPropertyDefined =
true;
1011 Setr =
"\nextern \"C\" __declspec(dllimport) " 1012 "void objc_setProperty (id, SEL, long, id, bool, bool);\n";
1020 if (GenSetProperty) {
1021 Setr +=
"objc_setProperty (self, _cmd, ";
1022 RewriteIvarOffsetComputation(OID, Setr);
1040 InsertText(startGetterSetterLoc, Setr);
1044 std::string &typedefString) {
1045 typedefString +=
"\n#ifndef _REWRITER_typedef_";
1047 typedefString +=
"\n";
1048 typedefString +=
"#define _REWRITER_typedef_";
1050 typedefString +=
"\n";
1051 typedefString +=
"typedef struct objc_object ";
1054 typedefString +=
";\ntypedef struct {} _objc_exc_";
1056 typedefString +=
";\n#endif\n";
1059 void RewriteModernObjC::RewriteForwardClassEpilogue(ObjCInterfaceDecl *ClassDecl,
1060 const std::string &typedefString) {
1063 const char *semiPtr = strchr(startBuf,
';');
1065 ReplaceText(startLoc, semiPtr-startBuf+1, typedefString);
1068 void RewriteModernObjC::RewriteForwardClassDecl(
DeclGroupRef D) {
1069 std::string typedefString;
1071 if (ObjCInterfaceDecl *ForwardDecl = dyn_cast<ObjCInterfaceDecl>(*I)) {
1072 if (I == D.
begin()) {
1076 typedefString +=
"// @class ";
1077 typedefString += ForwardDecl->getNameAsString();
1078 typedefString +=
";";
1083 HandleTopLevelSingleDecl(*I);
1086 RewriteForwardClassEpilogue(cast<ObjCInterfaceDecl>(*I), typedefString);
1089 void RewriteModernObjC::RewriteForwardClassDecl(
1091 std::string typedefString;
1092 for (
unsigned i = 0;
i < D.size();
i++) {
1093 ObjCInterfaceDecl *ForwardDecl = cast<ObjCInterfaceDecl>(D[
i]);
1095 typedefString +=
"// @class ";
1097 typedefString +=
";";
1101 RewriteForwardClassEpilogue(cast<ObjCInterfaceDecl>(D[0]), typedefString);
1104 void RewriteModernObjC::RewriteMethodDeclaration(
ObjCMethodDecl *Method) {
1114 InsertText(LocStart,
"#if 0\n");
1115 ReplaceText(LocEnd, 1,
";\n#endif\n");
1117 InsertText(LocStart,
"// ");
1124 ReplaceText(Loc, 0,
"// ");
1133 ReplaceText(LocStart, 1,
"/** ");
1137 ReplaceText(LocStart, 0,
"// ");
1144 RewriteMethodDeclaration(I);
1146 RewriteMethodDeclaration(I);
1150 strlen(
"@end"),
"/* @end */\n");
1158 ReplaceText(LocStart, 0,
"// ");
1161 RewriteMethodDeclaration(I);
1163 RewriteMethodDeclaration(I);
1169 ReplaceText(LocEnd, strlen(
"@end"),
"/* @end */\n");
1174 for (
const char *
p = startBuf;
p < endBuf;
p++) {
1175 if (*
p ==
'@' && !strncmp(
p+1,
"optional", strlen(
"optional"))) {
1177 ReplaceText(OptionalLoc, strlen(
"@optional"),
"/* @optional */");
1180 else if (*
p ==
'@' && !strncmp(
p+1,
"required", strlen(
"required"))) {
1182 ReplaceText(OptionalLoc, strlen(
"@required"),
"/* @required */");
1188 void RewriteModernObjC::RewriteForwardProtocolDecl(
DeclGroupRef D) {
1191 llvm_unreachable(
"Invalid SourceLocation");
1193 ReplaceText(LocStart, 0,
"// ");
1200 llvm_unreachable(
"Invalid SourceLocation");
1202 ReplaceText(LocStart, 0,
"// ");
1205 void RewriteModernObjC::RewriteTypeIntoString(
QualType T, std::string &ResultStr,
1228 void RewriteModernObjC::RewriteObjCMethodDecl(
const ObjCInterfaceDecl *IDecl,
1230 std::string &ResultStr) {
1233 ResultStr +=
"\nstatic ";
1234 RewriteTypeIntoString(OMD->
getReturnType(), ResultStr, FPRetType);
1238 std::string NameStr;
1256 int len = selString.size();
1257 for (
int i = 0;
i < len;
i++)
1258 if (selString[
i] ==
':')
1260 NameStr += selString;
1263 MethodInternalNames[OMD] = NameStr;
1264 ResultStr += NameStr;
1273 if (!LangOpts.MicrosoftExt) {
1274 if (ObjCSynthesizedStructs.count(const_cast<ObjCInterfaceDecl*>(IDecl)))
1275 ResultStr +=
"struct ";
1285 ResultStr +=
" self, ";
1287 ResultStr +=
" _cmd";
1290 for (
const auto *PDecl : OMD->
parameters()) {
1292 if (PDecl->getType()->isObjCQualifiedIdType()) {
1299 (void)convertBlockPointerToFunctionPointer(QT);
1305 ResultStr +=
", ...";
1314 for (
unsigned i = 0, e = FT->getNumParams();
i != e; ++
i) {
1315 if (
i) ResultStr +=
", ";
1316 std::string ParamStr =
1318 ResultStr += ParamStr;
1320 if (FT->isVariadic()) {
1321 if (FT->getNumParams())
1332 void RewriteModernObjC::RewriteImplementationDecl(
Decl *OID) {
1346 InsertText(CID->getBeginLoc(),
"// ");
1348 for (
auto *OMD : IMD ? IMD->
instance_methods() : CID->instance_methods()) {
1349 std::string ResultStr;
1356 ReplaceText(LocStart, endBuf-startBuf, ResultStr);
1359 for (
auto *OMD : IMD ? IMD->
class_methods() : CID->class_methods()) {
1360 std::string ResultStr;
1367 ReplaceText(LocStart, endBuf-startBuf, ResultStr);
1369 for (
auto *I : IMD ? IMD->
property_impls() : CID->property_impls())
1370 RewritePropertyImplDecl(I, IMD, CID);
1372 InsertText(IMD ? IMD->
getEndLoc() : CID->getEndLoc(),
"// ");
1375 void RewriteModernObjC::RewriteInterfaceDecl(ObjCInterfaceDecl *ClassDecl) {
1377 if (ObjCSynthesizedStructs.count(ClassDecl))
1381 while (SuperClass) {
1382 RewriteInterfaceDecl(SuperClass);
1385 std::string ResultStr;
1389 RewriteIvarOffsetSymbols(ClassDecl, ResultStr);
1391 RewriteObjCInternalStruct(ClassDecl, ResultStr);
1398 RewriteMethodDeclaration(I);
1400 RewriteMethodDeclaration(I);
1422 DisableReplaceStmtScope S(*
this);
1428 Base = cast<OpaqueValueExpr>(Base)->getSourceExpr();
1429 Base = cast<Expr>(RewriteFunctionBodyOrGlobalInitializer(Base));
1433 for (
unsigned i = 0;
i < numArgs;
i++) {
1435 if (isa<OpaqueValueExpr>(Arg))
1436 Arg = cast<OpaqueValueExpr>(Arg)->getSourceExpr();
1437 Arg = cast<Expr>(RewriteFunctionBodyOrGlobalInitializer(Arg));
1438 Args.push_back(Arg);
1491 Stmt *Replacement = SynthMessageExpr(NewMsg);
1492 ReplaceStmtWithRange(PseudoOp, Replacement, OldRange);
1509 DisableReplaceStmtScope S(*
this);
1513 Base = cast<OpaqueValueExpr>(Base)->getSourceExpr();
1514 Base = cast<Expr>(RewriteFunctionBodyOrGlobalInitializer(Base));
1517 for (
unsigned i = 0;
i < numArgs;
i++) {
1519 if (isa<OpaqueValueExpr>(Arg))
1520 Arg = cast<OpaqueValueExpr>(Arg)->getSourceExpr();
1521 Arg = cast<Expr>(RewriteFunctionBodyOrGlobalInitializer(Arg));
1522 Args.push_back(Arg);
1574 Stmt *Replacement = SynthMessageExpr(NewMsg);
1575 ReplaceStmtWithRange(PseudoOp, Replacement, OldRange);
1588 void RewriteModernObjC::SynthCountByEnumWithState(std::string &buf) {
1589 buf +=
"((_WIN_NSUInteger (*) (id, SEL, struct __objcFastEnumerationState *, " 1590 "id *, _WIN_NSUInteger))(void *)objc_msgSend)";
1592 buf +=
"((id)l_collection,\n\t\t";
1593 buf +=
"sel_registerName(\"countByEnumeratingWithState:objects:count:\"),";
1595 buf +=
"&enumState, " 1596 "(id *)__rw_items, (_WIN_NSUInteger)16)";
1603 if (Stmts.empty() || !isa<ObjCForCollectionStmt>(Stmts.back()))
1609 buf =
"goto __break_label_";
1610 buf += utostr(ObjCBcLabelNo.back());
1611 ReplaceText(startLoc, strlen(
"break"), buf);
1616 void RewriteModernObjC::ConvertSourceLocationToLineDirective(
1618 std::string &LineString) {
1619 if (Loc.
isFileID() && GenerateLineInfo) {
1620 LineString +=
"\n#line ";
1622 LineString += utostr(PLoc.
getLine());
1623 LineString +=
" \"";
1625 LineString +=
"\"\n";
1633 if (Stmts.empty() || !isa<ObjCForCollectionStmt>(Stmts.back()))
1639 buf =
"goto __continue_label_";
1640 buf += utostr(ObjCBcLabelNo.back());
1641 ReplaceText(startLoc, strlen(
"continue"), buf);
1680 assert(!Stmts.empty() &&
"ObjCForCollectionStmt - Statement stack empty");
1681 assert(isa<ObjCForCollectionStmt>(Stmts.back()) &&
1682 "ObjCForCollectionStmt Statement stack mismatch");
1683 assert(!ObjCBcLabelNo.empty() &&
1684 "ObjCForCollectionStmt - Label No stack empty");
1688 StringRef elementName;
1689 std::string elementTypeAsString;
1693 ConvertSourceLocationToLineDirective(ForEachLoc, buf);
1697 NamedDecl* D = cast<NamedDecl>(DS->getSingleDecl());
1698 QualType ElementType = cast<ValueDecl>(D)->getType();
1699 if (ElementType->isObjCQualifiedIdType() ||
1700 ElementType->isObjCQualifiedInterfaceType())
1702 elementTypeAsString =
"id";
1705 buf += elementTypeAsString;
1718 elementTypeAsString =
"id";
1724 buf +=
"struct __objcFastEnumerationState enumState = { 0 };\n\t";
1726 buf +=
"id __rw_items[16];\n\t";
1728 buf +=
"id l_collection = (id)";
1730 const char *startCollectionBuf = startBuf;
1731 startCollectionBuf += 3;
1732 startCollectionBuf = strchr(startCollectionBuf,
'(');
1733 startCollectionBuf++;
1735 while (*startCollectionBuf !=
' ' ||
1736 *(startCollectionBuf+1) !=
'i' || *(startCollectionBuf+2) !=
'n' ||
1737 (*(startCollectionBuf+3) !=
' ' &&
1738 *(startCollectionBuf+3) !=
'[' && *(startCollectionBuf+3) !=
'('))
1739 startCollectionBuf++;
1740 startCollectionBuf += 3;
1743 ReplaceText(startLoc, startCollectionBuf - startBuf, buf);
1761 buf +=
"_WIN_NSUInteger limit =\n\t\t";
1762 SynthCountByEnumWithState(buf);
1772 buf +=
"if (limit) {\n\t";
1773 buf +=
"unsigned long startMutations = *enumState.mutationsPtr;\n\t";
1774 buf +=
"do {\n\t\t";
1775 buf +=
"unsigned long counter = 0;\n\t\t";
1776 buf +=
"do {\n\t\t\t";
1777 buf +=
"if (startMutations != *enumState.mutationsPtr)\n\t\t\t\t";
1778 buf +=
"objc_enumerationMutation(l_collection);\n\t\t\t";
1781 buf += elementTypeAsString;
1782 buf +=
")enumState.itemsPtr[counter++];";
1784 ReplaceText(lparenLoc, 1, buf);
1798 buf +=
"__continue_label_";
1799 buf += utostr(ObjCBcLabelNo.back());
1802 buf +=
"} while (counter < limit);\n\t";
1803 buf +=
"} while ((limit = ";
1804 SynthCountByEnumWithState(buf);
1808 buf += elementTypeAsString;
1810 buf +=
"__break_label_";
1811 buf += utostr(ObjCBcLabelNo.back());
1814 buf +=
"else\n\t\t";
1817 buf += elementTypeAsString;
1823 if (isa<CompoundStmt>(S->
getBody())) {
1825 InsertText(endBodyLoc, buf);
1835 const char *semiBuf = strchr(stmtBuf,
';');
1836 assert(semiBuf &&
"Can't find ';'");
1838 InsertText(endBodyLoc, buf);
1841 ObjCBcLabelNo.pop_back();
1846 buf +=
"{ struct _FIN { _FIN(id reth) : rethrow(reth) {}\n";
1847 buf +=
"\t~_FIN() { if (rethrow) objc_exception_throw(rethrow); }\n";
1848 buf +=
"\tid rethrow;\n";
1849 buf +=
"\t} _fin_force_rethow(_rethrow);";
1863 assert((*startBuf ==
'@') &&
"bogus @synchronized location");
1867 ConvertSourceLocationToLineDirective(SynchLoc, buf);
1868 buf +=
"{ id _rethrow = 0; id _sync_obj = (id)";
1870 const char *lparenBuf = startBuf;
1871 while (*lparenBuf !=
'(') lparenBuf++;
1872 ReplaceText(startLoc, lparenBuf-startBuf+1, buf);
1874 buf =
"; objc_sync_enter(_sync_obj);\n";
1875 buf +=
"try {\n\tstruct _SYNC_EXIT { _SYNC_EXIT(id arg) : sync_exit(arg) {}";
1876 buf +=
"\n\t~_SYNC_EXIT() {objc_sync_exit(sync_exit);}";
1877 buf +=
"\n\tid sync_exit;";
1878 buf +=
"\n\t} _sync_exit(_sync_obj);\n";
1885 while (*RParenExprLocBuf !=
')') RParenExprLocBuf--;
1890 assert (*LBraceLocBuf ==
'{');
1891 ReplaceText(RParenExprLoc, (LBraceLocBuf - SM->
getCharacterData(RParenExprLoc) + 1), buf);
1895 "bogus @synchronized block");
1897 buf =
"} catch (id e) {_rethrow = e;}\n";
1902 ReplaceText(startRBraceLoc, 1, buf);
1907 void RewriteModernObjC::WarnAboutReturnGotoStmts(
Stmt *S)
1912 WarnAboutReturnGotoStmts(SubStmt);
1914 if (isa<ReturnStmt>(S) || isa<GotoStmt>(S)) {
1916 TryFinallyContainsReturnDiag);
1922 ReplaceText(startLoc, strlen(
"@autoreleasepool"),
"/* @autoreleasepool */");
1924 "{ __AtAutoreleasePool __autoreleasepool; ");
1934 ConvertSourceLocationToLineDirective(TryLocation, buf);
1938 buf +=
"{ id volatile _rethrow = 0;\n";
1940 buf +=
"{ id volatile _rethrow = 0;\ntry {\n";
1947 assert((*startBuf ==
'@') &&
"bogus @try location");
1949 ReplaceText(startLoc, 1, buf);
1952 ReplaceText(startLoc, 1,
"");
1959 bool AtRemoved =
false;
1964 ObjCInterfaceDecl *IDecl = Ptr->getObjectType()->getInterface();
1970 assert((*startBuf ==
'@') &&
"bogus @catch location");
1978 ReplaceText(startLoc, rParenBuf-startBuf+1, Result);
1989 ReplaceText(lBraceLoc, 1, Result);
1996 ReplaceText(startLoc, 1,
"");
2004 ConvertSourceLocationToLineDirective(FinallyLoc, buf);
2005 buf +=
"catch (id e) {_rethrow = e;}\n";
2009 ConvertSourceLocationToLineDirective(FinallyLoc, buf);
2010 buf +=
"catch (id e) {_rethrow = e;}\n";
2014 ReplaceText(startFinalLoc, 8, buf);
2019 ReplaceText(startFinalBodyLoc, 1, buf);
2022 ReplaceText(endFinalBodyLoc, 1,
"}\n}");
2038 assert((*startBuf ==
'@') &&
"bogus @throw location");
2043 buf =
"objc_exception_throw(";
2048 const char *wBuf = strchr(startBuf,
'w');
2049 assert((*wBuf ==
'w') &&
"@throw: can't find 'w'");
2050 ReplaceText(startLoc, wBuf-startBuf+1, buf);
2054 const char *semiBuf = strchr(endBuf,
';');
2055 assert((*semiBuf ==
';') &&
"@throw: can't find ';'");
2058 ReplaceText(semiLoc, 1,
");");
2064 std::string StrEncoding;
2066 Expr *Replacement = getStringLiteral(StrEncoding);
2067 ReplaceStmt(Exp, Replacement);
2075 if (!SelGetUidFunctionDecl)
2076 SynthSelGetUidFunctionDecl();
2077 assert(SelGetUidFunctionDecl &&
"Can't find sel_registerName() decl");
2081 CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl,
2083 ReplaceStmt(Exp, SelExp);
2089 RewriteModernObjC::SynthesizeCallToFunctionDecl(
FunctionDecl *FD,
2114 const char *&startRef,
const char *&endRef) {
2115 while (startBuf < endBuf) {
2116 if (*startBuf ==
'<')
2117 startRef = startBuf;
2118 if (*startBuf ==
'>') {
2119 if (startRef && *startRef ==
'<') {
2132 while (*argRef !=
')' && (*argRef !=
',' || angle > 0)) {
2135 else if (*argRef ==
'>')
2139 assert(angle == 0 &&
"scanToNextArgument - bad protocol type syntax");
2142 bool RewriteModernObjC::needToScanForQualifiers(
QualType T) {
2155 return needToScanForQualifiers(ElemTy);
2160 void RewriteModernObjC::RewriteObjCQualifiedInterfaceTypes(
Expr *E) {
2162 if (needToScanForQualifiers(Type)) {
2166 Loc = ECE->getLParenLoc();
2167 EndLoc = ECE->getRParenLoc();
2178 const char *startRef =
nullptr, *endRef =
nullptr;
2184 InsertText(LessLoc,
"/*");
2185 InsertText(GreaterLoc,
"*/");
2190 void RewriteModernObjC::RewriteObjCQualifiedInterfaceTypes(
Decl *Dcl) {
2194 if (
VarDecl *VD = dyn_cast<VarDecl>(Dcl)) {
2195 Loc = VD->getLocation();
2196 Type = VD->getType();
2198 else if (
FunctionDecl *FD = dyn_cast<FunctionDecl>(Dcl)) {
2203 assert(funcType &&
"missing function type");
2209 else if (
FieldDecl *FD = dyn_cast<FieldDecl>(Dcl)) {
2214 Loc = TD->getLocation();
2215 Type = TD->getUnderlyingType();
2220 if (needToScanForQualifiers(Type)) {
2224 const char *startBuf = endBuf;
2225 while (*startBuf !=
';' && *startBuf !=
'<' && startBuf != MainFileStart)
2227 const char *startRef =
nullptr, *endRef =
nullptr;
2233 InsertText(LessLoc,
"/*");
2234 InsertText(GreaterLoc,
"*/");
2241 const char *startFuncBuf = startBuf;
2246 const char *endBuf = startBuf;
2249 const char *startRef =
nullptr, *endRef =
nullptr;
2257 InsertText(LessLoc,
"/*");
2258 InsertText(GreaterLoc,
"*/");
2260 startBuf = ++endBuf;
2265 while (*startBuf && *startBuf !=
')' && *startBuf !=
',')
2272 void RewriteModernObjC::RewriteTypeOfDecl(
VarDecl *ND) {
2275 if (!isa<TypeOfExprType>(TypePtr))
2277 while (isa<TypeOfExprType>(TypePtr)) {
2278 const TypeOfExprType *TypeOfExprTypePtr = cast<TypeOfExprType>(TypePtr);
2289 TypeAsString +=
" " + Name +
" = ";
2293 startLoc = ECE->getLParenLoc();
2298 ReplaceText(DeclLoc, endBuf-startBuf-1, TypeAsString);
2304 ReplaceText(DeclLoc, endBuf-startBuf-1, TypeAsString);
2309 void RewriteModernObjC::SynthSelGetUidFunctionDecl() {
2318 SelGetUidIdent, getFuncType,
2322 void RewriteModernObjC::RewriteFunctionDecl(
FunctionDecl *FD) {
2325 FD->
getName() ==
"sel_registerName") {
2326 SelGetUidFunctionDecl = FD;
2329 RewriteObjCQualifiedInterfaceTypes(FD);
2332 void RewriteModernObjC::RewriteBlockPointerType(std::string& Str,
QualType Type) {
2334 const char *argPtr = TypeString.c_str();
2335 if (!strchr(argPtr,
'^')) {
2340 Str += (*argPtr ==
'^' ?
'*' : *argPtr);
2346 void RewriteModernObjC::RewriteBlockPointerTypeVariable(std::string& Str,
2350 const char *argPtr = TypeString.c_str();
2375 void RewriteModernObjC::RewriteBlockLiteralFunctionDecl(
FunctionDecl *FD) {
2381 QualType Type = proto->getReturnType();
2386 unsigned numArgs = proto->getNumParams();
2387 for (
unsigned i = 0;
i < numArgs;
i++) {
2388 QualType ArgType = proto->getParamType(
i);
2389 RewriteBlockPointerType(FdStr, ArgType);
2394 FdStr += (numArgs > 0) ?
", ...);\n" :
"...);\n";
2398 InsertText(FunLocStart, FdStr);
2402 void RewriteModernObjC::SynthSuperConstructorFunctionDecl() {
2403 if (SuperConstructorFunctionDecl)
2408 assert(!argT.
isNull() &&
"Can't find 'id' type");
2409 ArgTys.push_back(argT);
2410 ArgTys.push_back(argT);
2416 msgSendIdent, msgSendType,
2421 void RewriteModernObjC::SynthMsgSendFunctionDecl() {
2425 assert(!argT.
isNull() &&
"Can't find 'id' type");
2426 ArgTys.push_back(argT);
2428 assert(!argT.
isNull() &&
"Can't find 'SEL' type");
2429 ArgTys.push_back(argT);
2435 msgSendIdent, msgSendType,
nullptr,
2440 void RewriteModernObjC::SynthMsgSendSuperFunctionDecl() {
2443 ArgTys.push_back(Context->
VoidTy);
2449 msgSendIdent, msgSendType,
2454 void RewriteModernObjC::SynthMsgSendStretFunctionDecl() {
2458 assert(!argT.
isNull() &&
"Can't find 'id' type");
2459 ArgTys.push_back(argT);
2461 assert(!argT.
isNull() &&
"Can't find 'SEL' type");
2462 ArgTys.push_back(argT);
2468 msgSendIdent, msgSendType,
2474 void RewriteModernObjC::SynthMsgSendSuperStretFunctionDecl() {
2476 &Context->
Idents.
get(
"objc_msgSendSuper_stret");
2478 ArgTys.push_back(Context->
VoidTy);
2485 msgSendType,
nullptr,
2490 void RewriteModernObjC::SynthMsgSendFpretFunctionDecl() {
2494 assert(!argT.
isNull() &&
"Can't find 'id' type");
2495 ArgTys.push_back(argT);
2497 assert(!argT.
isNull() &&
"Can't find 'SEL' type");
2498 ArgTys.push_back(argT);
2504 msgSendIdent, msgSendType,
2509 void RewriteModernObjC::SynthGetClassFunctionDecl() {
2518 getClassIdent, getClassType,
2523 void RewriteModernObjC::SynthGetSuperClassFunctionDecl() {
2525 &Context->
Idents.
get(
"class_getSuperclass");
2534 getClassType,
nullptr,
2539 void RewriteModernObjC::SynthGetMetaClassFunctionDecl() {
2548 getClassIdent, getClassType,
2553 assert (Exp !=
nullptr &&
"Expected non-null ObjCStringLiteral");
2554 QualType strType = getConstantStringStructType();
2556 std::string S =
"__NSConstantStringImpl_";
2558 std::string tmpName = InFileName;
2560 for (i=0; i < tmpName.length(); i++) {
2561 char c = tmpName.at(i);
2568 S += utostr(NumObjCStringLiterals++);
2570 Preamble +=
"static __NSConstantStringImpl " + S;
2571 Preamble +=
" __attribute__ ((section (\"__DATA, __cfstring\"))) = {__CFConstantStringClassReference,";
2572 Preamble +=
"0x000007c8,";
2574 std::string prettyBufS;
2575 llvm::raw_string_ostream prettyBuf(prettyBufS);
2577 Preamble += prettyBuf.str();
2586 Expr *Unop =
new (Context)
2591 CK_CPointerToObjCPointerCast, Unop);
2592 ReplaceStmt(Exp, cast);
2602 llvm::APInt(IntSize, Exp->
getValue()),
2605 CK_BitCast, FlagExp);
2608 ReplaceStmt(Exp, PE);
2614 if (!SelGetUidFunctionDecl)
2615 SynthSelGetUidFunctionDecl();
2617 if (!MsgSendFunctionDecl)
2618 SynthMsgSendFunctionDecl();
2619 if (!GetClassFunctionDecl)
2620 SynthGetClassFunctionDecl();
2635 ClsExprs.push_back(getStringLiteral(clsName->
getName()));
2636 CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl, ClsExprs,
2638 MsgExprs.push_back(Cls);
2645 CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl,
2646 SelExprs, StartLoc, EndLoc);
2647 MsgExprs.push_back(SelExp);
2656 CK = CK_IntegralToBoolean;
2657 subExpr = NoTypeInfoCStyleCastExpr(Context, type, CK, subExpr);
2659 MsgExprs.push_back(subExpr);
2664 for (
const auto PI : BoxingMethod->
parameters())
2665 ArgTypes.push_back(PI->getType());
2680 getSimpleFunctionType(returnType, ArgTypes, BoxingMethod->
isVariadic());
2682 cast = NoTypeInfoCStyleCastExpr(Context, castType, CK_BitCast,
2691 ReplaceStmt(Exp, CE);
2697 if (!SelGetUidFunctionDecl)
2698 SynthSelGetUidFunctionDecl();
2700 if (!MsgSendFunctionDecl)
2701 SynthMsgSendFunctionDecl();
2702 if (!GetClassFunctionDecl)
2703 SynthGetClassFunctionDecl();
2712 getSimpleFunctionType(Context->
VoidTy, IntQT,
true);
2713 std::string NSArrayFName(
"__NSContainer_literal");
2714 FunctionDecl *NSArrayFD = SynthBlockInitFunctionDecl(NSArrayFName);
2720 unsigned UnsignedIntSize =
2723 llvm::APInt(UnsignedIntSize, NumElements),
2725 InitExprs.push_back(count);
2726 for (
unsigned i = 0;
i < NumElements;
i++)
2728 Expr *NSArrayCallExpr =
2743 NoTypeInfoCStyleCastExpr(Context,
2754 ObjCInterfaceDecl *Class =
2758 ClsExprs.push_back(getStringLiteral(clsName->
getName()));
2759 CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl, ClsExprs,
2761 MsgExprs.push_back(Cls);
2769 CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl,
2770 SelExprs, StartLoc, EndLoc);
2771 MsgExprs.push_back(SelExp);
2774 MsgExprs.push_back(ArrayLiteralObjects);
2778 llvm::APInt(UnsignedIntSize, NumElements),
2780 MsgExprs.push_back(cnt);
2785 for (
const auto *PI : ArrayMethod->
parameters())
2786 ArgTypes.push_back(PI->getType());
2801 getSimpleFunctionType(returnType, ArgTypes, ArrayMethod->
isVariadic());
2803 cast = NoTypeInfoCStyleCastExpr(Context, castType, CK_BitCast,
2812 ReplaceStmt(Exp, CE);
2818 if (!SelGetUidFunctionDecl)
2819 SynthSelGetUidFunctionDecl();
2821 if (!MsgSendFunctionDecl)
2822 SynthMsgSendFunctionDecl();
2823 if (!GetClassFunctionDecl)
2824 SynthGetClassFunctionDecl();
2833 getSimpleFunctionType(Context->
VoidTy, IntQT,
true);
2834 std::string NSDictFName(
"__NSContainer_literal");
2835 FunctionDecl *NSDictFD = SynthBlockInitFunctionDecl(NSDictFName);
2843 unsigned UnsignedIntSize =
2846 llvm::APInt(UnsignedIntSize, NumElements),
2848 KeyExprs.push_back(count);
2849 ValueExprs.push_back(count);
2850 for (
unsigned i = 0;
i < NumElements;
i++) {
2852 KeyExprs.push_back(Element.
Key);
2853 ValueExprs.push_back(Element.
Value);
2857 Expr *NSValueCallExpr =
2872 NoTypeInfoCStyleCastExpr(Context,
2875 DictLiteralValueME);
2885 NoTypeInfoCStyleCastExpr(Context,
2896 ObjCInterfaceDecl *Class =
2900 ClsExprs.push_back(getStringLiteral(clsName->
getName()));
2901 CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl, ClsExprs,
2903 MsgExprs.push_back(Cls);
2910 CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl,
2911 SelExprs, StartLoc, EndLoc);
2912 MsgExprs.push_back(SelExp);
2915 MsgExprs.push_back(DictValueObjects);
2918 MsgExprs.push_back(DictKeyObjects);
2922 llvm::APInt(UnsignedIntSize, NumElements),
2924 MsgExprs.push_back(cnt);
2929 for (
const auto *PI : DictMethod->
parameters()) {
2933 convertToUnqualifiedObjCType(PointeeTy);
2936 ArgTypes.push_back(T);
2952 getSimpleFunctionType(returnType, ArgTypes, DictMethod->
isVariadic());
2954 cast = NoTypeInfoCStyleCastExpr(Context, castType, CK_BitCast,
2963 ReplaceStmt(Exp, CE);
2970 QualType RewriteModernObjC::getSuperStructType() {
2971 if (!SuperStructDecl) {
2974 &Context->
Idents.
get(
"__rw_objc_super"));
2983 for (
unsigned i = 0;
i < 2; ++
i) {
2987 FieldTypes[
i],
nullptr,
2998 QualType RewriteModernObjC::getConstantStringStructType() {
2999 if (!ConstantStringDecl) {
3002 &Context->
Idents.
get(
"__NSConstantStringImpl"));
3008 FieldTypes[1] = Context->
IntTy;
3012 FieldTypes[3] = Context->
LongTy;
3015 for (
unsigned i = 0;
i < 4; ++
i) {
3020 FieldTypes[
i],
nullptr,
3040 if (!LSD->getRBraceLoc().isValid())
3041 return LSD->getExternLoc();
3044 R.RewriteBlockLiteralFunctionDecl(FD);
3048 void RewriteModernObjC::RewriteLineDirective(
const Decl *D) {
3052 if (Location.
isFileID() && GenerateLineInfo) {
3053 std::string LineString(
"\n#line ");
3055 LineString += utostr(PLoc.
getLine());
3056 LineString +=
" \"";
3058 if (isa<ObjCMethodDecl>(D))
3060 else LineString +=
"\"\n";
3063 if (
const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
3068 if (!LSD->getRBraceLoc().isValid())
3069 Location = LSD->getExternLoc();
3072 InsertText(Location, LineString);
3086 Expr *RewriteModernObjC::SynthMsgSendStretCallExpr(
FunctionDecl *MsgSendStretFlavor,
3092 QualType FuncType = getSimpleFunctionType(
3093 returnType, ArgTypes, Method ? Method->
isVariadic() :
false);
3097 static unsigned stretCount=0;
3098 std::string
name =
"__Stret"; name += utostr(stretCount);
3100 "extern \"C\" void * __cdecl memset(void *_Dst, int _Val, size_t _Size);\n";
3101 str +=
"namespace {\n";
3102 str +=
"struct "; str +=
name;
3105 str +=
"(id receiver, SEL sel";
3106 for (
unsigned i = 2;
i < ArgTypes.size();
i++) {
3107 std::string ArgName =
"arg"; ArgName += utostr(
i);
3109 str +=
", "; str += ArgName;
3112 for (
unsigned i = ArgTypes.size();
i < MsgExprs.size();
i++) {
3113 std::string ArgName =
"arg"; ArgName += utostr(
i);
3114 MsgExprs[
i]->getType().getAsStringInternal(ArgName,
3116 str +=
", "; str += ArgName;
3120 str +=
"\t unsigned size = sizeof(";
3123 str +=
"\t if (size == 1 || size == 2 || size == 4 || size == 8)\n";
3126 str +=
")(void *)objc_msgSend)(receiver, sel";
3127 for (
unsigned i = 2;
i < ArgTypes.size();
i++) {
3128 str +=
", arg"; str += utostr(
i);
3131 for (
unsigned i = ArgTypes.size();
i < MsgExprs.size();
i++) {
3132 str +=
", arg"; str += utostr(
i);
3136 str +=
"\t else if (receiver == 0)\n";
3137 str +=
"\t memset((void*)&s, 0, sizeof(s));\n";
3141 str +=
")(void *)objc_msgSend_stret)(receiver, sel";
3142 for (
unsigned i = 2;
i < ArgTypes.size();
i++) {
3143 str +=
", arg"; str += utostr(
i);
3146 for (
unsigned i = ArgTypes.size();
i < MsgExprs.size();
i++) {
3147 str +=
", arg"; str += utostr(
i);
3154 str +=
"};\n};\n\n";
3159 assert(CurMethodDef &&
"SynthMsgSendStretCallExpr - CurMethodDef is null");
3163 InsertText(FunLocStart, str);
3170 ID, FuncType,
nullptr,
SC_Extern,
false,
false);
3179 returnType,
nullptr,
3191 if (!SelGetUidFunctionDecl)
3192 SynthSelGetUidFunctionDecl();
3193 if (!MsgSendFunctionDecl)
3194 SynthMsgSendFunctionDecl();
3195 if (!MsgSendSuperFunctionDecl)
3196 SynthMsgSendSuperFunctionDecl();
3197 if (!MsgSendStretFunctionDecl)
3198 SynthMsgSendStretFunctionDecl();
3199 if (!MsgSendSuperStretFunctionDecl)
3200 SynthMsgSendSuperStretFunctionDecl();
3201 if (!MsgSendFpretFunctionDecl)
3202 SynthMsgSendFpretFunctionDecl();
3203 if (!GetClassFunctionDecl)
3204 SynthGetClassFunctionDecl();
3205 if (!GetSuperClassFunctionDecl)
3206 SynthGetSuperClassFunctionDecl();
3207 if (!GetMetaClassFunctionDecl)
3208 SynthGetMetaClassFunctionDecl();
3215 QualType resultType = mDecl->getReturnType();
3217 MsgSendStretFlavor = MsgSendStretFunctionDecl;
3219 MsgSendFlavor = MsgSendFpretFunctionDecl;
3226 MsgSendFlavor = MsgSendSuperFunctionDecl;
3227 if (MsgSendStretFlavor)
3228 MsgSendStretFlavor = MsgSendSuperStretFunctionDecl;
3229 assert(MsgSendFlavor &&
"MsgSendFlavor is NULL!");
3236 InitExprs.push_back(
3251 CallExpr *Cls = SynthesizeCallToFunctionDecl(GetMetaClassFunctionDecl,
3252 ClsExprs, StartLoc, EndLoc);
3254 ClsExprs.push_back(Cls);
3255 Cls = SynthesizeCallToFunctionDecl(GetSuperClassFunctionDecl, ClsExprs,
3260 InitExprs.push_back(
3261 NoTypeInfoCStyleCastExpr(Context,
3265 QualType superType = getSuperStructType();
3268 if (LangOpts.MicrosoftExt) {
3269 SynthSuperConstructorFunctionDecl();
3272 DeclRefExpr(*Context, SuperConstructorFunctionDecl,
false, superType,
3286 SuperRep = NoTypeInfoCStyleCastExpr(Context,
3288 CK_BitCast, SuperRep);
3305 MsgExprs.push_back(SuperRep);
3311 ObjCInterfaceDecl *Class
3314 ClsExprs.push_back(getStringLiteral(clsName->
getName()));
3315 CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl, ClsExprs,
3317 CastExpr *ArgExpr = NoTypeInfoCStyleCastExpr(Context,
3320 MsgExprs.push_back(ArgExpr);
3325 MsgSendFlavor = MsgSendSuperFunctionDecl;
3326 if (MsgSendStretFlavor)
3327 MsgSendStretFlavor = MsgSendSuperStretFunctionDecl;
3328 assert(MsgSendFlavor &&
"MsgSendFlavor is NULL!");
3332 InitExprs.push_back(
3346 CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl, ClsExprs,
3349 ClsExprs.push_back(Cls);
3350 Cls = SynthesizeCallToFunctionDecl(GetSuperClassFunctionDecl, ClsExprs,
3355 InitExprs.push_back(
3360 QualType superType = getSuperStructType();
3363 if (LangOpts.MicrosoftExt) {
3364 SynthSuperConstructorFunctionDecl();
3367 DeclRefExpr(*Context, SuperConstructorFunctionDecl,
false, superType,
3381 SuperRep = NoTypeInfoCStyleCastExpr(Context,
3383 CK_BitCast, SuperRep);
3395 MsgExprs.push_back(SuperRep);
3404 recExpr = CE->getSubExpr();
3407 ? CK_BlockPointerToObjCPointerCast
3408 : CK_CPointerToObjCPointerCast;
3410 recExpr = NoTypeInfoCStyleCastExpr(Context, Context->
getObjCIdType(),
3412 MsgExprs.push_back(recExpr);
3420 CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl,
3421 SelExprs, StartLoc, EndLoc);
3422 MsgExprs.push_back(SelExp);
3431 if (needToScanForQualifiers(type))
3434 (void)convertBlockPointerToFunctionPointer(type);
3439 CK = CK_IntegralToBoolean;
3442 CK = CK_BlockPointerToObjCPointerCast;
3444 CK = CK_CPointerToObjCPointerCast;
3452 userExpr = NoTypeInfoCStyleCastExpr(Context, type, CK, userExpr);
3455 else if (
CStyleCastExpr *CE = dyn_cast<CStyleCastExpr>(userExpr)) {
3456 if (CE->getType()->isObjCQualifiedIdType()) {
3457 while ((CE = dyn_cast<CStyleCastExpr>(userExpr)))
3458 userExpr = CE->getSubExpr();
3461 CK = CK_IntegralToPointer;
3463 CK = CK_BlockPointerToObjCPointerCast;
3465 CK = CK_CPointerToObjCPointerCast;
3469 userExpr = NoTypeInfoCStyleCastExpr(Context, Context->
getObjCIdType(),
3473 MsgExprs.push_back(userExpr);
3485 if (MsgSendFlavor == MsgSendSuperFunctionDecl)
3486 ArgTypes.push_back(Context->
getPointerType(getSuperStructType()));
3493 QualType t = PI->getType()->isObjCQualifiedIdType()
3497 (void)convertBlockPointerToFunctionPointer(t);
3498 ArgTypes.push_back(t);
3501 convertToUnqualifiedObjCType(returnType);
3502 (void)convertBlockPointerToFunctionPointer(returnType);
3517 cast = NoTypeInfoCStyleCastExpr(Context,
3525 getSimpleFunctionType(returnType, ArgTypes, MD ? MD->isVariadic() :
true);
3527 cast = NoTypeInfoCStyleCastExpr(Context, castType, CK_BitCast,
3536 Stmt *ReplacingStmt = CE;
3537 if (MsgSendStretFlavor) {
3543 Expr *STCE = SynthMsgSendStretCallExpr(MsgSendStretFlavor,
3547 ReplacingStmt = STCE;
3550 return ReplacingStmt;
3554 Stmt *ReplacingStmt =
3558 ReplaceStmt(Exp, ReplacingStmt);
3561 return ReplacingStmt;
3565 QualType RewriteModernObjC::getProtocolType() {
3566 if (!ProtocolTypeDecl) {
3582 std::string Name =
"_OBJC_PROTOCOL_REFERENCE_$_" +
3592 ReplaceStmt(Exp, castExpr);
3602 bool &IsNamedDefinition) {
3606 if (
RecordDecl *RD = dyn_cast<RecordDecl>(Tag)) {
3607 RD = RD->getDefinition();
3608 if (!RD || !RD->getDeclName().getAsIdentifierInfo())
3610 IsNamedDefinition =
true;
3611 TagLocation = RD->getLocation();
3615 if (
EnumDecl *ED = dyn_cast<EnumDecl>(Tag)) {
3616 if (!ED || !ED->getDeclName().getAsIdentifierInfo())
3618 IsNamedDefinition =
true;
3619 TagLocation = ED->getLocation();
3628 bool RewriteModernObjC::RewriteObjCFieldDeclType(
QualType &Type,
3630 if (isa<TypedefType>(Type)) {
3637 return RewriteObjCFieldDeclType(ElemTy, Result);
3643 Result +=
"\n\tstruct ";
3645 Result +=
"\n\tunion ";
3647 assert(
false &&
"class not allowed as an ivar type");
3650 if (GlobalDefinedTags.count(RD)) {
3656 for (
auto *FD : RD->
fields())
3657 RewriteObjCFieldDecl(FD, Result);
3665 Result +=
"\n\tenum ";
3667 if (GlobalDefinedTags.count(ED)) {
3675 Result +=
"\t"; Result += EC->getName(); Result +=
" = ";
3676 llvm::APSInt Val = EC->getInitVal();
3677 Result += Val.toString(10);
3686 convertObjCTypeToCStyleType(Type);
3694 std::string &Result) {
3698 bool EleboratedType = RewriteObjCFieldDeclType(Type, Result);
3699 if (!EleboratedType)
3710 llvm::APInt Dim = CAT->getSize();
3711 Result += utostr(Dim.getZExtValue());
3723 void RewriteModernObjC::RewriteLocallyDefinedNamedAggregates(
FieldDecl *fieldDecl,
3724 std::string &Result) {
3726 if (isa<TypedefType>(Type))
3742 if (GlobalDefinedTags.count(TD))
3745 bool IsNamedDefinition =
false;
3746 if (IsTagDefinedInsideClass(IDecl, TD, IsNamedDefinition)) {
3747 RewriteObjCFieldDeclType(Type, Result);
3750 if (IsNamedDefinition)
3751 GlobalDefinedTags.insert(TD);
3755 unsigned RewriteModernObjC::ObjCIvarBitfieldGroupNo(
ObjCIvarDecl *IV) {
3757 if (ObjCInterefaceHasBitfieldGroups.count(CDecl)) {
3758 return IvarGroupNumber[IV];
3760 unsigned GroupNo = 0;
3764 IVars.push_back(IVD);
3766 for (
unsigned i = 0, e = IVars.size();
i < e;
i++)
3767 if (IVars[
i]->isBitField()) {
3768 IvarGroupNumber[IVars[
i++]] = ++GroupNo;
3769 while (
i < e && IVars[
i]->isBitField())
3770 IvarGroupNumber[IVars[
i++]] = GroupNo;
3775 ObjCInterefaceHasBitfieldGroups.insert(CDecl);
3776 return IvarGroupNumber[IV];
3779 QualType RewriteModernObjC::SynthesizeBitfieldGroupStructType(
3782 std::string StructTagName;
3783 ObjCIvarBitfieldGroupType(IV, StructTagName);
3788 for (
unsigned i=0, e = IVars.size();
i < e;
i++) {
3802 unsigned GroupNo = ObjCIvarBitfieldGroupNo(IV);
3803 std::pair<const ObjCInterfaceDecl*, unsigned> tuple = std::make_pair(CDecl, GroupNo);
3804 if (GroupRecordType.count(tuple))
3805 return GroupRecordType[tuple];
3810 if (IVD->isBitField())
3811 IVars.push_back(const_cast<ObjCIvarDecl *>(IVD));
3813 if (!IVars.empty()) {
3814 unsigned GroupNo = ObjCIvarBitfieldGroupNo(IVars[0]);
3816 GroupRecordType[std::make_pair(CDecl, GroupNo)] =
3817 SynthesizeBitfieldGroupStructType(IVars[0], IVars);
3822 if (!IVars.empty()) {
3824 unsigned GroupNo = ObjCIvarBitfieldGroupNo(IVars[0]);
3825 GroupRecordType[std::make_pair(CDecl, GroupNo)] =
3826 SynthesizeBitfieldGroupStructType(IVars[0], IVars);
3828 QualType RetQT = GroupRecordType[tuple];
3829 assert(!RetQT.
isNull() &&
"GetGroupRecordTypeForObjCIvarBitfield struct type is NULL");
3836 void RewriteModernObjC::ObjCIvarBitfieldGroupDecl(
ObjCIvarDecl *IV,
3837 std::string &Result) {
3840 Result +=
"__GRBF_";
3841 unsigned GroupNo = ObjCIvarBitfieldGroupNo(IV);
3842 Result += utostr(GroupNo);
3848 void RewriteModernObjC::ObjCIvarBitfieldGroupType(
ObjCIvarDecl *IV,
3849 std::string &Result) {
3853 unsigned GroupNo = ObjCIvarBitfieldGroupNo(IV);
3854 Result += utostr(GroupNo);
3860 void RewriteModernObjC::ObjCIvarBitfieldGroupOffset(
ObjCIvarDecl *IV,
3861 std::string &Result) {
3862 Result +=
"OBJC_IVAR_$_";
3863 ObjCIvarBitfieldGroupDecl(IV, Result);
3866 #define SKIP_BITFIELDS(IX, ENDIX, VEC) { \ 3867 while ((IX < ENDIX) && VEC[IX]->isBitField()) \ 3875 void RewriteModernObjC::RewriteObjCInternalStruct(ObjCInterfaceDecl *CDecl,
3876 std::string &Result) {
3877 assert(CDecl &&
"Class missing in SynthesizeObjCInternalStruct");
3878 assert(CDecl->
getName() !=
"" &&
3879 "Name missing in SynthesizeObjCInternalStruct");
3884 IVars.push_back(IVD);
3895 (!RCDecl || !ObjCSynthesizedStructs.count(RCDecl))) {
3897 ReplaceText(LocStart, endBuf-startBuf, Result);
3904 for (
unsigned i = 0, e = IVars.size();
i < e;
i++)
3905 RewriteLocallyDefinedNamedAggregates(IVars[
i], Result);
3909 for (
unsigned i = 0, e = IVars.size(); i < e; i++)
3910 if (IVars[i]->isBitField()) {
3912 QualType QT = GetGroupRecordTypeForObjCIvarBitfield(IV);
3913 RewriteObjCFieldDeclType(QT, Result);
3919 Result +=
"\nstruct ";
3921 Result +=
"_IMPL {\n";
3923 if (RCDecl && ObjCSynthesizedStructs.count(RCDecl)) {
3924 Result +=
"\tstruct "; Result += RCDecl->getNameAsString();
3925 Result +=
"_IMPL "; Result += RCDecl->getNameAsString();
3926 Result +=
"_IVARS;\n";
3929 for (
unsigned i = 0, e = IVars.size(); i < e; i++) {
3930 if (IVars[i]->isBitField()) {
3932 Result +=
"\tstruct ";
3933 ObjCIvarBitfieldGroupType(IV, Result); Result +=
" ";
3934 ObjCIvarBitfieldGroupDecl(IV, Result); Result +=
";\n";
3939 RewriteObjCFieldDecl(IVars[i], Result);
3944 ReplaceText(LocStart, endBuf-startBuf, Result);
3946 if (!ObjCSynthesizedStructs.insert(CDecl).second)
3947 llvm_unreachable(
"struct already synthesize- RewriteObjCInternalStruct");
3952 void RewriteModernObjC::RewriteIvarOffsetSymbols(ObjCInterfaceDecl *CDecl,
3953 std::string &Result) {
3963 const ObjCInterfaceDecl *IDecl = IvarDecl->getContainingInterface();
3964 unsigned GroupNo = 0;
3965 if (IvarDecl->isBitField()) {
3966 GroupNo = ObjCIvarBitfieldGroupNo(IvarDecl);
3967 if (GroupSymbolOutput.count(std::make_pair(IDecl, GroupNo)))
3971 if (LangOpts.MicrosoftExt)
3972 Result +=
"__declspec(allocate(\".objc_ivar$B\")) ";
3973 Result +=
"extern \"C\" ";
3974 if (LangOpts.MicrosoftExt &&
3977 Result +=
"__declspec(dllimport) ";
3979 Result +=
"unsigned long ";
3980 if (IvarDecl->isBitField()) {
3981 ObjCIvarBitfieldGroupOffset(IvarDecl, Result);
3982 GroupSymbolOutput.insert(std::make_pair(IDecl, GroupNo));
3997 void RewriteModernObjC::RewriteImplementations() {
3998 int ClsDefCount = ClassImplementation.size();
3999 int CatDefCount = CategoryImplementation.size();
4002 for (
int i = 0;
i < ClsDefCount;
i++) {
4007 "Legacy implicit interface rewriting not supported in moder abi");
4008 RewriteImplementationDecl(OIMP);
4011 for (
int i = 0;
i < CatDefCount;
i++) {
4016 "Legacy implicit interface rewriting not supported in moder abi");
4017 RewriteImplementationDecl(CIMP);
4021 void RewriteModernObjC::RewriteByRefString(std::string &ResultStr,
4022 const std::string &Name,
4024 assert(BlockByRefDeclNo.count(VD) &&
4025 "RewriteByRefString: ByRef decl missing");
4027 ResultStr +=
"struct ";
4028 ResultStr +=
"__Block_byref_" + Name +
4029 "_" + utostr(BlockByRefDeclNo[VD]) ;
4033 if (
VarDecl *Var = dyn_cast<VarDecl>(VD))
4034 return (Var->isFunctionOrMethodVarDecl() && !Var->hasLocalStorage());
4038 std::string RewriteModernObjC::SynthesizeBlockFunc(
BlockExpr *CE,
int i,
4043 std::string StructRef =
"struct " + Tag;
4046 ConvertSourceLocationToLineDirective(BlockLoc, S);
4049 funcName.str() +
"_block_func_" + utostr(i);
4053 if (isa<FunctionNoProtoType>(AFT)) {
4056 S +=
"(" + StructRef +
" *__cself)";
4058 S +=
"(" + StructRef +
" *__cself)";
4061 assert(FT &&
"SynthesizeBlockFunc: No function proto");
4064 S += StructRef +
" *__cself, ";
4065 std::string ParamStr;
4069 ParamStr = (*AI)->getNameAsString();
4071 (void)convertBlockPointerToFunctionPointer(QT);
4086 E = BlockByRefDecls.end(); I != E; ++I) {
4088 std::string Name = (*I)->getNameAsString();
4089 std::string TypeString;
4090 RewriteByRefString(TypeString, Name, (*I));
4092 Name = TypeString + Name;
4093 S += Name +
" = __cself->" + (*I)->getNameAsString() +
"; // bound by ref\n";
4097 E = BlockByCopyDecls.end(); I != E; ++I) {
4109 if (isTopLevelBlockPointerType((*I)->getType())) {
4110 RewriteBlockPointerTypeVariable(S, (*I));
4112 RewriteBlockPointerType(S, (*I)->getType());
4114 S +=
"__cself->" + (*I)->getNameAsString() +
"; // bound by copy\n";
4117 std::string Name = (*I)->getNameAsString();
4122 S += Name +
" = __cself->" +
4123 (*I)->getNameAsString() +
"; // bound by copy\n";
4126 std::string RewrittenStr = RewrittenBlockExprs[CE];
4127 const char *cstr = RewrittenStr.c_str();
4128 while (*cstr++ !=
'{') ;
4134 std::string RewriteModernObjC::SynthesizeBlockHelperFuncs(
BlockExpr *CE,
int i,
4137 std::string StructRef =
"struct " + Tag;
4138 std::string S =
"static void __";
4141 S +=
"_block_copy_" + utostr(i);
4142 S +=
"(" + StructRef;
4143 S +=
"*dst, " + StructRef;
4145 for (
ValueDecl *VD : ImportedBlockDecls) {
4146 S +=
"_Block_object_assign((void*)&dst->";
4148 S +=
", (void*)src->";
4150 if (BlockByRefDeclsPtrSet.count(VD))
4159 S +=
"\nstatic void __";
4161 S +=
"_block_dispose_" + utostr(i);
4162 S +=
"(" + StructRef;
4164 for (
ValueDecl *VD : ImportedBlockDecls) {
4165 S +=
"_Block_object_dispose((void*)src->";
4167 if (BlockByRefDeclsPtrSet.count(VD))
4178 std::string RewriteModernObjC::SynthesizeBlockImpl(
BlockExpr *CE, std::string Tag,
4180 std::string S =
"\nstruct " + Tag;
4181 std::string Constructor =
" " + Tag;
4183 S +=
" {\n struct __block_impl impl;\n";
4184 S +=
" struct " + Desc;
4187 Constructor +=
"(void *fp, ";
4188 Constructor +=
"struct " + Desc;
4189 Constructor +=
" *desc";
4191 if (BlockDeclRefs.size()) {
4194 E = BlockByCopyDecls.end(); I != E; ++I) {
4196 std::string FieldName = (*I)->getNameAsString();
4197 std::string ArgName =
"_" + FieldName;
4208 if (isTopLevelBlockPointerType((*I)->getType())) {
4209 S +=
"struct __block_impl *";
4210 Constructor +=
", void *" + ArgName;
4217 Constructor +=
", " + ArgName;
4219 S += FieldName +
";\n";
4223 E = BlockByRefDecls.end(); I != E; ++I) {
4225 std::string FieldName = (*I)->getNameAsString();
4226 std::string ArgName =
"_" + FieldName;
4228 std::string TypeString;
4229 RewriteByRefString(TypeString, FieldName, (*I));
4231 FieldName = TypeString + FieldName;
4232 ArgName = TypeString + ArgName;
4233 Constructor +=
", " + ArgName;
4235 S += FieldName +
"; // by ref\n";
4238 Constructor +=
", int flags=0)";
4240 bool firsTime =
true;
4242 E = BlockByCopyDecls.end(); I != E; ++I) {
4243 std::string Name = (*I)->getNameAsString();
4245 Constructor +=
" : ";
4249 Constructor +=
", ";
4250 if (isTopLevelBlockPointerType((*I)->getType()))
4251 Constructor += Name +
"((struct __block_impl *)_" + Name +
")";
4253 Constructor += Name +
"(_" + Name +
")";
4257 E = BlockByRefDecls.end(); I != E; ++I) {
4258 std::string Name = (*I)->getNameAsString();
4260 Constructor +=
" : ";
4264 Constructor +=
", ";
4265 Constructor += Name +
"(_" + Name +
"->__forwarding)";
4268 Constructor +=
" {\n";
4270 Constructor +=
" impl.isa = &_NSConcreteGlobalBlock;\n";
4272 Constructor +=
" impl.isa = &_NSConcreteStackBlock;\n";
4273 Constructor +=
" impl.Flags = flags;\n impl.FuncPtr = fp;\n";
4275 Constructor +=
" Desc = desc;\n";
4278 Constructor +=
", int flags=0) {\n";
4280 Constructor +=
" impl.isa = &_NSConcreteGlobalBlock;\n";
4282 Constructor +=
" impl.isa = &_NSConcreteStackBlock;\n";
4283 Constructor +=
" impl.Flags = flags;\n impl.FuncPtr = fp;\n";
4284 Constructor +=
" Desc = desc;\n";
4287 Constructor +=
"}\n";
4293 std::string RewriteModernObjC::SynthesizeBlockDescriptor(std::string DescTag,
4294 std::string ImplTag,
int i,
4297 std::string S =
"\nstatic struct " + DescTag;
4299 S +=
" {\n size_t reserved;\n";
4300 S +=
" size_t Block_size;\n";
4302 S +=
" void (*copy)(struct ";
4303 S += ImplTag; S +=
"*, struct ";
4304 S += ImplTag; S +=
"*);\n";
4306 S +=
" void (*dispose)(struct ";
4307 S += ImplTag; S +=
"*);\n";
4311 S += DescTag +
"_DATA = { 0, sizeof(struct ";
4314 S +=
", __" + FunName.str() +
"_block_copy_" + utostr(i);
4315 S +=
", __" + FunName.str() +
"_block_dispose_" + utostr(i);
4321 void RewriteModernObjC::SynthesizeBlockLiterals(
SourceLocation FunLocStart,
4322 StringRef FunName) {
4323 bool RewriteSC = (GlobalVarDecl &&
4328 std::string SC(
" void __");
4331 InsertText(FunLocStart, SC);
4335 for (
unsigned i = 0, count=0; i < Blocks.size(); i++) {
4336 CollectBlockDeclRefInfo(Blocks[i]);
4339 for (
int j = 0; j < InnerDeclRefsCount[
i]; j++) {
4342 BlockDeclRefs.push_back(Exp);
4343 if (!VD->
hasAttr<BlocksAttr>()) {
4344 if (!BlockByCopyDeclsPtrSet.count(VD)) {
4345 BlockByCopyDeclsPtrSet.insert(VD);
4346 BlockByCopyDecls.push_back(VD);
4351 if (!BlockByRefDeclsPtrSet.count(VD)) {
4352 BlockByRefDeclsPtrSet.insert(VD);
4353 BlockByRefDecls.push_back(VD);
4360 ImportedBlockDecls.insert(VD);
4363 std::string ImplTag =
"__" + FunName.str() +
"_block_impl_" + utostr(i);
4364 std::string DescTag =
"__" + FunName.str() +
"_block_desc_" + utostr(i);
4366 std::string CI = SynthesizeBlockImpl(Blocks[i], ImplTag, DescTag);
4368 InsertText(FunLocStart, CI);
4370 std::string CF = SynthesizeBlockFunc(Blocks[i], i, FunName, ImplTag);
4372 InsertText(FunLocStart, CF);
4374 if (ImportedBlockDecls.size()) {
4375 std::string HF = SynthesizeBlockHelperFuncs(Blocks[i], i, FunName, ImplTag);
4376 InsertText(FunLocStart, HF);
4378 std::string BD = SynthesizeBlockDescriptor(DescTag, ImplTag, i, FunName,
4379 ImportedBlockDecls.size() > 0);
4380 InsertText(FunLocStart, BD);
4382 BlockDeclRefs.clear();
4383 BlockByRefDecls.clear();
4384 BlockByRefDeclsPtrSet.clear();
4385 BlockByCopyDecls.clear();
4386 BlockByCopyDeclsPtrSet.clear();
4387 ImportedBlockDecls.clear();
4401 InsertText(FunLocStart, SC);
4403 if (GlobalConstructionExp) {
4407 std::string Tag =
"__";
4409 Tag +=
"_block_impl_";
4410 Tag += utostr(Blocks.size()-1);
4411 std::string globalBuf =
"static ";
4412 globalBuf += Tag; globalBuf +=
" ";
4415 llvm::raw_string_ostream constructorExprBuf(SStr);
4416 GlobalConstructionExp->
printPretty(constructorExprBuf,
nullptr,
4418 globalBuf += constructorExprBuf.str();
4420 InsertText(FunLocStart, globalBuf);
4421 GlobalConstructionExp =
nullptr;
4425 InnerDeclRefsCount.clear();
4426 InnerDeclRefs.clear();
4427 RewrittenBlockExprs.clear();
4430 void RewriteModernObjC::InsertBlockLiteralsWithinFunction(
FunctionDecl *FD) {
4434 StringRef FuncName = FD->
getName();
4436 SynthesizeBlockLiterals(FunLocStart, FuncName);
4445 std::string::size_type loc = 0;
4446 while ((loc = Name.find(
':', loc)) != std::string::npos)
4447 Name.replace(loc, 1,
"_");
4450 void RewriteModernObjC::InsertBlockLiteralsWithinMethod(
ObjCMethodDecl *MD) {
4454 std::string FuncName;
4456 SynthesizeBlockLiterals(FunLocStart, FuncName);
4459 void RewriteModernObjC::GetBlockDeclRefExprs(
Stmt *S) {
4462 if (
BlockExpr *CBE = dyn_cast<BlockExpr>(SubStmt))
4463 GetBlockDeclRefExprs(CBE->getBody());
4465 GetBlockDeclRefExprs(SubStmt);
4469 if (DRE->refersToEnclosingVariableOrCapture() ||
4472 BlockDeclRefs.push_back(DRE);
4475 void RewriteModernObjC::GetInnerBlockDeclRefExprs(
Stmt *S,
4477 llvm::SmallPtrSetImpl<const DeclContext *> &InnerContexts) {
4480 if (
BlockExpr *CBE = dyn_cast<BlockExpr>(SubStmt)) {
4481 InnerContexts.insert(cast<DeclContext>(CBE->getBlockDecl()));
4482 GetInnerBlockDeclRefExprs(CBE->getBody(),
4487 GetInnerBlockDeclRefExprs(SubStmt, InnerBlockDeclRefs, InnerContexts);
4490 if (
DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(S)) {
4491 if (DRE->refersToEnclosingVariableOrCapture() ||
4493 if (!InnerContexts.count(DRE->getDecl()->getDeclContext()))
4494 InnerBlockDeclRefs.push_back(DRE);
4495 if (
VarDecl *Var = cast<VarDecl>(DRE->getDecl()))
4496 if (Var->isFunctionOrMethodVarDecl())
4497 ImportedLocalExternalDecls.insert(Var);
4505 bool RewriteModernObjC::convertObjCTypeToCStyleType(
QualType &T) {
4507 convertBlockPointerToFunctionPointer(T);
4513 T = convertFunctionTypeOfBlocks(FT);
4519 convertToUnqualifiedObjCType(T);
4533 bool modified = convertObjCTypeToCStyleType(Res);
4539 if (convertObjCTypeToCStyleType(t))
4541 ArgTypes.push_back(t);
4546 FuncType = getSimpleFunctionType(Res, ArgTypes);
4551 Stmt *RewriteModernObjC::SynthesizeBlockCall(
CallExpr *Exp,
const Expr *BlockExp) {
4555 if (
const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(BlockExp)) {
4557 }
else if (
const MemberExpr *MExpr = dyn_cast<MemberExpr>(BlockExp)) {
4560 else if (
const ParenExpr *PRE = dyn_cast<ParenExpr>(BlockExp)) {
4561 return SynthesizeBlockCall(Exp, PRE->getSubExpr());
4563 else if (
const ImplicitCastExpr *IEXPR = dyn_cast<ImplicitCastExpr>(BlockExp))
4566 dyn_cast<ConditionalOperator>(BlockExp)) {
4567 Expr *LHSExp = CEXPR->getLHS();
4568 Stmt *LHSStmt = SynthesizeBlockCall(Exp, LHSExp);
4569 Expr *RHSExp = CEXPR->getRHS();
4570 Stmt *RHSStmt = SynthesizeBlockCall(Exp, RHSExp);
4571 Expr *CONDExp = CEXPR->getCond();
4578 }
else if (
const ObjCIvarRefExpr *IRE = dyn_cast<ObjCIvarRefExpr>(BlockExp)) {
4581 = dyn_cast<PseudoObjectExpr>(BlockExp)) {
4584 assert(
false &&
"RewriteBlockClass: Bad type");
4586 assert(CPT &&
"RewriteBlockClass: Bad type");
4588 assert(FT &&
"RewriteBlockClass: Bad type");
4601 ArgTypes.push_back(PtrBlock);
4606 if (!convertBlockPointerToFunctionPointer(t))
4607 convertToUnqualifiedObjCType(t);
4608 ArgTypes.push_back(t);
4612 QualType PtrToFuncCastType = getSimpleFunctionType(Exp->
getType(), ArgTypes);
4616 CastExpr *BlkCast = NoTypeInfoCStyleCastExpr(Context, PtrBlock,
4618 const_cast<Expr*>(BlockExp));
4633 CastExpr *FunkCast = NoTypeInfoCStyleCastExpr(Context, PtrToFuncCastType,
4639 BlkExprs.push_back(BlkCast);
4642 E = Exp->
arg_end(); I != E; ++I) {
4643 BlkExprs.push_back(*I);
4663 Stmt *RewriteModernObjC::RewriteBlockDeclRefExpr(
DeclRefExpr *DeclRefExp) {
4679 StringRef Name = VD->
getName();
4692 ReplaceStmt(DeclRefExp, PE);
4699 Stmt *RewriteModernObjC::RewriteLocalVariableExternalStorage(
DeclRefExpr *DRE) {
4701 if (
VarDecl *Var = dyn_cast<VarDecl>(VD))
4702 if (!ImportedLocalExternalDecls.count(Var))
4710 ReplaceStmt(DRE, PE);
4728 const Type* TypePtr = QT->
getAs<Type>();
4729 if (isa<TypeOfExprType>(TypePtr)) {
4730 const TypeOfExprType *TypeOfExprTypePtr = cast<TypeOfExprType>(TypePtr);
4732 std::string TypeAsString =
"(";
4733 RewriteBlockPointerType(TypeAsString, QT);
4734 TypeAsString +=
")";
4735 ReplaceText(LocStart, endBuf-startBuf+1, TypeAsString);
4739 const char *argPtr = startBuf;
4741 while (*argPtr++ && (argPtr < endBuf)) {
4746 ReplaceText(LocStart, 1,
"*");
4752 void RewriteModernObjC::RewriteImplicitCastObjCExpr(
CastExpr *IC) {
4754 if (CastKind != CK_BlockPointerToObjCPointerCast &&
4755 CastKind != CK_AnyPointerToBlockPointerCast)
4759 (void)convertBlockPointerToFunctionPointer(QT);
4761 std::string Str =
"(";
4767 void RewriteModernObjC::RewriteBlockPointerFunctionArgs(
FunctionDecl *FD) {
4769 unsigned parenCount = 0;
4773 const char *startArgList = strchr(startBuf,
'(');
4775 assert((*startArgList ==
'(') &&
"Rewriter fuzzy parser confused");
4780 assert((DeclLoc.
isValid()) &&
"Invalid DeclLoc");
4782 const char *argPtr = startArgList;
4784 while (*argPtr++ && parenCount) {
4789 ReplaceText(DeclLoc, 1,
"*");
4801 bool RewriteModernObjC::PointerTypeTakesAnyBlockArguments(
QualType QT) {
4808 assert(BPT &&
"BlockPointerTypeTakeAnyBlockArguments(): not a block pointer type");
4813 if (isTopLevelBlockPointerType(I))
4819 bool RewriteModernObjC::PointerTypeTakesAnyObjCQualifiedType(
QualType QT) {
4826 assert(BPT &&
"BlockPointerTypeTakeAnyBlockArguments(): not a block pointer type");
4831 if (I->isObjCQualifiedIdType())
4833 if (I->isObjCObjectPointerType() &&
4834 I->getPointeeType()->isObjCQualifiedInterfaceType())
4842 void RewriteModernObjC::GetExtentOfArgList(
const char *Name,
const char *&LParen,
4843 const char *&RParen) {
4844 const char *argPtr = strchr(Name,
'(');
4845 assert((*argPtr ==
'(') &&
"Rewriter fuzzy parser confused");
4849 unsigned parenCount = 1;
4851 while (*argPtr && parenCount) {
4853 case '(': parenCount++;
break;
4854 case ')': parenCount--;
break;
4857 if (parenCount) argPtr++;
4859 assert((*argPtr ==
')') &&
"Rewriter fuzzy parser confused");
4863 void RewriteModernObjC::RewriteBlockPointerDecl(
NamedDecl *ND) {
4865 RewriteBlockPointerFunctionArgs(FD);
4871 if (
VarDecl *VD = dyn_cast<VarDecl>(ND))
4874 DeclT = TDD->getUnderlyingType();
4875 else if (
FieldDecl *FD = dyn_cast<FieldDecl>(ND))
4878 llvm_unreachable(
"RewriteBlockPointerDecl(): Decl type not yet handled");
4881 const char *endBuf = startBuf;
4883 while (*startBuf !=
'^' && *startBuf !=
';' && startBuf != MainFileStart)
4887 unsigned OrigLength=0;
4890 if (*startBuf ==
'^') {
4896 while (*startBuf !=
')') {
4904 if (PointerTypeTakesAnyBlockArguments(DeclT) ||
4905 PointerTypeTakesAnyObjCQualifiedType(DeclT)) {
4910 const char *argListBegin, *argListEnd;
4911 GetExtentOfArgList(startBuf, argListBegin, argListEnd);
4912 while (argListBegin < argListEnd) {
4913 if (*argListBegin ==
'^')
4915 else if (*argListBegin ==
'<') {
4917 buf += *argListBegin++;
4919 while (*argListBegin !=
'>') {
4920 buf += *argListBegin++;
4923 buf += *argListBegin;
4927 buf += *argListBegin;
4934 ReplaceText(Start, OrigLength, buf);
4957 std::string RewriteModernObjC::SynthesizeByrefCopyDestroyHelper(
VarDecl *VD,
4960 if (CopyDestroyCache.count(flag))
4962 CopyDestroyCache.insert(flag);
4963 S =
"static void __Block_byref_id_object_copy_";
4965 S +=
"(void *dst, void *src) {\n";
4971 unsigned VoidPtrSize =
4974 unsigned offset = (VoidPtrSize*4 + IntSize + IntSize)/Context->
getCharWidth();
4975 S +=
" _Block_object_assign((char*)dst + ";
4976 S += utostr(offset);
4977 S +=
", *(void * *) ((char*)src + ";
4978 S += utostr(offset);
4983 S +=
"static void __Block_byref_id_object_dispose_";
4985 S +=
"(void *src) {\n";
4986 S +=
" _Block_object_dispose(*(void * *) ((char*)src + ";
4987 S += utostr(offset);
5012 void RewriteModernObjC::RewriteByRefVar(
VarDecl *ND,
bool firstDecl,
5026 std::string ByrefType;
5027 RewriteByRefString(ByrefType, Name, ND,
true);
5028 ByrefType +=
" {\n";
5029 ByrefType +=
" void *__isa;\n";
5030 RewriteByRefString(ByrefType, Name, ND);
5031 ByrefType +=
" *__forwarding;\n";
5032 ByrefType +=
" int __flags;\n";
5033 ByrefType +=
" int __size;\n";
5038 if (HasCopyAndDispose) {
5039 ByrefType +=
" void (*__Block_byref_id_object_copy)(void*, void*);\n";
5040 ByrefType +=
" void (*__Block_byref_id_object_dispose)(void*);\n";
5044 (void)convertBlockPointerToFunctionPointer(T);
5047 ByrefType +=
" " + Name +
";\n";
5048 ByrefType +=
"};\n";
5054 assert(CurMethodDef &&
"RewriteByRefVar - CurMethodDef is null");
5057 InsertText(FunLocStart, ByrefType);
5063 if (HasCopyAndDispose) {
5071 std::string HF = SynthesizeByrefCopyDestroyHelper(ND, flag);
5079 bool hasInit = (ND->
getInit() !=
nullptr);
5090 if (HasCopyAndDispose)
5094 RewriteByRefString(ByrefType, Name, ND);
5095 std::string ForwardingCastType(
"(");
5096 ForwardingCastType += ByrefType +
" *)";
5097 ByrefType +=
" " + Name +
" = {(void*)";
5098 ByrefType += utostr(isa);
5099 ByrefType +=
"," + ForwardingCastType +
"&" + Name +
", ";
5100 ByrefType += utostr(flags);
5102 ByrefType +=
"sizeof(";
5103 RewriteByRefString(ByrefType, Name, ND);
5105 if (HasCopyAndDispose) {
5106 ByrefType +=
", __Block_byref_id_object_copy_";
5107 ByrefType += utostr(flag);
5108 ByrefType +=
", __Block_byref_id_object_dispose_";
5109 ByrefType += utostr(flag);
5118 const char *commaBuf = startDeclBuf;
5119 while (*commaBuf !=
',')
5121 assert((*commaBuf ==
',') &&
"RewriteByRefVar: can't find ','");
5123 startBuf = commaBuf;
5127 ByrefType +=
"};\n";
5128 unsigned nameSize = Name.size();
5133 ReplaceText(DeclLoc, endBuf-startBuf+nameSize, ByrefType);
5140 startLoc = ECE->getLParenLoc();
5145 ReplaceText(DeclLoc, endBuf-startBuf, ByrefType);
5147 const char separator = lastDecl ?
';' :
',';
5149 const char *separatorBuf = strchr(startInitializerBuf, separator);
5150 assert((*separatorBuf == separator) &&
5151 "RewriteByRefVar: can't find ';' or ','");
5155 InsertText(separatorLoc, lastDecl ?
"}" :
"};\n");
5159 void RewriteModernObjC::CollectBlockDeclRefInfo(
BlockExpr *Exp) {
5161 GetBlockDeclRefExprs(Exp->
getBody());
5162 if (BlockDeclRefs.size()) {
5164 for (
unsigned i = 0; i < BlockDeclRefs.size(); i++)
5165 if (!BlockDeclRefs[i]->getDecl()->hasAttr<BlocksAttr>()) {
5166 if (!BlockByCopyDeclsPtrSet.count(BlockDeclRefs[i]->getDecl())) {
5167 BlockByCopyDeclsPtrSet.insert(BlockDeclRefs[i]->getDecl());
5168 BlockByCopyDecls.push_back(BlockDeclRefs[i]->getDecl());
5172 for (
unsigned i = 0; i < BlockDeclRefs.size(); i++)
5173 if (BlockDeclRefs[i]->getDecl()->hasAttr<BlocksAttr>()) {
5174 if (!BlockByRefDeclsPtrSet.count(BlockDeclRefs[i]->getDecl())) {
5175 BlockByRefDeclsPtrSet.insert(BlockDeclRefs[i]->getDecl());
5176 BlockByRefDecls.push_back(BlockDeclRefs[i]->getDecl());
5180 for (
unsigned i = 0; i < BlockDeclRefs.size(); i++)
5181 if (BlockDeclRefs[i]->getDecl()->hasAttr<BlocksAttr>() ||
5182 BlockDeclRefs[i]->getType()->isObjCObjectPointerType() ||
5183 BlockDeclRefs[
i]->getType()->isBlockPointerType())
5184 ImportedBlockDecls.insert(BlockDeclRefs[i]->getDecl());
5188 FunctionDecl *RewriteModernObjC::SynthBlockInitFunctionDecl(StringRef
name) {
5200 Blocks.push_back(Exp);
5202 CollectBlockDeclRefInfo(Exp);
5205 int countOfInnerDecls = 0;
5206 if (!InnerBlockDeclRefs.empty()) {
5207 for (
unsigned i = 0; i < InnerBlockDeclRefs.size(); i++) {
5210 if (!VD->
hasAttr<BlocksAttr>() && !BlockByCopyDeclsPtrSet.count(VD)) {
5214 InnerDeclRefs.push_back(Exp); countOfInnerDecls++;
5215 BlockDeclRefs.push_back(Exp);
5216 BlockByCopyDeclsPtrSet.insert(VD);
5217 BlockByCopyDecls.push_back(VD);
5219 if (VD->
hasAttr<BlocksAttr>() && !BlockByRefDeclsPtrSet.count(VD)) {
5220 InnerDeclRefs.push_back(Exp); countOfInnerDecls++;
5221 BlockDeclRefs.push_back(Exp);
5222 BlockByRefDeclsPtrSet.insert(VD);
5223 BlockByRefDecls.push_back(VD);
5227 for (
unsigned i = 0; i < InnerBlockDeclRefs.size(); i++)
5228 if (InnerBlockDeclRefs[i]->getDecl()->hasAttr<BlocksAttr>() ||
5229 InnerBlockDeclRefs[i]->getType()->isObjCObjectPointerType() ||
5230 InnerBlockDeclRefs[
i]->getType()->isBlockPointerType())
5231 ImportedBlockDecls.insert(InnerBlockDeclRefs[i]->getDecl());
5233 InnerDeclRefsCount.push_back(countOfInnerDecls);
5235 std::string FuncName;
5239 else if (CurMethodDef)
5241 else if (GlobalVarDecl)
5244 bool GlobalBlockExpr =
5247 if (GlobalBlockExpr && !GlobalVarDecl) {
5249 GlobalBlockExpr =
false;
5252 std::string BlockNumber = utostr(Blocks.size()-1);
5254 std::string Func =
"__" + FuncName +
"_block_func_" + BlockNumber;
5266 if (GlobalBlockExpr)
5270 Tag += FuncName +
"_block_impl_" + BlockNumber;
5272 FD = SynthBlockInitFunctionDecl(Tag);
5279 FD = SynthBlockInitFunctionDecl(Func);
5284 InitExprs.push_back(castExpr);
5287 std::string DescData =
"__" + FuncName +
"_block_desc_" + BlockNumber +
"_DATA";
5297 InitExprs.push_back(DescRefExpr);
5300 if (BlockDeclRefs.size()) {
5304 E = BlockByCopyDecls.end(); I != E; ++I) {
5305 if (isObjCType((*I)->getType())) {
5307 FD = SynthBlockInitFunctionDecl((*I)->getName());
5317 }
else if (isTopLevelBlockPointerType((*I)->getType())) {
5318 FD = SynthBlockInitFunctionDecl((*I)->getName());
5321 Exp = NoTypeInfoCStyleCastExpr(Context, Context->
VoidPtrTy,
5324 FD = SynthBlockInitFunctionDecl((*I)->getName());
5336 InitExprs.push_back(Exp);
5340 E = BlockByRefDecls.end(); I != E; ++I) {
5343 std::string RecName;
5344 RewriteByRefString(RecName, Name, ND,
true);
5346 +
sizeof(
"struct"));
5350 assert(RD &&
"SynthBlockInitExpr(): Can't find RecordDecl");
5353 FD = SynthBlockInitFunctionDecl((*I)->getName());
5356 bool isNestedCapturedVar =
false;
5358 for (
const auto &CI : block->
captures()) {
5359 const VarDecl *variable = CI.getVariable();
5360 if (variable == ND && CI.isNested()) {
5361 assert (CI.isByRef() &&
5362 "SynthBlockInitExpr - captured block variable is not byref");
5363 isNestedCapturedVar =
true;
5369 if (!isNestedCapturedVar)
5374 Exp = NoTypeInfoCStyleCastExpr(Context, castT, CK_BitCast, Exp);
5375 InitExprs.push_back(Exp);
5378 if (ImportedBlockDecls.size()) {
5385 InitExprs.push_back(FlagExp);
5390 if (GlobalBlockExpr) {
5391 assert (!GlobalConstructionExp &&
5392 "SynthBlockInitExpr - GlobalConstructionExp must be null");
5393 GlobalConstructionExp = NewRep;
5400 NewRep = NoTypeInfoCStyleCastExpr(Context, FType, CK_BitCast,
5406 BlockDeclRefs.clear();
5407 BlockByRefDecls.clear();
5408 BlockByRefDeclsPtrSet.clear();
5409 BlockByCopyDecls.clear();
5410 BlockByCopyDeclsPtrSet.clear();
5411 ImportedBlockDecls.clear();
5415 bool RewriteModernObjC::IsDeclStmtInForeachHeader(
DeclStmt *DS) {
5417 dyn_cast<ObjCForCollectionStmt>(Stmts.back()))
5418 return CS->getElement() == DS;
5426 Stmt *RewriteModernObjC::RewriteFunctionBodyOrGlobalInitializer(
Stmt *S) {
5427 if (isa<SwitchStmt>(S) || isa<WhileStmt>(S) ||
5428 isa<DoStmt>(S) || isa<ForStmt>(S))
5430 else if (isa<ObjCForCollectionStmt>(S)) {
5432 ObjCBcLabelNo.push_back(++BcLabelCount);
5439 return RewritePropertyOrImplicitSetter(PseudoOp);
5441 return RewritePropertyOrImplicitGetter(PseudoOp);
5443 }
else if (
ObjCIvarRefExpr *IvarRefExpr = dyn_cast<ObjCIvarRefExpr>(S)) {
5444 return RewriteObjCIvarRefExpr(IvarRefExpr);
5446 else if (isa<OpaqueValueExpr>(S))
5447 S = cast<OpaqueValueExpr>(S)->getSourceExpr();
5454 Stmt *newStmt = RewriteFunctionBodyOrGlobalInitializer(childStmt);
5456 childStmt = newStmt;
5460 if (
BlockExpr *BE = dyn_cast<BlockExpr>(S)) {
5462 llvm::SmallPtrSet<const DeclContext *, 8> InnerContexts;
5463 InnerContexts.insert(BE->getBlockDecl());
5464 ImportedLocalExternalDecls.clear();
5465 GetInnerBlockDeclRefExprs(BE->getBody(),
5466 InnerBlockDeclRefs, InnerContexts);
5468 Stmt *SaveCurrentBody = CurrentBody;
5469 CurrentBody = BE->getBody();
5470 PropParentMap =
nullptr;
5476 bool saveDisableReplaceStmt = DisableReplaceStmt;
5477 DisableReplaceStmt =
false;
5478 RewriteFunctionBodyOrGlobalInitializer(BE->getBody());
5479 DisableReplaceStmt = saveDisableReplaceStmt;
5480 CurrentBody = SaveCurrentBody;
5481 PropParentMap =
nullptr;
5482 ImportedLocalExternalDecls.clear();
5485 RewrittenBlockExprs[BE] = Str;
5487 Stmt *blockTranscribed = SynthBlockInitExpr(BE, InnerBlockDeclRefs);
5490 ReplaceStmt(S, blockTranscribed);
5491 return blockTranscribed;
5495 return RewriteAtEncode(AtEncode);
5498 return RewriteAtSelector(AtSelector);
5501 return RewriteObjCStringLiteral(AtString);
5504 return RewriteObjCBoolLiteralExpr(BoolLitExpr);
5507 return RewriteObjCBoxedExpr(BoxedExpr);
5510 return RewriteObjCArrayLiteralExpr(ArrayLitExpr);
5513 dyn_cast<ObjCDictionaryLiteral>(S))
5514 return RewriteObjCDictionaryLiteralExpr(DictionaryLitExpr);
5525 std::string messString;
5526 messString +=
"// ";
5527 messString.append(startBuf, endBuf-startBuf+1);
5536 return RewriteMessageExpr(MessExpr);
5540 dyn_cast<ObjCAutoreleasePoolStmt>(S)) {
5541 return RewriteObjCAutoreleasePoolStmt(StmtAutoRelease);
5545 return RewriteObjCTryStmt(StmtTry);
5548 return RewriteObjCSynchronizedStmt(StmtTry);
5551 return RewriteObjCThrowStmt(StmtThrow);
5554 return RewriteObjCProtocolExpr(ProtocolExp);
5557 dyn_cast<ObjCForCollectionStmt>(S))
5558 return RewriteObjCForCollectionStmt(StmtForCollection,
5561 dyn_cast<BreakStmt>(S))
5562 return RewriteBreakStmt(StmtBreakStmt);
5564 dyn_cast<ContinueStmt>(S))
5565 return RewriteContinueStmt(StmtContinueStmt);
5569 if (
DeclStmt *DS = dyn_cast<DeclStmt>(S)) {
5579 if (Stmts.empty() || !IsDeclStmtInForeachHeader(DS))
5580 RewriteObjCQualifiedInterfaceTypes(*DS->
decl_begin());
5586 if (
ValueDecl *ND = dyn_cast<ValueDecl>(SD)) {
5587 if (isTopLevelBlockPointerType(ND->
getType()))
5588 RewriteBlockPointerDecl(ND);
5590 CheckFunctionPointerDecl(ND->
getType(), ND);
5591 if (
VarDecl *VD = dyn_cast<VarDecl>(SD)) {
5592 if (VD->
hasAttr<BlocksAttr>()) {
5593 static unsigned uniqueByrefDeclCount = 0;
5594 assert(!BlockByRefDeclNo.count(ND) &&
5595 "RewriteFunctionBodyOrGlobalInitializer: Duplicate byref decl");
5596 BlockByRefDeclNo[ND] = uniqueByrefDeclCount++;
5597 RewriteByRefVar(VD, (DI == DS->
decl_begin()), ((DI+1) == DE));
5600 RewriteTypeOfDecl(VD);
5604 if (isTopLevelBlockPointerType(TD->getUnderlyingType()))
5605 RewriteBlockPointerDecl(TD);
5606 else if (TD->getUnderlyingType()->isFunctionPointerType())
5607 CheckFunctionPointerDecl(TD->getUnderlyingType(), TD);
5613 RewriteObjCQualifiedInterfaceTypes(CE);
5615 if (isa<SwitchStmt>(S) || isa<WhileStmt>(S) ||
5616 isa<DoStmt>(S) || isa<ForStmt>(S)) {
5617 assert(!Stmts.empty() &&
"Statement stack is empty");
5618 assert ((isa<SwitchStmt>(Stmts.back()) || isa<WhileStmt>(Stmts.back()) ||
5619 isa<DoStmt>(Stmts.back()) || isa<ForStmt>(Stmts.back()))
5620 &&
"Statement stack mismatch");
5624 if (
DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(S)) {
5626 if (VD->
hasAttr<BlocksAttr>())
5627 return RewriteBlockDeclRefExpr(DRE);
5629 return RewriteLocalVariableExternalStorage(DRE);
5632 if (
CallExpr *CE = dyn_cast<CallExpr>(S)) {
5635 ReplaceStmt(S, BlockCall);
5640 RewriteCastExpr(CE);
5643 RewriteImplicitCastObjCExpr(ICE);
5653 llvm::raw_string_ostream Buf(SStr);
5655 const std::string &Str = Buf.str();
5657 printf(
"CAST = %s\n", &Str[0]);
5658 InsertText(ICE->getSubExpr()->getBeginLoc(), Str);
5667 void RewriteModernObjC::RewriteRecordBody(
RecordDecl *RD) {
5668 for (
auto *FD : RD->
fields()) {
5669 if (isTopLevelBlockPointerType(FD->
getType()))
5670 RewriteBlockPointerDecl(FD);
5673 RewriteObjCQualifiedInterfaceTypes(FD);
5679 void RewriteModernObjC::HandleDeclInMainFile(
Decl *D) {
5689 RewriteBlocksInFunctionProtoType(FD->
getType(), FD);
5696 CurFunctionDef = FD;
5699 cast_or_null<CompoundStmt>(RewriteFunctionBodyOrGlobalInitializer(Body));
5701 CurrentBody =
nullptr;
5702 if (PropParentMap) {
5703 delete PropParentMap;
5704 PropParentMap =
nullptr;
5708 InsertBlockLiteralsWithinFunction(FD);
5709 RewriteLineDirective(D);
5710 CurFunctionDef =
nullptr;
5714 case Decl::ObjCMethod: {
5720 cast_or_null<CompoundStmt>(RewriteFunctionBodyOrGlobalInitializer(Body));
5722 CurrentBody =
nullptr;
5723 if (PropParentMap) {
5724 delete PropParentMap;
5725 PropParentMap =
nullptr;
5727 InsertBlockLiteralsWithinMethod(MD);
5728 RewriteLineDirective(D);
5729 CurMethodDef =
nullptr;
5733 case Decl::ObjCImplementation: {
5735 ClassImplementation.push_back(CI);
5738 case Decl::ObjCCategoryImpl: {
5740 CategoryImplementation.push_back(CI);
5744 VarDecl *VD = cast<VarDecl>(D);
5745 RewriteObjCQualifiedInterfaceTypes(VD);
5746 if (isTopLevelBlockPointerType(VD->
getType()))
5747 RewriteBlockPointerDecl(VD);
5749 CheckFunctionPointerDecl(VD->
getType(), VD);
5752 RewriteCastExpr(CE);
5758 RewriteRecordBody(RD);
5763 RewriteFunctionBodyOrGlobalInitializer(VD->
getInit());
5764 CurrentBody =
nullptr;
5765 if (PropParentMap) {
5766 delete PropParentMap;
5767 PropParentMap =
nullptr;
5770 GlobalVarDecl =
nullptr;
5774 RewriteCastExpr(CE);
5779 case Decl::TypeAlias:
5780 case Decl::Typedef: {
5782 if (isTopLevelBlockPointerType(TD->getUnderlyingType()))
5783 RewriteBlockPointerDecl(TD);
5784 else if (TD->getUnderlyingType()->isFunctionPointerType())
5785 CheckFunctionPointerDecl(TD->getUnderlyingType(), TD);
5787 RewriteObjCQualifiedInterfaceTypes(TD);
5791 case Decl::CXXRecord:
5792 case Decl::Record: {
5795 RewriteRecordBody(RD);
5809 std::string &Result) {
5812 Result +=
"static ";
5813 Result +=
"struct _protocol_t *";
5814 Result +=
"_OBJC_PROTOCOL_REFERENCE_$_";
5821 void RewriteModernObjC::HandleTranslationUnit(
ASTContext &
C) {
5827 for (
unsigned i = 0, e = FunctionDefinitionsSeen.size(); i < e; i++) {
5832 HandleTopLevelSingleDecl(FDecl);
5838 RewriteObjCProtocolMetaData(ProtDecl, Preamble);
5844 if (ClassImplementation.size() || CategoryImplementation.size())
5845 RewriteImplementations();
5847 for (
unsigned i = 0, e = ObjCInterfacesSeen.size(); i < e; i++) {
5848 ObjCInterfaceDecl *CDecl = ObjCInterfacesSeen[
i];
5853 RewriteInterfaceDecl(CDecl);
5861 *OutFile << std::string(RewriteBuf->begin(), RewriteBuf->end());
5863 llvm::errs() <<
"No changes\n";
5866 if (ClassImplementation.size() || CategoryImplementation.size() ||
5867 ProtocolExprDecls.size()) {
5869 std::string ResultStr;
5870 RewriteMetaDataIntoBuffer(ResultStr);
5872 *OutFile << ResultStr;
5876 std::string ResultStr;
5877 WriteImageInfo(ResultStr);
5878 *OutFile << ResultStr;
5883 void RewriteModernObjC::Initialize(
ASTContext &context) {
5884 InitializeCommon(context);
5886 Preamble +=
"#ifndef __OBJC2__\n";
5887 Preamble +=
"#define __OBJC2__\n";
5888 Preamble +=
"#endif\n";
5893 Preamble =
"#pragma once\n";
5894 Preamble +=
"struct objc_selector; struct objc_class;\n";
5895 Preamble +=
"struct __rw_objc_super { \n\tstruct objc_object *object; ";
5896 Preamble +=
"\n\tstruct objc_object *superClass; ";
5898 Preamble +=
"\n\t__rw_objc_super(struct objc_object *o, struct objc_object *s) ";
5899 Preamble +=
": object(o), superClass(s) {} ";
5900 Preamble +=
"\n};\n";
5902 if (LangOpts.MicrosoftExt) {
5905 Preamble +=
"\n#pragma section(\".objc_classlist$B\", long, read, write)\n";
5906 Preamble +=
"#pragma section(\".objc_catlist$B\", long, read, write)\n";
5907 Preamble +=
"#pragma section(\".objc_imageinfo$B\", long, read, write)\n";
5908 Preamble +=
"#pragma section(\".objc_nlclslist$B\", long, read, write)\n";
5909 Preamble +=
"#pragma section(\".objc_nlcatlist$B\", long, read, write)\n";
5911 Preamble +=
"#pragma section(\".cat_cls_meth$B\", long, read, write)\n";
5912 Preamble +=
"#pragma section(\".inst_meth$B\", long, read, write)\n";
5913 Preamble +=
"#pragma section(\".cls_meth$B\", long, read, write)\n";
5914 Preamble +=
"#pragma section(\".objc_ivar$B\", long, read, write)\n";
5918 Preamble +=
"#pragma section(\".objc_selrefs$B\", long, read, write)\n";
5919 Preamble +=
"#pragma section(\".objc_classrefs$B\", long, read, write)\n";
5920 Preamble +=
"#pragma section(\".objc_superrefs$B\", long, read, write)\n";
5923 Preamble +=
"#ifndef _REWRITER_typedef_Protocol\n";
5924 Preamble +=
"typedef struct objc_object Protocol;\n";
5925 Preamble +=
"#define _REWRITER_typedef_Protocol\n";
5926 Preamble +=
"#endif\n";
5927 if (LangOpts.MicrosoftExt) {
5928 Preamble +=
"#define __OBJC_RW_DLLIMPORT extern \"C\" __declspec(dllimport)\n";
5929 Preamble +=
"#define __OBJC_RW_STATICIMPORT extern \"C\"\n";
5932 Preamble +=
"#define __OBJC_RW_DLLIMPORT extern\n";
5934 Preamble +=
"__OBJC_RW_DLLIMPORT void objc_msgSend(void);\n";
5935 Preamble +=
"__OBJC_RW_DLLIMPORT void objc_msgSendSuper(void);\n";
5936 Preamble +=
"__OBJC_RW_DLLIMPORT void objc_msgSend_stret(void);\n";
5937 Preamble +=
"__OBJC_RW_DLLIMPORT void objc_msgSendSuper_stret(void);\n";
5938 Preamble +=
"__OBJC_RW_DLLIMPORT void objc_msgSend_fpret(void);\n";
5940 Preamble +=
"__OBJC_RW_DLLIMPORT struct objc_class *objc_getClass";
5941 Preamble +=
"(const char *);\n";
5942 Preamble +=
"__OBJC_RW_DLLIMPORT struct objc_class *class_getSuperclass";
5943 Preamble +=
"(struct objc_class *);\n";
5944 Preamble +=
"__OBJC_RW_DLLIMPORT struct objc_class *objc_getMetaClass";
5945 Preamble +=
"(const char *);\n";
5946 Preamble +=
"__OBJC_RW_DLLIMPORT void objc_exception_throw( struct objc_object *);\n";
5948 Preamble +=
"__OBJC_RW_DLLIMPORT int objc_sync_enter( struct objc_object *);\n";
5949 Preamble +=
"__OBJC_RW_DLLIMPORT int objc_sync_exit( struct objc_object *);\n";
5950 Preamble +=
"__OBJC_RW_DLLIMPORT Protocol *objc_getProtocol(const char *);\n";
5951 Preamble +=
"#ifdef _WIN64\n";
5952 Preamble +=
"typedef unsigned long long _WIN_NSUInteger;\n";
5953 Preamble +=
"#else\n";
5954 Preamble +=
"typedef unsigned int _WIN_NSUInteger;\n";
5955 Preamble +=
"#endif\n";
5956 Preamble +=
"#ifndef __FASTENUMERATIONSTATE\n";
5957 Preamble +=
"struct __objcFastEnumerationState {\n\t";
5958 Preamble +=
"unsigned long state;\n\t";
5959 Preamble +=
"void **itemsPtr;\n\t";
5960 Preamble +=
"unsigned long *mutationsPtr;\n\t";
5961 Preamble +=
"unsigned long extra[5];\n};\n";
5962 Preamble +=
"__OBJC_RW_DLLIMPORT void objc_enumerationMutation(struct objc_object *);\n";
5963 Preamble +=
"#define __FASTENUMERATIONSTATE\n";
5964 Preamble +=
"#endif\n";
5965 Preamble +=
"#ifndef __NSCONSTANTSTRINGIMPL\n";
5966 Preamble +=
"struct __NSConstantStringImpl {\n";
5967 Preamble +=
" int *isa;\n";
5968 Preamble +=
" int flags;\n";
5969 Preamble +=
" char *str;\n";
5970 Preamble +=
"#if _WIN64\n";
5971 Preamble +=
" long long length;\n";
5972 Preamble +=
"#else\n";
5973 Preamble +=
" long length;\n";
5974 Preamble +=
"#endif\n";
5976 Preamble +=
"#ifdef CF_EXPORT_CONSTANT_STRING\n";
5977 Preamble +=
"extern \"C\" __declspec(dllexport) int __CFConstantStringClassReference[];\n";
5978 Preamble +=
"#else\n";
5979 Preamble +=
"__OBJC_RW_DLLIMPORT int __CFConstantStringClassReference[];\n";
5980 Preamble +=
"#endif\n";
5981 Preamble +=
"#define __NSCONSTANTSTRINGIMPL\n";
5982 Preamble +=
"#endif\n";
5984 Preamble +=
"#ifndef BLOCK_IMPL\n";
5985 Preamble +=
"#define BLOCK_IMPL\n";
5986 Preamble +=
"struct __block_impl {\n";
5987 Preamble +=
" void *isa;\n";
5988 Preamble +=
" int Flags;\n";
5989 Preamble +=
" int Reserved;\n";
5990 Preamble +=
" void *FuncPtr;\n";
5992 Preamble +=
"// Runtime copy/destroy helper functions (from Block_private.h)\n";
5993 Preamble +=
"#ifdef __OBJC_EXPORT_BLOCKS\n";
5994 Preamble +=
"extern \"C\" __declspec(dllexport) " 5995 "void _Block_object_assign(void *, const void *, const int);\n";
5996 Preamble +=
"extern \"C\" __declspec(dllexport) void _Block_object_dispose(const void *, const int);\n";
5997 Preamble +=
"extern \"C\" __declspec(dllexport) void *_NSConcreteGlobalBlock[32];\n";
5998 Preamble +=
"extern \"C\" __declspec(dllexport) void *_NSConcreteStackBlock[32];\n";
5999 Preamble +=
"#else\n";
6000 Preamble +=
"__OBJC_RW_DLLIMPORT void _Block_object_assign(void *, const void *, const int);\n";
6001 Preamble +=
"__OBJC_RW_DLLIMPORT void _Block_object_dispose(const void *, const int);\n";
6002 Preamble +=
"__OBJC_RW_DLLIMPORT void *_NSConcreteGlobalBlock[32];\n";
6003 Preamble +=
"__OBJC_RW_DLLIMPORT void *_NSConcreteStackBlock[32];\n";
6004 Preamble +=
"#endif\n";
6005 Preamble +=
"#endif\n";
6006 if (LangOpts.MicrosoftExt) {
6007 Preamble +=
"#undef __OBJC_RW_DLLIMPORT\n";
6008 Preamble +=
"#undef __OBJC_RW_STATICIMPORT\n";
6009 Preamble +=
"#ifndef KEEP_ATTRIBUTES\n";
6010 Preamble +=
"#define __attribute__(X)\n";
6011 Preamble +=
"#endif\n";
6012 Preamble +=
"#ifndef __weak\n";
6013 Preamble +=
"#define __weak\n";
6014 Preamble +=
"#endif\n";
6015 Preamble +=
"#ifndef __block\n";
6016 Preamble +=
"#define __block\n";
6017 Preamble +=
"#endif\n";
6020 Preamble +=
"#define __block\n";
6021 Preamble +=
"#define __weak\n";
6025 Preamble +=
"\n#include <stdarg.h>\n";
6026 Preamble +=
"struct __NSContainer_literal {\n";
6027 Preamble +=
" void * *arr;\n";
6028 Preamble +=
" __NSContainer_literal (unsigned int count, ...) {\n";
6029 Preamble +=
"\tva_list marker;\n";
6030 Preamble +=
"\tva_start(marker, count);\n";
6031 Preamble +=
"\tarr = new void *[count];\n";
6032 Preamble +=
"\tfor (unsigned i = 0; i < count; i++)\n";
6033 Preamble +=
"\t arr[i] = va_arg(marker, void *);\n";
6034 Preamble +=
"\tva_end( marker );\n";
6035 Preamble +=
" };\n";
6036 Preamble +=
" ~__NSContainer_literal() {\n";
6037 Preamble +=
"\tdelete[] arr;\n";
6042 Preamble +=
"extern \"C\" __declspec(dllimport) void * objc_autoreleasePoolPush(void);\n";
6043 Preamble +=
"extern \"C\" __declspec(dllimport) void objc_autoreleasePoolPop(void *);\n\n";
6044 Preamble +=
"struct __AtAutoreleasePool {\n";
6045 Preamble +=
" __AtAutoreleasePool() {atautoreleasepoolobj = objc_autoreleasePoolPush();}\n";
6046 Preamble +=
" ~__AtAutoreleasePool() {objc_autoreleasePoolPop(atautoreleasepoolobj);}\n";
6047 Preamble +=
" void * atautoreleasepoolobj;\n";
6052 Preamble +=
"\n#define __OFFSETOFIVAR__(TYPE, MEMBER) ((long long) &((TYPE *)0)->MEMBER)\n";
6057 void RewriteModernObjC::RewriteIvarOffsetComputation(
ObjCIvarDecl *ivar,
6058 std::string &Result) {
6059 Result +=
"__OFFSETOFIVAR__(struct ";
6061 if (LangOpts.MicrosoftExt)
6065 ObjCIvarBitfieldGroupDecl(ivar, Result);
6174 static bool meta_data_declared =
false;
6175 if (meta_data_declared)
6178 Result +=
"\nstruct _prop_t {\n";
6179 Result +=
"\tconst char *name;\n";
6180 Result +=
"\tconst char *attributes;\n";
6183 Result +=
"\nstruct _protocol_t;\n";
6185 Result +=
"\nstruct _objc_method {\n";
6186 Result +=
"\tstruct objc_selector * _cmd;\n";
6187 Result +=
"\tconst char *method_type;\n";
6188 Result +=
"\tvoid *_imp;\n";
6191 Result +=
"\nstruct _protocol_t {\n";
6192 Result +=
"\tvoid * isa; // NULL\n";
6193 Result +=
"\tconst char *protocol_name;\n";
6194 Result +=
"\tconst struct _protocol_list_t * protocol_list; // super protocols\n";
6195 Result +=
"\tconst struct method_list_t *instance_methods;\n";
6196 Result +=
"\tconst struct method_list_t *class_methods;\n";
6197 Result +=
"\tconst struct method_list_t *optionalInstanceMethods;\n";
6198 Result +=
"\tconst struct method_list_t *optionalClassMethods;\n";
6199 Result +=
"\tconst struct _prop_list_t * properties;\n";
6200 Result +=
"\tconst unsigned int size; // sizeof(struct _protocol_t)\n";
6201 Result +=
"\tconst unsigned int flags; // = 0\n";
6202 Result +=
"\tconst char ** extendedMethodTypes;\n";
6205 Result +=
"\nstruct _ivar_t {\n";
6206 Result +=
"\tunsigned long int *offset; // pointer to ivar offset location\n";
6207 Result +=
"\tconst char *name;\n";
6208 Result +=
"\tconst char *type;\n";
6209 Result +=
"\tunsigned int alignment;\n";
6210 Result +=
"\tunsigned int size;\n";
6213 Result +=
"\nstruct _class_ro_t {\n";
6214 Result +=
"\tunsigned int flags;\n";
6215 Result +=
"\tunsigned int instanceStart;\n";
6216 Result +=
"\tunsigned int instanceSize;\n";
6218 if (Triple.getArch() == llvm::Triple::x86_64)
6219 Result +=
"\tunsigned int reserved;\n";
6220 Result +=
"\tconst unsigned char *ivarLayout;\n";
6221 Result +=
"\tconst char *name;\n";
6222 Result +=
"\tconst struct _method_list_t *baseMethods;\n";
6223 Result +=
"\tconst struct _objc_protocol_list *baseProtocols;\n";
6224 Result +=
"\tconst struct _ivar_list_t *ivars;\n";
6225 Result +=
"\tconst unsigned char *weakIvarLayout;\n";
6226 Result +=
"\tconst struct _prop_list_t *properties;\n";
6229 Result +=
"\nstruct _class_t {\n";
6230 Result +=
"\tstruct _class_t *isa;\n";
6231 Result +=
"\tstruct _class_t *superclass;\n";
6232 Result +=
"\tvoid *cache;\n";
6233 Result +=
"\tvoid *vtable;\n";
6234 Result +=
"\tstruct _class_ro_t *ro;\n";
6237 Result +=
"\nstruct _category_t {\n";
6238 Result +=
"\tconst char *name;\n";
6239 Result +=
"\tstruct _class_t *cls;\n";
6240 Result +=
"\tconst struct _method_list_t *instance_methods;\n";
6241 Result +=
"\tconst struct _method_list_t *class_methods;\n";
6242 Result +=
"\tconst struct _protocol_list_t *protocols;\n";
6243 Result +=
"\tconst struct _prop_list_t *properties;\n";
6246 Result +=
"extern \"C\" __declspec(dllimport) struct objc_cache _objc_empty_cache;\n";
6247 Result +=
"#pragma warning(disable:4273)\n";
6248 meta_data_declared =
true;
6252 long super_protocol_count) {
6253 Result +=
"struct /*_protocol_list_t*/"; Result +=
" {\n";
6254 Result +=
"\tlong protocol_count; // Note, this is 32/64 bit\n";
6255 Result +=
"\tstruct _protocol_t *super_protocols[";
6256 Result += utostr(super_protocol_count); Result +=
"];\n";
6261 unsigned int method_count) {
6262 Result +=
"struct /*_method_list_t*/"; Result +=
" {\n";
6263 Result +=
"\tunsigned int entsize; // sizeof(struct _objc_method)\n";
6264 Result +=
"\tunsigned int method_count;\n";
6265 Result +=
"\tstruct _objc_method method_list[";
6266 Result += utostr(method_count); Result +=
"];\n";
6271 unsigned int property_count) {
6272 Result +=
"struct /*_prop_list_t*/"; Result +=
" {\n";
6273 Result +=
"\tunsigned int entsize; // sizeof(struct _prop_t)\n";
6274 Result +=
"\tunsigned int count_of_properties;\n";
6275 Result +=
"\tstruct _prop_t prop_list[";
6276 Result += utostr(property_count); Result +=
"];\n";
6281 unsigned int ivar_count) {
6282 Result +=
"struct /*_ivar_list_t*/"; Result +=
" {\n";
6283 Result +=
"\tunsigned int entsize; // sizeof(struct _prop_t)\n";
6284 Result +=
"\tunsigned int count;\n";
6285 Result +=
"\tstruct _ivar_t ivar_list[";
6286 Result += utostr(ivar_count); Result +=
"];\n";
6293 StringRef ProtocolName) {
6294 if (SuperProtocols.size() > 0) {
6295 Result +=
"\nstatic ";
6297 Result +=
" "; Result += VarName;
6298 Result += ProtocolName;
6299 Result +=
" __attribute__ ((used, section (\"__DATA,__objc_const\"))) = {\n";
6300 Result +=
"\t"; Result += utostr(SuperProtocols.size()); Result +=
",\n";
6301 for (
unsigned i = 0, e = SuperProtocols.size(); i < e; i++) {
6303 Result +=
"\t&"; Result +=
"_OBJC_PROTOCOL_";
6317 StringRef TopLevelDeclName,
6319 if (Methods.size() > 0) {
6320 Result +=
"\nstatic ";
6322 Result +=
" "; Result += VarName;
6323 Result += TopLevelDeclName;
6324 Result +=
" __attribute__ ((used, section (\"__DATA,__objc_const\"))) = {\n";
6325 Result +=
"\t"; Result +=
"sizeof(_objc_method)"; Result +=
",\n";
6326 Result +=
"\t"; Result += utostr(Methods.size()); Result +=
",\n";
6327 for (
unsigned i = 0, e = Methods.size(); i < e; i++) {
6330 Result +=
"\t{{(struct objc_selector *)\"";
6332 Result +=
"\t{(struct objc_selector *)\"";
6333 Result += (MD)->getSelector().getAsString(); Result +=
"\"";
6336 Result +=
"\""; Result += MethodTypeString; Result +=
"\"";
6341 Result +=
"(void *)";
6342 Result += RewriteObj.MethodInternalNames[MD];
6356 const Decl *Container,
6358 StringRef ProtocolName) {
6359 if (Properties.size() > 0) {
6360 Result +=
"\nstatic ";
6362 Result +=
" "; Result += VarName;
6363 Result += ProtocolName;
6364 Result +=
" __attribute__ ((used, section (\"__DATA,__objc_const\"))) = {\n";
6365 Result +=
"\t"; Result +=
"sizeof(_prop_t)"; Result +=
",\n";
6366 Result +=
"\t"; Result += utostr(Properties.size()); Result +=
",\n";
6367 for (
unsigned i = 0, e = Properties.size(); i < e; i++) {
6373 Result += PropDecl->
getName(); Result +=
"\",";
6374 std::string PropertyTypeString =
6376 std::string QuotePropertyTypeString;
6377 RewriteObj.QuoteDoublequotes(PropertyTypeString, QuotePropertyTypeString);
6378 Result +=
"\""; Result += QuotePropertyTypeString; Result +=
"\"";
6404 const std::string &InstanceStart,
6405 const std::string &InstanceSize,
6411 StringRef ClassName) {
6412 Result +=
"\nstatic struct _class_ro_t ";
6413 Result += VarName; Result += ClassName;
6414 Result +=
" __attribute__ ((used, section (\"__DATA,__objc_const\"))) = {\n";
6416 Result += llvm::utostr(flags); Result +=
", ";
6417 Result += InstanceStart; Result +=
", ";
6418 Result += InstanceSize; Result +=
", \n";
6421 if (Triple.getArch() == llvm::Triple::x86_64)
6423 Result +=
"(unsigned int)0, \n\t";
6425 Result +=
"0, \n\t";
6426 Result +=
"\""; Result += ClassName; Result +=
"\",\n\t";
6427 bool metaclass = ((flags &
CLS_META) != 0);
6428 if (baseMethods.size() > 0) {
6429 Result +=
"(const struct _method_list_t *)&";
6431 Result +=
"_OBJC_$_CLASS_METHODS_";
6433 Result +=
"_OBJC_$_INSTANCE_METHODS_";
6434 Result += ClassName;
6438 Result +=
"0, \n\t";
6440 if (!metaclass && baseProtocols.size() > 0) {
6441 Result +=
"(const struct _objc_protocol_list *)&";
6442 Result +=
"_OBJC_CLASS_PROTOCOLS_$_"; Result += ClassName;
6446 Result +=
"0, \n\t";
6448 if (!metaclass && ivars.size() > 0) {
6449 Result +=
"(const struct _ivar_list_t *)&";
6450 Result +=
"_OBJC_$_INSTANCE_VARIABLES_"; Result += ClassName;
6454 Result +=
"0, \n\t";
6457 Result +=
"0, \n\t";
6458 if (!metaclass && Properties.size() > 0) {
6459 Result +=
"(const struct _prop_list_t *)&";
6460 Result +=
"_OBJC_$_PROP_LIST_"; Result += ClassName;
6471 const ObjCInterfaceDecl *CDecl,
bool metaclass) {
6473 const ObjCInterfaceDecl *RootClass = CDecl;
6483 if (metaclass && rootClass) {
6486 Result +=
"extern \"C\" ";
6488 Result +=
"__declspec(dllexport) ";
6490 Result +=
"__declspec(dllimport) ";
6492 Result +=
"struct _class_t OBJC_CLASS_$_";
6500 Result +=
"extern \"C\" ";
6502 Result +=
"__declspec(dllexport) ";
6504 Result +=
"__declspec(dllimport) ";
6506 Result +=
"struct _class_t ";
6511 if (metaclass && RootClass != SuperClass) {
6512 Result +=
"extern \"C\" ";
6514 Result +=
"__declspec(dllexport) ";
6516 Result +=
"__declspec(dllimport) ";
6518 Result +=
"struct _class_t ";
6525 Result +=
"\nextern \"C\" __declspec(dllexport) struct _class_t ";
6527 Result +=
" __attribute__ ((used, section (\"__DATA,__objc_data\"))) = {\n";
6531 Result +=
"0, // &"; Result += VarName;
6534 Result +=
"0, // &"; Result += VarName;
6539 Result +=
"0, // &"; Result += VarName;
6547 Result +=
"0, // &OBJC_METACLASS_$_";
6551 Result +=
"0, // &"; Result += VarName;
6558 Result +=
"0, // (void *)&_objc_empty_cache,\n\t";
6559 Result +=
"0, // unused, was (void *)&_objc_empty_vtable,\n\t";
6561 Result +=
"&_OBJC_METACLASS_RO_$_";
6563 Result +=
"&_OBJC_CLASS_RO_$_";
6565 Result +=
",\n};\n";
6572 const ObjCInterfaceDecl *SuperClass =
6575 Result +=
"static void OBJC_CLASS_SETUP_$_";
6577 Result +=
"(void ) {\n";
6579 Result +=
".isa = "; Result +=
"&OBJC_METACLASS_$_";
6583 Result +=
".superclass = ";
6585 Result +=
"&OBJC_CLASS_$_";
6587 Result +=
"&OBJC_METACLASS_$_";
6592 Result +=
".cache = "; Result +=
"&_objc_empty_cache"; Result +=
";\n";
6595 Result +=
".isa = "; Result +=
"&OBJC_METACLASS_$_";
6600 Result +=
".superclass = "; Result +=
"&OBJC_CLASS_$_";
6605 Result +=
".cache = "; Result +=
"&_objc_empty_cache"; Result +=
";\n";
6610 std::string &Result,
6612 ObjCInterfaceDecl *ClassDecl,
6617 StringRef CatName = CatDecl->
getName();
6618 StringRef ClassName = ClassDecl->
getName();
6622 Result +=
"extern \"C\" ";
6624 Result +=
"__declspec(dllexport) ";
6626 Result +=
"__declspec(dllimport) ";
6628 Result +=
"struct _class_t ";
6629 Result +=
"OBJC_CLASS_$_"; Result += ClassName;
6632 Result +=
"\nstatic struct _category_t ";
6633 Result +=
"_OBJC_$_CATEGORY_";
6634 Result += ClassName; Result +=
"_$_"; Result += CatName;
6635 Result +=
" __attribute__ ((used, section (\"__DATA,__objc_const\"))) = \n";
6637 Result +=
"\t\""; Result += ClassName; Result +=
"\",\n";
6638 Result +=
"\t0, // &"; Result +=
"OBJC_CLASS_$_"; Result += ClassName;
6640 if (InstanceMethods.size() > 0) {
6641 Result +=
"\t(const struct _method_list_t *)&";
6642 Result +=
"_OBJC_$_CATEGORY_INSTANCE_METHODS_";
6643 Result += ClassName; Result +=
"_$_"; Result += CatName;
6649 if (ClassMethods.size() > 0) {
6650 Result +=
"\t(const struct _method_list_t *)&";
6651 Result +=
"_OBJC_$_CATEGORY_CLASS_METHODS_";
6652 Result += ClassName; Result +=
"_$_"; Result += CatName;
6658 if (RefedProtocols.size() > 0) {
6659 Result +=
"\t(const struct _protocol_list_t *)&";
6660 Result +=
"_OBJC_CATEGORY_PROTOCOLS_$_";
6661 Result += ClassName; Result +=
"_$_"; Result += CatName;
6667 if (ClassProperties.size() > 0) {
6668 Result +=
"\t(const struct _prop_list_t *)&"; Result +=
"_OBJC_$_PROP_LIST_";
6669 Result += ClassName; Result +=
"_$_"; Result += CatName;
6678 Result +=
"static void OBJC_CATEGORY_SETUP_$_";
6682 Result +=
"(void ) {\n";
6683 Result +=
"\t_OBJC_$_CATEGORY_";
6687 Result +=
".cls = "; Result +=
"&OBJC_CLASS_$_"; Result += ClassName;
6695 StringRef ProtocolName) {
6696 if (Methods.size() == 0)
6699 Result +=
"\nstatic const char *";
6700 Result += VarName; Result += ProtocolName;
6701 Result +=
" [] __attribute__ ((used, section (\"__DATA,__objc_const\"))) = \n";
6703 for (
unsigned i = 0, e = Methods.size(); i < e; i++) {
6705 std::string MethodTypeString =
6707 std::string QuoteMethodTypeString;
6708 RewriteObj.QuoteDoublequotes(MethodTypeString, QuoteMethodTypeString);
6709 Result +=
"\t\""; Result += QuoteMethodTypeString; Result +=
"\"";
6720 std::string &Result,
6722 ObjCInterfaceDecl *CDecl) {
6735 for (
unsigned i =0, e = Ivars.size(); i < e; i++) {
6738 Result +=
"__declspec(allocate(\".objc_ivar$B\")) ";
6743 Result +=
"extern \"C\" unsigned long int ";
6745 Result +=
"extern \"C\" __declspec(dllexport) unsigned long int ";
6746 if (Ivars[i]->isBitField())
6747 RewriteObj.ObjCIvarBitfieldGroupOffset(IvarDecl, Result);
6750 Result +=
" __attribute__ ((used, section (\"__DATA,__objc_ivar\")))";
6752 RewriteObj.RewriteIvarOffsetComputation(IvarDecl, Result);
6754 if (Ivars[i]->isBitField()) {
6765 ObjCInterfaceDecl *CDecl) {
6766 if (OriginalIvars.size() > 0) {
6772 for (
unsigned i = 0, e = OriginalIvars.size(); i < e; i++) {
6773 if (OriginalIvars[i]->isBitField()) {
6774 Ivars.push_back(OriginalIvars[i]);
6779 Ivars.push_back(OriginalIvars[i]);
6782 Result +=
"\nstatic ";
6784 Result +=
" "; Result += VarName;
6786 Result +=
" __attribute__ ((used, section (\"__DATA,__objc_const\"))) = {\n";
6787 Result +=
"\t"; Result +=
"sizeof(_ivar_t)"; Result +=
",\n";
6788 Result +=
"\t"; Result += utostr(Ivars.size()); Result +=
",\n";
6789 for (
unsigned i =0, e = Ivars.size(); i < e; i++) {
6795 Result +=
"(unsigned long int *)&";
6796 if (Ivars[i]->isBitField())
6797 RewriteObj.ObjCIvarBitfieldGroupOffset(IvarDecl, Result);
6803 if (Ivars[i]->isBitField())
6804 RewriteObj.ObjCIvarBitfieldGroupDecl(Ivars[i], Result);
6806 Result += IvarDecl->
getName();
6811 IVQT = RewriteObj.GetGroupRecordTypeForObjCIvarBitfield(IvarDecl);
6813 std::string IvarTypeString, QuoteIvarTypeString;
6816 RewriteObj.QuoteDoublequotes(IvarTypeString, QuoteIvarTypeString);
6817 Result +=
"\""; Result += QuoteIvarTypeString; Result +=
"\", ";
6822 Align = llvm::Log2_32(Align);
6823 Result += llvm::utostr(Align); Result +=
", ";
6836 void RewriteModernObjC::RewriteObjCProtocolMetaData(
ObjCProtocolDecl *PDecl,
6837 std::string &Result) {
6849 RewriteObjCProtocolMetaData(I, Result);
6852 std::vector<ObjCMethodDecl *> InstanceMethods, ClassMethods;
6853 std::vector<ObjCMethodDecl *> OptInstanceMethods, OptClassMethods;
6856 OptInstanceMethods.push_back(MD);
6858 InstanceMethods.push_back(MD);
6864 OptClassMethods.push_back(MD);
6866 ClassMethods.push_back(MD);
6869 std::vector<ObjCMethodDecl *> AllMethods;
6870 for (
unsigned i = 0, e = InstanceMethods.size(); i < e; i++)
6871 AllMethods.push_back(InstanceMethods[i]);
6872 for (
unsigned i = 0, e = ClassMethods.size(); i < e; i++)
6873 AllMethods.push_back(ClassMethods[i]);
6874 for (
unsigned i = 0, e = OptInstanceMethods.size(); i < e; i++)
6875 AllMethods.push_back(OptInstanceMethods[i]);
6876 for (
unsigned i = 0, e = OptClassMethods.size(); i < e; i++)
6877 AllMethods.push_back(OptClassMethods[i]);
6881 "_OBJC_PROTOCOL_METHOD_TYPES_",
6886 "_OBJC_PROTOCOL_REFS_",
6890 "_OBJC_PROTOCOL_INSTANCE_METHODS_",
6894 "_OBJC_PROTOCOL_CLASS_METHODS_",
6898 "_OBJC_PROTOCOL_OPT_INSTANCE_METHODS_",
6902 "_OBJC_PROTOCOL_OPT_CLASS_METHODS_",
6910 "_OBJC_PROTOCOL_PROPERTIES_",
6915 if (LangOpts.MicrosoftExt)
6916 Result +=
"static ";
6917 Result +=
"struct _protocol_t _OBJC_PROTOCOL_";
6919 Result +=
" __attribute__ ((used)) = {\n";
6921 Result +=
"\t\""; Result += PDecl->
getNameAsString(); Result +=
"\",\n";
6922 if (SuperProtocols.size() > 0) {
6923 Result +=
"\t(const struct _protocol_list_t *)&"; Result +=
"_OBJC_PROTOCOL_REFS_";
6928 if (InstanceMethods.size() > 0) {
6929 Result +=
"\t(const struct method_list_t *)&_OBJC_PROTOCOL_INSTANCE_METHODS_";
6935 if (ClassMethods.size() > 0) {
6936 Result +=
"\t(const struct method_list_t *)&_OBJC_PROTOCOL_CLASS_METHODS_";
6942 if (OptInstanceMethods.size() > 0) {
6943 Result +=
"\t(const struct method_list_t *)&_OBJC_PROTOCOL_OPT_INSTANCE_METHODS_";
6949 if (OptClassMethods.size() > 0) {
6950 Result +=
"\t(const struct method_list_t *)&_OBJC_PROTOCOL_OPT_CLASS_METHODS_";
6956 if (ProtocolProperties.size() > 0) {
6957 Result +=
"\t(const struct _prop_list_t *)&_OBJC_PROTOCOL_PROPERTIES_";
6963 Result +=
"\t"; Result +=
"sizeof(_protocol_t)"; Result +=
",\n";
6966 if (AllMethods.size() > 0) {
6967 Result +=
"\t(const char **)&"; Result +=
"_OBJC_PROTOCOL_METHOD_TYPES_";
6972 Result +=
"\t0\n};\n";
6974 if (LangOpts.MicrosoftExt)
6975 Result +=
"static ";
6976 Result +=
"struct _protocol_t *";
6977 Result +=
"_OBJC_LABEL_PROTOCOL_$_"; Result += PDecl->
getNameAsString();
6983 llvm_unreachable(
"protocol already synthesized");
6990 const ObjCInterfaceDecl *OID) {
6991 if (OID->
hasAttr<ObjCExceptionAttr>())
6999 std::string &Result) {
7005 "Legacy implicit interface rewriting not supported in moder abi");
7013 if (!IVD->getDeclName())
7015 IVars.push_back(IVD);
7019 "_OBJC_$_INSTANCE_VARIABLES_",
7030 if (!Prop->getPropertyIvarDecl())
7037 InstanceMethods.push_back(Getter);
7042 InstanceMethods.push_back(Setter);
7046 "_OBJC_$_INSTANCE_METHODS_",
7052 "_OBJC_$_CLASS_METHODS_",
7057 std::vector<ObjCProtocolDecl *> RefedProtocols;
7060 E = Protocols.
end();
7062 RefedProtocols.push_back(*I);
7065 RewriteObjCProtocolMetaData(*I, Result);
7070 "_OBJC_CLASS_PROTOCOLS_$_",
7078 "_OBJC_$_PROP_LIST_",
7083 std::string InstanceSize;
7084 std::string InstanceStart;
7093 InstanceSize =
"sizeof(struct _class_t)";
7094 InstanceStart = InstanceSize;
7096 InstanceStart, InstanceSize,
7101 "_OBJC_METACLASS_RO_$_",
7116 InstanceSize.clear();
7117 InstanceStart.clear();
7118 if (!ObjCSynthesizedStructs.count(CDecl)) {
7120 InstanceStart =
"0";
7123 InstanceSize =
"sizeof(struct ";
7125 InstanceSize +=
"_IMPL)";
7129 RewriteIvarOffsetComputation(IVD, InstanceStart);
7132 InstanceStart = InstanceSize;
7135 InstanceStart, InstanceSize,
7140 "_OBJC_CLASS_RO_$_",
7144 "OBJC_METACLASS_$_",
7151 if (ImplementationIsNonLazy(IDecl))
7152 DefinedNonLazyClasses.push_back(CDecl);
7155 void RewriteModernObjC::RewriteClassSetupInitHook(std::string &Result) {
7156 int ClsDefCount = ClassImplementation.size();
7159 Result +=
"#pragma section(\".objc_inithooks$B\", long, read, write)\n";
7160 Result +=
"__declspec(allocate(\".objc_inithooks$B\")) ";
7161 Result +=
"static void *OBJC_CLASS_SETUP[] = {\n";
7162 for (
int i = 0; i < ClsDefCount; i++) {
7165 Result +=
"\t(void *)&OBJC_CLASS_SETUP_$_";
7166 Result += CDecl->
getName(); Result +=
",\n";
7171 void RewriteModernObjC::RewriteMetaDataIntoBuffer(std::string &Result) {
7172 int ClsDefCount = ClassImplementation.size();
7173 int CatDefCount = CategoryImplementation.size();
7176 for (
int i = 0; i < ClsDefCount; i++)
7177 RewriteObjCClassMetaData(ClassImplementation[i], Result);
7179 RewriteClassSetupInitHook(Result);
7182 for (
int i = 0; i < CatDefCount; i++)
7183 RewriteObjCCategoryImplDecl(CategoryImplementation[i], Result);
7185 RewriteCategorySetupInitHook(Result);
7187 if (ClsDefCount > 0) {
7188 if (LangOpts.MicrosoftExt)
7189 Result +=
"__declspec(allocate(\".objc_classlist$B\")) ";
7190 Result +=
"static struct _class_t *L_OBJC_LABEL_CLASS_$ [";
7191 Result += llvm::utostr(ClsDefCount); Result +=
"]";
7193 " __attribute__((used, section (\"__DATA, __objc_classlist," 7194 "regular,no_dead_strip\")))= {\n";
7195 for (
int i = 0; i < ClsDefCount; i++) {
7196 Result +=
"\t&OBJC_CLASS_$_";
7197 Result += ClassImplementation[
i]->getNameAsString();
7202 if (!DefinedNonLazyClasses.empty()) {
7203 if (LangOpts.MicrosoftExt)
7204 Result +=
"__declspec(allocate(\".objc_nlclslist$B\")) \n";
7205 Result +=
"static struct _class_t *_OBJC_LABEL_NONLAZY_CLASS_$[] = {\n\t";
7206 for (
unsigned i = 0, e = DefinedNonLazyClasses.size(); i < e; i++) {
7207 Result +=
"\t&OBJC_CLASS_$_"; Result += DefinedNonLazyClasses[
i]->getNameAsString();
7214 if (CatDefCount > 0) {
7215 if (LangOpts.MicrosoftExt)
7216 Result +=
"__declspec(allocate(\".objc_catlist$B\")) ";
7217 Result +=
"static struct _category_t *L_OBJC_LABEL_CATEGORY_$ [";
7218 Result += llvm::utostr(CatDefCount); Result +=
"]";
7220 " __attribute__((used, section (\"__DATA, __objc_catlist," 7221 "regular,no_dead_strip\")))= {\n";
7222 for (
int i = 0; i < CatDefCount; i++) {
7223 Result +=
"\t&_OBJC_$_CATEGORY_";
7225 CategoryImplementation[
i]->getClassInterface()->getNameAsString();
7227 Result += CategoryImplementation[
i]->getNameAsString();
7233 if (!DefinedNonLazyCategories.empty()) {
7234 if (LangOpts.MicrosoftExt)
7235 Result +=
"__declspec(allocate(\".objc_nlcatlist$B\")) \n";
7236 Result +=
"static struct _category_t *_OBJC_LABEL_NONLAZY_CATEGORY_$[] = {\n\t";
7237 for (
unsigned i = 0, e = DefinedNonLazyCategories.size(); i < e; i++) {
7238 Result +=
"\t&_OBJC_$_CATEGORY_";
7240 DefinedNonLazyCategories[
i]->getClassInterface()->getNameAsString();
7242 Result += DefinedNonLazyCategories[
i]->getNameAsString();
7249 void RewriteModernObjC::WriteImageInfo(std::string &Result) {
7250 if (LangOpts.MicrosoftExt)
7251 Result +=
"__declspec(allocate(\".objc_imageinfo$B\")) \n";
7253 Result +=
"static struct IMAGE_INFO { unsigned version; unsigned flag; } ";
7255 Result +=
"_OBJC_IMAGE_INFO = { 0, 2 };\n";
7261 std::string &Result) {
7269 FullCategoryName +=
"_$_";
7280 if (!Prop->getPropertyIvarDecl())
7286 InstanceMethods.push_back(Getter);
7290 InstanceMethods.push_back(Setter);
7294 "_OBJC_$_CATEGORY_INSTANCE_METHODS_",
7295 FullCategoryName,
true);
7300 "_OBJC_$_CATEGORY_CLASS_METHODS_",
7301 FullCategoryName,
true);
7309 RewriteObjCProtocolMetaData(I, Result);
7313 "_OBJC_CATEGORY_PROTOCOLS_$_",
7321 "_OBJC_$_PROP_LIST_",
7333 if (ImplementationIsNonLazy(IDecl))
7334 DefinedNonLazyCategories.push_back(CDecl);
7337 void RewriteModernObjC::RewriteCategorySetupInitHook(std::string &Result) {
7338 int CatDefCount = CategoryImplementation.size();
7341 Result +=
"#pragma section(\".objc_inithooks$B\", long, read, write)\n";
7342 Result +=
"__declspec(allocate(\".objc_inithooks$B\")) ";
7343 Result +=
"static void *OBJC_CATEGORY_SETUP[] = {\n";
7344 for (
int i = 0; i < CatDefCount; i++) {
7348 Result +=
"\t(void *)&OBJC_CATEGORY_SETUP_$_";
7349 Result += ClassDecl->
getName();
7359 template<
typename MethodIterator>
7360 void RewriteModernObjC::RewriteObjCMethodsMetaData(MethodIterator MethodBegin,
7361 MethodIterator MethodEnd,
7362 bool IsInstanceMethod,
7364 StringRef ClassName,
7365 std::string &Result) {
7366 if (MethodBegin == MethodEnd)
return;
7368 if (!objc_impl_method) {
7375 Result +=
"\nstruct _objc_method {\n";
7376 Result +=
"\tSEL _cmd;\n";
7377 Result +=
"\tchar *method_types;\n";
7378 Result +=
"\tvoid *_imp;\n";
7381 objc_impl_method =
true;
7392 unsigned NumMethods =
std::distance(MethodBegin, MethodEnd);
7394 if (LangOpts.MicrosoftExt) {
7395 if (IsInstanceMethod)
7396 Result +=
"__declspec(allocate(\".inst_meth$B\")) ";
7398 Result +=
"__declspec(allocate(\".cls_meth$B\")) ";
7400 Result +=
"static struct {\n";
7401 Result +=
"\tstruct _objc_method_list *next_method;\n";
7402 Result +=
"\tint method_count;\n";
7403 Result +=
"\tstruct _objc_method method_list[";
7404 Result += utostr(NumMethods);
7405 Result +=
"];\n} _OBJC_";
7407 Result += IsInstanceMethod ?
"INSTANCE" :
"CLASS";
7408 Result +=
"_METHODS_";
7409 Result += ClassName;
7410 Result +=
" __attribute__ ((used, section (\"__OBJC, __";
7411 Result += IsInstanceMethod ?
"inst" :
"cls";
7412 Result +=
"_meth\")))= ";
7413 Result +=
"{\n\t0, " + utostr(NumMethods) +
"\n";
7415 Result +=
"\t,{{(SEL)\"";
7416 Result += (*MethodBegin)->getSelector().getAsString().c_str();
7417 std::string MethodTypeString;
7420 Result += MethodTypeString;
7421 Result +=
"\", (void *)";
7422 Result += MethodInternalNames[*MethodBegin];
7424 for (++MethodBegin; MethodBegin != MethodEnd; ++MethodBegin) {
7425 Result +=
"\t ,{(SEL)\"";
7426 Result += (*MethodBegin)->getSelector().getAsString().c_str();
7427 std::string MethodTypeString;
7430 Result += MethodTypeString;
7431 Result +=
"\", (void *)";
7432 Result += MethodInternalNames[*MethodBegin];
7435 Result +=
"\t }\n};\n";
7444 DisableReplaceStmtScope S(*
this);
7445 BaseExpr = cast<Expr>(RewriteFunctionBodyOrGlobalInitializer(BaseExpr));
7451 Expr *Replacement = IV;
7456 assert(iFaceDecl &&
"RewriteObjCIvarRefExpr - iFaceDecl is null");
7458 ObjCInterfaceDecl *clsDeclared =
nullptr;
7461 assert(clsDeclared &&
"RewriteObjCIvarRefExpr(): Can't find class");
7464 std::string IvarOffsetName;
7466 ObjCIvarBitfieldGroupOffset(D, IvarOffsetName);
7470 ReferencedIvars[clsDeclared].insert(D);
7494 IvarT = GetGroupRecordTypeForObjCIvarBitfield(D);
7496 if (!isa<TypedefType>(IvarT) && IvarT->
isRecordType()) {
7506 std::string RecName = CDecl->
getName();
7512 unsigned UnsignedIntSize =
7515 llvm::APInt(UnsignedIntSize, 0),
7517 Zero = NoTypeInfoCStyleCastExpr(Context, PtrStructIMPL, CK_BitCast, Zero);
7531 convertObjCTypeToCStyleType(IvarT);
7534 castExpr = NoTypeInfoCStyleCastExpr(Context,
7564 ReplaceStmtWithRange(IV, Replacement, OldRange);
7568 #endif // CLANG_ENABLE_OBJC_REWRITER unsigned getNumSemanticExprs() const
QualType getDecltypeType(Expr *e, QualType UnderlyingType) const
C++11 decltype.
SourceLocation getLocForStartOfFile(FileID FID) const
Return the source location corresponding to the first byte of the specified file. ...
The receiver is the instance of the superclass object.
const BlockDecl * getBlockDecl() const
static bool scanForProtocolRefs(const char *startBuf, const char *endBuf, const char *&startRef, const char *&endRef)
QualType withConst() const
Retrieves a version of this type with const applied.
Represents a function declaration or definition.
The receiver is an object instance.
static FunctionDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation NLoc, DeclarationName N, QualType T, TypeSourceInfo *TInfo, StorageClass SC, bool isInlineSpecified=false, bool hasWrittenPrototype=true, ConstexprSpecKind ConstexprKind=CSK_unspecified)
Expr * getSyntacticForm()
Return the syntactic form of this expression, i.e.
ObjCDictionaryElement getKeyValueElement(unsigned Index) const
static void Write__prop_list_t_TypeDecl(std::string &Result, unsigned int property_count)
bool hasErrorOccurred() const
SourceLocation getLocWithOffset(int Offset) const
Return a source location with the specified offset from this SourceLocation.
const FunctionProtoType * getFunctionType() const
getFunctionType - Return the underlying function type for this block.
Smart pointer class that efficiently represents Objective-C method names.
QualType getObjCIdType() const
Represents the Objective-CC id type.
PointerType - C99 6.7.5.1 - Pointer Declarators.
QualType getPointeeType() const
A (possibly-)qualified type.
bool isBlockPointerType() const
bool isOverloadedOperator() const
Whether this function declaration represents an C++ overloaded operator, e.g., "operator+".
ObjCInterfaceDecl * getClassInterface()
Selector getSelector() const
ObjCInterfaceDecl * getClassInterface()
ASTConsumer - This is an abstract interface that should be implemented by clients that read ASTs...
bool isExternC() const
Determines whether this function is a function with external, C linkage.
bool isThisDeclarationADefinition() const
Determine whether this particular declaration of this class is actually also a definition.
ObjCIvarDecl * getPropertyIvarDecl() const
static void scanToNextArgument(const char *&argRef)
SourceLocation getRParenLoc() const
ObjCProtocolDecl * getProtocol() const
Stmt - This represents one statement.
const ObjCAtFinallyStmt * getFinallyStmt() const
Retrieve the @finally statement, if any.
Expr * getBitWidth() const
SourceLocation getEndLoc() const LLVM_READONLY
FunctionType - C99 6.7.5.3 - Function Declarators.
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee...
bool isMain() const
Determines whether this function is "main", which is the entry point into an executable program...
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
bool isRealFloatingType() const
Floating point categories.
StorageClass getStorageClass() const
Returns the storage class as written in the source.
Defines the SourceManager interface.
static void Write_class_t(ASTContext *Context, std::string &Result, StringRef VarName, const ObjCInterfaceDecl *CDecl, bool metaclass)
bool isRecordType() const
Decl - This represents one declaration (or definition), e.g.
bool isVariadic() const
Whether this function prototype is variadic.
SourceLocation getBeginLoc() const LLVM_READONLY
param_iterator param_end()
bool isBeforeInTranslationUnit(SourceLocation LHS, SourceLocation RHS) const
Determines the order of 2 source locations in the translation unit.
ParenExpr - This represents a parethesized expression, e.g.
const char * getCharacterData(SourceLocation SL, bool *Invalid=nullptr) const
Return a pointer to the start of the specified location in the appropriate spelling MemoryBuffer...
The base class of the type hierarchy.
Represents Objective-C's @throw statement.
CanQual< T > getUnqualifiedType() const
Retrieve the unqualified form of this type.
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
Represents an array type, per C99 6.7.5.2 - Array Declarators.
Represents a call to a C++ constructor.
const ObjCObjectPointerType * getAsObjCInterfacePointerType() const
bool isRestrictQualified() const
Determine whether this type is restrict-qualified.
virtual void completeDefinition()
Note that the definition of this type is now complete.
SourceLocation getEndLoc() const LLVM_READONLY
QualType withConst() const
SourceLocation getLParenLoc() const
const TargetInfo & getTargetInfo() const
A container of type source information.
Floating point control options.
constexpr XRayInstrMask Function
Represents a C++ constructor within a class.
float __ovld __cnfn distance(float p0, float p1)
Returns the distance between p0 and p1.
MutableArrayRef< ParmVarDecl * >::iterator param_iterator
QualType getElementType() const
bool isCompleteDefinition() const
Return true if this decl has its body fully specified.
StringRef getBufferData(FileID FID, bool *Invalid=nullptr) const
Return a StringRef to the source buffer data for the specified FileID.
unsigned getTypeAlign(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in bits.
bool isDefaultConstructor() const
Whether this constructor is a default constructor (C++ [class.ctor]p5), which can be used to default-...
enumerator_range enumerators() const
Represents a variable declaration or definition.
Objects with "hidden" visibility are not seen by the dynamic linker.
SourceLocation getBeginLoc() const LLVM_READONLY
CompoundLiteralExpr - [C99 6.5.2.5].
unsigned getNumParams() const
bool isEnumeralType() const
const T * getAs() const
Member-template getAs<specific type>'.
static SourceLocation getFunctionSourceLocation(RewriteModernObjC &R, FunctionDecl *FD)
getFunctionSourceLocation - returns start location of a function definition.
Extra information about a function prototype.
static MemberExpr * CreateImplicit(const ASTContext &C, Expr *Base, bool IsArrow, ValueDecl *MemberDecl, QualType T, ExprValueKind VK, ExprObjectKind OK)
Create an implicit MemberExpr, with no location, qualifier, template arguments, and so on...
ObjCMethodDecl - Represents an instance or class method declaration.
SourceLocation getLeftLoc() const
RewriteBuffer - As code is rewritten, SourceBuffer's from the original input with modifications get a...
static void Write_RethrowObject(std::string &buf)
std::string getRewrittenText(CharSourceRange Range) const
getRewrittenText - Return the rewritten form of the text in the specified range.
QualType getObjCClassType() const
Represents the Objective-C Class type.
Describes how types, statements, expressions, and declarations should be printed. ...
classmeth_range class_methods() const
protocol_range protocols() const
const Stmt * getSubStmt() const
static void Write_protocol_list_initializer(ASTContext *Context, std::string &Result, ArrayRef< ObjCProtocolDecl *> SuperProtocols, StringRef VarName, StringRef ProtocolName)
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
static void Write__ivar_list_t_TypeDecl(std::string &Result, unsigned int ivar_count)
Represents a struct/union/class.
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
ObjCProtocolDecl * getCanonicalDecl() override
Retrieves the canonical declaration of this Objective-C protocol.
instprop_range instance_properties() const
One of these records is kept for each identifier that is lexed.
An element in an Objective-C dictionary literal.
QualType IgnoreParens() const
Returns the specified type after dropping any outer-level parentheses.
Represents a class type in Objective C.
static RecordDecl * Create(const ASTContext &C, TagKind TK, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, IdentifierInfo *Id, RecordDecl *PrevDecl=nullptr)
QualType getPointeeType() const
static void Write_method_list_t_TypeDecl(std::string &Result, unsigned int method_count)
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
ObjCMethodDecl * getClassMethod(Selector Sel, bool AllowHidden=false) const
RecordDecl * getDefinition() const
Returns the RecordDecl that actually defines this struct/union/class.
field_range fields() const
SourceLocation getBeginLoc() const LLVM_READONLY
Represents a member of a struct/union/class.
std::unique_ptr< ASTConsumer > CreateModernObjCRewriter(const std::string &InFile, std::unique_ptr< raw_ostream > OS, DiagnosticsEngine &Diags, const LangOptions &LOpts, bool SilenceRewriteMacroWarning, bool LineInfo)
static ObjCMessageExpr * Create(const ASTContext &Context, QualType T, ExprValueKind VK, SourceLocation LBracLoc, SourceLocation SuperLoc, bool IsInstanceSuper, QualType SuperType, Selector Sel, ArrayRef< SourceLocation > SelLocs, ObjCMethodDecl *Method, ArrayRef< Expr *> Args, SourceLocation RBracLoc, bool isImplicit)
Create a message send to super.
instmeth_range instance_methods() const
StringLiteral * getString()
std::string getNameAsString() const
Get the name of the class associated with this interface.
SourceLocation getRParenLoc() const
ObjCMethodDecl * getSetterMethodDecl() const
bool ReplaceText(SourceLocation Start, unsigned OrigLength, StringRef NewStr)
ReplaceText - This method replaces a range of characters in the input buffer with a new string...
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
ObjCArrayLiteral - used for objective-c array containers; as in: @["Hello", NSApp, [NSNumber numberWithInt:42]];.
bool isObjCQualifiedClassType() const
SourceLocation getEndLoc() const LLVM_READONLY
An r-value expression (a pr-value in the C++11 taxonomy) produces a temporary value.
Selector getSelector() const
Represents Objective-C's @catch statement.
Describes an C or C++ initializer list.
SourceLocation getIvarRBraceLoc() const
bool isBitField() const
Determines whether this field is a bitfield.
Stmt * getBody(const FunctionDecl *&Definition) const
Retrieve the body (definition) of the function.
ObjCContainerDecl - Represents a container for method declarations.
const Expr * getThrowExpr() const
CharUnits - This is an opaque type for sizes expressed in character units.
ExprValueKind getValueKind() const
getValueKind - The value kind that this expression produces.
SourceLocation getExpansionLoc(SourceLocation Loc) const
Given a SourceLocation object Loc, return the expansion location referenced by the ID...
PropertyAttributeKind getPropertyAttributes() const
Concrete class used by the front-end to report problems and issues.
Represents a typeof (or typeof) expression (a GCC extension).
const clang::PrintingPolicy & getPrintingPolicy() const
Represents a declaration of a type.
A builtin binary operation expression such as "x + y" or "x <= y".
bool isVolatileQualified() const
Determine whether this type is volatile-qualified.
SourceLocation getBeginLoc() const LLVM_READONLY
SourceLocation getEndLoc() const LLVM_READONLY
bool isReadOnly() const
isReadOnly - Return true iff the property has a setter.
Defines the Diagnostic-related interfaces.
ObjCStringLiteral, used for Objective-C string literals i.e.
ObjCProtocolDecl * getDefinition()
Retrieve the definition of this protocol, if any.
unsigned getBitWidthValue(const ASTContext &Ctx) const
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
CompoundStmt * getCompoundBody()
Represents an Objective-C protocol declaration.
Expr * Key
The key for the dictionary element.
const internal::VariadicDynCastAllOfMatcher< Stmt, CastExpr > castExpr
Matches any cast nodes of Clang's AST.
ObjCMethodDecl * getArrayWithObjectsMethod() const
static VarDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, StorageClass S)
static IntegerLiteral * Create(const ASTContext &C, const llvm::APInt &V, QualType type, SourceLocation l)
Returns a new integer literal with value 'V' and type 'type'.
An ordinary object is located at an address in memory.
Represents an ObjC class declaration.
Represents a linkage specification.
QualType getReturnType() const
SourceLocation getTypeSpecStartLoc() const
const Stmt * getBody() const
SourceLocation getLocation() const
static void WriteInternalIvarName(const ObjCInterfaceDecl *IDecl, ObjCIvarDecl *IvarDecl, std::string &Result)
std::string getObjCEncodingForMethodDecl(const ObjCMethodDecl *Decl, bool Extended=false) const
Emit the encoded type for the method declaration Decl into S.
ObjCMethodDecl * getDictWithObjectsMethod() const
static void Write_prop_list_t_initializer(RewriteModernObjC &RewriteObj, ASTContext *Context, std::string &Result, ArrayRef< ObjCPropertyDecl *> Properties, const Decl *Container, StringRef VarName, StringRef ProtocolName)
static void Write_protocol_list_t_TypeDecl(std::string &Result, long super_protocol_count)
const ObjCAtCatchStmt * getCatchStmt(unsigned I) const
Retrieve a @catch statement.
ObjCPropertyImplDecl - Represents implementation declaration of a property in a class or category imp...
ConditionalOperator - The ?: ternary operator.
static bool hasObjCExceptionAttribute(ASTContext &Context, const ObjCInterfaceDecl *OID)
hasObjCExceptionAttribute - Return true if this class or any super class has the objc_exception attri...
CompoundStmt - This represents a group of statements like { stmt stmt }.
Represents a prototype with parameter type info, e.g.
CastKind
CastKind - The kind of operation required for a conversion.
static ImplicitCastExpr * Create(const ASTContext &Context, QualType T, CastKind Kind, Expr *Operand, const CXXCastPath *BasePath, ExprValueKind Cat)
static void RewriteOneForwardClassDecl(ObjCInterfaceDecl *ForwardDecl, std::string &typedefString)
SourceLocation getLocation() const
static bool IsHeaderFile(const std::string &Filename)
SourceLocation getEndLoc() const LLVM_READONLY
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
TypeSourceInfo * getTrivialTypeSourceInfo(QualType T, SourceLocation Loc=SourceLocation()) const
Allocate a TypeSourceInfo where all locations have been initialized to a given location, which defaults to the empty location.
ObjCMethodDecl * getBoxingMethod() const
static StringLiteral * Create(const ASTContext &Ctx, StringRef Str, StringKind Kind, bool Pascal, QualType Ty, const SourceLocation *Loc, unsigned NumConcatenated)
This is the "fully general" constructor that allows representation of strings formed from multiple co...
static CallExpr * Create(const ASTContext &Ctx, Expr *Fn, ArrayRef< Expr *> Args, QualType Ty, ExprValueKind VK, SourceLocation RParenLoc, unsigned MinNumArgs=0, ADLCallKind UsesADL=NotADL)
Create a call expression.
Represents a block literal declaration, which is like an unnamed FunctionDecl.
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
This represents one expression.
bool isVariadic() const
Whether this function is variadic.
Selector getSetterName() const
static unsigned MeasureTokenLength(SourceLocation Loc, const SourceManager &SM, const LangOptions &LangOpts)
MeasureTokenLength - Relex the token at the specified location and return its length in bytes in the ...
const T * castAs() const
Member-template castAs<specific type>.
std::string getObjCEncodingForPropertyDecl(const ObjCPropertyDecl *PD, const Decl *Container) const
getObjCEncodingForPropertyDecl - Return the encoded type for this method declaration.
unsigned getLine() const
Return the presumed line number of this location.
BlockExpr - Adaptor class for mixing a BlockDecl with expressions.
bool isThisDeclarationADefinition() const
Returns whether this specific declaration of the function is also a definition that does not contain ...
bool isThisDeclarationADefinition() const
Determine whether this particular declaration is also the definition.
SourceLocation getEndLoc() const LLVM_READONLY
bool isImplicit() const
isImplicit - Indicates whether the declaration was implicitly generated by the implementation.
QualType getTagDeclType(const TagDecl *Decl) const
Return the unique reference to the type for the specified TagDecl (struct/union/class/enum) decl...
bool isFileContext() const
ObjCDictionaryLiteral - AST node to represent objective-c dictionary literals; as in:"name" : NSUserN...
const CompoundStmt * getSynchBody() const
DeclContext * getDeclContext()
bool isWrittenInMainFile(SourceLocation Loc) const
Returns true if the spelling location for the given location is in the main file buffer.
Represents Objective-C's @synchronized statement.
ObjCInterfaceDecl * getSuperClass() const
ObjCSelectorExpr used for @selector in Objective-C.
const internal::VariadicDynCastAllOfMatcher< Decl, FieldDecl > fieldDecl
Matches field declarations.
static bool mustSynthesizeSetterGetterMethod(ObjCImplementationDecl *IMP, ObjCPropertyDecl *PD, bool getter)
mustSynthesizeSetterGetterMethod - returns true if setter or getter has not been found in the class i...
StorageClass getStorageClass() const
Returns the storage class as written in the source.
LLVM_READONLY bool isAlphanumeric(unsigned char c)
Return true if this character is an ASCII letter or digit: [a-zA-Z0-9].
SourceLocation getAtTryLoc() const
Retrieve the location of the @ in the @try.
SourceLocation getBeginLoc() const LLVM_READONLY
bool refersToEnclosingVariableOrCapture() const
Does this DeclRefExpr refer to an enclosing local or a captured variable?
void getAsStringInternal(std::string &Str, const PrintingPolicy &Policy) const
IdentifierInfo * getAsIdentifierInfo() const
Retrieve the IdentifierInfo * stored in this declaration name, or null if this declaration name isn't...
Defines the clang::IdentifierInfo, clang::IdentifierTable, and clang::Selector interfaces.
ObjCIvarDecl * lookupInstanceVariable(IdentifierInfo *IVarName, ObjCInterfaceDecl *&ClassDeclared)
Expr * getElement(unsigned Index)
getElement - Return the Element at the specified index.
propimpl_range property_impls() const
QualType getConstantArrayType(QualType EltTy, const llvm::APInt &ArySize, ArrayType::ArraySizeModifier ASM, unsigned IndexTypeQuals) const
Return the unique reference to the type for a constant array of the specified element type...
const Stmt * getTryBody() const
Retrieve the @try body.
QualType getEncodedType() const
bool isa(CodeGen::Address addr)
An expression that sends a message to the given Objective-C object or class.
SourceLocation getAtLoc() const
Represents an unpacked "presumed" location which can be presented to the user.
QualType getObjCInterfaceType(const ObjCInterfaceDecl *Decl, ObjCInterfaceDecl *PrevDecl=nullptr) const
getObjCInterfaceType - Return the unique reference to the type for the specified ObjC interface decl...
SourceLocation getEnd() const
#define SKIP_BITFIELDS(IX, ENDIX, VEC)
UnaryOperator - This represents the unary-expression's (except sizeof and alignof), the postinc/postdec operators from postfix-expression, and various extensions.
bool isInstanceMethod() const
QualType getFunctionType(QualType ResultTy, ArrayRef< QualType > Args, const FunctionProtoType::ExtProtoInfo &EPI) const
Return a normal function type with a typed argument list.
ReceiverKind getReceiverKind() const
Determine the kind of receiver that this message is being sent to.
static void BuildUniqueMethodName(std::string &Name, ObjCMethodDecl *MD)
int getRangeSize(SourceRange Range, RewriteOptions opts=RewriteOptions()) const
getRangeSize - Return the size in bytes of the specified range if they are in the same file...
Selector getSelector() const
QualType getTypeDeclType(const TypeDecl *Decl, const TypeDecl *PrevDecl=nullptr) const
Return the unique reference to the type for the specified type declaration.
The result type of a method or function.
unsigned getExpansionLineNumber(SourceLocation Loc, bool *Invalid=nullptr) const
SourceLocation getForLoc() const
SourceLocation getBeginLoc() const LLVM_READONLY
CStyleCastExpr - An explicit cast in C (C99 6.5.4) or a C-style cast in C++ (C++ [expr.cast]), which uses the syntax (Type)expr.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
ImplicitParamDecl * getSelfDecl() const
SourceLocation getBeginLoc() const LLVM_READONLY
SourceLocation getEndLoc() const
Expr * getArg(unsigned Arg)
getArg - Return the specified argument.
Expr * getUnderlyingExpr() const
SourceLocation getEndLoc() const LLVM_READONLY
unsigned getCVRQualifiers() const
Retrieve the set of CVR (const-volatile-restrict) qualifiers applied to this type.
static std::string getIvarAccessString(ObjCIvarDecl *OID)
bool isConstQualified() const
Determine whether this type is const-qualified.
param_iterator param_begin()
const char * getFilename() const
Return the presumed filename of this location.
unsigned getNumArgs() const
Return the number of actual arguments in this message, not counting the receiver. ...
std::string getAsString() const
Derive the full selector name (e.g.
SelectorTable & Selectors
void setSourceMgr(SourceManager &SM, const LangOptions &LO)
PseudoObjectExpr - An expression which accesses a pseudo-object l-value.
param_type_range param_types() const
Encodes a location in the source.
ObjCInterfaceDecl * getDecl() const
Get the declaration of this interface.
SourceLocation getEndLoc() const LLVM_READONLY
QualType getReturnType() const
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of enums...
const Stmt * getCatchBody() const
Interfaces are the core concept in Objective-C for object oriented design.
CastKind getCastKind() const
static void Write_category_t(RewriteModernObjC &RewriteObj, ASTContext *Context, std::string &Result, ObjCCategoryDecl *CatDecl, ObjCInterfaceDecl *ClassDecl, ArrayRef< ObjCMethodDecl *> InstanceMethods, ArrayRef< ObjCMethodDecl *> ClassMethods, ArrayRef< ObjCProtocolDecl *> RefedProtocols, ArrayRef< ObjCPropertyDecl *> ClassProperties)
std::string getNameAsString() const
Get a human-readable name for the declaration, even if it is one of the special kinds of names (C++ c...
unsigned getNumElements() const
getNumElements - Return number of elements of objective-c dictionary literal.
Represents the declaration of a struct/union/class/enum.
static void Write_method_list_t_initializer(RewriteModernObjC &RewriteObj, ASTContext *Context, std::string &Result, ArrayRef< ObjCMethodDecl *> Methods, StringRef VarName, StringRef TopLevelDeclName, bool MethodImpl)
ObjCCategoryDecl * getCategoryDecl() const
DeclStmt - Adaptor class for mixing declarations with statements and expressions. ...
QualType getObjCSelType() const
Retrieve the type that corresponds to the predefined Objective-C 'SEL' type.
const RewriteBuffer * getRewriteBufferFor(FileID FID) const
getRewriteBufferFor - Return the rewrite buffer for the specified FileID.
QualType getBaseElementType(const ArrayType *VAT) const
Return the innermost element type of an array type.
bool isIntegralType(const ASTContext &Ctx) const
Determine whether this type is an integral type.
bool InsertText(SourceLocation Loc, StringRef Str, bool InsertAfter=true, bool indentNewLines=false)
InsertText - Insert the specified string at the specified location in the original buffer...
SourceLocation getSuperLoc() const
Retrieve the location of the 'super' keyword for a class or instance message to 'super', otherwise an invalid source location.
const ArrayType * getAsArrayType(QualType T) const
Type Query functions.
ObjCCategoryDecl - Represents a category declaration.
decl_iterator decl_begin()
ObjCProtocolExpr used for protocol expression in Objective-C.
bool isObjCObjectPointerType() const
Represents one property declaration in an Objective-C interface.
ImplicitCastExpr - Allows us to explicitly represent implicit type conversions, which have no direct ...
bool isImplicit() const
Indicates whether the message send was implicitly generated by the implementation.
unsigned getCustomDiagID(Level L, const char(&FormatString)[N])
Return an ID for a diagnostic with the specified format string and level.
bool isImplicitInterfaceDecl() const
isImplicitInterfaceDecl - check that this is an implicitly declared ObjCInterfaceDecl node...
const ObjCMethodDecl * getMethodDecl() const
ObjCBoxedExpr - used for generalized expression boxing.
static void Write__extendedMethodTypes_initializer(RewriteModernObjC &RewriteObj, ASTContext *Context, std::string &Result, ArrayRef< ObjCMethodDecl *> Methods, StringRef VarName, StringRef ProtocolName)
ObjCImplementationDecl * getImplementation() const
SourceLocation getBeginLoc() const
SourceLocation getBeginLoc() const LLVM_READONLY
protocol_range protocols() const
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
QualType getObjCInstanceType()
Retrieve the Objective-C "instancetype" type, if already known; otherwise, returns a NULL type;...
Expr * Value
The value of the dictionary element.
StringRef getName() const
Return the actual identifier string.
decl_iterator - Iterates through the declarations stored within this context.
Expr * getInstanceReceiver()
Returns the object expression (receiver) for an instance message, or null for a message that is not a...
ObjCIvarDecl * getNextIvar()
bool isObjCGCWeak() const
true when Type is objc's weak.
Base class for declarations which introduce a typedef-name.
Expr * getResultExpr()
Return the result-bearing expression, or null if there is none.
An opaque identifier used by SourceManager which refers to a source file (MemoryBuffer) along with it...
const llvm::MemoryBuffer * getBuffer(FileID FID, SourceLocation Loc, bool *Invalid=nullptr) const
Return the buffer for the specified FileID.
const ObjCInterfaceDecl * getClassInterface() const
Dataflow Directional Tag Classes.
bool isObjCQualifiedInterfaceType() const
bool isValid() const
Return true if this is a valid SourceLocation object.
static void Write__class_ro_t_initializer(ASTContext *Context, std::string &Result, unsigned int flags, const std::string &InstanceStart, const std::string &InstanceSize, ArrayRef< ObjCMethodDecl *>baseMethods, ArrayRef< ObjCProtocolDecl *>baseProtocols, ArrayRef< ObjCIvarDecl *>ivars, ArrayRef< ObjCPropertyDecl *>Properties, StringRef VarName, StringRef ClassName)
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
ArrayRef< Capture > captures() const
Kind getPropertyImplementation() const
const Stmt * getFinallyBody() const
SourceLocation getAtLoc() const
QualType getSuperType() const
Retrieve the type referred to by 'super'.
const ObjCProtocolList & getReferencedProtocols() const
const Expr * getInit() const
FileID getMainFileID() const
Returns the FileID of the main source file.
SourceLocation getBeginLoc() const LLVM_READONLY
int printf(__constant const char *st,...) __attribute__((format(printf
static std::string getAsString(SplitQualType split, const PrintingPolicy &Policy)
bool isBooleanType() const
QualType getFunctionNoProtoType(QualType ResultTy, const FunctionType::ExtInfo &Info) const
Return a K&R style C function type like 'int()'.
U cast(CodeGen::Address addr)
PresumedLoc getPresumedLoc(SourceLocation Loc, bool UseLineDirectives=true) const
Returns the "presumed" location of a SourceLocation specifies.
const ObjCInterfaceDecl * getContainingInterface() const
Return the class interface that this ivar is logically contained in; this is either the interface whe...
QualType getCallResultType(const ASTContext &Context) const
Determine the type of an expression that calls a function of this type.
Expr * IgnoreParenImpCasts() LLVM_READONLY
Skip past any parentheses and implicit casts which might surround this expression until reaching a fi...
SourceLocation getBeginLoc() const LLVM_READONLY
QualType getClassReceiver() const
Returns the type of a class message send, or NULL if the message is not a class message.
Represents a pointer to an Objective C object.
unsigned getByteLength() const
CanQualType ObjCBuiltinBoolTy
ObjCImplementationDecl - Represents a class definition - this is where method definitions are specifi...
Expr * IgnoreImplicit() LLVM_READONLY
Skip past any implicit AST nodes which might surround this expression until reaching a fixed point...
SourceLocation getRParenLoc() const
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
(Obsolete) ARC-specific: this class has a .release_ivars method
Iterator for iterating over Stmt * arrays that contain only T *.
unsigned getNumElements() const
getNumElements - Return number of elements of objective-c array literal.
Represents Objective-C's collection statement.
CanQualType UnsignedLongTy
ObjCEncodeExpr, used for @encode in Objective-C.
Selector getSelector(unsigned NumArgs, IdentifierInfo **IIV)
Can create any sort of selector.
static CStyleCastExpr * Create(const ASTContext &Context, QualType T, ExprValueKind VK, CastKind K, Expr *Op, const CXXCastPath *BasePath, TypeSourceInfo *WrittenTy, SourceLocation L, SourceLocation R)
uint64_t getCharWidth() const
Return the size of the character type, in bits.
void getObjCEncodingForType(QualType T, std::string &S, const FieldDecl *Field=nullptr, QualType *NotEncodedT=nullptr) const
Emit the Objective-CC type encoding for the given type T into S.
bool isObjCQualifiedIdType() const
DeclContext * getRedeclContext()
getRedeclContext - Retrieve the context in which an entity conflicts with other entities of the same ...
ObjCInterfaceDecl * getCanonicalDecl() override
Retrieves the canonical declaration of this Objective-C class.
Represents Objective-C's @finally statement.
void addDecl(Decl *D)
Add the declaration D into this context.
const Expr * getBase() const
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
ObjCIvarRefExpr - A reference to an ObjC instance variable.
SourceManager & getSourceManager()
ImplementationControl getImplementationControl() const
CanQualType getCanonicalType(QualType T) const
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
SourceRange getAtEndRange() const
X
Add a minimal nested name specifier fixit hint to allow lookup of a tag name from an outer enclosing ...
SourceLocation getBeginLoc() const
Rewriter - This is the main interface to the rewrite buffers.
QualType getParamType(unsigned i) const
void printPretty(raw_ostream &OS, PrinterHelper *Helper, const PrintingPolicy &Policy, unsigned Indentation=0, StringRef NewlineSymbol="\, const ASTContext *Context=nullptr) const
TranslationUnitDecl * getTranslationUnitDecl() const
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
ContinueStmt - This represents a continue.
SourceLocation getBeginLoc() const LLVM_READONLY
ObjCIvarDecl - Represents an ObjC instance variable.
static bool isRewritable(SourceLocation Loc)
isRewritable - Return true if this location is a raw file location, which is rewritable.
static TypedefDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, IdentifierInfo *Id, TypeSourceInfo *TInfo)
SourceLocation getAtSynchronizedLoc() const
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
static bool HasLocalVariableExternalStorage(ValueDecl *VD)
Represents Objective-C's @try ... @catch ... @finally statement.
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
unsigned getNumCatchStmts() const
Retrieve the number of @catch statements in this try-catch-finally block.
StringLiteral - This represents a string literal expression, e.g.
Defines the clang::TargetInfo interface.
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
SourceLocation getBeginLoc() const LLVM_READONLY
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
SourceLocation getBeginLoc() const LLVM_READONLY
static void Write_ProtocolExprReferencedMetadata(ASTContext *Context, ObjCProtocolDecl *PDecl, std::string &Result)
Write_ProtocolExprReferencedMetadata - This routine writer out the protocol reference symbols in the ...
ObjCBoolLiteralExpr - Objective-C Boolean Literal.
The top declaration context.
A reference to a declared variable, function, enum, etc.
ObjCPropertyDecl * getPropertyDecl() const
Visibility getVisibility() const
Determines the visibility of this entity.
SourceLocation getBeginLoc() const
bool isPointerType() const
BreakStmt - This represents a break.
Expr * getSemanticExpr(unsigned index)
const VarDecl * getCatchParamDecl() const
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
An l-value expression is a reference to an object with independent storage.
class was compiled with -fobjc-arr
A trivial tuple used to represent a source range.
ObjCMethodDecl * getGetterMethodDecl() const
This represents a decl that may have a name.
ObjCIvarDecl * all_declared_ivar_begin()
all_declared_ivar_begin - return first ivar declared in this class, its extensions and its implementa...
ObjCMethodDecl * getInstanceMethod(Selector Sel, bool AllowHidden=false) const
AccessControl getAccessControl() const
SourceLocation getIvarRBraceLoc() const
Selector getGetterName() const
SourceLocation getEndOfDefinitionLoc() const
SourceLocation getRightLoc() const
bool isFunctionPointerType() const
static FieldDecl * Create(const ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, Expr *BW, bool Mutable, InClassInitStyle InitStyle)
The receiver is a superclass.
static void Write__ivar_list_t_initializer(RewriteModernObjC &RewriteObj, ASTContext *Context, std::string &Result, ArrayRef< ObjCIvarDecl *> OriginalIvars, StringRef VarName, ObjCInterfaceDecl *CDecl)
void getSelectorLocs(SmallVectorImpl< SourceLocation > &SelLocs) const
SourceLocation getBegin() const
const LangOptions & getLangOpts() const
Represents Objective-C's @autoreleasepool Statement.
FullSourceLoc getFullLoc(SourceLocation Loc) const
ObjCCategoryImplDecl - An object of this class encapsulates a category @implementation declaration...
SourceLocation getBeginLoc() const LLVM_READONLY
static void Write_IvarOffsetVar(RewriteModernObjC &RewriteObj, ASTContext *Context, std::string &Result, ArrayRef< ObjCIvarDecl *> Ivars, ObjCInterfaceDecl *CDecl)
Represents the canonical version of C arrays with a specified constant size.
This class handles loading and caching of source files into memory.
bool BlockRequiresCopying(QualType Ty, const VarDecl *D)
Returns true iff we need copy/dispose helpers for the given type.
SourceLocation getLocation() const
static void WriteModernMetadataDeclarations(ASTContext *Context, std::string &Result)
WriteModernMetadataDeclarations - Writes out metadata declarations for modern ABI.
ArrayRef< ParmVarDecl * > parameters() const
static std::string Stringify(StringRef Str, bool Charify=false)
Stringify - Convert the specified string into a C string by i) escaping '\' and " characters and ii) ...
CanQualType UnsignedIntTy
TypeSourceInfo * getClassReceiverTypeInfo() const
Returns a type-source information of a class message send, or nullptr if the message is not a class m...
ObjCCategoryDecl * FindCategoryDeclaration(IdentifierInfo *CategoryId) const
FindCategoryDeclaration - Finds category declaration in the list of categories for this class and ret...