23#include "clang/Config/config.h"
26#include "llvm/ADT/DenseSet.h"
27#include "llvm/ADT/SetVector.h"
28#include "llvm/ADT/SmallPtrSet.h"
29#include "llvm/ADT/StringExtras.h"
30#include "llvm/Support/MemoryBuffer.h"
31#include "llvm/Support/raw_ostream.h"
34#if CLANG_ENABLE_OBJC_REWRITER
57 BLOCK_NEEDS_FREE = (1 << 24),
58 BLOCK_HAS_COPY_DISPOSE = (1 << 25),
60 BLOCK_IS_GC = (1 << 27),
62 BLOCK_HAS_DESCRIPTOR = (1 << 29)
72 const char *MainFileStart, *MainFileEnd;
75 std::string InFileName;
76 std::unique_ptr<raw_ostream> OutFile;
81 Expr *GlobalConstructionExp;
82 unsigned RewriteFailedDiag;
83 unsigned GlobalBlockRewriteFailedDiag;
85 unsigned NumObjCStringLiterals;
86 VarDecl *ConstantStringClassReference;
92 unsigned TryFinallyContainsReturnDiag;
144 llvm::DenseMap<ValueDecl *, unsigned> BlockByRefDeclNo;
148 llvm::DenseMap<BlockExpr *, std::string> RewrittenBlockExprs;
154 llvm::DenseMap<const ObjCIvarDecl* , unsigned> IvarGroupNumber;
157 llvm::DenseMap<std::pair<const ObjCInterfaceDecl*, unsigned>,
QualType> GroupRecordType;
163 llvm::DenseMap<Stmt *, Stmt *> ReplacedNodes;
167 bool SilenceRewriteMacroWarning;
168 bool GenerateLineInfo;
169 bool objc_impl_method;
171 bool DisableReplaceStmt;
172 class DisableReplaceStmtScope {
173 RewriteModernObjC &R;
177 DisableReplaceStmtScope(RewriteModernObjC &R)
178 : R(R), SavedValue(R.DisableReplaceStmt) {
179 R.DisableReplaceStmt =
true;
181 ~DisableReplaceStmtScope() {
182 R.DisableReplaceStmt = SavedValue;
188 llvm::DenseMap<ObjCMethodDecl*, std::string> MethodInternalNames;
194 if (!
Class->isThisDeclarationADefinition()) {
195 RewriteForwardClassDecl(D);
199 ObjCInterfacesSeen.push_back(Class);
205 if (!Proto->isThisDeclarationADefinition()) {
206 RewriteForwardProtocolDecl(D);
216 if (FDecl->isThisDeclarationADefinition() &&
218 !FDecl->isTopLevelDeclInObjCContainer()) {
219 FunctionDefinitionsSeen.push_back(FDecl);
223 HandleTopLevelSingleDecl(*I);
228 void HandleTopLevelDeclInObjCContainer(
DeclGroupRef D)
override {
231 if (isTopLevelBlockPointerType(TD->getUnderlyingType()))
232 RewriteBlockPointerDecl(TD);
233 else if (TD->getUnderlyingType()->isFunctionPointerType())
234 CheckFunctionPointerDecl(TD->getUnderlyingType(), TD);
236 RewriteObjCQualifiedInterfaceTypes(TD);
241 void HandleTopLevelSingleDecl(
Decl *D);
242 void HandleDeclInMainFile(
Decl *D);
243 RewriteModernObjC(std::string inFile, std::unique_ptr<raw_ostream> OS,
245 bool silenceMacroWarn,
bool LineInfo);
247 ~RewriteModernObjC()
override {}
249 void HandleTranslationUnit(
ASTContext &C)
override;
251 void ReplaceStmt(
Stmt *Old,
Stmt *New) {
256 assert(Old !=
nullptr && New !=
nullptr &&
"Expected non-null Stmt's");
258 Stmt *ReplacingStmt = ReplacedNodes[Old];
262 if (DisableReplaceStmt)
274 llvm::raw_string_ostream S(SStr);
276 const std::string &Str = S.str();
280 ReplacedNodes[Old] = New;
283 if (SilenceRewriteMacroWarning)
290 bool InsertAfter =
true) {
292 if (!
Rewrite.InsertText(Loc, Str, InsertAfter) ||
293 SilenceRewriteMacroWarning)
296 Diags.
Report(Context->getFullLoc(Loc), RewriteFailedDiag);
302 if (!
Rewrite.ReplaceText(Start, OrigLength, Str) ||
303 SilenceRewriteMacroWarning)
306 Diags.
Report(Context->getFullLoc(Start), RewriteFailedDiag);
311 void RewriteInclude();
312 void RewriteLineDirective(
const Decl *D);
314 std::string &LineString);
318 const std::string &typedefString);
319 void RewriteImplementations();
324 void RewriteImplementationDecl(
Decl *Dcl);
327 void RewriteTypeIntoString(
QualType T, std::string &ResultStr,
329 void RewriteByRefString(std::string &ResultStr,
const std::string &Name,
338 void RewriteBlockPointerType(std::string& Str,
QualType Type);
339 void RewriteBlockPointerTypeVariable(std::string& Str,
ValueDecl *VD);
341 void RewriteObjCQualifiedInterfaceTypes(
Decl *Dcl);
342 void RewriteTypeOfDecl(
VarDecl *VD);
343 void RewriteObjCQualifiedInterfaceTypes(
Expr *E);
348 Stmt *RewriteFunctionBodyOrGlobalInitializer(
Stmt *S);
369 void RewriteImplicitCastObjCExpr(
CastExpr *IE);
374 void ObjCIvarBitfieldGroupDecl(
ObjCIvarDecl *IV, std::string &Result);
376 void ObjCIvarBitfieldGroupType(
ObjCIvarDecl *IV, std::string &Result);
378 void ObjCIvarBitfieldGroupOffset(
ObjCIvarDecl *IV, std::string &Result);
381 QualType SynthesizeBitfieldGroupStructType(
389 void RewriteBlockPointerDecl(
NamedDecl *VD);
390 void RewriteByRefVar(
VarDecl *VD,
bool firstDecl,
bool lastDecl);
396 std::string &Result);
398 void RewriteObjCFieldDecl(
FieldDecl *fieldDecl, std::string &Result);
400 bool &IsNamedDefinition);
401 void RewriteLocallyDefinedNamedAggregates(
FieldDecl *fieldDecl,
402 std::string &Result);
404 bool RewriteObjCFieldDeclType(
QualType &
Type, std::string &Result);
407 std::string &Result);
409 void Initialize(
ASTContext &context)
override;
428 void SynthCountByEnumWithState(std::string &buf);
429 void SynthMsgSendFunctionDecl();
430 void SynthMsgSendSuperFunctionDecl();
431 void SynthMsgSendStretFunctionDecl();
432 void SynthMsgSendFpretFunctionDecl();
433 void SynthMsgSendSuperStretFunctionDecl();
434 void SynthGetClassFunctionDecl();
435 void SynthGetMetaClassFunctionDecl();
436 void SynthGetSuperClassFunctionDecl();
437 void SynthSelGetUidFunctionDecl();
438 void SynthSuperConstructorFunctionDecl();
441 template<
typename MethodIterator>
442 void RewriteObjCMethodsMetaData(MethodIterator MethodBegin,
443 MethodIterator MethodEnd,
444 bool IsInstanceMethod,
447 std::string &Result);
449 std::string &Result);
451 std::string &Result);
452 void RewriteClassSetupInitHook(std::string &Result);
454 void RewriteMetaDataIntoBuffer(std::string &Result);
455 void WriteImageInfo(std::string &Result);
457 std::string &Result);
458 void RewriteCategorySetupInitHook(std::string &Result);
462 std::string &Result);
466 std::string SynthesizeByrefCopyDestroyHelper(
VarDecl *VD,
int flag);
467 std::string SynthesizeBlockHelperFuncs(
BlockExpr *CE,
int i,
468 StringRef funcName, std::string Tag);
469 std::string SynthesizeBlockFunc(
BlockExpr *CE,
int i,
470 StringRef funcName, std::string Tag);
471 std::string SynthesizeBlockImpl(
BlockExpr *CE,
472 std::string Tag, std::string Desc);
473 std::string SynthesizeBlockDescriptor(std::string DescTag,
475 int i, StringRef funcName,
480 FunctionDecl *SynthBlockInitFunctionDecl(StringRef name);
486 void WarnAboutReturnGotoStmts(
Stmt *S);
488 void InsertBlockLiteralsWithinFunction(
FunctionDecl *FD);
491 bool IsDeclStmtInForeachHeader(
DeclStmt *DS);
492 void CollectBlockDeclRefInfo(
BlockExpr *Exp);
493 void GetBlockDeclRefExprs(
Stmt *S);
494 void GetInnerBlockDeclRefExprs(
Stmt *S,
496 llvm::SmallPtrSetImpl<const DeclContext *> &InnerContexts);
500 bool isTopLevelBlockPointerType(
QualType T) {
501 return isa<BlockPointerType>(T);
507 bool convertBlockPointerToFunctionPointer(
QualType &T) {
508 if (isTopLevelBlockPointerType(T)) {
510 T = Context->getPointerType(BPT->getPointeeType());
516 bool convertObjCTypeToCStyleType(
QualType &T);
518 bool needToScanForQualifiers(
QualType T);
520 QualType getConstantStringStructType();
523 void convertToUnqualifiedObjCType(
QualType &T) {
526 T = isConst ? Context->getObjCIdType().withConst()
527 : Context->getObjCIdType();
530 T = Context->getObjCClassType();
537 T = Context->getPointerType(T);
547 QualType OCT = Context->getCanonicalType(T).getUnqualifiedType();
549 if (OCT == Context->getCanonicalType(Context->getObjCIdType()) ||
550 OCT == Context->getCanonicalType(Context->getObjCClassType()))
554 if (isa<ObjCInterfaceType>(PT->getPointeeType()) ||
555 PT->getPointeeType()->isObjCQualifiedIdType())
561 bool PointerTypeTakesAnyBlockArguments(
QualType QT);
562 bool PointerTypeTakesAnyObjCQualifiedType(
QualType QT);
563 void GetExtentOfArgList(
const char *Name,
const char *&LParen,
564 const char *&RParen);
566 void QuoteDoublequotes(std::string &From, std::string &To) {
567 for (
unsigned i = 0; i < From.length(); i++) {
577 bool variadic =
false) {
578 if (result == Context->getObjCInstanceType())
579 result = Context->getObjCIdType();
582 return Context->getFunctionType(result, args, fpi);
589 return CStyleCastExpr::Create(*Ctx, Ty, VK_PRValue, Kind, E,
nullptr,
594 bool ImplementationIsNonLazy(
const ObjCImplDecl *OD)
const {
596 Selector LoadSel = Context->Selectors.getSelector(0, &II);
601 QualType StrType = Context->getConstantArrayType(
602 Context->CharTy, llvm::APInt(32, Str.size() + 1),
nullptr,
603 ArraySizeModifier::Normal, 0);
604 return StringLiteral::Create(*Context, Str, StringLiteralKind::Ordinary,
610void RewriteModernObjC::RewriteBlocksInFunctionProtoType(
QualType funcType,
613 = dyn_cast<FunctionProtoType>(funcType.
IgnoreParens())) {
614 for (
const auto &I : fproto->param_types())
615 if (isTopLevelBlockPointerType(I)) {
617 RewriteBlockPointerDecl(D);
623void RewriteModernObjC::CheckFunctionPointerDecl(
QualType funcType,
NamedDecl *ND) {
625 if (PT && PointerTypeTakesAnyBlockArguments(funcType))
629static bool IsHeaderFile(
const std::string &
Filename) {
630 std::string::size_type DotPos =
Filename.rfind(
'.');
632 if (DotPos == std::string::npos) {
637 std::string Ext =
Filename.substr(DotPos + 1);
640 return Ext ==
"h" || Ext ==
"hh" || Ext ==
"H";
643RewriteModernObjC::RewriteModernObjC(std::string inFile,
644 std::unique_ptr<raw_ostream> OS,
647 bool silenceMacroWarn,
bool LineInfo)
648 : Diags(D), LangOpts(LOpts), InFileName(inFile), OutFile(
std::move(OS)),
649 SilenceRewriteMacroWarning(silenceMacroWarn), GenerateLineInfo(LineInfo) {
650 IsHeader = IsHeaderFile(inFile);
652 "rewriting sub-expression within a macro (may not be correct)");
655 GlobalBlockRewriteFailedDiag = Diags.
getCustomDiagID(DiagnosticsEngine::Warning,
656 "rewriting block literal declared in global scope is not implemented");
659 DiagnosticsEngine::Warning,
660 "rewriter doesn't support user-specified control flow semantics "
661 "for @try/@finally (code may not execute properly)");
665 const std::string &InFile, std::unique_ptr<raw_ostream> OS,
667 bool SilenceRewriteMacroWarning,
bool LineInfo) {
668 return std::make_unique<RewriteModernObjC>(InFile, std::move(OS), Diags,
669 LOpts, SilenceRewriteMacroWarning,
673void RewriteModernObjC::InitializeCommon(
ASTContext &context) {
675 SM = &Context->getSourceManager();
676 TUDecl = Context->getTranslationUnitDecl();
677 MsgSendFunctionDecl =
nullptr;
678 MsgSendSuperFunctionDecl =
nullptr;
679 MsgSendStretFunctionDecl =
nullptr;
680 MsgSendSuperStretFunctionDecl =
nullptr;
681 MsgSendFpretFunctionDecl =
nullptr;
682 GetClassFunctionDecl =
nullptr;
683 GetMetaClassFunctionDecl =
nullptr;
684 GetSuperClassFunctionDecl =
nullptr;
685 SelGetUidFunctionDecl =
nullptr;
686 CFStringFunctionDecl =
nullptr;
687 ConstantStringClassReference =
nullptr;
688 NSStringRecord =
nullptr;
689 CurMethodDef =
nullptr;
690 CurFunctionDef =
nullptr;
691 GlobalVarDecl =
nullptr;
692 GlobalConstructionExp =
nullptr;
693 SuperStructDecl =
nullptr;
694 ProtocolTypeDecl =
nullptr;
695 ConstantStringDecl =
nullptr;
697 SuperConstructorFunctionDecl =
nullptr;
698 NumObjCStringLiterals = 0;
699 PropParentMap =
nullptr;
700 CurrentBody =
nullptr;
701 DisableReplaceStmt =
false;
702 objc_impl_method =
false;
705 MainFileID =
SM->getMainFileID();
706 llvm::MemoryBufferRef MainBuf =
SM->getBufferOrFake(MainFileID);
707 MainFileStart = MainBuf.getBufferStart();
708 MainFileEnd = MainBuf.getBufferEnd();
710 Rewrite.setSourceMgr(Context->getSourceManager(), Context->getLangOpts());
717void RewriteModernObjC::HandleTopLevelSingleDecl(
Decl *D) {
725 Loc =
SM->getExpansionLoc(Loc);
732 RewriteFunctionDecl(FD);
733 }
else if (
VarDecl *FVD = dyn_cast<VarDecl>(D)) {
735 if (FVD->getName() ==
"_NSConstantStringClassReference") {
736 ConstantStringClassReference = FVD;
740 RewriteCategoryDecl(CD);
742 if (PD->isThisDeclarationADefinition())
743 RewriteProtocolDecl(PD);
747 DIEnd = LSD->decls_end();
750 if (!IFace->isThisDeclarationADefinition()) {
754 if (isa<ObjCInterfaceDecl>(*DI) &&
755 !cast<ObjCInterfaceDecl>(*DI)->isThisDeclarationADefinition() &&
756 StartLoc == (*DI)->getBeginLoc())
762 }
while (DI != DIEnd);
763 RewriteForwardClassDecl(DG);
768 ObjCInterfacesSeen.push_back(IFace);
775 if (!Proto->isThisDeclarationADefinition()) {
779 if (isa<ObjCProtocolDecl>(*DI) &&
780 !cast<ObjCProtocolDecl>(*DI)->isThisDeclarationADefinition() &&
781 StartLoc == (*DI)->getBeginLoc())
787 }
while (DI != DIEnd);
788 RewriteForwardProtocolDecl(DG);
793 HandleTopLevelSingleDecl(*DI);
798 if (
SM->isWrittenInMainFile(Loc))
799 return HandleDeclInMainFile(D);
806void RewriteModernObjC::RewriteInclude() {
808 StringRef MainBuf =
SM->getBufferData(MainFileID);
809 const char *MainBufStart = MainBuf.begin();
810 const char *MainBufEnd = MainBuf.end();
811 size_t ImportLen = strlen(
"import");
814 for (
const char *BufPtr = MainBufStart; BufPtr < MainBufEnd; ++BufPtr) {
815 if (*BufPtr ==
'#') {
816 if (++BufPtr == MainBufEnd)
818 while (*BufPtr ==
' ' || *BufPtr ==
'\t')
819 if (++BufPtr == MainBufEnd)
821 if (!strncmp(BufPtr,
"import", ImportLen)) {
825 ReplaceText(ImportLoc, ImportLen,
"include");
834 Result +=
"OBJC_IVAR_$_";
841RewriteModernObjC::getIvarAccessString(
ObjCIvarDecl *D) {
845 std::string IvarOffsetName;
847 ObjCIvarBitfieldGroupOffset(D, IvarOffsetName);
849 WriteInternalIvarName(ClassDecl, D, IvarOffsetName);
851 std::string S =
"(*(";
854 IvarT = GetGroupRecordTypeForObjCIvarBitfield(D);
864 CDecl = CatDecl->getClassInterface();
865 std::string RecName = std::string(CDecl->getName());
867 RecordDecl *RD = RecordDecl::Create(*Context, TagTypeKind::Struct, TUDecl,
869 &Context->Idents.get(RecName));
870 QualType PtrStructIMPL = Context->getPointerType(Context->getTagDeclType(RD));
871 unsigned UnsignedIntSize =
872 static_cast<unsigned>(Context->getTypeSize(Context->UnsignedIntTy));
873 Expr *
Zero = IntegerLiteral::Create(*Context,
874 llvm::APInt(UnsignedIntSize, 0),
876 Zero = NoTypeInfoCStyleCastExpr(Context, PtrStructIMPL, CK_BitCast, Zero);
886 *Context, PE,
true, FD, FD->
getType(), VK_LValue, OK_Ordinary);
887 IvarT = Context->getDecltypeType(ME, ME->
getType());
890 convertObjCTypeToCStyleType(IvarT);
891 QualType castT = Context->getPointerType(IvarT);
892 std::string TypeString(castT.
getAsString(Context->getPrintingPolicy()));
897 S +=
"((char *)self + ";
921 static bool objcGetPropertyDefined =
false;
922 static bool objcSetPropertyDefined =
false;
927 InsertText(startLoc,
"// ");
928 const char *startBuf =
SM->getCharacterData(startLoc);
929 assert((*startBuf ==
'@') &&
"bogus @synthesize location");
930 const char *semiBuf = strchr(startBuf,
';');
931 assert((*semiBuf ==
';') &&
"@synthesize: can't find ';'");
942 assert(IMD && OID &&
"Synthesized ivars must be attached to @implementation");
945 if (mustSynthesizeSetterGetterMethod(IMD, PD,
true )) {
946 bool GenGetProperty =
947 !(Attributes & ObjCPropertyAttribute::kind_nonatomic) &&
948 (Attributes & (ObjCPropertyAttribute::kind_retain |
949 ObjCPropertyAttribute::kind_copy));
951 if (GenGetProperty && !objcGetPropertyDefined) {
952 objcGetPropertyDefined =
true;
954 Getr =
"\nextern \"C\" __declspec(dllimport) "
955 "id objc_getProperty(id, SEL, long, bool);\n";
962 if (GenGetProperty) {
975 for (
unsigned i = 0, e = FT->getNumParams(); i != e; ++i) {
977 std::string ParamStr =
978 FT->getParamType(i).getAsString(Context->getPrintingPolicy());
981 if (FT->isVariadic()) {
982 if (FT->getNumParams())
991 Getr +=
"return (_TYPE)";
992 Getr +=
"objc_getProperty(self, _cmd, ";
993 RewriteIvarOffsetComputation(OID, Getr);
997 Getr +=
"return " + getIvarAccessString(OID);
999 InsertText(startGetterSetterLoc, Getr);
1003 !mustSynthesizeSetterGetterMethod(IMD, PD,
false ))
1008 bool GenSetProperty = Attributes & (ObjCPropertyAttribute::kind_retain |
1009 ObjCPropertyAttribute::kind_copy);
1010 if (GenSetProperty && !objcSetPropertyDefined) {
1011 objcSetPropertyDefined =
true;
1013 Setr =
"\nextern \"C\" __declspec(dllimport) "
1014 "void objc_setProperty (id, SEL, long, id, bool, bool);\n";
1022 if (GenSetProperty) {
1023 Setr +=
"objc_setProperty (self, _cmd, ";
1024 RewriteIvarOffsetComputation(OID, Setr);
1028 if (Attributes & ObjCPropertyAttribute::kind_nonatomic)
1032 if (Attributes & ObjCPropertyAttribute::kind_copy)
1038 Setr += getIvarAccessString(OID) +
" = ";
1042 InsertText(startGetterSetterLoc, Setr);
1046 std::string &typedefString) {
1047 typedefString +=
"\n#ifndef _REWRITER_typedef_";
1049 typedefString +=
"\n";
1050 typedefString +=
"#define _REWRITER_typedef_";
1052 typedefString +=
"\n";
1053 typedefString +=
"typedef struct objc_object ";
1056 typedefString +=
";\ntypedef struct {} _objc_exc_";
1058 typedefString +=
";\n#endif\n";
1061void RewriteModernObjC::RewriteForwardClassEpilogue(
ObjCInterfaceDecl *ClassDecl,
1062 const std::string &typedefString) {
1064 const char *startBuf =
SM->getCharacterData(startLoc);
1065 const char *semiPtr = strchr(startBuf,
';');
1067 ReplaceText(startLoc, semiPtr-startBuf+1, typedefString);
1070void RewriteModernObjC::RewriteForwardClassDecl(
DeclGroupRef D) {
1071 std::string typedefString;
1074 if (I == D.
begin()) {
1078 typedefString +=
"// @class ";
1080 typedefString +=
";";
1082 RewriteOneForwardClassDecl(ForwardDecl, typedefString);
1085 HandleTopLevelSingleDecl(*I);
1088 RewriteForwardClassEpilogue(cast<ObjCInterfaceDecl>(*I), typedefString);
1091void RewriteModernObjC::RewriteForwardClassDecl(
1093 std::string typedefString;
1094 for (
unsigned i = 0; i < D.size(); i++) {
1097 typedefString +=
"// @class ";
1099 typedefString +=
";";
1101 RewriteOneForwardClassDecl(ForwardDecl, typedefString);
1103 RewriteForwardClassEpilogue(cast<ObjCInterfaceDecl>(D[0]), typedefString);
1106void RewriteModernObjC::RewriteMethodDeclaration(
ObjCMethodDecl *Method) {
1114 if (
SM->getExpansionLineNumber(LocEnd) >
1115 SM->getExpansionLineNumber(LocStart)) {
1116 InsertText(LocStart,
"#if 0\n");
1117 ReplaceText(LocEnd, 1,
";\n#endif\n");
1119 InsertText(LocStart,
"// ");
1126 ReplaceText(Loc, 0,
"// ");
1135 ReplaceText(LocStart, 1,
"/** ");
1139 ReplaceText(LocStart, 0,
"// ");
1146 RewriteMethodDeclaration(I);
1148 RewriteMethodDeclaration(I);
1152 strlen(
"@end"),
"/* @end */\n");
1160 ReplaceText(LocStart, 0,
"// ");
1163 RewriteMethodDeclaration(I);
1165 RewriteMethodDeclaration(I);
1171 ReplaceText(LocEnd, strlen(
"@end"),
"/* @end */\n");
1174 const char *startBuf =
SM->getCharacterData(LocStart);
1175 const char *endBuf =
SM->getCharacterData(LocEnd);
1176 for (
const char *p = startBuf; p < endBuf; p++) {
1177 if (*p ==
'@' && !strncmp(p+1,
"optional", strlen(
"optional"))) {
1179 ReplaceText(OptionalLoc, strlen(
"@optional"),
"/* @optional */");
1182 else if (*p ==
'@' && !strncmp(p+1,
"required", strlen(
"required"))) {
1184 ReplaceText(OptionalLoc, strlen(
"@required"),
"/* @required */");
1190void RewriteModernObjC::RewriteForwardProtocolDecl(
DeclGroupRef D) {
1193 llvm_unreachable(
"Invalid SourceLocation");
1195 ReplaceText(LocStart, 0,
"// ");
1202 llvm_unreachable(
"Invalid SourceLocation");
1204 ReplaceText(LocStart, 0,
"// ");
1207void RewriteModernObjC::RewriteTypeIntoString(
QualType T, std::string &ResultStr,
1227 ResultStr += T.
getAsString(Context->getPrintingPolicy());
1232 std::string &ResultStr) {
1235 ResultStr +=
"\nstatic ";
1236 RewriteTypeIntoString(OMD->
getReturnType(), ResultStr, FPRetType);
1240 std::string NameStr;
1258 int len = selString.size();
1259 for (
int i = 0; i < len; i++)
1260 if (selString[i] ==
':')
1262 NameStr += selString;
1265 MethodInternalNames[OMD] = NameStr;
1266 ResultStr += NameStr;
1273 QualType selfTy = Context->getObjCInterfaceType(IDecl);
1274 selfTy = Context->getPointerType(selfTy);
1275 if (!LangOpts.MicrosoftExt) {
1277 ResultStr +=
"struct ";
1284 ResultStr += Context->getObjCClassType().getAsString(
1285 Context->getPrintingPolicy());
1287 ResultStr +=
" self, ";
1288 ResultStr += Context->getObjCSelType().getAsString(Context->getPrintingPolicy());
1289 ResultStr +=
" _cmd";
1292 for (
const auto *PDecl : OMD->
parameters()) {
1294 if (PDecl->getType()->isObjCQualifiedIdType()) {
1301 (void)convertBlockPointerToFunctionPointer(QT);
1307 ResultStr +=
", ...";
1316 for (
unsigned i = 0, e = FT->getNumParams(); i != e; ++i) {
1317 if (i) ResultStr +=
", ";
1318 std::string ParamStr =
1319 FT->getParamType(i).getAsString(Context->getPrintingPolicy());
1320 ResultStr += ParamStr;
1322 if (FT->isVariadic()) {
1323 if (FT->getNumParams())
1334void RewriteModernObjC::RewriteImplementationDecl(
Decl *OID) {
1337 assert((IMD || CID) &&
"Unknown implementation type");
1354 std::string ResultStr;
1359 const char *startBuf =
SM->getCharacterData(LocStart);
1360 const char *endBuf =
SM->getCharacterData(LocEnd);
1361 ReplaceText(LocStart, endBuf-startBuf, ResultStr);
1367 std::string ResultStr;
1372 const char *startBuf =
SM->getCharacterData(LocStart);
1373 const char *endBuf =
SM->getCharacterData(LocEnd);
1374 ReplaceText(LocStart, endBuf-startBuf, ResultStr);
1377 RewritePropertyImplDecl(I, IMD, CID);
1384 if (ObjCSynthesizedStructs.count(ClassDecl))
1388 while (SuperClass) {
1389 RewriteInterfaceDecl(SuperClass);
1392 std::string ResultStr;
1395 RewriteOneForwardClassDecl(ClassDecl, ResultStr);
1396 RewriteIvarOffsetSymbols(ClassDecl, ResultStr);
1398 RewriteObjCInternalStruct(ClassDecl, ResultStr);
1405 RewriteMethodDeclaration(I);
1407 RewriteMethodDeclaration(I);
1429 DisableReplaceStmtScope S(*
this);
1435 Base = cast<OpaqueValueExpr>(
Base)->getSourceExpr();
1436 Base = cast<Expr>(RewriteFunctionBodyOrGlobalInitializer(
Base));
1440 for (
unsigned i = 0; i < numArgs; i++) {
1442 if (isa<OpaqueValueExpr>(Arg))
1443 Arg = cast<OpaqueValueExpr>(Arg)->getSourceExpr();
1444 Arg = cast<Expr>(RewriteFunctionBodyOrGlobalInitializer(Arg));
1445 Args.push_back(Arg);
1455 case ObjCMessageExpr::Class:
1456 NewMsg = ObjCMessageExpr::Create(*Context, OldMsg->
getType(),
1468 case ObjCMessageExpr::Instance:
1469 NewMsg = ObjCMessageExpr::Create(*Context, OldMsg->
getType(),
1481 case ObjCMessageExpr::SuperClass:
1482 case ObjCMessageExpr::SuperInstance:
1483 NewMsg = ObjCMessageExpr::Create(*Context, OldMsg->
getType(),
1498 Stmt *Replacement = SynthMessageExpr(NewMsg);
1499 ReplaceStmtWithRange(PseudoOp, Replacement, OldRange);
1516 DisableReplaceStmtScope S(*
this);
1520 Base = cast<OpaqueValueExpr>(
Base)->getSourceExpr();
1521 Base = cast<Expr>(RewriteFunctionBodyOrGlobalInitializer(
Base));
1524 for (
unsigned i = 0; i < numArgs; i++) {
1526 if (isa<OpaqueValueExpr>(Arg))
1527 Arg = cast<OpaqueValueExpr>(Arg)->getSourceExpr();
1528 Arg = cast<Expr>(RewriteFunctionBodyOrGlobalInitializer(Arg));
1529 Args.push_back(Arg);
1538 case ObjCMessageExpr::Class:
1539 NewMsg = ObjCMessageExpr::Create(*Context, OldMsg->
getType(),
1551 case ObjCMessageExpr::Instance:
1552 NewMsg = ObjCMessageExpr::Create(*Context, OldMsg->
getType(),
1564 case ObjCMessageExpr::SuperClass:
1565 case ObjCMessageExpr::SuperInstance:
1566 NewMsg = ObjCMessageExpr::Create(*Context, OldMsg->
getType(),
1581 Stmt *Replacement = SynthMessageExpr(NewMsg);
1582 ReplaceStmtWithRange(PseudoOp, Replacement, OldRange);
1595void RewriteModernObjC::SynthCountByEnumWithState(std::string &buf) {
1596 buf +=
"((_WIN_NSUInteger (*) (id, SEL, struct __objcFastEnumerationState *, "
1597 "id *, _WIN_NSUInteger))(void *)objc_msgSend)";
1599 buf +=
"((id)l_collection,\n\t\t";
1600 buf +=
"sel_registerName(\"countByEnumeratingWithState:objects:count:\"),";
1602 buf +=
"&enumState, "
1603 "(id *)__rw_items, (_WIN_NSUInteger)16)";
1610 if (Stmts.empty() || !isa<ObjCForCollectionStmt>(Stmts.back()))
1616 buf =
"goto __break_label_";
1617 buf += utostr(ObjCBcLabelNo.back());
1618 ReplaceText(startLoc, strlen(
"break"), buf);
1623void RewriteModernObjC::ConvertSourceLocationToLineDirective(
1625 std::string &LineString) {
1626 if (Loc.
isFileID() && GenerateLineInfo) {
1627 LineString +=
"\n#line ";
1629 LineString += utostr(PLoc.
getLine());
1630 LineString +=
" \"";
1631 LineString += Lexer::Stringify(PLoc.
getFilename());
1632 LineString +=
"\"\n";
1640 if (Stmts.empty() || !isa<ObjCForCollectionStmt>(Stmts.back()))
1646 buf =
"goto __continue_label_";
1647 buf += utostr(ObjCBcLabelNo.back());
1648 ReplaceText(startLoc, strlen(
"continue"), buf);
1687 assert(!Stmts.empty() &&
"ObjCForCollectionStmt - Statement stack empty");
1688 assert(isa<ObjCForCollectionStmt>(Stmts.back()) &&
1689 "ObjCForCollectionStmt Statement stack mismatch");
1690 assert(!ObjCBcLabelNo.empty() &&
1691 "ObjCForCollectionStmt - Label No stack empty");
1694 const char *startBuf =
SM->getCharacterData(startLoc);
1695 StringRef elementName;
1696 std::string elementTypeAsString;
1700 ConvertSourceLocationToLineDirective(ForEachLoc, buf);
1702 if (
DeclStmt *DS = dyn_cast<DeclStmt>(S->getElement())) {
1704 NamedDecl* D = cast<NamedDecl>(DS->getSingleDecl());
1705 QualType ElementType = cast<ValueDecl>(D)->getType();
1709 elementTypeAsString =
"id";
1711 elementTypeAsString = ElementType.
getAsString(Context->getPrintingPolicy());
1712 buf += elementTypeAsString;
1719 DeclRefExpr *DR = cast<DeclRefExpr>(S->getElement());
1725 elementTypeAsString =
"id";
1731 buf +=
"struct __objcFastEnumerationState enumState = { 0 };\n\t";
1733 buf +=
"id __rw_items[16];\n\t";
1735 buf +=
"id l_collection = (id)";
1737 const char *startCollectionBuf = startBuf;
1738 startCollectionBuf += 3;
1739 startCollectionBuf = strchr(startCollectionBuf,
'(');
1740 startCollectionBuf++;
1742 while (*startCollectionBuf !=
' ' ||
1743 *(startCollectionBuf+1) !=
'i' || *(startCollectionBuf+2) !=
'n' ||
1744 (*(startCollectionBuf+3) !=
' ' &&
1745 *(startCollectionBuf+3) !=
'[' && *(startCollectionBuf+3) !=
'('))
1746 startCollectionBuf++;
1747 startCollectionBuf += 3;
1750 ReplaceText(startLoc, startCollectionBuf - startBuf, buf);
1753 const char *rparenBuf =
SM->getCharacterData(rightParenLoc);
1768 buf +=
"_WIN_NSUInteger limit =\n\t\t";
1769 SynthCountByEnumWithState(buf);
1779 buf +=
"if (limit) {\n\t";
1780 buf +=
"unsigned long startMutations = *enumState.mutationsPtr;\n\t";
1781 buf +=
"do {\n\t\t";
1782 buf +=
"unsigned long counter = 0;\n\t\t";
1783 buf +=
"do {\n\t\t\t";
1784 buf +=
"if (startMutations != *enumState.mutationsPtr)\n\t\t\t\t";
1785 buf +=
"objc_enumerationMutation(l_collection);\n\t\t\t";
1788 buf += elementTypeAsString;
1789 buf +=
")enumState.itemsPtr[counter++];";
1791 ReplaceText(lparenLoc, 1, buf);
1805 buf +=
"__continue_label_";
1806 buf += utostr(ObjCBcLabelNo.back());
1809 buf +=
"} while (counter < limit);\n\t";
1810 buf +=
"} while ((limit = ";
1811 SynthCountByEnumWithState(buf);
1815 buf += elementTypeAsString;
1817 buf +=
"__break_label_";
1818 buf += utostr(ObjCBcLabelNo.back());
1821 buf +=
"else\n\t\t";
1824 buf += elementTypeAsString;
1830 if (isa<CompoundStmt>(S->getBody())) {
1832 InsertText(endBodyLoc, buf);
1841 const char *stmtBuf =
SM->getCharacterData(OrigEnd);
1842 const char *semiBuf = strchr(stmtBuf,
';');
1843 assert(semiBuf &&
"Can't find ';'");
1845 InsertText(endBodyLoc, buf);
1848 ObjCBcLabelNo.pop_back();
1852static void Write_RethrowObject(std::string &buf) {
1853 buf +=
"{ struct _FIN { _FIN(id reth) : rethrow(reth) {}\n";
1854 buf +=
"\t~_FIN() { if (rethrow) objc_exception_throw(rethrow); }\n";
1855 buf +=
"\tid rethrow;\n";
1856 buf +=
"\t} _fin_force_rethow(_rethrow);";
1868 const char *startBuf =
SM->getCharacterData(startLoc);
1870 assert((*startBuf ==
'@') &&
"bogus @synchronized location");
1874 ConvertSourceLocationToLineDirective(SynchLoc, buf);
1875 buf +=
"{ id _rethrow = 0; id _sync_obj = (id)";
1877 const char *lparenBuf = startBuf;
1878 while (*lparenBuf !=
'(') lparenBuf++;
1879 ReplaceText(startLoc, lparenBuf-startBuf+1, buf);
1881 buf =
"; objc_sync_enter(_sync_obj);\n";
1882 buf +=
"try {\n\tstruct _SYNC_EXIT { _SYNC_EXIT(id arg) : sync_exit(arg) {}";
1883 buf +=
"\n\t~_SYNC_EXIT() {objc_sync_exit(sync_exit);}";
1884 buf +=
"\n\tid sync_exit;";
1885 buf +=
"\n\t} _sync_exit(_sync_obj);\n";
1891 const char *RParenExprLocBuf =
SM->getCharacterData(RParenExprLoc);
1892 while (*RParenExprLocBuf !=
')') RParenExprLocBuf--;
1896 const char *LBraceLocBuf =
SM->getCharacterData(LBranceLoc);
1897 assert (*LBraceLocBuf ==
'{');
1898 ReplaceText(RParenExprLoc, (LBraceLocBuf -
SM->getCharacterData(RParenExprLoc) + 1), buf);
1901 assert((*
SM->getCharacterData(startRBraceLoc) ==
'}') &&
1902 "bogus @synchronized block");
1904 buf =
"} catch (id e) {_rethrow = e;}\n";
1905 Write_RethrowObject(buf);
1909 ReplaceText(startRBraceLoc, 1, buf);
1914void RewriteModernObjC::WarnAboutReturnGotoStmts(
Stmt *S)
1917 for (
Stmt *SubStmt : S->children())
1919 WarnAboutReturnGotoStmts(SubStmt);
1921 if (isa<ReturnStmt>(S) || isa<GotoStmt>(S)) {
1922 Diags.
Report(Context->getFullLoc(S->getBeginLoc()),
1923 TryFinallyContainsReturnDiag);
1929 ReplaceText(startLoc, strlen(
"@autoreleasepool"),
"/* @autoreleasepool */");
1930 ReplaceText(S->getSubStmt()->getBeginLoc(), 1,
1931 "{ __AtAutoreleasePool __autoreleasepool; ");
1938 bool noCatch = S->getNumCatchStmts() == 0;
1941 ConvertSourceLocationToLineDirective(TryLocation, buf);
1945 buf +=
"{ id volatile _rethrow = 0;\n";
1947 buf +=
"{ id volatile _rethrow = 0;\ntry {\n";
1952 const char *startBuf =
SM->getCharacterData(startLoc);
1954 assert((*startBuf ==
'@') &&
"bogus @try location");
1956 ReplaceText(startLoc, 1, buf);
1959 ReplaceText(startLoc, 1,
"");
1962 VarDecl *catchDecl = Catch->getCatchParamDecl();
1964 startLoc = Catch->getBeginLoc();
1965 bool AtRemoved =
false;
1974 ConvertSourceLocationToLineDirective(Catch->getBeginLoc(), Result);
1976 startBuf =
SM->getCharacterData(startLoc);
1977 assert((*startBuf ==
'@') &&
"bogus @catch location");
1979 const char *rParenBuf =
SM->getCharacterData(rParenLoc);
1985 ReplaceText(startLoc, rParenBuf-startBuf+1, Result);
1996 ReplaceText(lBraceLoc, 1, Result);
2003 ReplaceText(startLoc, 1,
"");
2011 ConvertSourceLocationToLineDirective(FinallyLoc, buf);
2012 buf +=
"catch (id e) {_rethrow = e;}\n";
2016 ConvertSourceLocationToLineDirective(FinallyLoc, buf);
2017 buf +=
"catch (id e) {_rethrow = e;}\n";
2021 ReplaceText(startFinalLoc, 8, buf);
2025 Write_RethrowObject(buf);
2026 ReplaceText(startFinalBodyLoc, 1, buf);
2029 ReplaceText(endFinalBodyLoc, 1,
"}\n}");
2031 WarnAboutReturnGotoStmts(S->getTryBody());
2043 const char *startBuf =
SM->getCharacterData(startLoc);
2045 assert((*startBuf ==
'@') &&
"bogus @throw location");
2049 if (S->getThrowExpr())
2050 buf =
"objc_exception_throw(";
2055 const char *wBuf = strchr(startBuf,
'w');
2056 assert((*wBuf ==
'w') &&
"@throw: can't find 'w'");
2057 ReplaceText(startLoc, wBuf-startBuf+1, buf);
2060 const char *endBuf =
SM->getCharacterData(endLoc);
2061 const char *semiBuf = strchr(endBuf,
';');
2062 assert((*semiBuf ==
';') &&
"@throw: can't find ';'");
2064 if (S->getThrowExpr())
2065 ReplaceText(semiLoc, 1,
");");
2071 std::string StrEncoding;
2072 Context->getObjCEncodingForType(Exp->
getEncodedType(), StrEncoding);
2073 Expr *Replacement = getStringLiteral(StrEncoding);
2074 ReplaceStmt(Exp, Replacement);
2082 if (!SelGetUidFunctionDecl)
2083 SynthSelGetUidFunctionDecl();
2084 assert(SelGetUidFunctionDecl &&
"Can't find sel_registerName() decl");
2088 CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl,
2090 ReplaceStmt(Exp, SelExp);
2096RewriteModernObjC::SynthesizeCallToFunctionDecl(
FunctionDecl *FD,
2108 QualType pToFunc = Context->getPointerType(msgSendType);
2110 ImplicitCastExpr::Create(*Context, pToFunc, CK_FunctionToPointerDecay,
2115 CallExpr::Create(*Context, ICE, Args, FT->getCallResultType(*Context),
2120static bool scanForProtocolRefs(
const char *startBuf,
const char *endBuf,
2121 const char *&startRef,
const char *&endRef) {
2122 while (startBuf < endBuf) {
2123 if (*startBuf ==
'<')
2124 startRef = startBuf;
2125 if (*startBuf ==
'>') {
2126 if (startRef && *startRef ==
'<') {
2137static void scanToNextArgument(
const char *&argRef) {
2139 while (*argRef !=
')' && (*argRef !=
',' || angle > 0)) {
2142 else if (*argRef ==
'>')
2146 assert(angle == 0 &&
"scanToNextArgument - bad protocol type syntax");
2149bool RewriteModernObjC::needToScanForQualifiers(
QualType T) {
2161 QualType ElemTy = Context->getBaseElementType(T);
2162 return needToScanForQualifiers(ElemTy);
2167void RewriteModernObjC::RewriteObjCQualifiedInterfaceTypes(
Expr *E) {
2169 if (needToScanForQualifiers(
Type)) {
2173 Loc = ECE->getLParenLoc();
2174 EndLoc = ECE->getRParenLoc();
2183 const char *startBuf =
SM->getCharacterData(Loc);
2184 const char *endBuf =
SM->getCharacterData(EndLoc);
2185 const char *startRef =
nullptr, *endRef =
nullptr;
2186 if (scanForProtocolRefs(startBuf, endBuf, startRef, endRef)) {
2191 InsertText(LessLoc,
"/*");
2192 InsertText(GreaterLoc,
"*/");
2197void RewriteModernObjC::RewriteObjCQualifiedInterfaceTypes(
Decl *Dcl) {
2201 if (
VarDecl *VD = dyn_cast<VarDecl>(Dcl)) {
2205 else if (
FunctionDecl *FD = dyn_cast<FunctionDecl>(Dcl)) {
2210 assert(funcType &&
"missing function type");
2211 proto = dyn_cast<FunctionProtoType>(funcType);
2216 else if (
FieldDecl *FD = dyn_cast<FieldDecl>(Dcl)) {
2221 Loc = TD->getLocation();
2222 Type = TD->getUnderlyingType();
2227 if (needToScanForQualifiers(
Type)) {
2230 const char *endBuf =
SM->getCharacterData(Loc);
2231 const char *startBuf = endBuf;
2232 while (*startBuf !=
';' && *startBuf !=
'<' && startBuf != MainFileStart)
2234 const char *startRef =
nullptr, *endRef =
nullptr;
2235 if (scanForProtocolRefs(startBuf, endBuf, startRef, endRef)) {
2240 InsertText(LessLoc,
"/*");
2241 InsertText(GreaterLoc,
"*/");
2247 const char *startBuf =
SM->getCharacterData(Loc);
2248 const char *startFuncBuf = startBuf;
2253 const char *endBuf = startBuf;
2255 scanToNextArgument(endBuf);
2256 const char *startRef =
nullptr, *endRef =
nullptr;
2257 if (scanForProtocolRefs(startBuf, endBuf, startRef, endRef)) {
2264 InsertText(LessLoc,
"/*");
2265 InsertText(GreaterLoc,
"*/");
2267 startBuf = ++endBuf;
2272 while (*startBuf && *startBuf !=
')' && *startBuf !=
',')
2279void RewriteModernObjC::RewriteTypeOfDecl(
VarDecl *ND) {
2282 if (!isa<TypeOfExprType>(TypePtr))
2284 while (isa<TypeOfExprType>(TypePtr)) {
2285 const TypeOfExprType *TypeOfExprTypePtr = cast<TypeOfExprType>(TypePtr);
2291 std::string TypeAsString(QT.
getAsString(Context->getPrintingPolicy()));
2293 const char *startBuf =
SM->getCharacterData(DeclLoc);
2296 TypeAsString +=
" " + Name +
" = ";
2300 startLoc = ECE->getLParenLoc();
2303 startLoc =
SM->getExpansionLoc(startLoc);
2304 const char *endBuf =
SM->getCharacterData(startLoc);
2305 ReplaceText(DeclLoc, endBuf-startBuf-1, TypeAsString);
2309 X =
SM->getExpansionLoc(
X);
2310 const char *endBuf =
SM->getCharacterData(
X);
2311 ReplaceText(DeclLoc, endBuf-startBuf-1, TypeAsString);
2316void RewriteModernObjC::SynthSelGetUidFunctionDecl() {
2317 IdentifierInfo *SelGetUidIdent = &Context->Idents.get(
"sel_registerName");
2319 ArgTys.push_back(Context->getPointerType(Context->CharTy.withConst()));
2321 getSimpleFunctionType(Context->getObjCSelType(), ArgTys);
2322 SelGetUidFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
2325 SelGetUidIdent, getFuncType,
2326 nullptr, SC_Extern);
2329void RewriteModernObjC::RewriteFunctionDecl(
FunctionDecl *FD) {
2332 FD->
getName() ==
"sel_registerName") {
2333 SelGetUidFunctionDecl = FD;
2336 RewriteObjCQualifiedInterfaceTypes(FD);
2339void RewriteModernObjC::RewriteBlockPointerType(std::string& Str,
QualType Type) {
2340 std::string TypeString(
Type.getAsString(Context->getPrintingPolicy()));
2341 const char *argPtr = TypeString.c_str();
2342 if (!strchr(argPtr,
'^')) {
2347 Str += (*argPtr ==
'^' ?
'*' : *argPtr);
2353void RewriteModernObjC::RewriteBlockPointerTypeVariable(std::string& Str,
2356 std::string TypeString(
Type.getAsString(Context->getPrintingPolicy()));
2357 const char *argPtr = TypeString.c_str();
2382void RewriteModernObjC::RewriteBlockLiteralFunctionDecl(
FunctionDecl *FD) {
2389 std::string FdStr =
Type.getAsString(Context->getPrintingPolicy());
2393 unsigned numArgs = proto->getNumParams();
2394 for (
unsigned i = 0; i < numArgs; i++) {
2395 QualType ArgType = proto->getParamType(i);
2396 RewriteBlockPointerType(FdStr, ArgType);
2401 FdStr += (numArgs > 0) ?
", ...);\n" :
"...);\n";
2405 InsertText(FunLocStart, FdStr);
2409void RewriteModernObjC::SynthSuperConstructorFunctionDecl() {
2410 if (SuperConstructorFunctionDecl)
2412 IdentifierInfo *msgSendIdent = &Context->Idents.get(
"__rw_objc_super");
2414 QualType argT = Context->getObjCIdType();
2415 assert(!argT.
isNull() &&
"Can't find 'id' type");
2416 ArgTys.push_back(argT);
2417 ArgTys.push_back(argT);
2418 QualType msgSendType = getSimpleFunctionType(Context->getObjCIdType(),
2420 SuperConstructorFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
2423 msgSendIdent, msgSendType,
2424 nullptr, SC_Extern);
2428void RewriteModernObjC::SynthMsgSendFunctionDecl() {
2429 IdentifierInfo *msgSendIdent = &Context->Idents.get(
"objc_msgSend");
2431 QualType argT = Context->getObjCIdType();
2432 assert(!argT.
isNull() &&
"Can't find 'id' type");
2433 ArgTys.push_back(argT);
2434 argT = Context->getObjCSelType();
2435 assert(!argT.
isNull() &&
"Can't find 'SEL' type");
2436 ArgTys.push_back(argT);
2437 QualType msgSendType = getSimpleFunctionType(Context->getObjCIdType(),
2439 MsgSendFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
2442 msgSendIdent, msgSendType,
nullptr,
2447void RewriteModernObjC::SynthMsgSendSuperFunctionDecl() {
2448 IdentifierInfo *msgSendIdent = &Context->Idents.get(
"objc_msgSendSuper");
2450 ArgTys.push_back(Context->VoidTy);
2451 QualType msgSendType = getSimpleFunctionType(Context->getObjCIdType(),
2453 MsgSendSuperFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
2456 msgSendIdent, msgSendType,
2457 nullptr, SC_Extern);
2461void RewriteModernObjC::SynthMsgSendStretFunctionDecl() {
2462 IdentifierInfo *msgSendIdent = &Context->Idents.get(
"objc_msgSend_stret");
2464 QualType argT = Context->getObjCIdType();
2465 assert(!argT.
isNull() &&
"Can't find 'id' type");
2466 ArgTys.push_back(argT);
2467 argT = Context->getObjCSelType();
2468 assert(!argT.
isNull() &&
"Can't find 'SEL' type");
2469 ArgTys.push_back(argT);
2470 QualType msgSendType = getSimpleFunctionType(Context->getObjCIdType(),
2472 MsgSendStretFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
2475 msgSendIdent, msgSendType,
2476 nullptr, SC_Extern);
2481void RewriteModernObjC::SynthMsgSendSuperStretFunctionDecl() {
2483 &Context->Idents.get(
"objc_msgSendSuper_stret");
2485 ArgTys.push_back(Context->VoidTy);
2486 QualType msgSendType = getSimpleFunctionType(Context->getObjCIdType(),
2488 MsgSendSuperStretFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
2492 msgSendType,
nullptr,
2497void RewriteModernObjC::SynthMsgSendFpretFunctionDecl() {
2498 IdentifierInfo *msgSendIdent = &Context->Idents.get(
"objc_msgSend_fpret");
2500 QualType argT = Context->getObjCIdType();
2501 assert(!argT.
isNull() &&
"Can't find 'id' type");
2502 ArgTys.push_back(argT);
2503 argT = Context->getObjCSelType();
2504 assert(!argT.
isNull() &&
"Can't find 'SEL' type");
2505 ArgTys.push_back(argT);
2506 QualType msgSendType = getSimpleFunctionType(Context->DoubleTy,
2508 MsgSendFpretFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
2511 msgSendIdent, msgSendType,
2512 nullptr, SC_Extern);
2516void RewriteModernObjC::SynthGetClassFunctionDecl() {
2517 IdentifierInfo *getClassIdent = &Context->Idents.get(
"objc_getClass");
2519 ArgTys.push_back(Context->getPointerType(Context->CharTy.withConst()));
2520 QualType getClassType = getSimpleFunctionType(Context->getObjCClassType(),
2522 GetClassFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
2525 getClassIdent, getClassType,
2526 nullptr, SC_Extern);
2530void RewriteModernObjC::SynthGetSuperClassFunctionDecl() {
2532 &Context->Idents.get(
"class_getSuperclass");
2534 ArgTys.push_back(Context->getObjCClassType());
2535 QualType getClassType = getSimpleFunctionType(Context->getObjCClassType(),
2537 GetSuperClassFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
2541 getClassType,
nullptr,
2546void RewriteModernObjC::SynthGetMetaClassFunctionDecl() {
2547 IdentifierInfo *getClassIdent = &Context->Idents.get(
"objc_getMetaClass");
2549 ArgTys.push_back(Context->getPointerType(Context->CharTy.withConst()));
2550 QualType getClassType = getSimpleFunctionType(Context->getObjCClassType(),
2552 GetMetaClassFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
2555 getClassIdent, getClassType,
2556 nullptr, SC_Extern);
2560 assert (Exp !=
nullptr &&
"Expected non-null ObjCStringLiteral");
2561 QualType strType = getConstantStringStructType();
2563 std::string S =
"__NSConstantStringImpl_";
2565 std::string tmpName = InFileName;
2567 for (i=0; i < tmpName.length(); i++) {
2568 char c = tmpName.at(i);
2575 S += utostr(NumObjCStringLiterals++);
2577 Preamble +=
"static __NSConstantStringImpl " + S;
2578 Preamble +=
" __attribute__ ((section (\"__DATA, __cfstring\"))) = {__CFConstantStringClassReference,";
2581 std::string prettyBufS;
2582 llvm::raw_string_ostream prettyBuf(prettyBufS);
2590 strType,
nullptr, SC_Static);
2593 Expr *Unop = UnaryOperator::Create(
2594 const_cast<ASTContext &
>(*Context), DRE, UO_AddrOf,
2595 Context->getPointerType(DRE->
getType()), VK_PRValue, OK_Ordinary,
2599 CK_CPointerToObjCPointerCast, Unop);
2600 ReplaceStmt(Exp, cast);
2607 static_cast<unsigned>(Context->getTypeSize(Context->IntTy));
2609 Expr *FlagExp = IntegerLiteral::Create(*Context,
2610 llvm::APInt(IntSize, Exp->
getValue()),
2612 CastExpr *
cast = NoTypeInfoCStyleCastExpr(Context, Context->ObjCBuiltinBoolTy,
2613 CK_BitCast, FlagExp);
2616 ReplaceStmt(Exp, PE);
2622 if (!SelGetUidFunctionDecl)
2623 SynthSelGetUidFunctionDecl();
2625 if (!MsgSendFunctionDecl)
2626 SynthMsgSendFunctionDecl();
2627 if (!GetClassFunctionDecl)
2628 SynthGetClassFunctionDecl();
2643 ClsExprs.push_back(getStringLiteral(clsName->
getName()));
2644 CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl, ClsExprs,
2646 MsgExprs.push_back(Cls);
2653 CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl,
2654 SelExprs, StartLoc, EndLoc);
2655 MsgExprs.push_back(SelExp);
2664 CK = CK_IntegralToBoolean;
2665 subExpr = NoTypeInfoCStyleCastExpr(Context, type, CK, subExpr);
2667 MsgExprs.push_back(subExpr);
2670 ArgTypes.push_back(Context->getObjCClassType());
2671 ArgTypes.push_back(Context->getObjCSelType());
2672 for (
const auto PI : BoxingMethod->
parameters())
2673 ArgTypes.push_back(PI->getType());
2681 *Context, MsgSendFlavor,
false, msgSendType, VK_LValue,
SourceLocation());
2684 Context, Context->getPointerType(Context->VoidTy), CK_BitCast, DRE);
2688 getSimpleFunctionType(returnType, ArgTypes, BoxingMethod->
isVariadic());
2689 castType = Context->getPointerType(castType);
2690 cast = NoTypeInfoCStyleCastExpr(Context, castType, CK_BitCast,
2697 CallExpr *CE = CallExpr::Create(*Context, PE, MsgExprs, FT->getReturnType(),
2699 ReplaceStmt(Exp, CE);
2705 if (!SelGetUidFunctionDecl)
2706 SynthSelGetUidFunctionDecl();
2708 if (!MsgSendFunctionDecl)
2709 SynthMsgSendFunctionDecl();
2710 if (!GetClassFunctionDecl)
2711 SynthGetClassFunctionDecl();
2720 getSimpleFunctionType(Context->VoidTy, IntQT,
true);
2721 std::string NSArrayFName(
"__NSContainer_literal");
2722 FunctionDecl *NSArrayFD = SynthBlockInitFunctionDecl(NSArrayFName);
2724 *Context, NSArrayFD,
false, NSArrayFType, VK_PRValue,
SourceLocation());
2728 unsigned UnsignedIntSize =
2729 static_cast<unsigned>(Context->getTypeSize(Context->UnsignedIntTy));
2730 Expr *count = IntegerLiteral::Create(*Context,
2731 llvm::APInt(UnsignedIntSize, NumElements),
2733 InitExprs.push_back(count);
2734 for (
unsigned i = 0; i < NumElements; i++)
2736 Expr *NSArrayCallExpr =
2737 CallExpr::Create(*Context, NSArrayDRE, InitExprs, NSArrayFType, VK_LValue,
2742 &Context->Idents.get(
"arr"),
2743 Context->getPointerType(Context->VoidPtrTy),
2747 MemberExpr::CreateImplicit(*Context, NSArrayCallExpr,
false, ARRFD,
2748 ARRFD->
getType(), VK_LValue, OK_Ordinary);
2749 QualType ConstIdT = Context->getObjCIdType().withConst();
2751 NoTypeInfoCStyleCastExpr(Context,
2752 Context->getPointerType(ConstIdT),
2766 ClsExprs.push_back(getStringLiteral(clsName->
getName()));
2767 CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl, ClsExprs,
2769 MsgExprs.push_back(Cls);
2777 CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl,
2778 SelExprs, StartLoc, EndLoc);
2779 MsgExprs.push_back(SelExp);
2782 MsgExprs.push_back(ArrayLiteralObjects);
2785 Expr *cnt = IntegerLiteral::Create(*Context,
2786 llvm::APInt(UnsignedIntSize, NumElements),
2788 MsgExprs.push_back(cnt);
2791 ArgTypes.push_back(Context->getObjCClassType());
2792 ArgTypes.push_back(Context->getObjCSelType());
2793 for (
const auto *PI : ArrayMethod->
parameters())
2794 ArgTypes.push_back(PI->getType());
2802 *Context, MsgSendFlavor,
false, msgSendType, VK_LValue,
SourceLocation());
2805 Context, Context->getPointerType(Context->VoidTy), CK_BitCast, DRE);
2809 getSimpleFunctionType(returnType, ArgTypes, ArrayMethod->
isVariadic());
2810 castType = Context->getPointerType(castType);
2811 cast = NoTypeInfoCStyleCastExpr(Context, castType, CK_BitCast,
2820 ReplaceStmt(Exp, CE);
2826 if (!SelGetUidFunctionDecl)
2827 SynthSelGetUidFunctionDecl();
2829 if (!MsgSendFunctionDecl)
2830 SynthMsgSendFunctionDecl();
2831 if (!GetClassFunctionDecl)
2832 SynthGetClassFunctionDecl();
2841 getSimpleFunctionType(Context->VoidTy, IntQT,
true);
2842 std::string NSDictFName(
"__NSContainer_literal");
2843 FunctionDecl *NSDictFD = SynthBlockInitFunctionDecl(NSDictFName);
2845 *Context, NSDictFD,
false, NSDictFType, VK_PRValue,
SourceLocation());
2851 unsigned UnsignedIntSize =
2852 static_cast<unsigned>(Context->getTypeSize(Context->UnsignedIntTy));
2853 Expr *count = IntegerLiteral::Create(*Context,
2854 llvm::APInt(UnsignedIntSize, NumElements),
2856 KeyExprs.push_back(count);
2857 ValueExprs.push_back(count);
2858 for (
unsigned i = 0; i < NumElements; i++) {
2860 KeyExprs.push_back(Element.Key);
2861 ValueExprs.push_back(Element.Value);
2865 Expr *NSValueCallExpr =
2866 CallExpr::Create(*Context, NSDictDRE, ValueExprs, NSDictFType, VK_LValue,
2871 &Context->Idents.get(
"arr"),
2872 Context->getPointerType(Context->VoidPtrTy),
2876 MemberExpr::CreateImplicit(*Context, NSValueCallExpr,
false, ARRFD,
2877 ARRFD->
getType(), VK_LValue, OK_Ordinary);
2878 QualType ConstIdT = Context->getObjCIdType().withConst();
2880 NoTypeInfoCStyleCastExpr(Context,
2881 Context->getPointerType(ConstIdT),
2883 DictLiteralValueME);
2885 Expr *NSKeyCallExpr =
2886 CallExpr::Create(*Context, NSDictDRE, KeyExprs, NSDictFType, VK_LValue,
2890 MemberExpr::CreateImplicit(*Context, NSKeyCallExpr,
false, ARRFD,
2891 ARRFD->
getType(), VK_LValue, OK_Ordinary);
2894 NoTypeInfoCStyleCastExpr(Context,
2895 Context->getPointerType(ConstIdT),
2909 ClsExprs.push_back(getStringLiteral(clsName->
getName()));
2910 CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl, ClsExprs,
2912 MsgExprs.push_back(Cls);
2919 CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl,
2920 SelExprs, StartLoc, EndLoc);
2921 MsgExprs.push_back(SelExp);
2924 MsgExprs.push_back(DictValueObjects);
2927 MsgExprs.push_back(DictKeyObjects);
2930 Expr *cnt = IntegerLiteral::Create(*Context,
2931 llvm::APInt(UnsignedIntSize, NumElements),
2933 MsgExprs.push_back(cnt);
2936 ArgTypes.push_back(Context->getObjCClassType());
2937 ArgTypes.push_back(Context->getObjCSelType());
2938 for (
const auto *PI : DictMethod->
parameters()) {
2942 convertToUnqualifiedObjCType(PointeeTy);
2943 T = Context->getPointerType(PointeeTy);
2945 ArgTypes.push_back(T);
2954 *Context, MsgSendFlavor,
false, msgSendType, VK_LValue,
SourceLocation());
2957 Context, Context->getPointerType(Context->VoidTy), CK_BitCast, DRE);
2961 getSimpleFunctionType(returnType, ArgTypes, DictMethod->
isVariadic());
2962 castType = Context->getPointerType(castType);
2963 cast = NoTypeInfoCStyleCastExpr(Context, castType, CK_BitCast,
2972 ReplaceStmt(Exp, CE);
2979QualType RewriteModernObjC::getSuperStructType() {
2980 if (!SuperStructDecl) {
2981 SuperStructDecl = RecordDecl::Create(
2987 FieldTypes[0] = Context->getObjCIdType();
2989 FieldTypes[1] = Context->getObjCIdType();
2992 for (
unsigned i = 0; i < 2; ++i) {
2993 SuperStructDecl->
addDecl(FieldDecl::Create(*Context, SuperStructDecl,
2996 FieldTypes[i],
nullptr,
3004 return Context->getTagDeclType(SuperStructDecl);
3007QualType RewriteModernObjC::getConstantStringStructType() {
3008 if (!ConstantStringDecl) {
3009 ConstantStringDecl = RecordDecl::Create(
3011 SourceLocation(), &Context->Idents.get(
"__NSConstantStringImpl"));
3015 FieldTypes[0] = Context->getObjCIdType();
3017 FieldTypes[1] = Context->IntTy;
3019 FieldTypes[2] = Context->getPointerType(Context->CharTy);
3021 FieldTypes[3] = Context->LongTy;
3024 for (
unsigned i = 0; i < 4; ++i) {
3025 ConstantStringDecl->
addDecl(FieldDecl::Create(*Context,
3029 FieldTypes[i],
nullptr,
3037 return Context->getTagDeclType(ConstantStringDecl);
3043static SourceLocation getFunctionSourceLocation (RewriteModernObjC &R,
3049 if (!LSD->getRBraceLoc().isValid())
3050 return LSD->getExternLoc();
3053 R.RewriteBlockLiteralFunctionDecl(FD);
3057void RewriteModernObjC::RewriteLineDirective(
const Decl *D) {
3061 if (Location.
isFileID() && GenerateLineInfo) {
3062 std::string LineString(
"\n#line ");
3064 LineString += utostr(PLoc.
getLine());
3065 LineString +=
" \"";
3066 LineString += Lexer::Stringify(PLoc.
getFilename());
3067 if (isa<ObjCMethodDecl>(D))
3069 else LineString +=
"\"\n";
3072 if (
const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
3077 if (!LSD->getRBraceLoc().isValid())
3078 Location = LSD->getExternLoc();
3081 InsertText(Location, LineString);
3095Expr *RewriteModernObjC::SynthMsgSendStretCallExpr(
FunctionDecl *MsgSendStretFlavor,
3101 QualType FuncType = getSimpleFunctionType(
3102 returnType, ArgTypes, Method ? Method->
isVariadic() :
false);
3103 QualType castType = Context->getPointerType(FuncType);
3106 static unsigned stretCount=0;
3107 std::string
name =
"__Stret";
name += utostr(stretCount);
3109 "extern \"C\" void * __cdecl memset(void *_Dst, int _Val, size_t _Size);\n";
3110 str +=
"namespace {\n";
3111 str +=
"struct "; str +=
name;
3114 str +=
"(id receiver, SEL sel";
3115 for (
unsigned i = 2; i < ArgTypes.size(); i++) {
3116 std::string ArgName =
"arg"; ArgName += utostr(i);
3117 ArgTypes[i].getAsStringInternal(ArgName, Context->getPrintingPolicy());
3118 str +=
", "; str += ArgName;
3121 for (
unsigned i = ArgTypes.size(); i < MsgExprs.size(); i++) {
3122 std::string ArgName =
"arg"; ArgName += utostr(i);
3123 MsgExprs[i]->getType().getAsStringInternal(ArgName,
3124 Context->getPrintingPolicy());
3125 str +=
", "; str += ArgName;
3129 str +=
"\t unsigned size = sizeof(";
3130 str += returnType.
getAsString(Context->getPrintingPolicy()); str +=
");\n";
3132 str +=
"\t if (size == 1 || size == 2 || size == 4 || size == 8)\n";
3134 str +=
"\t s = (("; str += castType.
getAsString(Context->getPrintingPolicy());
3135 str +=
")(void *)objc_msgSend)(receiver, sel";
3136 for (
unsigned i = 2; i < ArgTypes.size(); i++) {
3137 str +=
", arg"; str += utostr(i);
3140 for (
unsigned i = ArgTypes.size(); i < MsgExprs.size(); i++) {
3141 str +=
", arg"; str += utostr(i);
3145 str +=
"\t else if (receiver == 0)\n";
3146 str +=
"\t memset((void*)&s, 0, sizeof(s));\n";
3149 str +=
"\t s = (("; str += castType.
getAsString(Context->getPrintingPolicy());
3150 str +=
")(void *)objc_msgSend_stret)(receiver, sel";
3151 for (
unsigned i = 2; i < ArgTypes.size(); i++) {
3152 str +=
", arg"; str += utostr(i);
3155 for (
unsigned i = ArgTypes.size(); i < MsgExprs.size(); i++) {
3156 str +=
", arg"; str += utostr(i);
3161 str +=
"\t"; str += returnType.
getAsString(Context->getPrintingPolicy());
3163 str +=
"};\n};\n\n";
3166 FunLocStart = getFunctionSourceLocation(*
this, CurFunctionDef);
3168 assert(CurMethodDef &&
"SynthMsgSendStretCallExpr - CurMethodDef is null");
3172 InsertText(FunLocStart, str);
3179 ID, FuncType,
nullptr, SC_Extern,
false,
false);
3183 CallExpr::Create(*Context, DRE, MsgExprs, castType, VK_LValue,
3188 &Context->Idents.get(
"s"),
3189 returnType,
nullptr,
3193 *Context, STCE,
false, FieldD, FieldD->
getType(), VK_LValue, OK_Ordinary);
3201 if (!SelGetUidFunctionDecl)
3202 SynthSelGetUidFunctionDecl();
3203 if (!MsgSendFunctionDecl)
3204 SynthMsgSendFunctionDecl();
3205 if (!MsgSendSuperFunctionDecl)
3206 SynthMsgSendSuperFunctionDecl();
3207 if (!MsgSendStretFunctionDecl)
3208 SynthMsgSendStretFunctionDecl();
3209 if (!MsgSendSuperStretFunctionDecl)
3210 SynthMsgSendSuperStretFunctionDecl();
3211 if (!MsgSendFpretFunctionDecl)
3212 SynthMsgSendFpretFunctionDecl();
3213 if (!GetClassFunctionDecl)
3214 SynthGetClassFunctionDecl();
3215 if (!GetSuperClassFunctionDecl)
3216 SynthGetSuperClassFunctionDecl();
3217 if (!GetMetaClassFunctionDecl)
3218 SynthGetMetaClassFunctionDecl();
3225 QualType resultType = mDecl->getReturnType();
3227 MsgSendStretFlavor = MsgSendStretFunctionDecl;
3229 MsgSendFlavor = MsgSendFpretFunctionDecl;
3235 case ObjCMessageExpr::SuperClass: {
3236 MsgSendFlavor = MsgSendSuperFunctionDecl;
3237 if (MsgSendStretFlavor)
3238 MsgSendStretFlavor = MsgSendSuperStretFunctionDecl;
3239 assert(MsgSendFlavor &&
"MsgSendFlavor is NULL!");
3246 InitExprs.push_back(NoTypeInfoCStyleCastExpr(
3247 Context, Context->getObjCIdType(), CK_BitCast,
3249 Context->getObjCIdType(), VK_PRValue,
3256 CallExpr *Cls = SynthesizeCallToFunctionDecl(GetMetaClassFunctionDecl,
3257 ClsExprs, StartLoc, EndLoc);
3259 ClsExprs.push_back(Cls);
3260 Cls = SynthesizeCallToFunctionDecl(GetSuperClassFunctionDecl, ClsExprs,
3265 InitExprs.push_back(
3266 NoTypeInfoCStyleCastExpr(Context,
3267 Context->getObjCIdType(),
3270 QualType superType = getSuperStructType();
3273 if (LangOpts.MicrosoftExt) {
3274 SynthSuperConstructorFunctionDecl();
3277 DeclRefExpr(*Context, SuperConstructorFunctionDecl,
false, superType,
3280 CallExpr::Create(*Context, DRE, InitExprs, superType, VK_LValue,
3288 SuperRep = UnaryOperator::Create(
3289 const_cast<ASTContext &
>(*Context), SuperRep, UO_AddrOf,
3290 Context->getPointerType(SuperRep->
getType()), VK_PRValue, OK_Ordinary,
3292 SuperRep = NoTypeInfoCStyleCastExpr(Context,
3293 Context->getPointerType(superType),
3294 CK_BitCast, SuperRep);
3301 = Context->getTrivialTypeSourceInfo(superType);
3306 SuperRep = UnaryOperator::Create(
3307 const_cast<ASTContext &
>(*Context), SuperRep, UO_AddrOf,
3308 Context->getPointerType(SuperRep->
getType()), VK_PRValue, OK_Ordinary,
3311 MsgExprs.push_back(SuperRep);
3315 case ObjCMessageExpr::Class: {
3320 ClsExprs.push_back(getStringLiteral(clsName->
getName()));
3321 CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl, ClsExprs,
3323 CastExpr *ArgExpr = NoTypeInfoCStyleCastExpr(Context,
3324 Context->getObjCIdType(),
3326 MsgExprs.push_back(ArgExpr);
3330 case ObjCMessageExpr::SuperInstance:{
3331 MsgSendFlavor = MsgSendSuperFunctionDecl;
3332 if (MsgSendStretFlavor)
3333 MsgSendStretFlavor = MsgSendSuperStretFunctionDecl;
3334 assert(MsgSendFlavor &&
"MsgSendFlavor is NULL!");
3338 InitExprs.push_back(NoTypeInfoCStyleCastExpr(
3339 Context, Context->getObjCIdType(), CK_BitCast,
3341 Context->getObjCIdType(), VK_PRValue,
3348 CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl, ClsExprs,
3351 ClsExprs.push_back(Cls);
3352 Cls = SynthesizeCallToFunctionDecl(GetSuperClassFunctionDecl, ClsExprs,
3357 InitExprs.push_back(
3359 NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(),
3362 QualType superType = getSuperStructType();
3365 if (LangOpts.MicrosoftExt) {
3366 SynthSuperConstructorFunctionDecl();
3369 DeclRefExpr(*Context, SuperConstructorFunctionDecl,
false, superType,
3372 CallExpr::Create(*Context, DRE, InitExprs, superType, VK_LValue,
3380 SuperRep = UnaryOperator::Create(
3381 const_cast<ASTContext &
>(*Context), SuperRep, UO_AddrOf,
3382 Context->getPointerType(SuperRep->
getType()), VK_PRValue, OK_Ordinary,
3384 SuperRep = NoTypeInfoCStyleCastExpr(Context,
3385 Context->getPointerType(superType),
3386 CK_BitCast, SuperRep);
3393 = Context->getTrivialTypeSourceInfo(superType);
3397 MsgExprs.push_back(SuperRep);
3401 case ObjCMessageExpr::Instance: {
3406 recExpr = CE->getSubExpr();
3409 ? CK_BlockPointerToObjCPointerCast
3410 : CK_CPointerToObjCPointerCast;
3412 recExpr = NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(),
3414 MsgExprs.push_back(recExpr);
3422 CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl,
3423 SelExprs, StartLoc, EndLoc);
3424 MsgExprs.push_back(SelExp);
3427 for (
unsigned i = 0; i < Exp->
getNumArgs(); i++) {
3433 if (needToScanForQualifiers(type))
3434 type = Context->getObjCIdType();
3436 (void)convertBlockPointerToFunctionPointer(type);
3440 type->isBooleanType()) {
3441 CK = CK_IntegralToBoolean;
3442 }
else if (
type->isObjCObjectPointerType()) {
3444 CK = CK_BlockPointerToObjCPointerCast;
3446 CK = CK_CPointerToObjCPointerCast;
3454 userExpr = NoTypeInfoCStyleCastExpr(Context, type, CK, userExpr);
3457 else if (
CStyleCastExpr *CE = dyn_cast<CStyleCastExpr>(userExpr)) {
3458 if (CE->getType()->isObjCQualifiedIdType()) {
3459 while ((CE = dyn_cast<CStyleCastExpr>(userExpr)))
3460 userExpr = CE->getSubExpr();
3463 CK = CK_IntegralToPointer;
3465 CK = CK_BlockPointerToObjCPointerCast;
3467 CK = CK_CPointerToObjCPointerCast;
3471 userExpr = NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(),
3475 MsgExprs.push_back(userExpr);
3487 if (MsgSendFlavor == MsgSendSuperFunctionDecl)
3488 ArgTypes.push_back(Context->getPointerType(getSuperStructType()));
3490 ArgTypes.push_back(Context->getObjCIdType());
3491 ArgTypes.push_back(Context->getObjCSelType());
3496 ? Context->getObjCIdType()
3499 (void)convertBlockPointerToFunctionPointer(t);
3500 ArgTypes.push_back(t);
3503 convertToUnqualifiedObjCType(returnType);
3504 (void)convertBlockPointerToFunctionPointer(returnType);
3506 returnType = Context->getObjCIdType();
3513 *Context, MsgSendFlavor,
false, msgSendType, VK_LValue,
SourceLocation());
3519 cast = NoTypeInfoCStyleCastExpr(Context,
3520 Context->getPointerType(Context->VoidTy),
3527 getSimpleFunctionType(returnType, ArgTypes, MD ? MD->
isVariadic() :
true);
3528 castType = Context->getPointerType(castType);
3529 cast = NoTypeInfoCStyleCastExpr(Context, castType, CK_BitCast,
3538 Stmt *ReplacingStmt = CE;
3539 if (MsgSendStretFlavor) {
3545 Expr *STCE = SynthMsgSendStretCallExpr(MsgSendStretFlavor,
3549 ReplacingStmt = STCE;
3552 return ReplacingStmt;
3556 Stmt *ReplacingStmt =
3560 ReplaceStmt(Exp, ReplacingStmt);
3563 return ReplacingStmt;
3567QualType RewriteModernObjC::getProtocolType() {
3568 if (!ProtocolTypeDecl) {
3570 = Context->getTrivialTypeSourceInfo(Context->getObjCIdType());
3571 ProtocolTypeDecl = TypedefDecl::Create(*Context, TUDecl,
3573 &Context->Idents.get(
"Protocol"),
3576 return Context->getTypeDeclType(ProtocolTypeDecl);
3584 std::string Name =
"_OBJC_PROTOCOL_REFERENCE_$_" +
3589 nullptr, SC_Extern);
3593 Context, Context->getPointerType(DRE->
getType()), CK_BitCast, DRE);
3594 ReplaceStmt(Exp, castExpr);
3604 bool &IsNamedDefinition) {
3608 if (
RecordDecl *RD = dyn_cast<RecordDecl>(Tag)) {
3612 IsNamedDefinition =
true;
3614 return Context->getSourceManager().isBeforeInTranslationUnit(
3617 if (
EnumDecl *ED = dyn_cast<EnumDecl>(Tag)) {
3618 if (!ED || !ED->getDeclName().getAsIdentifierInfo())
3620 IsNamedDefinition =
true;
3621 TagLocation = ED->getLocation();
3622 return Context->getSourceManager().isBeforeInTranslationUnit(
3630bool RewriteModernObjC::RewriteObjCFieldDeclType(
QualType &
Type,
3631 std::string &Result) {
3639 return RewriteObjCFieldDeclType(ElemTy, Result);
3645 Result +=
"\n\tstruct ";
3647 Result +=
"\n\tunion ";
3649 assert(
false &&
"class not allowed as an ivar type");
3652 if (GlobalDefinedTags.count(RD)) {
3658 for (
auto *FD : RD->
fields())
3659 RewriteObjCFieldDecl(FD, Result);
3667 Result +=
"\n\tenum ";
3669 if (GlobalDefinedTags.count(ED)) {
3677 Result +=
"\t"; Result += EC->getName(); Result +=
" = ";
3678 Result +=
toString(EC->getInitVal(), 10);
3687 convertObjCTypeToCStyleType(
Type);
3694void RewriteModernObjC::RewriteObjCFieldDecl(
FieldDecl *fieldDecl,
3695 std::string &Result) {
3697 std::string Name =
fieldDecl->getNameAsString();
3699 bool EleboratedType = RewriteObjCFieldDeclType(
Type, Result);
3700 if (!EleboratedType)
3701 Type.getAsStringInternal(Name, Context->getPrintingPolicy());
3704 Result +=
" : "; Result += utostr(
fieldDecl->getBitWidthValue(*Context));
3711 llvm::APInt Dim = CAT->getSize();
3712 Result += utostr(Dim.getZExtValue());
3724void RewriteModernObjC::RewriteLocallyDefinedNamedAggregates(
FieldDecl *fieldDecl,
3725 std::string &Result) {
3730 Type = Context->getBaseElementType(
Type);
3732 auto *IDecl = dyn_cast<ObjCContainerDecl>(
fieldDecl->getDeclContext());
3743 if (GlobalDefinedTags.count(TD))
3746 bool IsNamedDefinition =
false;
3747 if (IsTagDefinedInsideClass(IDecl, TD, IsNamedDefinition)) {
3748 RewriteObjCFieldDeclType(
Type, Result);
3751 if (IsNamedDefinition)
3752 GlobalDefinedTags.insert(TD);
3756unsigned RewriteModernObjC::ObjCIvarBitfieldGroupNo(
ObjCIvarDecl *IV) {
3758 if (ObjCInterefaceHasBitfieldGroups.count(CDecl)) {
3759 return IvarGroupNumber[IV];
3761 unsigned GroupNo = 0;
3765 IVars.push_back(IVD);
3767 for (
unsigned i = 0, e = IVars.size(); i < e; i++)
3768 if (IVars[i]->isBitField()) {
3769 IvarGroupNumber[IVars[i++]] = ++GroupNo;
3770 while (i < e && IVars[i]->isBitField())
3771 IvarGroupNumber[IVars[i++]] = GroupNo;
3776 ObjCInterefaceHasBitfieldGroups.insert(CDecl);
3777 return IvarGroupNumber[IV];
3780QualType RewriteModernObjC::SynthesizeBitfieldGroupStructType(
3783 std::string StructTagName;
3784 ObjCIvarBitfieldGroupType(IV, StructTagName);
3786 *Context, TagTypeKind::Struct, Context->getTranslationUnitDecl(),
3788 for (
unsigned i=0, e = IVars.size(); i < e; i++) {
3791 &Context->Idents.get(Ivar->
getName()),
3794 false, ICIS_NoInit));
3797 return Context->getTagDeclType(RD);
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())
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");
3836void RewriteModernObjC::ObjCIvarBitfieldGroupDecl(
ObjCIvarDecl *IV,
3837 std::string &Result) {
3840 Result +=
"__GRBF_";
3841 unsigned GroupNo = ObjCIvarBitfieldGroupNo(IV);
3842 Result += utostr(GroupNo);
3848void RewriteModernObjC::ObjCIvarBitfieldGroupType(
ObjCIvarDecl *IV,
3849 std::string &Result) {
3853 unsigned GroupNo = ObjCIvarBitfieldGroupNo(IV);
3854 Result += utostr(GroupNo);
3860void 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()) \
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);
3889 const char *startBuf =
SM->getCharacterData(LocStart);
3890 const char *endBuf =
SM->getCharacterData(LocEnd);
3895 (!RCDecl || !ObjCSynthesizedStructs.count(RCDecl))) {
3896 endBuf += Lexer::MeasureTokenLength(LocEnd, *
SM, LangOpts);
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);
3916 SKIP_BITFIELDS(i , e, IVars);
3919 Result +=
"\nstruct ";
3921 Result +=
"_IMPL {\n";
3923 if (RCDecl && ObjCSynthesizedStructs.count(RCDecl)) {
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";
3936 SKIP_BITFIELDS(i , e, IVars);
3939 RewriteObjCFieldDecl(IVars[i], Result);
3943 endBuf += Lexer::MeasureTokenLength(LocEnd, *
SM, LangOpts);
3944 ReplaceText(LocStart, endBuf-startBuf, Result);
3946 if (!ObjCSynthesizedStructs.insert(CDecl).second)
3947 llvm_unreachable(
"struct already synthesize- RewriteObjCInternalStruct");
3953 std::string &Result) {
3964 unsigned GroupNo = 0;
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 ";
3981 ObjCIvarBitfieldGroupOffset(IvarDecl, Result);
3982 GroupSymbolOutput.insert(std::make_pair(IDecl, GroupNo));
3985 WriteInternalIvarName(CDecl, IvarDecl, Result);
3997void 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);
4021void 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]) ;
4032static bool HasLocalVariableExternalStorage(
ValueDecl *VD) {
4033 if (
VarDecl *Var = dyn_cast<VarDecl>(VD))
4034 return (Var->isFunctionOrMethodVarDecl() && !Var->hasLocalStorage());
4038std::string RewriteModernObjC::SynthesizeBlockFunc(
BlockExpr *CE,
int i,
4043 std::string StructRef =
"struct " + Tag;
4046 ConvertSourceLocationToLineDirective(BlockLoc, S);
4048 S +=
"static " + RT.
getAsString(Context->getPrintingPolicy()) +
" __" +
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();
4119 if (HasLocalVariableExternalStorage(*I))
4120 QT = Context->getPointerType(QT);
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++ !=
'{') ;
4134std::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))
4151 S +=
", " + utostr(BLOCK_FIELD_IS_BYREF) +
"/*BLOCK_FIELD_IS_BYREF*/);";
4153 S +=
", " + utostr(BLOCK_FIELD_IS_BLOCK) +
"/*BLOCK_FIELD_IS_BLOCK*/);";
4155 S +=
", " + utostr(BLOCK_FIELD_IS_OBJECT) +
"/*BLOCK_FIELD_IS_OBJECT*/);";
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))
4168 S +=
", " + utostr(BLOCK_FIELD_IS_BYREF) +
"/*BLOCK_FIELD_IS_BYREF*/);";
4170 S +=
", " + utostr(BLOCK_FIELD_IS_BLOCK) +
"/*BLOCK_FIELD_IS_BLOCK*/);";
4172 S +=
", " + utostr(BLOCK_FIELD_IS_OBJECT) +
"/*BLOCK_FIELD_IS_OBJECT*/);";
4178std::string RewriteModernObjC::SynthesizeBlockImpl(
BlockExpr *CE, std::string Tag,
4180 std::string S =
"\nstruct " + Tag;
4183 S +=
" {\n struct __block_impl impl;\n";
4184 S +=
" struct " + 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 *";
4213 if (HasLocalVariableExternalStorage(*I))
4214 QT = Context->getPointerType(QT);
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;
4235 S += FieldName +
"; // by ref\n";
4240 bool firsTime =
true;
4242 E = BlockByCopyDecls.end(); I != E; ++I) {
4243 std::string Name = (*I)->getNameAsString();
4250 if (isTopLevelBlockPointerType((*I)->getType()))
4251 Constructor += Name +
"((struct __block_impl *)_" + Name +
")";
4257 E = BlockByRefDecls.end(); I != E; ++I) {
4258 std::string Name = (*I)->getNameAsString();
4265 Constructor += Name +
"(_" + Name +
"->__forwarding)";
4270 Constructor +=
" impl.isa = &_NSConcreteGlobalBlock;\n";
4272 Constructor +=
" impl.isa = &_NSConcreteStackBlock;\n";
4273 Constructor +=
" impl.Flags = flags;\n impl.FuncPtr = fp;\n";
4280 Constructor +=
" impl.isa = &_NSConcreteGlobalBlock;\n";
4282 Constructor +=
" impl.isa = &_NSConcreteStackBlock;\n";
4283 Constructor +=
" impl.Flags = flags;\n impl.FuncPtr = fp;\n";
4293std::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);
4321void 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();
4430void RewriteModernObjC::InsertBlockLiteralsWithinFunction(
FunctionDecl *FD) {
4432 (!Blocks.empty()) ? getFunctionSourceLocation(*
this, FD)
4434 StringRef FuncName = FD->
getName();
4436 SynthesizeBlockLiterals(FunLocStart, FuncName);
4439static void BuildUniqueMethodName(std::string &Name,
4442 Name = std::string(IFace->
getName());
4445 std::string::size_type loc = 0;
4446 while ((loc = Name.find(
':', loc)) != std::string::npos)
4447 Name.replace(loc, 1,
"_");
4450void RewriteModernObjC::InsertBlockLiteralsWithinMethod(
ObjCMethodDecl *MD) {
4454 std::string FuncName;
4455 BuildUniqueMethodName(FuncName, MD);
4456 SynthesizeBlockLiterals(FunLocStart, FuncName);
4459void RewriteModernObjC::GetBlockDeclRefExprs(
Stmt *S) {
4460 for (
Stmt *SubStmt : S->children())
4462 if (
BlockExpr *CBE = dyn_cast<BlockExpr>(SubStmt))
4463 GetBlockDeclRefExprs(CBE->getBody());
4465 GetBlockDeclRefExprs(SubStmt);
4470 HasLocalVariableExternalStorage(DRE->
getDecl()))
4472 BlockDeclRefs.push_back(DRE);
4475void RewriteModernObjC::GetInnerBlockDeclRefExprs(
Stmt *S,
4477 llvm::SmallPtrSetImpl<const DeclContext *> &InnerContexts) {
4478 for (
Stmt *SubStmt : S->children())
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)) {
4492 HasLocalVariableExternalStorage(DRE->
getDecl())) {
4494 InnerBlockDeclRefs.push_back(DRE);
4496 if (Var->isFunctionOrMethodVarDecl())
4497 ImportedLocalExternalDecls.insert(Var);
4505bool RewriteModernObjC::convertObjCTypeToCStyleType(
QualType &T) {
4507 convertBlockPointerToFunctionPointer(T);
4513 T = convertFunctionTypeOfBlocks(FT);
4514 T = Context->getPointerType(T);
4519 convertToUnqualifiedObjCType(T);
4533 bool modified = convertObjCTypeToCStyleType(Res);
4539 if (convertObjCTypeToCStyleType(t))
4541 ArgTypes.push_back(t);
4546 FuncType = getSimpleFunctionType(Res, ArgTypes);
4551Stmt *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();
4576 }
else if (
const ObjCIvarRefExpr *IRE = dyn_cast<ObjCIvarRefExpr>(BlockExp)) {
4579 = dyn_cast<PseudoObjectExpr>(BlockExp)) {
4582 assert(
false &&
"RewriteBlockClass: Bad type");
4584 assert(CPT &&
"RewriteBlockClass: Bad type");
4586 assert(FT &&
"RewriteBlockClass: Bad type");
4590 RecordDecl *RD = RecordDecl::Create(*Context, TagTypeKind::Struct, TUDecl,
4592 &Context->Idents.get(
"__block_impl"));
4593 QualType PtrBlock = Context->getPointerType(Context->getTagDeclType(RD));
4599 ArgTypes.push_back(PtrBlock);
4604 if (!convertBlockPointerToFunctionPointer(t))
4605 convertToUnqualifiedObjCType(t);
4606 ArgTypes.push_back(t);
4610 QualType PtrToFuncCastType = getSimpleFunctionType(Exp->
getType(), ArgTypes);
4612 PtrToFuncCastType = Context->getPointerType(PtrToFuncCastType);
4614 CastExpr *BlkCast = NoTypeInfoCStyleCastExpr(Context, PtrBlock,
4616 const_cast<Expr*
>(BlockExp));
4624 &Context->Idents.get(
"FuncPtr"),
4625 Context->VoidPtrTy,
nullptr,
4629 *Context, PE,
true, FD, FD->
getType(), VK_LValue, OK_Ordinary);
4631 CastExpr *FunkCast = NoTypeInfoCStyleCastExpr(Context, PtrToFuncCastType,
4637 BlkExprs.push_back(BlkCast);
4640 E = Exp->
arg_end(); I != E; ++I) {
4641 BlkExprs.push_back(*I);
4644 CallExpr::Create(*Context, PE, BlkExprs, Exp->
getType(), VK_PRValue,
4662Stmt *RewriteModernObjC::RewriteBlockDeclRefExpr(
DeclRefExpr *DeclRefExp) {
4667 HasLocalVariableExternalStorage(DeclRefExp->
getDecl());
4671 &Context->Idents.get(
"__forwarding"),
4672 Context->VoidPtrTy,
nullptr,
4676 *Context, DeclRefExp, isArrow, FD, FD->
getType(), VK_LValue, OK_Ordinary);
4678 StringRef Name = VD->
getName();
4680 &Context->Idents.get(Name),
4681 Context->VoidPtrTy,
nullptr,
4684 ME = MemberExpr::CreateImplicit(*Context, ME,
true, FD, DeclRefExp->
getType(),
4685 VK_LValue, OK_Ordinary);
4691 ReplaceStmt(DeclRefExp, PE);
4698Stmt *RewriteModernObjC::RewriteLocalVariableExternalStorage(
DeclRefExpr *DRE) {
4700 if (
VarDecl *Var = dyn_cast<VarDecl>(VD))
4701 if (!ImportedLocalExternalDecls.count(Var))
4703 Expr *Exp = UnaryOperator::Create(
4709 ReplaceStmt(DRE, PE);
4721 if (!Rewriter::isRewritable(LocStart) || !Rewriter::isRewritable(LocEnd))
4724 const char *startBuf =
SM->getCharacterData(LocStart);
4725 const char *endBuf =
SM->getCharacterData(LocEnd);
4728 if (isa<TypeOfExprType>(TypePtr)) {
4729 const TypeOfExprType *TypeOfExprTypePtr = cast<TypeOfExprType>(TypePtr);
4731 std::string TypeAsString =
"(";
4732 RewriteBlockPointerType(TypeAsString, QT);
4733 TypeAsString +=
")";
4734 ReplaceText(LocStart, endBuf-startBuf+1, TypeAsString);
4738 const char *argPtr = startBuf;
4740 while (*argPtr++ && (argPtr < endBuf)) {
4745 ReplaceText(LocStart, 1,
"*");
4751void RewriteModernObjC::RewriteImplicitCastObjCExpr(
CastExpr *IC) {
4753 if (
CastKind != CK_BlockPointerToObjCPointerCast &&
4754 CastKind != CK_AnyPointerToBlockPointerCast)
4758 (void)convertBlockPointerToFunctionPointer(QT);
4759 std::string TypeString(QT.
getAsString(Context->getPrintingPolicy()));
4760 std::string Str =
"(";
4766void RewriteModernObjC::RewriteBlockPointerFunctionArgs(
FunctionDecl *FD) {
4768 unsigned parenCount = 0;
4771 const char *startBuf =
SM->getCharacterData(DeclLoc);
4772 const char *startArgList = strchr(startBuf,
'(');
4774 assert((*startArgList ==
'(') &&
"Rewriter fuzzy parser confused");
4779 assert((DeclLoc.
isValid()) &&
"Invalid DeclLoc");
4781 const char *argPtr = startArgList;
4783 while (*argPtr++ && parenCount) {
4788 ReplaceText(DeclLoc, 1,
"*");
4800bool RewriteModernObjC::PointerTypeTakesAnyBlockArguments(
QualType QT) {
4807 assert(BPT &&
"BlockPointerTypeTakeAnyBlockArguments(): not a block pointer type");
4812 if (isTopLevelBlockPointerType(I))
4818bool RewriteModernObjC::PointerTypeTakesAnyObjCQualifiedType(
QualType QT) {
4825 assert(BPT &&
"BlockPointerTypeTakeAnyBlockArguments(): not a block pointer type");
4830 if (I->isObjCQualifiedIdType())
4832 if (I->isObjCObjectPointerType() &&
4833 I->getPointeeType()->isObjCQualifiedInterfaceType())
4841void RewriteModernObjC::GetExtentOfArgList(
const char *Name,
const char *&LParen,
4842 const char *&RParen) {
4843 const char *argPtr = strchr(Name,
'(');
4844 assert((*argPtr ==
'(') &&
"Rewriter fuzzy parser confused");
4848 unsigned parenCount = 1;
4850 while (*argPtr && parenCount) {
4852 case '(': parenCount++;
break;
4853 case ')': parenCount--;
break;
4856 if (parenCount) argPtr++;
4858 assert((*argPtr ==
')') &&
"Rewriter fuzzy parser confused");
4862void RewriteModernObjC::RewriteBlockPointerDecl(
NamedDecl *ND) {
4864 RewriteBlockPointerFunctionArgs(FD);
4870 if (
VarDecl *VD = dyn_cast<VarDecl>(ND))
4873 DeclT = TDD->getUnderlyingType();
4874 else if (
FieldDecl *FD = dyn_cast<FieldDecl>(ND))
4877 llvm_unreachable(
"RewriteBlockPointerDecl(): Decl type not yet handled");
4879 const char *startBuf =
SM->getCharacterData(DeclLoc);
4880 const char *endBuf = startBuf;
4882 while (*startBuf !=
'^' && *startBuf !=
';' && startBuf != MainFileStart)
4886 unsigned OrigLength=0;
4889 if (*startBuf ==
'^') {
4895 while (*startBuf !=
')') {
4903 if (PointerTypeTakesAnyBlockArguments(DeclT) ||
4904 PointerTypeTakesAnyObjCQualifiedType(DeclT)) {
4908 startBuf =
SM->getCharacterData(DeclLoc);
4909 const char *argListBegin, *argListEnd;
4910 GetExtentOfArgList(startBuf, argListBegin, argListEnd);
4911 while (argListBegin < argListEnd) {
4912 if (*argListBegin ==
'^')
4914 else if (*argListBegin ==
'<') {
4916 buf += *argListBegin++;
4918 while (*argListBegin !=
'>') {
4919 buf += *argListBegin++;
4922 buf += *argListBegin;
4926 buf += *argListBegin;
4933 ReplaceText(Start, OrigLength, buf);
4956std::string RewriteModernObjC::SynthesizeByrefCopyDestroyHelper(
VarDecl *VD,
4959 if (CopyDestroyCache.count(flag))
4961 CopyDestroyCache.insert(flag);
4962 S =
"static void __Block_byref_id_object_copy_";
4964 S +=
"(void *dst, void *src) {\n";
4969 static_cast<unsigned>(Context->getTypeSize(Context->IntTy));
4970 unsigned VoidPtrSize =
4971 static_cast<unsigned>(Context->getTypeSize(Context->VoidPtrTy));
4973 unsigned offset = (VoidPtrSize*4 + IntSize + IntSize)/Context->getCharWidth();
4974 S +=
" _Block_object_assign((char*)dst + ";
4975 S += utostr(offset);
4976 S +=
", *(void * *) ((char*)src + ";
4977 S += utostr(offset);
4982 S +=
"static void __Block_byref_id_object_dispose_";
4984 S +=
"(void *src) {\n";
4985 S +=
" _Block_object_dispose(*(void * *) ((char*)src + ";
4986 S += utostr(offset);
5011void RewriteModernObjC::RewriteByRefVar(
VarDecl *ND,
bool firstDecl,
5020 const char *startBuf =
SM->getCharacterData(DeclLoc);
5022 X =
SM->getExpansionLoc(
X);
5023 const char *endBuf =
SM->getCharacterData(
X);
5025 std::string ByrefType;
5026 RewriteByRefString(ByrefType, Name, ND,
true);
5027 ByrefType +=
" {\n";
5028 ByrefType +=
" void *__isa;\n";
5029 RewriteByRefString(ByrefType, Name, ND);
5030 ByrefType +=
" *__forwarding;\n";
5031 ByrefType +=
" int __flags;\n";
5032 ByrefType +=
" int __size;\n";
5036 bool HasCopyAndDispose = Context->BlockRequiresCopying(Ty, ND);
5037 if (HasCopyAndDispose) {
5038 ByrefType +=
" void (*__Block_byref_id_object_copy)(void*, void*);\n";
5039 ByrefType +=
" void (*__Block_byref_id_object_dispose)(void*);\n";
5043 (void)convertBlockPointerToFunctionPointer(T);
5046 ByrefType +=
" " + Name +
";\n";
5047 ByrefType +=
"};\n";
5051 FunLocStart = getFunctionSourceLocation(*
this, CurFunctionDef);
5053 assert(CurMethodDef &&
"RewriteByRefVar - CurMethodDef is null");
5056 InsertText(FunLocStart, ByrefType);
5062 if (HasCopyAndDispose) {
5070 std::string HF = SynthesizeByrefCopyDestroyHelper(ND, flag);
5078 bool hasInit = (ND->
getInit() !=
nullptr);
5089 if (HasCopyAndDispose)
5093 RewriteByRefString(ByrefType, Name, ND);
5094 std::string ForwardingCastType(
"(");
5095 ForwardingCastType += ByrefType +
" *)";
5096 ByrefType +=
" " + Name +
" = {(void*)";
5097 ByrefType += utostr(isa);
5098 ByrefType +=
"," + ForwardingCastType +
"&" + Name +
", ";
5099 ByrefType += utostr(flags);
5101 ByrefType +=
"sizeof(";
5102 RewriteByRefString(ByrefType, Name, ND);
5104 if (HasCopyAndDispose) {
5105 ByrefType +=
", __Block_byref_id_object_copy_";
5106 ByrefType += utostr(flag);
5107 ByrefType +=
", __Block_byref_id_object_dispose_";
5108 ByrefType += utostr(flag);
5116 const char *startDeclBuf =
SM->getCharacterData(DeclLoc);
5117 const char *commaBuf = startDeclBuf;
5118 while (*commaBuf !=
',')
5120 assert((*commaBuf ==
',') &&
"RewriteByRefVar: can't find ','");
5122 startBuf = commaBuf;
5126 ByrefType +=
"};\n";
5127 unsigned nameSize = Name.size();
5132 ReplaceText(DeclLoc, endBuf-startBuf+nameSize, ByrefType);
5139 startLoc = ECE->getLParenLoc();
5142 startLoc =
SM->getExpansionLoc(startLoc);
5143 endBuf =
SM->getCharacterData(startLoc);
5144 ReplaceText(DeclLoc, endBuf-startBuf, ByrefType);
5146 const char separator = lastDecl ?
';' :
',';
5147 const char *startInitializerBuf =
SM->getCharacterData(startLoc);
5148 const char *separatorBuf = strchr(startInitializerBuf, separator);
5149 assert((*separatorBuf == separator) &&
5150 "RewriteByRefVar: can't find ';' or ','");
5154 InsertText(separatorLoc, lastDecl ?
"}" :
"};\n");
5158void RewriteModernObjC::CollectBlockDeclRefInfo(
BlockExpr *Exp) {
5160 GetBlockDeclRefExprs(Exp->
getBody());
5161 if (BlockDeclRefs.size()) {
5163 for (
unsigned i = 0; i < BlockDeclRefs.size(); i++)
5164 if (!BlockDeclRefs[i]->getDecl()->hasAttr<BlocksAttr>()) {
5165 if (!BlockByCopyDeclsPtrSet.count(BlockDeclRefs[i]->getDecl())) {
5166 BlockByCopyDeclsPtrSet.insert(BlockDeclRefs[i]->getDecl());
5167 BlockByCopyDecls.push_back(BlockDeclRefs[i]->getDecl());
5171 for (
unsigned i = 0; i < BlockDeclRefs.size(); i++)
5172 if (BlockDeclRefs[i]->getDecl()->hasAttr<BlocksAttr>()) {
5173 if (!BlockByRefDeclsPtrSet.count(BlockDeclRefs[i]->getDecl())) {
5174 BlockByRefDeclsPtrSet.insert(BlockDeclRefs[i]->getDecl());
5175 BlockByRefDecls.push_back(BlockDeclRefs[i]->getDecl());
5179 for (
unsigned i = 0; i < BlockDeclRefs.size(); i++)
5180 if (BlockDeclRefs[i]->getDecl()->hasAttr<BlocksAttr>() ||
5181 BlockDeclRefs[i]->getType()->isObjCObjectPointerType() ||
5182 BlockDeclRefs[i]->getType()->isBlockPointerType())
5183 ImportedBlockDecls.insert(BlockDeclRefs[i]->getDecl());
5187FunctionDecl *RewriteModernObjC::SynthBlockInitFunctionDecl(StringRef name) {
5189 QualType FType = Context->getFunctionNoProtoType(Context->VoidPtrTy);
5199 Blocks.push_back(Exp);
5201 CollectBlockDeclRefInfo(Exp);
5204 int countOfInnerDecls = 0;
5205 if (!InnerBlockDeclRefs.empty()) {
5206 for (
unsigned i = 0; i < InnerBlockDeclRefs.size(); i++) {
5209 if (!VD->
hasAttr<BlocksAttr>() && !BlockByCopyDeclsPtrSet.count(VD)) {
5213 InnerDeclRefs.push_back(Exp); countOfInnerDecls++;
5214 BlockDeclRefs.push_back(Exp);
5215 BlockByCopyDeclsPtrSet.insert(VD);
5216 BlockByCopyDecls.push_back(VD);
5218 if (VD->
hasAttr<BlocksAttr>() && !BlockByRefDeclsPtrSet.count(VD)) {
5219 InnerDeclRefs.push_back(Exp); countOfInnerDecls++;
5220 BlockDeclRefs.push_back(Exp);
5221 BlockByRefDeclsPtrSet.insert(VD);
5222 BlockByRefDecls.push_back(VD);
5226 for (
unsigned i = 0; i < InnerBlockDeclRefs.size(); i++)
5227 if (InnerBlockDeclRefs[i]->getDecl()->hasAttr<BlocksAttr>() ||
5228 InnerBlockDeclRefs[i]->getType()->isObjCObjectPointerType() ||
5229 InnerBlockDeclRefs[i]->getType()->isBlockPointerType())
5230 ImportedBlockDecls.insert(InnerBlockDeclRefs[i]->getDecl());
5232 InnerDeclRefsCount.push_back(countOfInnerDecls);
5234 std::string FuncName;
5238 else if (CurMethodDef)
5239 BuildUniqueMethodName(FuncName, CurMethodDef);
5240 else if (GlobalVarDecl)
5243 bool GlobalBlockExpr =
5246 if (GlobalBlockExpr && !GlobalVarDecl) {
5248 GlobalBlockExpr =
false;
5251 std::string BlockNumber = utostr(Blocks.size()-1);
5253 std::string
Func =
"__" + FuncName +
"_block_func_" + BlockNumber;
5256 QualType BFT = convertFunctionTypeOfBlocks(Exp->getFunctionType());
5257 QualType FType = Context->getPointerType(BFT);
5265 if (GlobalBlockExpr)
5269 Tag += FuncName +
"_block_impl_" + BlockNumber;
5271 FD = SynthBlockInitFunctionDecl(Tag);
5278 FD = SynthBlockInitFunctionDecl(Func);
5283 InitExprs.push_back(castExpr);
5286 std::string DescData =
"__" + FuncName +
"_block_desc_" + BlockNumber +
"_DATA";
5288 VarDecl *NewVD = VarDecl::Create(
5290 &Context->Idents.get(DescData), Context->VoidPtrTy,
nullptr, SC_Static);
5293 new (Context)
DeclRefExpr(*Context, NewVD,
false, Context->VoidPtrTy,
5295 UO_AddrOf, Context->getPointerType(Context->VoidPtrTy), VK_PRValue,
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());
5310 if (HasLocalVariableExternalStorage(*I)) {
5312 QT = Context->getPointerType(QT);
5313 Exp = UnaryOperator::Create(
const_cast<ASTContext &
>(*Context), Exp,
5314 UO_AddrOf, QT, VK_PRValue, OK_Ordinary,
5318 }
else if (isTopLevelBlockPointerType((*I)->getType())) {
5319 FD = SynthBlockInitFunctionDecl((*I)->getName());
5322 Exp = NoTypeInfoCStyleCastExpr(Context, Context->VoidPtrTy,
5325 FD = SynthBlockInitFunctionDecl((*I)->getName());
5328 if (HasLocalVariableExternalStorage(*I)) {
5330 QT = Context->getPointerType(QT);
5331 Exp = UnaryOperator::Create(
const_cast<ASTContext &
>(*Context), Exp,
5332 UO_AddrOf, QT, VK_PRValue, OK_Ordinary,
5338 InitExprs.push_back(Exp);
5342 E = BlockByRefDecls.end(); I != E; ++I) {
5345 std::string RecName;
5346 RewriteByRefString(RecName, Name, ND,
true);
5348 +
sizeof(
"struct"));
5350 RecordDecl::Create(*Context, TagTypeKind::Struct, TUDecl,
5352 assert(RD &&
"SynthBlockInitExpr(): Can't find RecordDecl");
5353 QualType castT = Context->getPointerType(Context->getTagDeclType(RD));
5355 FD = SynthBlockInitFunctionDecl((*I)->getName());
5358 bool isNestedCapturedVar =
false;
5359 for (
const auto &CI : block->
captures()) {
5360 const VarDecl *variable = CI.getVariable();
5361 if (variable == ND && CI.isNested()) {
5362 assert(CI.isByRef() &&
5363 "SynthBlockInitExpr - captured block variable is not byref");
5364 isNestedCapturedVar =
true;
5370 if (!isNestedCapturedVar)
5371 Exp = UnaryOperator::Create(
5372 const_cast<ASTContext &
>(*Context), Exp, UO_AddrOf,
5373 Context->getPointerType(Exp->
getType()), VK_PRValue, OK_Ordinary,
5375 Exp = NoTypeInfoCStyleCastExpr(Context, castT, CK_BitCast, Exp);
5376 InitExprs.push_back(Exp);
5379 if (ImportedBlockDecls.size()) {
5383 static_cast<unsigned>(Context->getTypeSize(Context->IntTy));
5384 Expr *FlagExp = IntegerLiteral::Create(*Context, llvm::APInt(IntSize, flag),
5386 InitExprs.push_back(FlagExp);
5388 NewRep = CallExpr::Create(*Context, DRE, InitExprs, FType, VK_LValue,
5391 if (GlobalBlockExpr) {
5392 assert (!GlobalConstructionExp &&
5393 "SynthBlockInitExpr - GlobalConstructionExp must be null");
5394 GlobalConstructionExp = NewRep;
5398 NewRep = UnaryOperator::Create(
5399 const_cast<ASTContext &
>(*Context), NewRep, UO_AddrOf,
5400 Context->getPointerType(NewRep->
getType()), VK_PRValue, OK_Ordinary,
5402 NewRep = NoTypeInfoCStyleCastExpr(Context, FType, CK_BitCast,
5408 BlockDeclRefs.clear();
5409 BlockByRefDecls.clear();
5410 BlockByRefDeclsPtrSet.clear();
5411 BlockByCopyDecls.clear();
5412 BlockByCopyDeclsPtrSet.clear();
5413 ImportedBlockDecls.clear();
5417bool RewriteModernObjC::IsDeclStmtInForeachHeader(
DeclStmt *DS) {
5419 dyn_cast<ObjCForCollectionStmt>(Stmts.back()))
5420 return CS->getElement() == DS;
5428Stmt *RewriteModernObjC::RewriteFunctionBodyOrGlobalInitializer(
Stmt *S) {
5429 if (isa<SwitchStmt>(S) || isa<WhileStmt>(S) ||
5430 isa<DoStmt>(S) || isa<ForStmt>(S))
5432 else if (isa<ObjCForCollectionStmt>(S)) {
5434 ObjCBcLabelNo.push_back(++BcLabelCount);
5441 return RewritePropertyOrImplicitSetter(PseudoOp);
5443 return RewritePropertyOrImplicitGetter(PseudoOp);
5445 }
else if (
ObjCIvarRefExpr *IvarRefExpr = dyn_cast<ObjCIvarRefExpr>(S)) {
5446 return RewriteObjCIvarRefExpr(IvarRefExpr);
5448 else if (isa<OpaqueValueExpr>(S))
5449 S = cast<OpaqueValueExpr>(S)->getSourceExpr();
5454 for (
Stmt *&childStmt : S->children())
5456 Stmt *newStmt = RewriteFunctionBodyOrGlobalInitializer(childStmt);
5458 childStmt = newStmt;
5462 if (
BlockExpr *BE = dyn_cast<BlockExpr>(S)) {
5465 InnerContexts.insert(BE->getBlockDecl());
5466 ImportedLocalExternalDecls.clear();
5467 GetInnerBlockDeclRefExprs(BE->getBody(),
5468 InnerBlockDeclRefs, InnerContexts);
5470 Stmt *SaveCurrentBody = CurrentBody;
5471 CurrentBody = BE->getBody();
5472 PropParentMap =
nullptr;
5478 bool saveDisableReplaceStmt = DisableReplaceStmt;
5479 DisableReplaceStmt =
false;
5480 RewriteFunctionBodyOrGlobalInitializer(BE->getBody());
5481 DisableReplaceStmt = saveDisableReplaceStmt;
5482 CurrentBody = SaveCurrentBody;
5483 PropParentMap =
nullptr;
5484 ImportedLocalExternalDecls.clear();
5486 std::string Str =
Rewrite.getRewrittenText(BE->getSourceRange());
5487 RewrittenBlockExprs[BE] = Str;
5489 Stmt *blockTranscribed = SynthBlockInitExpr(BE, InnerBlockDeclRefs);
5492 ReplaceStmt(S, blockTranscribed);
5493 return blockTranscribed;
5497 return RewriteAtEncode(AtEncode);
5500 return RewriteAtSelector(AtSelector);
5503 return RewriteObjCStringLiteral(AtString);
5506 return RewriteObjCBoolLiteralExpr(BoolLitExpr);
5509 return RewriteObjCBoxedExpr(BoxedExpr);
5512 return RewriteObjCArrayLiteralExpr(ArrayLitExpr);
5515 dyn_cast<ObjCDictionaryLiteral>(S))
5516 return RewriteObjCDictionaryLiteralExpr(DictionaryLitExpr);
5524 const char *startBuf =
SM->getCharacterData(startLoc);
5525 const char *endBuf =
SM->getCharacterData(endLoc);
5527 std::string messString;
5528 messString +=
"// ";
5529 messString.append(startBuf, endBuf-startBuf+1);
5538 return RewriteMessageExpr(MessExpr);
5542 dyn_cast<ObjCAutoreleasePoolStmt>(S)) {
5543 return RewriteObjCAutoreleasePoolStmt(StmtAutoRelease);
5547 return RewriteObjCTryStmt(StmtTry);
5550 return RewriteObjCSynchronizedStmt(StmtTry);
5553 return RewriteObjCThrowStmt(StmtThrow);
5556 return RewriteObjCProtocolExpr(ProtocolExp);
5559 dyn_cast<ObjCForCollectionStmt>(S))
5560 return RewriteObjCForCollectionStmt(StmtForCollection,
5563 dyn_cast<BreakStmt>(S))
5564 return RewriteBreakStmt(StmtBreakStmt);
5566 dyn_cast<ContinueStmt>(S))
5567 return RewriteContinueStmt(StmtContinueStmt);
5571 if (
DeclStmt *DS = dyn_cast<DeclStmt>(S)) {
5581 if (Stmts.empty() || !IsDeclStmtInForeachHeader(DS))
5582 RewriteObjCQualifiedInterfaceTypes(*DS->
decl_begin());
5588 if (
ValueDecl *ND = dyn_cast<ValueDecl>(SD)) {
5589 if (isTopLevelBlockPointerType(ND->
getType()))
5590 RewriteBlockPointerDecl(ND);
5592 CheckFunctionPointerDecl(ND->
getType(), ND);
5593 if (
VarDecl *VD = dyn_cast<VarDecl>(SD)) {
5594 if (VD->
hasAttr<BlocksAttr>()) {
5595 static unsigned uniqueByrefDeclCount = 0;
5596 assert(!BlockByRefDeclNo.count(ND) &&
5597 "RewriteFunctionBodyOrGlobalInitializer: Duplicate byref decl");
5598 BlockByRefDeclNo[ND] = uniqueByrefDeclCount++;
5599 RewriteByRefVar(VD, (DI == DS->
decl_begin()), ((DI+1) == DE));
5602 RewriteTypeOfDecl(VD);
5606 if (isTopLevelBlockPointerType(TD->getUnderlyingType()))
5607 RewriteBlockPointerDecl(TD);
5609 CheckFunctionPointerDecl(TD->getUnderlyingType(), TD);
5615 RewriteObjCQualifiedInterfaceTypes(CE);
5617 if (isa<SwitchStmt>(S) || isa<WhileStmt>(S) ||
5618 isa<DoStmt>(S) || isa<ForStmt>(S)) {
5619 assert(!Stmts.empty() &&
"Statement stack is empty");
5620 assert ((isa<SwitchStmt>(Stmts.back()) || isa<WhileStmt>(Stmts.back()) ||
5621 isa<DoStmt>(Stmts.back()) || isa<ForStmt>(Stmts.back()))
5622 &&
"Statement stack mismatch");
5626 if (
DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(S)) {
5628 if (VD->
hasAttr<BlocksAttr>())
5629 return RewriteBlockDeclRefExpr(DRE);
5630 if (HasLocalVariableExternalStorage(VD))
5631 return RewriteLocalVariableExternalStorage(DRE);
5634 if (
CallExpr *CE = dyn_cast<CallExpr>(S)) {
5636 Stmt *BlockCall = SynthesizeBlockCall(CE, CE->getCallee());
5637 ReplaceStmt(S, BlockCall);
5642 RewriteCastExpr(CE);
5645 RewriteImplicitCastObjCExpr(ICE);
5655 llvm::raw_string_ostream Buf(SStr);
5656 Replacement->printPretty(Buf);
5657 const std::string &Str = Buf.str();
5659 printf(
"CAST = %s\n", &Str[0]);
5669void RewriteModernObjC::RewriteRecordBody(
RecordDecl *RD) {
5670 for (
auto *FD : RD->
fields()) {
5671 if (isTopLevelBlockPointerType(FD->
getType()))
5672 RewriteBlockPointerDecl(FD);
5675 RewriteObjCQualifiedInterfaceTypes(FD);
5681void RewriteModernObjC::HandleDeclInMainFile(
Decl *D) {
5683 case Decl::Function: {
5691 RewriteBlocksInFunctionProtoType(FD->
getType(), FD);
5698 CurFunctionDef = FD;
5701 cast_or_null<CompoundStmt>(RewriteFunctionBodyOrGlobalInitializer(Body));
5703 CurrentBody =
nullptr;
5704 if (PropParentMap) {
5705 delete PropParentMap;
5706 PropParentMap =
nullptr;
5710 InsertBlockLiteralsWithinFunction(FD);
5711 RewriteLineDirective(D);
5712 CurFunctionDef =
nullptr;
5716 case Decl::ObjCMethod: {
5722 cast_or_null<CompoundStmt>(RewriteFunctionBodyOrGlobalInitializer(Body));
5724 CurrentBody =
nullptr;
5725 if (PropParentMap) {
5726 delete PropParentMap;
5727 PropParentMap =
nullptr;
5729 InsertBlockLiteralsWithinMethod(MD);
5730 RewriteLineDirective(D);
5731 CurMethodDef =
nullptr;
5735 case Decl::ObjCImplementation: {
5737 ClassImplementation.push_back(CI);
5740 case Decl::ObjCCategoryImpl: {
5742 CategoryImplementation.push_back(CI);
5746 VarDecl *VD = cast<VarDecl>(D);
5747 RewriteObjCQualifiedInterfaceTypes(VD);
5748 if (isTopLevelBlockPointerType(VD->
getType()))
5749 RewriteBlockPointerDecl(VD);
5751 CheckFunctionPointerDecl(VD->
getType(), VD);
5754 RewriteCastExpr(CE);
5760 RewriteRecordBody(RD);
5765 RewriteFunctionBodyOrGlobalInitializer(VD->
getInit());
5766 CurrentBody =
nullptr;
5767 if (PropParentMap) {
5768 delete PropParentMap;
5769 PropParentMap =
nullptr;
5772 GlobalVarDecl =
nullptr;
5776 RewriteCastExpr(CE);
5781 case Decl::TypeAlias:
5782 case Decl::Typedef: {
5784 if (isTopLevelBlockPointerType(TD->getUnderlyingType()))
5785 RewriteBlockPointerDecl(TD);
5787 CheckFunctionPointerDecl(TD->getUnderlyingType(), TD);
5789 RewriteObjCQualifiedInterfaceTypes(TD);
5793 case Decl::CXXRecord:
5794 case Decl::Record: {
5797 RewriteRecordBody(RD);
5809static void Write_ProtocolExprReferencedMetadata(
ASTContext *Context,
5811 std::string &Result) {
5813 if (Context->getLangOpts().MicrosoftExt)
5814 Result +=
"static ";
5815 Result +=
"struct _protocol_t *";
5816 Result +=
"_OBJC_PROTOCOL_REFERENCE_$_";
5823void RewriteModernObjC::HandleTranslationUnit(
ASTContext &C) {
5829 for (
unsigned i = 0, e = FunctionDefinitionsSeen.size(); i < e; i++) {
5834 HandleTopLevelSingleDecl(FDecl);
5840 RewriteObjCProtocolMetaData(ProtDecl, Preamble);
5841 Write_ProtocolExprReferencedMetadata(Context, ProtDecl, Preamble);
5844 InsertText(
SM->getLocForStartOfFile(MainFileID), Preamble,
false);
5846 if (ClassImplementation.size() || CategoryImplementation.size())
5847 RewriteImplementations();
5849 for (
unsigned i = 0, e = ObjCInterfacesSeen.size(); i < e; i++) {
5855 RewriteInterfaceDecl(CDecl);
5861 Rewrite.getRewriteBufferFor(MainFileID)) {
5863 *OutFile << std::string(RewriteBuf->begin(), RewriteBuf->end());
5865 llvm::errs() <<
"No changes\n";
5868 if (ClassImplementation.size() || CategoryImplementation.size() ||
5869 ProtocolExprDecls.size()) {
5871 std::string ResultStr;
5872 RewriteMetaDataIntoBuffer(ResultStr);
5874 *OutFile << ResultStr;
5878 std::string ResultStr;
5879 WriteImageInfo(ResultStr);
5880 *OutFile << ResultStr;
5885void RewriteModernObjC::Initialize(
ASTContext &context) {
5886 InitializeCommon(context);
5896 Preamble +=
"struct objc_selector; struct objc_class;\n";
5897 Preamble +=
"struct __rw_objc_super { \n\tstruct objc_object *object; ";
5898 Preamble +=
"\n\tstruct objc_object *superClass; ";
5900 Preamble +=
"\n\t__rw_objc_super(struct objc_object *o, struct objc_object *s) ";
5901 Preamble +=
": object(o), superClass(s) {} ";
5904 if (LangOpts.MicrosoftExt) {
5907 Preamble +=
"\n#pragma section(\".objc_classlist$B\", long, read, write)\n";
5908 Preamble +=
"#pragma section(\".objc_catlist$B\", long, read, write)\n";
5909 Preamble +=
"#pragma section(\".objc_imageinfo$B\", long, read, write)\n";
5910 Preamble +=
"#pragma section(\".objc_nlclslist$B\", long, read, write)\n";
5911 Preamble +=
"#pragma section(\".objc_nlcatlist$B\", long, read, write)\n";
5913 Preamble +=
"#pragma section(\".cat_cls_meth$B\", long, read, write)\n";
5914 Preamble +=
"#pragma section(\".inst_meth$B\", long, read, write)\n";
5915 Preamble +=
"#pragma section(\".cls_meth$B\", long, read, write)\n";
5916 Preamble +=
"#pragma section(\".objc_ivar$B\", long, read, write)\n";
5920 Preamble +=
"#pragma section(\".objc_selrefs$B\", long, read, write)\n";
5921 Preamble +=
"#pragma section(\".objc_classrefs$B\", long, read, write)\n";
5922 Preamble +=
"#pragma section(\".objc_superrefs$B\", long, read, write)\n";
5925 Preamble +=
"#ifndef _REWRITER_typedef_Protocol\n";
5926 Preamble +=
"typedef struct objc_object Protocol;\n";
5927 Preamble +=
"#define _REWRITER_typedef_Protocol\n";
5929 if (LangOpts.MicrosoftExt) {
5930 Preamble +=
"#define __OBJC_RW_DLLIMPORT extern \"C\" __declspec(dllimport)\n";
5931 Preamble +=
"#define __OBJC_RW_STATICIMPORT extern \"C\"\n";
5934 Preamble +=
"#define __OBJC_RW_DLLIMPORT extern\n";
5936 Preamble +=
"__OBJC_RW_DLLIMPORT void objc_msgSend(void);\n";
5937 Preamble +=
"__OBJC_RW_DLLIMPORT void objc_msgSendSuper(void);\n";
5938 Preamble +=
"__OBJC_RW_DLLIMPORT void objc_msgSend_stret(void);\n";
5939 Preamble +=
"__OBJC_RW_DLLIMPORT void objc_msgSendSuper_stret(void);\n";
5940 Preamble +=
"__OBJC_RW_DLLIMPORT void objc_msgSend_fpret(void);\n";
5942 Preamble +=
"__OBJC_RW_DLLIMPORT struct objc_class *objc_getClass";
5944 Preamble +=
"__OBJC_RW_DLLIMPORT struct objc_class *class_getSuperclass";
5945 Preamble +=
"(struct objc_class *);\n";
5946 Preamble +=
"__OBJC_RW_DLLIMPORT struct objc_class *objc_getMetaClass";
5948 Preamble +=
"__OBJC_RW_DLLIMPORT void objc_exception_throw( struct objc_object *);\n";
5950 Preamble +=
"__OBJC_RW_DLLIMPORT int objc_sync_enter( struct objc_object *);\n";
5951 Preamble +=
"__OBJC_RW_DLLIMPORT int objc_sync_exit( struct objc_object *);\n";
5952 Preamble +=
"__OBJC_RW_DLLIMPORT Protocol *objc_getProtocol(const char *);\n";
5954 Preamble +=
"typedef unsigned long long _WIN_NSUInteger;\n";
5956 Preamble +=
"typedef unsigned int _WIN_NSUInteger;\n";
5958 Preamble +=
"#ifndef __FASTENUMERATIONSTATE\n";
5959 Preamble +=
"struct __objcFastEnumerationState {\n\t";
5960 Preamble +=
"unsigned long state;\n\t";
5961 Preamble +=
"void **itemsPtr;\n\t";
5962 Preamble +=
"unsigned long *mutationsPtr;\n\t";
5963 Preamble +=
"unsigned long extra[5];\n};\n";
5964 Preamble +=
"__OBJC_RW_DLLIMPORT void objc_enumerationMutation(struct objc_object *);\n";
5965 Preamble +=
"#define __FASTENUMERATIONSTATE\n";
5967 Preamble +=
"#ifndef __NSCONSTANTSTRINGIMPL\n";
5968 Preamble +=
"struct __NSConstantStringImpl {\n";
5973 Preamble +=
" long long length;\n";
5978 Preamble +=
"#ifdef CF_EXPORT_CONSTANT_STRING\n";
5979 Preamble +=
"extern \"C\" __declspec(dllexport) int __CFConstantStringClassReference[];\n";
5981 Preamble +=
"__OBJC_RW_DLLIMPORT int __CFConstantStringClassReference[];\n";
5983 Preamble +=
"#define __NSCONSTANTSTRINGIMPL\n";
5986 Preamble +=
"#ifndef BLOCK_IMPL\n";
5987 Preamble +=
"#define BLOCK_IMPL\n";
5988 Preamble +=
"struct __block_impl {\n";
5994 Preamble +=
"// Runtime copy/destroy helper functions (from Block_private.h)\n";
5995 Preamble +=
"#ifdef __OBJC_EXPORT_BLOCKS\n";
5996 Preamble +=
"extern \"C\" __declspec(dllexport) "
5997 "void _Block_object_assign(void *, const void *, const int);\n";
5998 Preamble +=
"extern \"C\" __declspec(dllexport) void _Block_object_dispose(const void *, const int);\n";
5999 Preamble +=
"extern \"C\" __declspec(dllexport) void *_NSConcreteGlobalBlock[32];\n";
6000 Preamble +=
"extern \"C\" __declspec(dllexport) void *_NSConcreteStackBlock[32];\n";
6002 Preamble +=
"__OBJC_RW_DLLIMPORT void _Block_object_assign(void *, const void *, const int);\n";
6003 Preamble +=
"__OBJC_RW_DLLIMPORT void _Block_object_dispose(const void *, const int);\n";
6004 Preamble +=
"__OBJC_RW_DLLIMPORT void *_NSConcreteGlobalBlock[32];\n";
6005 Preamble +=
"__OBJC_RW_DLLIMPORT void *_NSConcreteStackBlock[32];\n";
6008 if (LangOpts.MicrosoftExt) {
6009 Preamble +=
"#undef __OBJC_RW_DLLIMPORT\n";
6010 Preamble +=
"#undef __OBJC_RW_STATICIMPORT\n";
6011 Preamble +=
"#ifndef KEEP_ATTRIBUTES\n";
6012 Preamble +=
"#define __attribute__(X)\n";
6027 Preamble +=
"\n#include <stdarg.h>\n";
6028 Preamble +=
"struct __NSContainer_literal {\n";
6030 Preamble +=
" __NSContainer_literal (unsigned int count, ...) {\n";
6032 Preamble +=
"\tva_start(marker, count);\n";
6033 Preamble +=
"\tarr = new void *[count];\n";
6034 Preamble +=
"\tfor (unsigned i = 0; i < count; i++)\n";
6035 Preamble +=
"\t arr[i] = va_arg(marker, void *);\n";
6036 Preamble +=
"\tva_end( marker );\n";
6038 Preamble +=
" ~__NSContainer_literal() {\n";
6044 Preamble +=
"extern \"C\" __declspec(dllimport) void * objc_autoreleasePoolPush(void);\n";
6045 Preamble +=
"extern \"C\" __declspec(dllimport) void objc_autoreleasePoolPop(void *);\n\n";
6046 Preamble +=
"struct __AtAutoreleasePool {\n";
6047 Preamble +=
" __AtAutoreleasePool() {atautoreleasepoolobj = objc_autoreleasePoolPush();}\n";
6048 Preamble +=
" ~__AtAutoreleasePool() {objc_autoreleasePoolPop(atautoreleasepoolobj);}\n";
6049 Preamble +=
" void * atautoreleasepoolobj;\n";
6054 Preamble +=
"\n#define __OFFSETOFIVAR__(TYPE, MEMBER) ((long long) &((TYPE *)0)->MEMBER)\n";
6059void RewriteModernObjC::RewriteIvarOffsetComputation(
ObjCIvarDecl *ivar,
6060 std::string &Result) {
6061 Result +=
"__OFFSETOFIVAR__(struct ";
6063 if (LangOpts.MicrosoftExt)
6067 ObjCIvarBitfieldGroupDecl(ivar, Result);
6175static void WriteModernMetadataDeclarations(
ASTContext *Context, std::string &Result) {
6176 static bool meta_data_declared =
false;
6177 if (meta_data_declared)
6180 Result +=
"\nstruct _prop_t {\n";
6181 Result +=
"\tconst char *name;\n";
6182 Result +=
"\tconst char *attributes;\n";
6185 Result +=
"\nstruct _protocol_t;\n";
6187 Result +=
"\nstruct _objc_method {\n";
6188 Result +=
"\tstruct objc_selector * _cmd;\n";
6189 Result +=
"\tconst char *method_type;\n";
6190 Result +=
"\tvoid *_imp;\n";
6193 Result +=
"\nstruct _protocol_t {\n";
6194 Result +=
"\tvoid * isa; // NULL\n";
6195 Result +=
"\tconst char *protocol_name;\n";
6196 Result +=
"\tconst struct _protocol_list_t * protocol_list; // super protocols\n";
6197 Result +=
"\tconst struct method_list_t *instance_methods;\n";
6198 Result +=
"\tconst struct method_list_t *class_methods;\n";
6199 Result +=
"\tconst struct method_list_t *optionalInstanceMethods;\n";
6200 Result +=
"\tconst struct method_list_t *optionalClassMethods;\n";
6201 Result +=
"\tconst struct _prop_list_t * properties;\n";
6202 Result +=
"\tconst unsigned int size; // sizeof(struct _protocol_t)\n";
6203 Result +=
"\tconst unsigned int flags; // = 0\n";
6204 Result +=
"\tconst char ** extendedMethodTypes;\n";
6207 Result +=
"\nstruct _ivar_t {\n";
6208 Result +=
"\tunsigned long int *offset; // pointer to ivar offset location\n";
6209 Result +=
"\tconst char *name;\n";
6210 Result +=
"\tconst char *type;\n";
6211 Result +=
"\tunsigned int alignment;\n";
6212 Result +=
"\tunsigned int size;\n";
6215 Result +=
"\nstruct _class_ro_t {\n";
6216 Result +=
"\tunsigned int flags;\n";
6217 Result +=
"\tunsigned int instanceStart;\n";
6218 Result +=
"\tunsigned int instanceSize;\n";
6219 const llvm::Triple &Triple(Context->getTargetInfo().getTriple());
6220 if (Triple.getArch() == llvm::Triple::x86_64)
6221 Result +=
"\tunsigned int reserved;\n";
6222 Result +=
"\tconst unsigned char *ivarLayout;\n";
6223 Result +=
"\tconst char *name;\n";
6224 Result +=
"\tconst struct _method_list_t *baseMethods;\n";
6225 Result +=
"\tconst struct _objc_protocol_list *baseProtocols;\n";
6226 Result +=
"\tconst struct _ivar_list_t *ivars;\n";
6227 Result +=
"\tconst unsigned char *weakIvarLayout;\n";
6228 Result +=
"\tconst struct _prop_list_t *properties;\n";
6231 Result +=
"\nstruct _class_t {\n";
6232 Result +=
"\tstruct _class_t *isa;\n";
6233 Result +=
"\tstruct _class_t *superclass;\n";
6234 Result +=
"\tvoid *cache;\n";
6235 Result +=
"\tvoid *vtable;\n";
6236 Result +=
"\tstruct _class_ro_t *ro;\n";
6239 Result +=
"\nstruct _category_t {\n";
6240 Result +=
"\tconst char *name;\n";
6241 Result +=
"\tstruct _class_t *cls;\n";
6242 Result +=
"\tconst struct _method_list_t *instance_methods;\n";
6243 Result +=
"\tconst struct _method_list_t *class_methods;\n";
6244 Result +=
"\tconst struct _protocol_list_t *protocols;\n";
6245 Result +=
"\tconst struct _prop_list_t *properties;\n";
6248 Result +=
"extern \"C\" __declspec(dllimport) struct objc_cache _objc_empty_cache;\n";
6249 Result +=
"#pragma warning(disable:4273)\n";
6250 meta_data_declared =
true;
6253static void Write_protocol_list_t_TypeDecl(std::string &Result,
6254 long super_protocol_count) {
6255 Result +=
"struct /*_protocol_list_t*/"; Result +=
" {\n";
6256 Result +=
"\tlong protocol_count; // Note, this is 32/64 bit\n";
6257 Result +=
"\tstruct _protocol_t *super_protocols[";
6258 Result += utostr(super_protocol_count); Result +=
"];\n";
6262static void Write_method_list_t_TypeDecl(std::string &Result,
6263 unsigned int method_count) {
6264 Result +=
"struct /*_method_list_t*/"; Result +=
" {\n";
6265 Result +=
"\tunsigned int entsize; // sizeof(struct _objc_method)\n";
6266 Result +=
"\tunsigned int method_count;\n";
6267 Result +=
"\tstruct _objc_method method_list[";
6268 Result += utostr(method_count); Result +=
"];\n";
6272static void Write__prop_list_t_TypeDecl(std::string &Result,
6273 unsigned int property_count) {
6274 Result +=
"struct /*_prop_list_t*/"; Result +=
" {\n";
6275 Result +=
"\tunsigned int entsize; // sizeof(struct _prop_t)\n";
6276 Result +=
"\tunsigned int count_of_properties;\n";
6277 Result +=
"\tstruct _prop_t prop_list[";
6278 Result += utostr(property_count); Result +=
"];\n";
6282static void Write__ivar_list_t_TypeDecl(std::string &Result,
6283 unsigned int ivar_count) {
6284 Result +=
"struct /*_ivar_list_t*/"; Result +=
" {\n";
6285 Result +=
"\tunsigned int entsize; // sizeof(struct _prop_t)\n";
6286 Result +=
"\tunsigned int count;\n";
6287 Result +=
"\tstruct _ivar_t ivar_list[";
6288 Result += utostr(ivar_count); Result +=
"];\n";
6292static void Write_protocol_list_initializer(
ASTContext *Context, std::string &Result,
6295 StringRef ProtocolName) {
6296 if (SuperProtocols.size() > 0) {
6297 Result +=
"\nstatic ";
6298 Write_protocol_list_t_TypeDecl(Result, SuperProtocols.size());
6299 Result +=
" "; Result += VarName;
6300 Result += ProtocolName;
6301 Result +=
" __attribute__ ((used, section (\"__DATA,__objc_const\"))) = {\n";
6302 Result +=
"\t"; Result += utostr(SuperProtocols.size()); Result +=
",\n";
6303 for (
unsigned i = 0, e = SuperProtocols.size(); i < e; i++) {
6305 Result +=
"\t&"; Result +=
"_OBJC_PROTOCOL_";
6315static void Write_method_list_t_initializer(RewriteModernObjC &RewriteObj,
6319 StringRef TopLevelDeclName,
6321 if (Methods.size() > 0) {
6322 Result +=
"\nstatic ";
6323 Write_method_list_t_TypeDecl(Result, Methods.size());
6324 Result +=
" "; Result += VarName;
6325 Result += TopLevelDeclName;
6326 Result +=
" __attribute__ ((used, section (\"__DATA,__objc_const\"))) = {\n";
6327 Result +=
"\t"; Result +=
"sizeof(_objc_method)"; Result +=
",\n";
6328 Result +=
"\t"; Result += utostr(Methods.size()); Result +=
",\n";
6329 for (
unsigned i = 0, e = Methods.size(); i < e; i++) {
6332 Result +=
"\t{{(struct objc_selector *)\"";
6334 Result +=
"\t{(struct objc_selector *)\"";
6335 Result += (MD)->getSelector().getAsString(); Result +=
"\"";
6337 std::string MethodTypeString = Context->getObjCEncodingForMethodDecl(MD);
6338 Result +=
"\""; Result += MethodTypeString; Result +=
"\"";
6343 Result +=
"(void *)";
6344 Result += RewriteObj.MethodInternalNames[MD];
6355static void Write_prop_list_t_initializer(RewriteModernObjC &RewriteObj,
6358 const Decl *Container,
6360 StringRef ProtocolName) {
6361 if (Properties.size() > 0) {
6362 Result +=
"\nstatic ";
6363 Write__prop_list_t_TypeDecl(Result, Properties.size());
6364 Result +=
" "; Result += VarName;
6365 Result += ProtocolName;
6366 Result +=
" __attribute__ ((used, section (\"__DATA,__objc_const\"))) = {\n";
6367 Result +=
"\t"; Result +=
"sizeof(_prop_t)"; Result +=
",\n";
6368 Result +=
"\t"; Result += utostr(Properties.size()); Result +=
",\n";
6369 for (
unsigned i = 0, e = Properties.size(); i < e; i++) {
6375 Result += PropDecl->
getName(); Result +=
"\",";
6376 std::string PropertyTypeString =
6377 Context->getObjCEncodingForPropertyDecl(PropDecl, Container);
6378 std::string QuotePropertyTypeString;
6379 RewriteObj.QuoteDoublequotes(PropertyTypeString, QuotePropertyTypeString);
6380 Result +=
"\""; Result += QuotePropertyTypeString; Result +=
"\"";
6395 OBJC2_CLS_HIDDEN = 0x10,
6396 CLS_EXCEPTION = 0x20,
6399 CLS_HAS_IVAR_RELEASER = 0x40,
6401 CLS_COMPILED_BY_ARC = 0x80
6404static void Write__class_ro_t_initializer(
ASTContext *Context, std::string &Result,
6406 const std::string &InstanceStart,
6407 const std::string &InstanceSize,
6413 StringRef ClassName) {
6414 Result +=
"\nstatic struct _class_ro_t ";
6415 Result += VarName; Result += ClassName;
6416 Result +=
" __attribute__ ((used, section (\"__DATA,__objc_const\"))) = {\n";
6418 Result += llvm::utostr(flags); Result +=
", ";
6419 Result += InstanceStart; Result +=
", ";
6420 Result += InstanceSize; Result +=
", \n";
6422 const llvm::Triple &Triple(Context->getTargetInfo().getTriple());
6423 if (Triple.getArch() == llvm::Triple::x86_64)
6425 Result +=
"(unsigned int)0, \n\t";
6427 Result +=
"0, \n\t";
6428 Result +=
"\""; Result += ClassName; Result +=
"\",\n\t";
6429 bool metaclass = ((flags & CLS_META) != 0);
6430 if (baseMethods.size() > 0) {
6431 Result +=
"(const struct _method_list_t *)&";
6433 Result +=
"_OBJC_$_CLASS_METHODS_";
6435 Result +=
"_OBJC_$_INSTANCE_METHODS_";
6436 Result += ClassName;
6440 Result +=
"0, \n\t";
6442 if (!metaclass && baseProtocols.size() > 0) {
6443 Result +=
"(const struct _objc_protocol_list *)&";
6444 Result +=
"_OBJC_CLASS_PROTOCOLS_$_"; Result += ClassName;
6448 Result +=
"0, \n\t";
6450 if (!metaclass && ivars.size() > 0) {
6451 Result +=
"(const struct _ivar_list_t *)&";
6452 Result +=
"_OBJC_$_INSTANCE_VARIABLES_"; Result += ClassName;
6456 Result +=
"0, \n\t";
6459 Result +=
"0, \n\t";
6460 if (!metaclass && Properties.size() > 0) {
6461 Result +=
"(const struct _prop_list_t *)&";
6462 Result +=
"_OBJC_$_PROP_LIST_"; Result += ClassName;
6471static void Write_class_t(
ASTContext *Context, std::string &Result,
6485 if (metaclass && rootClass) {
6488 Result +=
"extern \"C\" ";
6490 Result +=
"__declspec(dllexport) ";
6492 Result +=
"__declspec(dllimport) ";
6494 Result +=
"struct _class_t OBJC_CLASS_$_";
6502 Result +=
"extern \"C\" ";
6504 Result +=
"__declspec(dllexport) ";
6506 Result +=
"__declspec(dllimport) ";
6508 Result +=
"struct _class_t ";
6513 if (metaclass && RootClass != SuperClass) {
6514 Result +=
"extern \"C\" ";
6516 Result +=
"__declspec(dllexport) ";
6518 Result +=
"__declspec(dllimport) ";
6520 Result +=
"struct _class_t ";
6527 Result +=
"\nextern \"C\" __declspec(dllexport) struct _class_t ";
6529 Result +=
" __attribute__ ((used, section (\"__DATA,__objc_data\"))) = {\n";
6533 Result +=
"0, // &"; Result += VarName;
6536 Result +=
"0, // &"; Result += VarName;
6541 Result +=
"0, // &"; Result += VarName;
6549 Result +=
"0, // &OBJC_METACLASS_$_";
6553 Result +=
"0, // &"; Result += VarName;
6560 Result +=
"0, // (void *)&_objc_empty_cache,\n\t";
6561 Result +=
"0, // unused, was (void *)&_objc_empty_vtable,\n\t";
6563 Result +=
"&_OBJC_METACLASS_RO_$_";
6565 Result +=
"&_OBJC_CLASS_RO_$_";
6567 Result +=
",\n};\n";
6577 Result +=
"static void OBJC_CLASS_SETUP_$_";
6579 Result +=
"(void ) {\n";
6581 Result +=
".isa = "; Result +=
"&OBJC_METACLASS_$_";
6585 Result +=
".superclass = ";
6587 Result +=
"&OBJC_CLASS_$_";
6589 Result +=
"&OBJC_METACLASS_$_";
6594 Result +=
".cache = "; Result +=
"&_objc_empty_cache"; Result +=
";\n";
6597 Result +=
".isa = "; Result +=
"&OBJC_METACLASS_$_";
6602 Result +=
".superclass = "; Result +=
"&OBJC_CLASS_$_";
6607 Result +=
".cache = "; Result +=
"&_objc_empty_cache"; Result +=
";\n";
6611static void Write_category_t(RewriteModernObjC &RewriteObj,
ASTContext *Context,
6612 std::string &Result,
6619 StringRef CatName = CatDecl->
getName();
6620 StringRef ClassName = ClassDecl->
getName();
6624 Result +=
"extern \"C\" ";
6626 Result +=
"__declspec(dllexport) ";
6628 Result +=
"__declspec(dllimport) ";
6630 Result +=
"struct _class_t ";
6631 Result +=
"OBJC_CLASS_$_"; Result += ClassName;
6634 Result +=
"\nstatic struct _category_t ";
6635 Result +=
"_OBJC_$_CATEGORY_";
6636 Result += ClassName; Result +=
"_$_"; Result += CatName;
6637 Result +=
" __attribute__ ((used, section (\"__DATA,__objc_const\"))) = \n";
6639 Result +=
"\t\""; Result += ClassName; Result +=
"\",\n";
6640 Result +=
"\t0, // &"; Result +=
"OBJC_CLASS_$_"; Result += ClassName;
6642 if (InstanceMethods.size() > 0) {
6643 Result +=
"\t(const struct _method_list_t *)&";
6644 Result +=
"_OBJC_$_CATEGORY_INSTANCE_METHODS_";
6645 Result += ClassName; Result +=
"_$_"; Result += CatName;
6651 if (ClassMethods.size() > 0) {
6652 Result +=
"\t(const struct _method_list_t *)&";
6653 Result +=
"_OBJC_$_CATEGORY_CLASS_METHODS_";
6654 Result += ClassName; Result +=
"_$_"; Result += CatName;
6660 if (RefedProtocols.size() > 0) {
6661 Result +=
"\t(const struct _protocol_list_t *)&";
6662 Result +=
"_OBJC_CATEGORY_PROTOCOLS_$_";
6663 Result += ClassName; Result +=
"_$_"; Result += CatName;
6669 if (ClassProperties.size() > 0) {
6670 Result +=
"\t(const struct _prop_list_t *)&"; Result +=
"_OBJC_$_PROP_LIST_";
6671 Result += ClassName; Result +=
"_$_"; Result += CatName;
6680 Result +=
"static void OBJC_CATEGORY_SETUP_$_";
6684 Result +=
"(void ) {\n";
6685 Result +=
"\t_OBJC_$_CATEGORY_";
6689 Result +=
".cls = "; Result +=
"&OBJC_CLASS_$_"; Result += ClassName;
6693static void Write__extendedMethodTypes_initializer(RewriteModernObjC &RewriteObj,
6697 StringRef ProtocolName) {
6698 if (Methods.size() == 0)
6701 Result +=
"\nstatic const char *";
6702 Result += VarName; Result += ProtocolName;
6703 Result +=
" [] __attribute__ ((used, section (\"__DATA,__objc_const\"))) = \n";
6705 for (
unsigned i = 0, e = Methods.size(); i < e; i++) {
6707 std::string MethodTypeString =
6708 Context->getObjCEncodingForMethodDecl(MD,
true);
6709 std::string QuoteMethodTypeString;
6710 RewriteObj.QuoteDoublequotes(MethodTypeString, QuoteMethodTypeString);
6711 Result +=
"\t\""; Result += QuoteMethodTypeString; Result +=
"\"";
6720static void Write_IvarOffsetVar(RewriteModernObjC &RewriteObj,
6722 std::string &Result,
6737 for (
unsigned i =0, e = Ivars.size(); i < e; i++) {
6739 if (Context->getLangOpts().MicrosoftExt)
6740 Result +=
"__declspec(allocate(\".objc_ivar$B\")) ";
6742 if (!Context->getLangOpts().MicrosoftExt ||
6745 Result +=
"extern \"C\" unsigned long int ";
6747 Result +=
"extern \"C\" __declspec(dllexport) unsigned long int ";
6748 if (Ivars[i]->isBitField())
6749 RewriteObj.ObjCIvarBitfieldGroupOffset(IvarDecl, Result);
6751 WriteInternalIvarName(CDecl, IvarDecl, Result);
6752 Result +=
" __attribute__ ((used, section (\"__DATA,__objc_ivar\")))";
6754 RewriteObj.RewriteIvarOffsetComputation(IvarDecl, Result);
6756 if (Ivars[i]->isBitField()) {
6758 SKIP_BITFIELDS(i , e, Ivars);
6763static void Write__ivar_list_t_initializer(RewriteModernObjC &RewriteObj,
6768 if (OriginalIvars.size() > 0) {
6769 Write_IvarOffsetVar(RewriteObj, Context, Result, OriginalIvars, CDecl);
6774 for (
unsigned i = 0, e = OriginalIvars.size(); i < e; i++) {
6775 if (OriginalIvars[i]->isBitField()) {
6776 Ivars.push_back(OriginalIvars[i]);
6778 SKIP_BITFIELDS(i , e, OriginalIvars);
6781 Ivars.push_back(OriginalIvars[i]);
6784 Result +=
"\nstatic ";
6785 Write__ivar_list_t_TypeDecl(Result, Ivars.size());
6786 Result +=
" "; Result += VarName;
6788 Result +=
" __attribute__ ((used, section (\"__DATA,__objc_const\"))) = {\n";
6789 Result +=
"\t"; Result +=
"sizeof(_ivar_t)"; Result +=
",\n";
6790 Result +=
"\t"; Result += utostr(Ivars.size()); Result +=
",\n";
6791 for (
unsigned i =0, e = Ivars.size(); i < e; i++) {
6797 Result +=
"(unsigned long int *)&";
6798 if (Ivars[i]->isBitField())
6799 RewriteObj.ObjCIvarBitfieldGroupOffset(IvarDecl, Result);
6801 WriteInternalIvarName(CDecl, IvarDecl, Result);
6805 if (Ivars[i]->isBitField())
6806 RewriteObj.ObjCIvarBitfieldGroupDecl(Ivars[i], Result);
6808 Result += IvarDecl->
getName();
6813 IVQT = RewriteObj.GetGroupRecordTypeForObjCIvarBitfield(IvarDecl);
6815 std::string IvarTypeString, QuoteIvarTypeString;
6816 Context->getObjCEncodingForType(IVQT, IvarTypeString,
6818 RewriteObj.QuoteDoublequotes(IvarTypeString, QuoteIvarTypeString);
6819 Result +=
"\""; Result += QuoteIvarTypeString; Result +=
"\", ";
6823 unsigned Align = Context->getTypeAlign(IVQT)/8;
6824 Align = llvm::Log2_32(Align);
6825 Result += llvm::utostr(Align); Result +=
", ";
6827 Result += llvm::utostr(
Size.getQuantity());
6838void RewriteModernObjC::RewriteObjCProtocolMetaData(
ObjCProtocolDecl *PDecl,
6839 std::string &Result) {
6844 WriteModernMetadataDeclarations(Context, Result);
6851 RewriteObjCProtocolMetaData(I, Result);
6854 std::vector<ObjCMethodDecl *> InstanceMethods, ClassMethods;
6855 std::vector<ObjCMethodDecl *> OptInstanceMethods, OptClassMethods;
6858 OptInstanceMethods.push_back(MD);
6860 InstanceMethods.push_back(MD);
6866 OptClassMethods.push_back(MD);
6868 ClassMethods.push_back(MD);
6871 std::vector<ObjCMethodDecl *> AllMethods;
6872 for (
unsigned i = 0, e = InstanceMethods.size(); i < e; i++)
6873 AllMethods.push_back(InstanceMethods[i]);
6874 for (
unsigned i = 0, e = ClassMethods.size(); i < e; i++)
6875 AllMethods.push_back(ClassMethods[i]);
6876 for (
unsigned i = 0, e = OptInstanceMethods.size(); i < e; i++)
6877 AllMethods.push_back(OptInstanceMethods[i]);
6878 for (
unsigned i = 0, e = OptClassMethods.size(); i < e; i++)
6879 AllMethods.push_back(OptClassMethods[i]);
6881 Write__extendedMethodTypes_initializer(*
this, Context, Result,
6883 "_OBJC_PROTOCOL_METHOD_TYPES_",
6887 Write_protocol_list_initializer(Context, Result, SuperProtocols,
6888 "_OBJC_PROTOCOL_REFS_",
6891 Write_method_list_t_initializer(*
this, Context, Result, InstanceMethods,
6892 "_OBJC_PROTOCOL_INSTANCE_METHODS_",
6895 Write_method_list_t_initializer(*
this, Context, Result, ClassMethods,
6896 "_OBJC_PROTOCOL_CLASS_METHODS_",
6899 Write_method_list_t_initializer(*
this, Context, Result, OptInstanceMethods,
6900 "_OBJC_PROTOCOL_OPT_INSTANCE_METHODS_",
6903 Write_method_list_t_initializer(*
this, Context, Result, OptClassMethods,
6904 "_OBJC_PROTOCOL_OPT_CLASS_METHODS_",
6910 Write_prop_list_t_initializer(*
this, Context, Result, ProtocolProperties,
6912 "_OBJC_PROTOCOL_PROPERTIES_",
6917 if (LangOpts.MicrosoftExt)
6918 Result +=
"static ";
6919 Result +=
"struct _protocol_t _OBJC_PROTOCOL_";
6921 Result +=
" __attribute__ ((used)) = {\n";
6923 Result +=
"\t\""; Result += PDecl->
getNameAsString(); Result +=
"\",\n";
6924 if (SuperProtocols.size() > 0) {
6925 Result +=
"\t(const struct _protocol_list_t *)&"; Result +=
"_OBJC_PROTOCOL_REFS_";
6930 if (InstanceMethods.size() > 0) {
6931 Result +=
"\t(const struct method_list_t *)&_OBJC_PROTOCOL_INSTANCE_METHODS_";
6937 if (ClassMethods.size() > 0) {
6938 Result +=
"\t(const struct method_list_t *)&_OBJC_PROTOCOL_CLASS_METHODS_";
6944 if (OptInstanceMethods.size() > 0) {
6945 Result +=
"\t(const struct method_list_t *)&_OBJC_PROTOCOL_OPT_INSTANCE_METHODS_";
6951 if (OptClassMethods.size() > 0) {
6952 Result +=
"\t(const struct method_list_t *)&_OBJC_PROTOCOL_OPT_CLASS_METHODS_";
6958 if (ProtocolProperties.size() > 0) {
6959 Result +=
"\t(const struct _prop_list_t *)&_OBJC_PROTOCOL_PROPERTIES_";
6965 Result +=
"\t"; Result +=
"sizeof(_protocol_t)"; Result +=
",\n";
6968 if (AllMethods.size() > 0) {
6969 Result +=
"\t(const char **)&"; Result +=
"_OBJC_PROTOCOL_METHOD_TYPES_";
6974 Result +=
"\t0\n};\n";
6976 if (LangOpts.MicrosoftExt)
6977 Result +=
"static ";
6978 Result +=
"struct _protocol_t *";
6979 Result +=
"_OBJC_LABEL_PROTOCOL_$_"; Result += PDecl->
getNameAsString();
6985 llvm_unreachable(
"protocol already synthesized");
6993 if (OID->
hasAttr<ObjCExceptionAttr>())
7001 std::string &Result) {
7007 "Legacy implicit interface rewriting not supported in moder abi");
7009 WriteModernMetadataDeclarations(Context, Result);
7015 if (!IVD->getDeclName())
7017 IVars.push_back(IVD);
7020 Write__ivar_list_t_initializer(*
this, Context, Result, IVars,
7021 "_OBJC_$_INSTANCE_VARIABLES_",
7030 if (Prop->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic)
7032 if (!Prop->getPropertyIvarDecl())
7038 if (mustSynthesizeSetterGetterMethod(IDecl, PD,
true ))
7039 InstanceMethods.push_back(Getter);
7043 if (mustSynthesizeSetterGetterMethod(IDecl, PD,
false ))
7044 InstanceMethods.push_back(Setter);
7047 Write_method_list_t_initializer(*
this, Context, Result, InstanceMethods,
7048 "_OBJC_$_INSTANCE_METHODS_",
7053 Write_method_list_t_initializer(*
this, Context, Result, ClassMethods,
7054 "_OBJC_$_CLASS_METHODS_",
7059 std::vector<ObjCProtocolDecl *> RefedProtocols;
7062 E = Protocols.
end();
7064 RefedProtocols.push_back(*I);
7067 RewriteObjCProtocolMetaData(*I, Result);
7070 Write_protocol_list_initializer(Context, Result,
7072 "_OBJC_CLASS_PROTOCOLS_$_",
7078 Write_prop_list_t_initializer(*
this, Context, Result, ClassProperties,
7080 "_OBJC_$_PROP_LIST_",
7084 uint32_t flags = CLS_META;
7085 std::string InstanceSize;
7086 std::string InstanceStart;
7090 flags |= OBJC2_CLS_HIDDEN;
7095 InstanceSize =
"sizeof(struct _class_t)";
7096 InstanceStart = InstanceSize;
7097 Write__class_ro_t_initializer(Context, Result, flags,
7098 InstanceStart, InstanceSize,
7103 "_OBJC_METACLASS_RO_$_",
7109 flags |= OBJC2_CLS_HIDDEN;
7112 flags |= CLS_EXCEPTION;
7118 InstanceSize.clear();
7119 InstanceStart.clear();
7120 if (!ObjCSynthesizedStructs.count(CDecl)) {
7122 InstanceStart =
"0";
7125 InstanceSize =
"sizeof(struct ";
7127 InstanceSize +=
"_IMPL)";
7131 RewriteIvarOffsetComputation(IVD, InstanceStart);
7134 InstanceStart = InstanceSize;
7136 Write__class_ro_t_initializer(Context, Result, flags,
7137 InstanceStart, InstanceSize,
7142 "_OBJC_CLASS_RO_$_",
7145 Write_class_t(Context, Result,
7146 "OBJC_METACLASS_$_",
7149 Write_class_t(Context, Result,
7153 if (ImplementationIsNonLazy(IDecl))
7154 DefinedNonLazyClasses.push_back(CDecl);
7157void RewriteModernObjC::RewriteClassSetupInitHook(std::string &Result) {
7158 int ClsDefCount = ClassImplementation.size();
7161 Result +=
"#pragma section(\".objc_inithooks$B\", long, read, write)\n";
7162 Result +=
"__declspec(allocate(\".objc_inithooks$B\")) ";
7163 Result +=
"static void *OBJC_CLASS_SETUP[] = {\n";
7164 for (
int i = 0; i < ClsDefCount; i++) {
7167 Result +=
"\t(void *)&OBJC_CLASS_SETUP_$_";
7168 Result += CDecl->
getName(); Result +=
",\n";
7173void RewriteModernObjC::RewriteMetaDataIntoBuffer(std::string &Result) {
7174 int ClsDefCount = ClassImplementation.size();
7175 int CatDefCount = CategoryImplementation.size();
7178 for (
int i = 0; i < ClsDefCount; i++)
7179 RewriteObjCClassMetaData(ClassImplementation[i], Result);
7181 RewriteClassSetupInitHook(Result);
7184 for (
int i = 0; i < CatDefCount; i++)
7185 RewriteObjCCategoryImplDecl(CategoryImplementation[i], Result);
7187 RewriteCategorySetupInitHook(Result);
7189 if (ClsDefCount > 0) {
7190 if (LangOpts.MicrosoftExt)
7191 Result +=
"__declspec(allocate(\".objc_classlist$B\")) ";
7192 Result +=
"static struct _class_t *L_OBJC_LABEL_CLASS_$ [";
7193 Result += llvm::utostr(ClsDefCount); Result +=
"]";
7195 " __attribute__((used, section (\"__DATA, __objc_classlist,"
7196 "regular,no_dead_strip\")))= {\n";
7197 for (
int i = 0; i < ClsDefCount; i++) {
7198 Result +=
"\t&OBJC_CLASS_$_";
7199 Result += ClassImplementation[i]->getNameAsString();
7204 if (!DefinedNonLazyClasses.empty()) {
7205 if (LangOpts.MicrosoftExt)
7206 Result +=
"__declspec(allocate(\".objc_nlclslist$B\")) \n";
7207 Result +=
"static struct _class_t *_OBJC_LABEL_NONLAZY_CLASS_$[] = {\n\t";
7208 for (
unsigned i = 0, e = DefinedNonLazyClasses.size(); i < e; i++) {
7209 Result +=
"\t&OBJC_CLASS_$_"; Result += DefinedNonLazyClasses[i]->getNameAsString();
7216 if (CatDefCount > 0) {
7217 if (LangOpts.MicrosoftExt)
7218 Result +=
"__declspec(allocate(\".objc_catlist$B\")) ";
7219 Result +=
"static struct _category_t *L_OBJC_LABEL_CATEGORY_$ [";
7220 Result += llvm::utostr(CatDefCount); Result +=
"]";
7222 " __attribute__((used, section (\"__DATA, __objc_catlist,"
7223 "regular,no_dead_strip\")))= {\n";
7224 for (
int i = 0; i < CatDefCount; i++) {
7225 Result +=
"\t&_OBJC_$_CATEGORY_";
7227 CategoryImplementation[i]->getClassInterface()->getNameAsString();
7229 Result += CategoryImplementation[i]->getNameAsString();
7235 if (!DefinedNonLazyCategories.empty()) {
7236 if (LangOpts.MicrosoftExt)
7237 Result +=
"__declspec(allocate(\".objc_nlcatlist$B\")) \n";
7238 Result +=
"static struct _category_t *_OBJC_LABEL_NONLAZY_CATEGORY_$[] = {\n\t";
7239 for (
unsigned i = 0, e = DefinedNonLazyCategories.size(); i < e; i++) {
7240 Result +=
"\t&_OBJC_$_CATEGORY_";
7242 DefinedNonLazyCategories[i]->getClassInterface()->getNameAsString();
7244 Result += DefinedNonLazyCategories[i]->getNameAsString();
7251void RewriteModernObjC::WriteImageInfo(std::string &Result) {
7252 if (LangOpts.MicrosoftExt)
7253 Result +=
"__declspec(allocate(\".objc_imageinfo$B\")) \n";
7255 Result +=
"static struct IMAGE_INFO { unsigned version; unsigned flag; } ";
7257 Result +=
"_OBJC_IMAGE_INFO = { 0, 2 };\n";
7263 std::string &Result) {
7264 WriteModernMetadataDeclarations(Context, Result);
7271 FullCategoryName +=
"_$_";
7280 if (Prop->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic)
7282 if (!Prop->getPropertyIvarDecl())
7288 InstanceMethods.push_back(Getter);
7292 InstanceMethods.push_back(Setter);
7295 Write_method_list_t_initializer(*
this, Context, Result, InstanceMethods,
7296 "_OBJC_$_CATEGORY_INSTANCE_METHODS_",
7297 FullCategoryName,
true);
7301 Write_method_list_t_initializer(*
this, Context, Result, ClassMethods,
7302 "_OBJC_$_CATEGORY_CLASS_METHODS_",
7303 FullCategoryName,
true);
7311 RewriteObjCProtocolMetaData(I, Result);
7313 Write_protocol_list_initializer(Context, Result,
7315 "_OBJC_CATEGORY_PROTOCOLS_$_",
7321 Write_prop_list_t_initializer(*
this, Context, Result, ClassProperties,
7323 "_OBJC_$_PROP_LIST_",
7326 Write_category_t(*
this, Context, Result,
7335 if (ImplementationIsNonLazy(IDecl))
7336 DefinedNonLazyCategories.push_back(CDecl);
7339void RewriteModernObjC::RewriteCategorySetupInitHook(std::string &Result) {
7340 int CatDefCount = CategoryImplementation.size();
7343 Result +=
"#pragma section(\".objc_inithooks$B\", long, read, write)\n";
7344 Result +=
"__declspec(allocate(\".objc_inithooks$B\")) ";
7345 Result +=
"static void *OBJC_CATEGORY_SETUP[] = {\n";
7346 for (
int i = 0; i < CatDefCount; i++) {
7350 Result +=
"\t(void *)&OBJC_CATEGORY_SETUP_$_";
7351 Result += ClassDecl->
getName();
7361template<
typename MethodIterator>
7362void RewriteModernObjC::RewriteObjCMethodsMetaData(MethodIterator MethodBegin,
7363 MethodIterator MethodEnd,
7364 bool IsInstanceMethod,
7366 StringRef ClassName,
7367 std::string &Result) {
7368 if (MethodBegin == MethodEnd)
return;
7370 if (!objc_impl_method) {
7377 Result +=
"\nstruct _objc_method {\n";
7378 Result +=
"\tSEL _cmd;\n";
7379 Result +=
"\tchar *method_types;\n";
7380 Result +=
"\tvoid *_imp;\n";
7383 objc_impl_method =
true;
7394 unsigned NumMethods = std::distance(MethodBegin, MethodEnd);
7396 if (LangOpts.MicrosoftExt) {
7397 if (IsInstanceMethod)
7398 Result +=
"__declspec(allocate(\".inst_meth$B\")) ";
7400 Result +=
"__declspec(allocate(\".cls_meth$B\")) ";
7402 Result +=
"static struct {\n";
7403 Result +=
"\tstruct _objc_method_list *next_method;\n";
7404 Result +=
"\tint method_count;\n";
7405 Result +=
"\tstruct _objc_method method_list[";
7406 Result += utostr(NumMethods);
7407 Result +=
"];\n} _OBJC_";
7410 Result +=
"_METHODS_";
7411 Result += ClassName;
7412 Result +=
" __attribute__ ((used, section (\"__OBJC, __";
7414 Result +=
"_meth\")))= ";
7415 Result +=
"{\n\t0, " + utostr(NumMethods) +
"\n";
7417 Result +=
"\t,{{(SEL)\"";
7418 Result += (*MethodBegin)->getSelector().getAsString().c_str();
7419 std::string MethodTypeString;
7420 Context->getObjCEncodingForMethodDecl(*MethodBegin, MethodTypeString);
7422 Result += MethodTypeString;
7423 Result +=
"\", (void *)";
7424 Result += MethodInternalNames[*MethodBegin];
7426 for (++MethodBegin; MethodBegin != MethodEnd; ++MethodBegin) {
7427 Result +=
"\t ,{(SEL)\"";
7428 Result += (*MethodBegin)->getSelector().getAsString().c_str();
7429 std::string MethodTypeString;
7430 Context->getObjCEncodingForMethodDecl(*MethodBegin, MethodTypeString);
7432 Result += MethodTypeString;
7433 Result +=
"\", (void *)";
7434 Result += MethodInternalNames[*MethodBegin];
7437 Result +=
"\t }\n};\n";
7446 DisableReplaceStmtScope S(*
this);
7447 BaseExpr = cast<Expr>(RewriteFunctionBodyOrGlobalInitializer(BaseExpr));
7453 Expr *Replacement = IV;
7458 assert(iFaceDecl &&
"RewriteObjCIvarRefExpr - iFaceDecl is null");
7463 assert(clsDeclared &&
"RewriteObjCIvarRefExpr(): Can't find class");
7466 std::string IvarOffsetName;
7468 ObjCIvarBitfieldGroupOffset(D, IvarOffsetName);
7470 WriteInternalIvarName(clsDeclared, D, IvarOffsetName);
7472 ReferencedIvars[clsDeclared].insert(D);
7476 Context->getPointerType(Context->CharTy),
7481 Context->UnsignedLongTy,
nullptr,
7484 DeclRefExpr(*Context, NewVD,
false, Context->UnsignedLongTy,
7487 *Context, castExpr, DRE, BO_Add,
7488 Context->getPointerType(Context->CharTy), VK_PRValue, OK_Ordinary,
7496 IvarT = GetGroupRecordTypeForObjCIvarBitfield(D);
7507 std::string RecName = std::string(CDecl->
getName());
7512 QualType PtrStructIMPL = Context->getPointerType(Context->getTagDeclType(RD));
7513 unsigned UnsignedIntSize =
7514 static_cast<unsigned>(Context->getTypeSize(Context->UnsignedIntTy));
7515 Expr *
Zero = IntegerLiteral::Create(*Context,
7516 llvm::APInt(UnsignedIntSize, 0),
7518 Zero = NoTypeInfoCStyleCastExpr(Context, PtrStructIMPL, CK_BitCast, Zero);
7528 *Context, PE,
true, FD, FD->
getType(), VK_LValue, OK_Ordinary);
7529 IvarT = Context->getDecltypeType(ME, ME->
getType());
7532 convertObjCTypeToCStyleType(IvarT);
7533 QualType castT = Context->getPointerType(IvarT);
7535 castExpr = NoTypeInfoCStyleCastExpr(Context,
7540 Expr *Exp = UnaryOperator::Create(
7541 const_cast<ASTContext &
>(*Context), castExpr, UO_Deref, IvarT,
7555 MemberExpr::CreateImplicit(*Context, PE,
false, FD,
7556 FD->
getType(), VK_LValue, OK_Ordinary);
7564 ReplaceStmtWithRange(IV, Replacement, OldRange);
Defines the Diagnostic-related interfaces.
static bool hasObjCExceptionAttribute(ASTContext &Context, const ObjCInterfaceDecl *OID)
hasObjCExceptionAttribute - Return true if this class or any super class has the objc_exception attri...
Defines the clang::IdentifierInfo, clang::IdentifierTable, and clang::Selector interfaces.
static std::string toString(const clang::SanitizerSet &Sanitizers)
Produce a string containing comma-separated names of sanitizers in Sanitizers set.
Defines the SourceManager interface.
__device__ __2f16 float c
ASTConsumer - This is an abstract interface that should be implemented by clients that read ASTs.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
TypeSourceInfo * getTrivialTypeSourceInfo(QualType T, SourceLocation Loc=SourceLocation()) const
Allocate a TypeSourceInfo where all locations have been initialized to a given location,...
Represents an array type, per C99 6.7.5.2 - Array Declarators.
QualType getElementType() const
A builtin binary operation expression such as "x + y" or "x <= y".
Represents a block literal declaration, which is like an unnamed FunctionDecl.
param_iterator param_end()
MutableArrayRef< ParmVarDecl * >::iterator param_iterator
param_iterator param_begin()
ArrayRef< Capture > captures() const
BlockExpr - Adaptor class for mixing a BlockDecl with expressions.
const Stmt * getBody() const
const FunctionProtoType * getFunctionType() const
getFunctionType - Return the underlying function type for this block.
const BlockDecl * getBlockDecl() const
QualType getPointeeType() const
BreakStmt - This represents a break.
CStyleCastExpr - An explicit cast in C (C99 6.5.4) or a C-style cast in C++ (C++ [expr....
SourceLocation getRParenLoc() const
SourceLocation getLParenLoc() const
Represents a call to a C++ constructor.
Represents a C++ constructor within a class.
bool isDefaultConstructor() const
Whether this constructor is a default constructor (C++ [class.ctor]p5), which can be used to default-...
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
CastKind getCastKind() const
CharUnits - This is an opaque type for sizes expressed in character units.
CompoundLiteralExpr - [C99 6.5.2.5].
CompoundStmt - This represents a group of statements like { stmt stmt }.
SourceLocation getBeginLoc() const
ConditionalOperator - The ?: ternary operator.
Represents the canonical version of C arrays with a specified constant size.
ContinueStmt - This represents a continue.
decl_iterator - Iterates through the declarations stored within this context.
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
bool isFileContext() const
DeclContext * getRedeclContext()
getRedeclContext - Retrieve the context in which an entity conflicts with other entities of the same ...
void addDecl(Decl *D)
Add the declaration D into this context.
A reference to a declared variable, function, enum, etc.
bool refersToEnclosingVariableOrCapture() const
Does this DeclRefExpr refer to an enclosing local or a captured variable?
SourceLocation getLocation() const
DeclStmt - Adaptor class for mixing declarations with statements and expressions.
decl_iterator decl_begin()
Decl - This represents one declaration (or definition), e.g.
SourceLocation getEndLoc() const LLVM_READONLY
bool isImplicit() const
isImplicit - Indicates whether the declaration was implicitly generated by the implementation.
bool isFunctionPointerType() const
SourceLocation getLocation() const
DeclContext * getDeclContext()
SourceLocation getBeginLoc() const LLVM_READONLY
IdentifierInfo * getAsIdentifierInfo() const
Retrieve the IdentifierInfo * stored in this declaration name, or null if this declaration name isn't...
SourceLocation getTypeSpecStartLoc() const
Concrete class used by the front-end to report problems and issues.
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
unsigned getCustomDiagID(Level L, const char(&FormatString)[N])
Return an ID for a diagnostic with the specified format string and level.
bool hasErrorOccurred() const
enumerator_range enumerators() const
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of enums.
This represents one expression.
ExprValueKind getValueKind() const
getValueKind - The value kind that this expression produces.
Expr * IgnoreParenImpCasts() LLVM_READONLY
Skip past any parentheses and implicit casts which might surround this expression until reaching a fi...
Expr * IgnoreImplicit() LLVM_READONLY
Skip past any implicit AST nodes which might surround this expression until reaching a fixed point.
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
Represents difference between two FPOptions values.
Represents a member of a struct/union/class.
bool isBitField() const
Determines whether this field is a bitfield.
Expr * getBitWidth() const
Returns the expression that represents the bit width, if this field is a bit field.
An opaque identifier used by SourceManager which refers to a source file (MemoryBuffer) along with it...
Represents a function declaration or definition.
Stmt * getBody(const FunctionDecl *&Definition) const
Retrieve the body (definition) of the function.
bool isThisDeclarationADefinition() const
Returns whether this specific declaration of the function is also a definition that does not contain ...
bool isVariadic() const
Whether this function is variadic.
StorageClass getStorageClass() const
Returns the storage class as written in the source.
bool isExternC() const
Determines whether this function is a function with external, C linkage.
bool isMain() const
Determines whether this function is "main", which is the entry point into an executable program.
bool isOverloadedOperator() const
Whether this function declaration represents an C++ overloaded operator, e.g., "operator+".
Represents a prototype with parameter type info, e.g.
unsigned getNumParams() const
QualType getParamType(unsigned i) const
bool isVariadic() const
Whether this function prototype is variadic.
ArrayRef< QualType > param_types() const
FunctionType - C99 6.7.5.3 - Function Declarators.
QualType getReturnType() const
One of these records is kept for each identifier that is lexed.
StringRef getName() const
Return the actual identifier string.
ImplicitCastExpr - Allows us to explicitly represent implicit type conversions, which have no direct ...
Describes an C or C++ initializer list.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Represents a linkage specification.
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
This represents a decl that may have a name.
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
Visibility getVisibility() const
Determines the visibility of this entity.
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
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...
ObjCArrayLiteral - used for objective-c array containers; as in: @["Hello", NSApp,...
Expr * getElement(unsigned Index)
getElement - Return the Element at the specified index.
SourceLocation getBeginLoc() const LLVM_READONLY
unsigned getNumElements() const
getNumElements - Return number of elements of objective-c array literal.
ObjCMethodDecl * getArrayWithObjectsMethod() const
SourceLocation getEndLoc() const LLVM_READONLY
Represents Objective-C's @catch statement.
Represents Objective-C's @finally statement.
const Stmt * getFinallyBody() const
SourceLocation getBeginLoc() const LLVM_READONLY
Represents Objective-C's @synchronized statement.
Represents Objective-C's @throw statement.
Represents Objective-C's @try ... @catch ... @finally statement.
Represents Objective-C's @autoreleasepool Statement.
ObjCBoolLiteralExpr - Objective-C Boolean Literal.
SourceLocation getLocation() const
ObjCBoxedExpr - used for generalized expression boxing.
ObjCMethodDecl * getBoxingMethod() const
SourceLocation getBeginLoc() const LLVM_READONLY
SourceLocation getEndLoc() const LLVM_READONLY
ObjCCategoryDecl - Represents a category declaration.
ObjCInterfaceDecl * getClassInterface()
SourceLocation getIvarRBraceLoc() const
protocol_range protocols() const
ObjCCategoryImplDecl - An object of this class encapsulates a category @implementation declaration.
ObjCCategoryDecl * getCategoryDecl() const
ObjCContainerDecl - Represents a container for method declarations.
SourceRange getAtEndRange() const
instmeth_range instance_methods() const
instprop_range instance_properties() const
ObjCMethodDecl * getClassMethod(Selector Sel, bool AllowHidden=false) const
classmeth_range class_methods() const
ObjCMethodDecl * getInstanceMethod(Selector Sel, bool AllowHidden=false) const
ObjCDictionaryLiteral - AST node to represent objective-c dictionary literals; as in:"name" : NSUserN...
unsigned getNumElements() const
getNumElements - Return number of elements of objective-c dictionary literal.
ObjCMethodDecl * getDictWithObjectsMethod() const
ObjCDictionaryElement getKeyValueElement(unsigned Index) const
SourceLocation getBeginLoc() const LLVM_READONLY
SourceLocation getEndLoc() const LLVM_READONLY
ObjCEncodeExpr, used for @encode in Objective-C.
QualType getEncodedType() const
Represents Objective-C's collection statement.
propimpl_range property_impls() const
const ObjCInterfaceDecl * getClassInterface() const
ObjCImplementationDecl - Represents a class definition - this is where method definitions are specifi...
SourceLocation getIvarRBraceLoc() const
std::string getNameAsString() const
Get the name of the class associated with this interface.
Represents an ObjC class declaration.
ObjCIvarDecl * lookupInstanceVariable(IdentifierInfo *IVarName, ObjCInterfaceDecl *&ClassDeclared)
bool isImplicitInterfaceDecl() const
isImplicitInterfaceDecl - check that this is an implicitly declared ObjCInterfaceDecl node.
ObjCIvarDecl * all_declared_ivar_begin()
all_declared_ivar_begin - return first ivar declared in this class, its extensions and its implementa...
bool isThisDeclarationADefinition() const
Determine whether this particular declaration of this class is actually also a definition.
ObjCCategoryDecl * FindCategoryDeclaration(IdentifierInfo *CategoryId) const
FindCategoryDeclaration - Finds category declaration in the list of categories for this class and ret...
const ObjCProtocolList & getReferencedProtocols() const
ObjCImplementationDecl * getImplementation() const
SourceLocation getEndOfDefinitionLoc() const
ObjCInterfaceDecl * getCanonicalDecl() override
Retrieves the canonical declaration of this Objective-C class.
ObjCInterfaceDecl * getSuperClass() const
Interfaces are the core concept in Objective-C for object oriented design.
ObjCInterfaceDecl * getDecl() const
Get the declaration of this interface.
ObjCIvarDecl - Represents an ObjC instance variable.
AccessControl getAccessControl() const
ObjCInterfaceDecl * getContainingInterface()
Return the class interface that this ivar is logically contained in; this is either the interface whe...
ObjCIvarDecl * getNextIvar()
ObjCIvarRefExpr - A reference to an ObjC instance variable.
const Expr * getBase() const
ObjCList - This is a simple template class used to hold various lists of decls etc,...
An expression that sends a message to the given Objective-C object or class.
Expr * getArg(unsigned Arg)
getArg - Return the specified argument.
void getSelectorLocs(SmallVectorImpl< SourceLocation > &SelLocs) const
bool isImplicit() const
Indicates whether the message send was implicitly generated by the implementation.
SourceLocation getBeginLoc() const LLVM_READONLY
SourceLocation getLeftLoc() const
Expr * getInstanceReceiver()
Returns the object expression (receiver) for an instance message, or null for a message that is not a...
SourceLocation getSuperLoc() const
Retrieve the location of the 'super' keyword for a class or instance message to 'super',...
Selector getSelector() const
TypeSourceInfo * getClassReceiverTypeInfo() const
Returns a type-source information of a class message send, or nullptr if the message is not a class m...
QualType getClassReceiver() const
Returns the type of a class message send, or NULL if the message is not a class message.
QualType getSuperType() const
Retrieve the type referred to by 'super'.
const ObjCMethodDecl * getMethodDecl() const
ReceiverKind getReceiverKind() const
Determine the kind of receiver that this message is being sent to.
SourceLocation getEndLoc() const LLVM_READONLY
SourceLocation getRightLoc() const
unsigned getNumArgs() const
Return the number of actual arguments in this message, not counting the receiver.
ObjCMethodDecl - Represents an instance or class method declaration.
ImplicitParamDecl * getSelfDecl() const
ArrayRef< ParmVarDecl * > parameters() const
CompoundStmt * getCompoundBody()
Stmt * getBody() const override
Retrieve the body of this method, if it has one.
SourceLocation getEndLoc() const LLVM_READONLY
bool isSynthesizedAccessorStub() const
SourceLocation getBeginLoc() const LLVM_READONLY
Selector getSelector() const
bool isInstanceMethod() const
QualType getReturnType() const
ObjCImplementationControl getImplementationControl() const
ObjCInterfaceDecl * getClassInterface()
Represents a pointer to an Objective C object.
Represents a class type in Objective C.
Represents one property declaration in an Objective-C interface.
SourceLocation getAtLoc() const
bool isReadOnly() const
isReadOnly - Return true iff the property has a setter.
Selector getSetterName() const
Selector getGetterName() const
ObjCPropertyAttribute::Kind getPropertyAttributes() const
ObjCPropertyImplDecl - Represents implementation declaration of a property in a class or category imp...
ObjCIvarDecl * getPropertyIvarDecl() const
Kind getPropertyImplementation() const
ObjCPropertyDecl * getPropertyDecl() const
ObjCMethodDecl * getSetterMethodDecl() const
SourceLocation getBeginLoc() const LLVM_READONLY
ObjCMethodDecl * getGetterMethodDecl() const
Represents an Objective-C protocol declaration.
bool isThisDeclarationADefinition() const
Determine whether this particular declaration is also the definition.
ObjCProtocolDecl * getDefinition()
Retrieve the definition of this protocol, if any.
ObjCProtocolDecl * getCanonicalDecl() override
Retrieves the canonical declaration of this Objective-C protocol.
protocol_range protocols() const
ObjCProtocolExpr used for protocol expression in Objective-C.
ObjCProtocolDecl * getProtocol() const
ObjCSelectorExpr used for @selector in Objective-C.
Selector getSelector() const
ObjCStringLiteral, used for Objective-C string literals i.e.
StringLiteral * getString()
ParenExpr - This represents a parethesized expression, e.g.
PointerType - C99 6.7.5.1 - Pointer Declarators.
QualType getPointeeType() const
Represents an unpacked "presumed" location which can be presented to the user.
const char * getFilename() const
Return the presumed filename of this location.
unsigned getLine() const
Return the presumed line number of this location.
PseudoObjectExpr - An expression which accesses a pseudo-object l-value.
Expr * getResultExpr()
Return the result-bearing expression, or null if there is none.
unsigned getNumSemanticExprs() const
Expr * getSemanticExpr(unsigned index)
Expr * getSyntacticForm()
Return the syntactic form of this expression, i.e.
A (possibly-)qualified type.
bool isVolatileQualified() const
Determine whether this type is volatile-qualified.
bool isRestrictQualified() const
Determine whether this type is restrict-qualified.
QualType IgnoreParens() const
Returns the specified type after dropping any outer-level parentheses.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
void getAsStringInternal(std::string &Str, const PrintingPolicy &Policy) const
bool isConstQualified() const
Determine whether this type is const-qualified.
bool isObjCGCWeak() const
true when Type is objc's weak.
unsigned getCVRQualifiers() const
Retrieve the set of CVR (const-volatile-restrict) qualifiers applied to this type.
static std::string getAsString(SplitQualType split, const PrintingPolicy &Policy)
Represents a struct/union/class.
field_range fields() const
virtual void completeDefinition()
Note that the definition of this type is now complete.
RecordDecl * getDefinition() const
Returns the RecordDecl that actually defines this struct/union/class.
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
RewriteBuffer - As code is rewritten, SourceBuffer's from the original input with modifications get a...
Rewriter - This is the main interface to the rewrite buffers.
Smart pointer class that efficiently represents Objective-C method names.
std::string getAsString() const
Derive the full selector name (e.g.
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
SourceLocation getLocWithOffset(IntTy Offset) const
Return a source location with the specified offset from this SourceLocation.
This class handles loading and caching of source files into memory.
A trivial tuple used to represent a source range.
SourceLocation getEnd() const
SourceLocation getBegin() const
Stmt - This represents one statement.
SourceLocation getEndLoc() const LLVM_READONLY
void printPretty(raw_ostream &OS, PrinterHelper *Helper, const PrintingPolicy &Policy, unsigned Indentation=0, StringRef NewlineSymbol="\n", const ASTContext *Context=nullptr) const
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
SourceLocation getBeginLoc() const LLVM_READONLY
StringLiteral - This represents a string literal expression, e.g.
unsigned getByteLength() const
Represents the declaration of a struct/union/class/enum.
bool isCompleteDefinition() const
Return true if this decl has its body fully specified.
The top declaration context.
Represents a declaration of a type.
Represents a typeof (or typeof) expression (a C23 feature and GCC extension) or a typeof_unqual expre...
Expr * getUnderlyingExpr() const
A container of type source information.
The base class of the type hierarchy.
bool isBlockPointerType() const
bool isFunctionPointerType() const
bool isPointerType() const
const T * castAs() const
Member-template castAs<specific type>.
bool isEnumeralType() const
const ObjCObjectPointerType * getAsObjCInterfacePointerType() const
bool isIntegralType(const ASTContext &Ctx) const
Determine whether this type is an integral type.
bool isObjCQualifiedIdType() const
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
bool isObjCQualifiedInterfaceType() const
bool isObjCObjectPointerType() const
bool isObjCQualifiedClassType() const
bool isRealFloatingType() const
Floating point categories.
const T * getAs() const
Member-template getAs<specific type>'.
bool isRecordType() const
Base class for declarations which introduce a typedef-name.
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Represents a variable declaration or definition.
const Expr * getInit() const
StorageClass getStorageClass() const
Returns the storage class as written in the source.
Defines the clang::TargetInfo interface.
@ BLOCK_BYREF_CURRENT_MAX
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
const internal::VariadicDynCastAllOfMatcher< Decl, FieldDecl > fieldDecl
Matches field declarations.
const internal::VariadicDynCastAllOfMatcher< Stmt, CastExpr > castExpr
Matches any cast nodes of Clang's AST.
@ CF
Indicates that the tracked object is a CF object.
bool Zero(InterpState &S, CodePtr OpPC)
The JSON file list parser is used to communicate input to InstallAPI.
bool isa(CodeGen::Address addr)
@ Rewrite
We are substituting template parameters for (typically) other template parameters in order to rewrite...
@ OK_Ordinary
An ordinary object is located at an address in memory.
LLVM_READONLY bool isAlphanumeric(unsigned char c)
Return true if this character is an ASCII letter or digit: [a-zA-Z0-9].
std::unique_ptr< ASTConsumer > CreateModernObjCRewriter(const std::string &InFile, std::unique_ptr< raw_ostream > OS, DiagnosticsEngine &Diags, const LangOptions &LOpts, bool SilenceRewriteMacroWarning, bool LineInfo)
CastKind
CastKind - The kind of operation required for a conversion.
@ VK_PRValue
A pr-value expression (in the C++11 taxonomy) produces a temporary value.
@ VK_LValue
An l-value expression is a reference to an object with independent storage.
U cast(CodeGen::Address addr)
@ Class
The "class" keyword introduces the elaborated-type-specifier.
@ HiddenVisibility
Objects with "hidden" visibility are not seen by the dynamic linker.
int printf(__constant const char *st,...) __attribute__((format(printf
Extra information about a function prototype.
An element in an Objective-C dictionary literal.
Describes how types, statements, expressions, and declarations should be printed.
Iterator for iterating over Stmt * arrays that contain only T *.