22#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
37using llvm::RewriteBuffer;
58 BLOCK_NEEDS_FREE = (1 << 24),
59 BLOCK_HAS_COPY_DISPOSE = (1 << 25),
61 BLOCK_IS_GC = (1 << 27),
63 BLOCK_HAS_DESCRIPTOR = (1 << 29)
73 const char *MainFileStart, *MainFileEnd;
76 std::string InFileName;
77 std::unique_ptr<raw_ostream> OutFile;
82 Expr *GlobalConstructionExp;
83 unsigned RewriteFailedDiag;
84 unsigned GlobalBlockRewriteFailedDiag;
86 unsigned NumObjCStringLiterals;
87 VarDecl *ConstantStringClassReference;
93 unsigned TryFinallyContainsReturnDiag;
131 llvm::DenseSet<uint64_t> CopyDestroyCache;
145 llvm::DenseMap<ValueDecl *, unsigned> BlockByRefDeclNo;
149 llvm::DenseMap<BlockExpr *, std::string> RewrittenBlockExprs;
154 llvm::DenseSet<const ObjCInterfaceDecl *> ObjCInterefaceHasBitfieldGroups;
155 llvm::DenseMap<const ObjCIvarDecl* , unsigned> IvarGroupNumber;
158 llvm::DenseMap<std::pair<const ObjCInterfaceDecl*, unsigned>,
QualType> GroupRecordType;
164 llvm::DenseMap<Stmt *, Stmt *> ReplacedNodes;
168 bool SilenceRewriteMacroWarning;
169 bool GenerateLineInfo;
170 bool objc_impl_method;
172 bool DisableReplaceStmt;
173 class DisableReplaceStmtScope {
174 RewriteModernObjC &R;
178 DisableReplaceStmtScope(RewriteModernObjC &R)
179 : R(R), SavedValue(R.DisableReplaceStmt) {
180 R.DisableReplaceStmt =
true;
182 ~DisableReplaceStmtScope() {
183 R.DisableReplaceStmt = SavedValue;
189 llvm::DenseMap<ObjCMethodDecl*, std::string> MethodInternalNames;
195 if (!
Class->isThisDeclarationADefinition()) {
196 RewriteForwardClassDecl(
D);
200 ObjCInterfacesSeen.push_back(Class);
206 if (!Proto->isThisDeclarationADefinition()) {
207 RewriteForwardProtocolDecl(
D);
217 if (FDecl->isThisDeclarationADefinition() &&
219 !FDecl->isTopLevelDeclInObjCContainer()) {
220 FunctionDefinitionsSeen.push_back(FDecl);
224 HandleTopLevelSingleDecl(*I);
229 void HandleTopLevelDeclInObjCContainer(
DeclGroupRef D)
override {
232 if (isTopLevelBlockPointerType(TD->getUnderlyingType()))
233 RewriteBlockPointerDecl(TD);
234 else if (TD->getUnderlyingType()->isFunctionPointerType())
235 CheckFunctionPointerDecl(TD->getUnderlyingType(), TD);
237 RewriteObjCQualifiedInterfaceTypes(TD);
242 void HandleTopLevelSingleDecl(
Decl *
D);
243 void HandleDeclInMainFile(
Decl *
D);
244 RewriteModernObjC(std::string inFile, std::unique_ptr<raw_ostream> OS,
246 bool silenceMacroWarn,
bool LineInfo);
248 ~RewriteModernObjC()
override {}
250 void HandleTranslationUnit(
ASTContext &C)
override;
252 void ReplaceStmt(
Stmt *Old,
Stmt *New) {
257 assert(Old !=
nullptr && New !=
nullptr &&
"Expected non-null Stmt's");
259 Stmt *ReplacingStmt = ReplacedNodes[Old];
263 if (DisableReplaceStmt)
275 llvm::raw_string_ostream S(SStr);
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,
469 const std::string &Tag);
470 std::string SynthesizeBlockFunc(
BlockExpr *CE,
int i, StringRef funcName,
471 const std::string &Tag);
472 std::string SynthesizeBlockImpl(
BlockExpr *CE,
const std::string &Tag,
473 const std::string &Desc);
474 std::string SynthesizeBlockDescriptor(
const std::string &DescTag,
475 const std::string &ImplTag,
int i,
476 StringRef funcName,
unsigned hasCopy);
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) {
525 bool isConst =
T.isConstQualified();
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) {
728 if (
Loc.isInvalid())
return;
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_$_";
845 std::string IvarOffsetName;
847 ObjCIvarBitfieldGroupOffset(
D, IvarOffsetName);
849 WriteInternalIvarName(ClassDecl,
D, IvarOffsetName);
851 std::string S =
"(*(";
854 IvarT = GetGroupRecordTypeForObjCIvarBitfield(
D);
861 auto *CDecl = cast<ObjCContainerDecl>(
D->getDeclContext());
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);
881 &Context->Idents.get(
D->getNameAsString()),
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 + ";
900 if (
D->isBitField()) {
902 S +=
D->getNameAsString();
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;
1714 elementName =
D->getName();
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();
2176 Loc =
E->getBeginLoc();
2177 EndLoc =
E->getEndLoc();
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)) {
2260 Loc.getLocWithOffset(startRef-startFuncBuf);
2262 Loc.getLocWithOffset(endRef-startFuncBuf+1);
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();
2302 startLoc =
E->getBeginLoc();
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";
3071 Location =
D->getBeginLoc();
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) {
3961 llvm::DenseSet<std::pair<const ObjCInterfaceDecl*, unsigned> > GroupSymbolOutput;
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,
4040 const std::string &Tag) {
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(
4135 BlockExpr *CE,
int i, StringRef funcName,
const std::string &Tag) {
4136 std::string StructRef =
"struct " +
Tag;
4137 std::string S =
"static void __";
4140 S +=
"_block_copy_" + utostr(i);
4141 S +=
"(" + StructRef;
4142 S +=
"*dst, " + StructRef;
4144 for (
ValueDecl *VD : ImportedBlockDecls) {
4145 S +=
"_Block_object_assign((void*)&dst->";
4147 S +=
", (void*)src->";
4149 if (BlockByRefDeclsPtrSet.count(VD))
4150 S +=
", " + utostr(BLOCK_FIELD_IS_BYREF) +
"/*BLOCK_FIELD_IS_BYREF*/);";
4152 S +=
", " + utostr(BLOCK_FIELD_IS_BLOCK) +
"/*BLOCK_FIELD_IS_BLOCK*/);";
4154 S +=
", " + utostr(BLOCK_FIELD_IS_OBJECT) +
"/*BLOCK_FIELD_IS_OBJECT*/);";
4158 S +=
"\nstatic void __";
4160 S +=
"_block_dispose_" + utostr(i);
4161 S +=
"(" + StructRef;
4163 for (
ValueDecl *VD : ImportedBlockDecls) {
4164 S +=
"_Block_object_dispose((void*)src->";
4166 if (BlockByRefDeclsPtrSet.count(VD))
4167 S +=
", " + utostr(BLOCK_FIELD_IS_BYREF) +
"/*BLOCK_FIELD_IS_BYREF*/);";
4169 S +=
", " + utostr(BLOCK_FIELD_IS_BLOCK) +
"/*BLOCK_FIELD_IS_BLOCK*/);";
4171 S +=
", " + utostr(BLOCK_FIELD_IS_OBJECT) +
"/*BLOCK_FIELD_IS_OBJECT*/);";
4177std::string RewriteModernObjC::SynthesizeBlockImpl(
BlockExpr *CE,
4178 const std::string &Tag,
4179 const std::string &Desc) {
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(
4294 const std::string &DescTag,
const std::string &ImplTag,
int i,
4295 StringRef FunName,
unsigned hasCopy) {
4296 std::string S =
"\nstatic struct " + DescTag;
4298 S +=
" {\n size_t reserved;\n";
4299 S +=
" size_t Block_size;\n";
4301 S +=
" void (*copy)(struct ";
4302 S += ImplTag; S +=
"*, struct ";
4303 S += ImplTag; S +=
"*);\n";
4305 S +=
" void (*dispose)(struct ";
4306 S += ImplTag; S +=
"*);\n";
4310 S += DescTag +
"_DATA = { 0, sizeof(struct ";
4313 S +=
", __" + FunName.str() +
"_block_copy_" + utostr(i);
4314 S +=
", __" + FunName.str() +
"_block_dispose_" + utostr(i);
4320void RewriteModernObjC::SynthesizeBlockLiterals(
SourceLocation FunLocStart,
4321 StringRef FunName) {
4322 bool RewriteSC = (GlobalVarDecl &&
4327 std::string SC(
" void __");
4330 InsertText(FunLocStart, SC);
4334 for (
unsigned i = 0, count=0; i < Blocks.size(); i++) {
4335 CollectBlockDeclRefInfo(Blocks[i]);
4338 for (
int j = 0; j < InnerDeclRefsCount[i]; j++) {
4341 BlockDeclRefs.push_back(Exp);
4342 if (!VD->
hasAttr<BlocksAttr>()) {
4343 if (!BlockByCopyDeclsPtrSet.count(VD)) {
4344 BlockByCopyDeclsPtrSet.insert(VD);
4345 BlockByCopyDecls.push_back(VD);
4350 if (!BlockByRefDeclsPtrSet.count(VD)) {
4351 BlockByRefDeclsPtrSet.insert(VD);
4352 BlockByRefDecls.push_back(VD);
4359 ImportedBlockDecls.insert(VD);
4362 std::string ImplTag =
"__" + FunName.str() +
"_block_impl_" + utostr(i);
4363 std::string DescTag =
"__" + FunName.str() +
"_block_desc_" + utostr(i);
4365 std::string CI = SynthesizeBlockImpl(Blocks[i], ImplTag, DescTag);
4367 InsertText(FunLocStart, CI);
4369 std::string
CF = SynthesizeBlockFunc(Blocks[i], i, FunName, ImplTag);
4371 InsertText(FunLocStart, CF);
4373 if (ImportedBlockDecls.size()) {
4374 std::string HF = SynthesizeBlockHelperFuncs(Blocks[i], i, FunName, ImplTag);
4375 InsertText(FunLocStart, HF);
4377 std::string BD = SynthesizeBlockDescriptor(DescTag, ImplTag, i, FunName,
4378 ImportedBlockDecls.size() > 0);
4379 InsertText(FunLocStart, BD);
4381 BlockDeclRefs.clear();
4382 BlockByRefDecls.clear();
4383 BlockByRefDeclsPtrSet.clear();
4384 BlockByCopyDecls.clear();
4385 BlockByCopyDeclsPtrSet.clear();
4386 ImportedBlockDecls.clear();
4400 InsertText(FunLocStart, SC);
4402 if (GlobalConstructionExp) {
4406 std::string
Tag =
"__";
4408 Tag +=
"_block_impl_";
4409 Tag += utostr(Blocks.size()-1);
4410 std::string globalBuf =
"static ";
4411 globalBuf +=
Tag; globalBuf +=
" ";
4414 llvm::raw_string_ostream constructorExprBuf(SStr);
4415 GlobalConstructionExp->
printPretty(constructorExprBuf,
nullptr,
4419 InsertText(FunLocStart, globalBuf);
4420 GlobalConstructionExp =
nullptr;
4424 InnerDeclRefsCount.clear();
4425 InnerDeclRefs.clear();
4426 RewrittenBlockExprs.clear();
4429void RewriteModernObjC::InsertBlockLiteralsWithinFunction(
FunctionDecl *FD) {
4431 (!Blocks.empty()) ? getFunctionSourceLocation(*
this, FD)
4433 StringRef FuncName = FD->
getName();
4435 SynthesizeBlockLiterals(FunLocStart, FuncName);
4438static void BuildUniqueMethodName(std::string &Name,
4441 Name = std::string(IFace->
getName());
4444 std::string::size_type loc = 0;
4445 while ((loc = Name.find(
':', loc)) != std::string::npos)
4446 Name.replace(loc, 1,
"_");
4449void RewriteModernObjC::InsertBlockLiteralsWithinMethod(
ObjCMethodDecl *MD) {
4453 std::string FuncName;
4454 BuildUniqueMethodName(FuncName, MD);
4455 SynthesizeBlockLiterals(FunLocStart, FuncName);
4458void RewriteModernObjC::GetBlockDeclRefExprs(
Stmt *S) {
4459 for (
Stmt *SubStmt : S->children())
4461 if (
BlockExpr *CBE = dyn_cast<BlockExpr>(SubStmt))
4462 GetBlockDeclRefExprs(CBE->getBody());
4464 GetBlockDeclRefExprs(SubStmt);
4469 HasLocalVariableExternalStorage(DRE->
getDecl()))
4471 BlockDeclRefs.push_back(DRE);
4474void RewriteModernObjC::GetInnerBlockDeclRefExprs(
Stmt *S,
4476 llvm::SmallPtrSetImpl<const DeclContext *> &InnerContexts) {
4477 for (
Stmt *SubStmt : S->children())
4479 if (
BlockExpr *CBE = dyn_cast<BlockExpr>(SubStmt)) {
4480 InnerContexts.insert(cast<DeclContext>(CBE->getBlockDecl()));
4481 GetInnerBlockDeclRefExprs(CBE->getBody(),
4486 GetInnerBlockDeclRefExprs(SubStmt, InnerBlockDeclRefs, InnerContexts);
4489 if (
DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(S)) {
4491 HasLocalVariableExternalStorage(DRE->
getDecl())) {
4493 InnerBlockDeclRefs.push_back(DRE);
4495 if (Var->isFunctionOrMethodVarDecl())
4496 ImportedLocalExternalDecls.insert(Var);
4504bool RewriteModernObjC::convertObjCTypeToCStyleType(
QualType &T) {
4506 convertBlockPointerToFunctionPointer(T);
4512 T = convertFunctionTypeOfBlocks(FT);
4513 T = Context->getPointerType(T);
4518 convertToUnqualifiedObjCType(T);
4532 bool modified = convertObjCTypeToCStyleType(Res);
4538 if (convertObjCTypeToCStyleType(t))
4540 ArgTypes.push_back(t);
4545 FuncType = getSimpleFunctionType(Res, ArgTypes);
4550Stmt *RewriteModernObjC::SynthesizeBlockCall(
CallExpr *Exp,
const Expr *BlockExp) {
4554 if (
const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(BlockExp)) {
4556 }
else if (
const MemberExpr *MExpr = dyn_cast<MemberExpr>(BlockExp)) {
4559 else if (
const ParenExpr *PRE = dyn_cast<ParenExpr>(BlockExp)) {
4560 return SynthesizeBlockCall(Exp, PRE->getSubExpr());
4562 else if (
const ImplicitCastExpr *IEXPR = dyn_cast<ImplicitCastExpr>(BlockExp))
4565 dyn_cast<ConditionalOperator>(BlockExp)) {
4566 Expr *LHSExp = CEXPR->getLHS();
4567 Stmt *LHSStmt = SynthesizeBlockCall(Exp, LHSExp);
4568 Expr *RHSExp = CEXPR->getRHS();
4569 Stmt *RHSStmt = SynthesizeBlockCall(Exp, RHSExp);
4570 Expr *CONDExp = CEXPR->getCond();
4575 }
else if (
const ObjCIvarRefExpr *IRE = dyn_cast<ObjCIvarRefExpr>(BlockExp)) {
4578 = dyn_cast<PseudoObjectExpr>(BlockExp)) {
4581 assert(
false &&
"RewriteBlockClass: Bad type");
4583 assert(CPT &&
"RewriteBlockClass: Bad type");
4585 assert(FT &&
"RewriteBlockClass: Bad type");
4589 RecordDecl *RD = RecordDecl::Create(*Context, TagTypeKind::Struct, TUDecl,
4591 &Context->Idents.get(
"__block_impl"));
4592 QualType PtrBlock = Context->getPointerType(Context->getTagDeclType(RD));
4598 ArgTypes.push_back(PtrBlock);
4603 if (!convertBlockPointerToFunctionPointer(t))
4604 convertToUnqualifiedObjCType(t);
4605 ArgTypes.push_back(t);
4609 QualType PtrToFuncCastType = getSimpleFunctionType(Exp->
getType(), ArgTypes);
4611 PtrToFuncCastType = Context->getPointerType(PtrToFuncCastType);
4613 CastExpr *BlkCast = NoTypeInfoCStyleCastExpr(Context, PtrBlock,
4615 const_cast<Expr*
>(BlockExp));
4623 &Context->Idents.get(
"FuncPtr"),
4624 Context->VoidPtrTy,
nullptr,
4628 *Context, PE,
true, FD, FD->
getType(), VK_LValue, OK_Ordinary);
4630 CastExpr *FunkCast = NoTypeInfoCStyleCastExpr(Context, PtrToFuncCastType,
4636 BlkExprs.push_back(BlkCast);
4640 BlkExprs.push_back(*I);
4643 CallExpr::Create(*Context, PE, BlkExprs, Exp->
getType(), VK_PRValue,
4661Stmt *RewriteModernObjC::RewriteBlockDeclRefExpr(
DeclRefExpr *DeclRefExp) {
4666 HasLocalVariableExternalStorage(DeclRefExp->
getDecl());
4670 &Context->Idents.get(
"__forwarding"),
4671 Context->VoidPtrTy,
nullptr,
4675 *Context, DeclRefExp, isArrow, FD, FD->
getType(), VK_LValue, OK_Ordinary);
4677 StringRef Name = VD->
getName();
4679 &Context->Idents.get(Name),
4680 Context->VoidPtrTy,
nullptr,
4683 ME = MemberExpr::CreateImplicit(*Context, ME,
true, FD, DeclRefExp->
getType(),
4684 VK_LValue, OK_Ordinary);
4690 ReplaceStmt(DeclRefExp, PE);
4697Stmt *RewriteModernObjC::RewriteLocalVariableExternalStorage(
DeclRefExpr *DRE) {
4699 if (
VarDecl *Var = dyn_cast<VarDecl>(VD))
4700 if (!ImportedLocalExternalDecls.count(Var))
4702 Expr *Exp = UnaryOperator::Create(
4708 ReplaceStmt(DRE, PE);
4720 if (!Rewriter::isRewritable(LocStart) || !Rewriter::isRewritable(LocEnd))
4723 const char *startBuf =
SM->getCharacterData(LocStart);
4724 const char *endBuf =
SM->getCharacterData(LocEnd);
4727 if (isa<TypeOfExprType>(TypePtr)) {
4728 const TypeOfExprType *TypeOfExprTypePtr = cast<TypeOfExprType>(TypePtr);
4730 std::string TypeAsString =
"(";
4731 RewriteBlockPointerType(TypeAsString, QT);
4732 TypeAsString +=
")";
4733 ReplaceText(LocStart, endBuf-startBuf+1, TypeAsString);
4737 const char *argPtr = startBuf;
4739 while (*argPtr++ && (argPtr < endBuf)) {
4744 ReplaceText(LocStart, 1,
"*");
4750void RewriteModernObjC::RewriteImplicitCastObjCExpr(
CastExpr *IC) {
4752 if (
CastKind != CK_BlockPointerToObjCPointerCast &&
4753 CastKind != CK_AnyPointerToBlockPointerCast)
4757 (void)convertBlockPointerToFunctionPointer(QT);
4758 std::string TypeString(QT.
getAsString(Context->getPrintingPolicy()));
4759 std::string Str =
"(";
4765void RewriteModernObjC::RewriteBlockPointerFunctionArgs(
FunctionDecl *FD) {
4767 unsigned parenCount = 0;
4770 const char *startBuf =
SM->getCharacterData(DeclLoc);
4771 const char *startArgList = strchr(startBuf,
'(');
4773 assert((*startArgList ==
'(') &&
"Rewriter fuzzy parser confused");
4778 assert((DeclLoc.
isValid()) &&
"Invalid DeclLoc");
4780 const char *argPtr = startArgList;
4782 while (*argPtr++ && parenCount) {
4787 ReplaceText(DeclLoc, 1,
"*");
4799bool RewriteModernObjC::PointerTypeTakesAnyBlockArguments(
QualType QT) {
4806 assert(BPT &&
"BlockPointerTypeTakeAnyBlockArguments(): not a block pointer type");
4811 if (isTopLevelBlockPointerType(I))
4817bool RewriteModernObjC::PointerTypeTakesAnyObjCQualifiedType(
QualType QT) {
4824 assert(BPT &&
"BlockPointerTypeTakeAnyBlockArguments(): not a block pointer type");
4829 if (I->isObjCQualifiedIdType())
4831 if (I->isObjCObjectPointerType() &&
4832 I->getPointeeType()->isObjCQualifiedInterfaceType())
4840void RewriteModernObjC::GetExtentOfArgList(
const char *Name,
const char *&LParen,
4841 const char *&RParen) {
4842 const char *argPtr = strchr(Name,
'(');
4843 assert((*argPtr ==
'(') &&
"Rewriter fuzzy parser confused");
4847 unsigned parenCount = 1;
4849 while (*argPtr && parenCount) {
4851 case '(': parenCount++;
break;
4852 case ')': parenCount--;
break;
4855 if (parenCount) argPtr++;
4857 assert((*argPtr ==
')') &&
"Rewriter fuzzy parser confused");
4861void RewriteModernObjC::RewriteBlockPointerDecl(
NamedDecl *ND) {
4863 RewriteBlockPointerFunctionArgs(FD);
4869 if (
VarDecl *VD = dyn_cast<VarDecl>(ND))
4872 DeclT = TDD->getUnderlyingType();
4873 else if (
FieldDecl *FD = dyn_cast<FieldDecl>(ND))
4876 llvm_unreachable(
"RewriteBlockPointerDecl(): Decl type not yet handled");
4878 const char *startBuf =
SM->getCharacterData(DeclLoc);
4879 const char *endBuf = startBuf;
4881 while (*startBuf !=
'^' && *startBuf !=
';' && startBuf != MainFileStart)
4885 unsigned OrigLength=0;
4888 if (*startBuf ==
'^') {
4894 while (*startBuf !=
')') {
4902 if (PointerTypeTakesAnyBlockArguments(DeclT) ||
4903 PointerTypeTakesAnyObjCQualifiedType(DeclT)) {
4907 startBuf =
SM->getCharacterData(DeclLoc);
4908 const char *argListBegin, *argListEnd;
4909 GetExtentOfArgList(startBuf, argListBegin, argListEnd);
4910 while (argListBegin < argListEnd) {
4911 if (*argListBegin ==
'^')
4913 else if (*argListBegin ==
'<') {
4915 buf += *argListBegin++;
4917 while (*argListBegin !=
'>') {
4918 buf += *argListBegin++;
4921 buf += *argListBegin;
4925 buf += *argListBegin;
4932 ReplaceText(Start, OrigLength, buf);
4955std::string RewriteModernObjC::SynthesizeByrefCopyDestroyHelper(
VarDecl *VD,
4958 if (CopyDestroyCache.count(flag))
4960 CopyDestroyCache.insert(flag);
4961 S =
"static void __Block_byref_id_object_copy_";
4963 S +=
"(void *dst, void *src) {\n";
4968 static_cast<unsigned>(Context->getTypeSize(Context->IntTy));
4969 unsigned VoidPtrSize =
4970 static_cast<unsigned>(Context->getTypeSize(Context->VoidPtrTy));
4972 unsigned offset = (VoidPtrSize*4 + IntSize + IntSize)/Context->getCharWidth();
4973 S +=
" _Block_object_assign((char*)dst + ";
4974 S += utostr(offset);
4975 S +=
", *(void * *) ((char*)src + ";
4976 S += utostr(offset);
4981 S +=
"static void __Block_byref_id_object_dispose_";
4983 S +=
"(void *src) {\n";
4984 S +=
" _Block_object_dispose(*(void * *) ((char*)src + ";
4985 S += utostr(offset);
5010void RewriteModernObjC::RewriteByRefVar(
VarDecl *ND,
bool firstDecl,
5019 const char *startBuf =
SM->getCharacterData(DeclLoc);
5021 X =
SM->getExpansionLoc(
X);
5022 const char *endBuf =
SM->getCharacterData(
X);
5024 std::string ByrefType;
5025 RewriteByRefString(ByrefType, Name, ND,
true);
5026 ByrefType +=
" {\n";
5027 ByrefType +=
" void *__isa;\n";
5028 RewriteByRefString(ByrefType, Name, ND);
5029 ByrefType +=
" *__forwarding;\n";
5030 ByrefType +=
" int __flags;\n";
5031 ByrefType +=
" int __size;\n";
5035 bool HasCopyAndDispose = Context->BlockRequiresCopying(Ty, ND);
5036 if (HasCopyAndDispose) {
5037 ByrefType +=
" void (*__Block_byref_id_object_copy)(void*, void*);\n";
5038 ByrefType +=
" void (*__Block_byref_id_object_dispose)(void*);\n";
5042 (void)convertBlockPointerToFunctionPointer(T);
5043 T.getAsStringInternal(Name, Context->getPrintingPolicy());
5045 ByrefType +=
" " + Name +
";\n";
5046 ByrefType +=
"};\n";
5050 FunLocStart = getFunctionSourceLocation(*
this, CurFunctionDef);
5052 assert(CurMethodDef &&
"RewriteByRefVar - CurMethodDef is null");
5055 InsertText(FunLocStart, ByrefType);
5061 if (HasCopyAndDispose) {
5069 std::string HF = SynthesizeByrefCopyDestroyHelper(ND, flag);
5077 bool hasInit = (ND->
getInit() !=
nullptr);
5088 if (HasCopyAndDispose)
5092 RewriteByRefString(ByrefType, Name, ND);
5093 std::string ForwardingCastType(
"(");
5094 ForwardingCastType += ByrefType +
" *)";
5095 ByrefType +=
" " + Name +
" = {(void*)";
5096 ByrefType += utostr(isa);
5097 ByrefType +=
"," + ForwardingCastType +
"&" + Name +
", ";
5098 ByrefType += utostr(flags);
5100 ByrefType +=
"sizeof(";
5101 RewriteByRefString(ByrefType, Name, ND);
5103 if (HasCopyAndDispose) {
5104 ByrefType +=
", __Block_byref_id_object_copy_";
5105 ByrefType += utostr(flag);
5106 ByrefType +=
", __Block_byref_id_object_dispose_";
5107 ByrefType += utostr(flag);
5115 const char *startDeclBuf =
SM->getCharacterData(DeclLoc);
5116 const char *commaBuf = startDeclBuf;
5117 while (*commaBuf !=
',')
5119 assert((*commaBuf ==
',') &&
"RewriteByRefVar: can't find ','");
5121 startBuf = commaBuf;
5125 ByrefType +=
"};\n";
5126 unsigned nameSize = Name.size();
5131 ReplaceText(DeclLoc, endBuf-startBuf+nameSize, ByrefType);
5138 startLoc = ECE->getLParenLoc();
5140 startLoc =
E->getBeginLoc();
5141 startLoc =
SM->getExpansionLoc(startLoc);
5142 endBuf =
SM->getCharacterData(startLoc);
5143 ReplaceText(DeclLoc, endBuf-startBuf, ByrefType);
5145 const char separator = lastDecl ?
';' :
',';
5146 const char *startInitializerBuf =
SM->getCharacterData(startLoc);
5147 const char *separatorBuf = strchr(startInitializerBuf, separator);
5148 assert((*separatorBuf == separator) &&
5149 "RewriteByRefVar: can't find ';' or ','");
5153 InsertText(separatorLoc, lastDecl ?
"}" :
"};\n");
5157void RewriteModernObjC::CollectBlockDeclRefInfo(
BlockExpr *Exp) {
5159 GetBlockDeclRefExprs(Exp->
getBody());
5160 if (BlockDeclRefs.size()) {
5162 for (
unsigned i = 0; i < BlockDeclRefs.size(); i++)
5163 if (!BlockDeclRefs[i]->getDecl()->hasAttr<BlocksAttr>()) {
5164 if (!BlockByCopyDeclsPtrSet.count(BlockDeclRefs[i]->getDecl())) {
5165 BlockByCopyDeclsPtrSet.insert(BlockDeclRefs[i]->getDecl());
5166 BlockByCopyDecls.push_back(BlockDeclRefs[i]->getDecl());
5170 for (
unsigned i = 0; i < BlockDeclRefs.size(); i++)
5171 if (BlockDeclRefs[i]->getDecl()->hasAttr<BlocksAttr>()) {
5172 if (!BlockByRefDeclsPtrSet.count(BlockDeclRefs[i]->getDecl())) {
5173 BlockByRefDeclsPtrSet.insert(BlockDeclRefs[i]->getDecl());
5174 BlockByRefDecls.push_back(BlockDeclRefs[i]->getDecl());
5178 for (
unsigned i = 0; i < BlockDeclRefs.size(); i++)
5179 if (BlockDeclRefs[i]->getDecl()->hasAttr<BlocksAttr>() ||
5180 BlockDeclRefs[i]->getType()->isObjCObjectPointerType() ||
5181 BlockDeclRefs[i]->getType()->isBlockPointerType())
5182 ImportedBlockDecls.insert(BlockDeclRefs[i]->getDecl());
5186FunctionDecl *RewriteModernObjC::SynthBlockInitFunctionDecl(StringRef name) {
5188 QualType FType = Context->getFunctionNoProtoType(Context->VoidPtrTy);
5198 Blocks.push_back(Exp);
5200 CollectBlockDeclRefInfo(Exp);
5203 int countOfInnerDecls = 0;
5204 if (!InnerBlockDeclRefs.empty()) {
5205 for (
unsigned i = 0; i < InnerBlockDeclRefs.size(); i++) {
5208 if (!VD->
hasAttr<BlocksAttr>() && !BlockByCopyDeclsPtrSet.count(VD)) {
5212 InnerDeclRefs.push_back(Exp); countOfInnerDecls++;
5213 BlockDeclRefs.push_back(Exp);
5214 BlockByCopyDeclsPtrSet.insert(VD);
5215 BlockByCopyDecls.push_back(VD);
5217 if (VD->
hasAttr<BlocksAttr>() && !BlockByRefDeclsPtrSet.count(VD)) {
5218 InnerDeclRefs.push_back(Exp); countOfInnerDecls++;
5219 BlockDeclRefs.push_back(Exp);
5220 BlockByRefDeclsPtrSet.insert(VD);
5221 BlockByRefDecls.push_back(VD);
5225 for (
unsigned i = 0; i < InnerBlockDeclRefs.size(); i++)
5226 if (InnerBlockDeclRefs[i]->getDecl()->hasAttr<BlocksAttr>() ||
5227 InnerBlockDeclRefs[i]->getType()->isObjCObjectPointerType() ||
5228 InnerBlockDeclRefs[i]->getType()->isBlockPointerType())
5229 ImportedBlockDecls.insert(InnerBlockDeclRefs[i]->getDecl());
5231 InnerDeclRefsCount.push_back(countOfInnerDecls);
5233 std::string FuncName;
5237 else if (CurMethodDef)
5238 BuildUniqueMethodName(FuncName, CurMethodDef);
5239 else if (GlobalVarDecl)
5242 bool GlobalBlockExpr =
5245 if (GlobalBlockExpr && !GlobalVarDecl) {
5247 GlobalBlockExpr =
false;
5250 std::string BlockNumber = utostr(Blocks.size()-1);
5252 std::string
Func =
"__" + FuncName +
"_block_func_" + BlockNumber;
5255 QualType BFT = convertFunctionTypeOfBlocks(Exp->getFunctionType());
5256 QualType FType = Context->getPointerType(BFT);
5264 if (GlobalBlockExpr)
5268 Tag += FuncName +
"_block_impl_" + BlockNumber;
5270 FD = SynthBlockInitFunctionDecl(Tag);
5277 FD = SynthBlockInitFunctionDecl(Func);
5282 InitExprs.push_back(castExpr);
5285 std::string DescData =
"__" + FuncName +
"_block_desc_" + BlockNumber +
"_DATA";
5287 VarDecl *NewVD = VarDecl::Create(
5289 &Context->Idents.get(DescData), Context->VoidPtrTy,
nullptr, SC_Static);
5292 new (Context)
DeclRefExpr(*Context, NewVD,
false, Context->VoidPtrTy,
5294 UO_AddrOf, Context->getPointerType(Context->VoidPtrTy), VK_PRValue,
5296 InitExprs.push_back(DescRefExpr);
5299 if (BlockDeclRefs.size()) {
5303 E = BlockByCopyDecls.end(); I !=
E; ++I) {
5304 if (isObjCType((*I)->getType())) {
5306 FD = SynthBlockInitFunctionDecl((*I)->getName());
5309 if (HasLocalVariableExternalStorage(*I)) {
5311 QT = Context->getPointerType(QT);
5312 Exp = UnaryOperator::Create(
const_cast<ASTContext &
>(*Context), Exp,
5313 UO_AddrOf, QT, VK_PRValue, OK_Ordinary,
5317 }
else if (isTopLevelBlockPointerType((*I)->getType())) {
5318 FD = SynthBlockInitFunctionDecl((*I)->getName());
5321 Exp = NoTypeInfoCStyleCastExpr(Context, Context->VoidPtrTy,
5324 FD = SynthBlockInitFunctionDecl((*I)->getName());
5327 if (HasLocalVariableExternalStorage(*I)) {
5329 QT = Context->getPointerType(QT);
5330 Exp = UnaryOperator::Create(
const_cast<ASTContext &
>(*Context), Exp,
5331 UO_AddrOf, QT, VK_PRValue, OK_Ordinary,
5337 InitExprs.push_back(Exp);
5341 E = BlockByRefDecls.end(); I !=
E; ++I) {
5344 std::string RecName;
5345 RewriteByRefString(RecName, Name, ND,
true);
5347 +
sizeof(
"struct"));
5349 RecordDecl::Create(*Context, TagTypeKind::Struct, TUDecl,
5351 assert(RD &&
"SynthBlockInitExpr(): Can't find RecordDecl");
5352 QualType castT = Context->getPointerType(Context->getTagDeclType(RD));
5354 FD = SynthBlockInitFunctionDecl((*I)->getName());
5357 bool isNestedCapturedVar =
false;
5358 for (
const auto &CI : block->
captures()) {
5359 const VarDecl *variable = CI.getVariable();
5360 if (variable == ND && CI.isNested()) {
5361 assert(CI.isByRef() &&
5362 "SynthBlockInitExpr - captured block variable is not byref");
5363 isNestedCapturedVar =
true;
5369 if (!isNestedCapturedVar)
5370 Exp = UnaryOperator::Create(
5371 const_cast<ASTContext &
>(*Context), Exp, UO_AddrOf,
5372 Context->getPointerType(Exp->
getType()), VK_PRValue, OK_Ordinary,
5374 Exp = NoTypeInfoCStyleCastExpr(Context, castT, CK_BitCast, Exp);
5375 InitExprs.push_back(Exp);
5378 if (ImportedBlockDecls.size()) {
5382 static_cast<unsigned>(Context->getTypeSize(Context->IntTy));
5383 Expr *FlagExp = IntegerLiteral::Create(*Context, llvm::APInt(IntSize, flag),
5385 InitExprs.push_back(FlagExp);
5387 NewRep = CallExpr::Create(*Context, DRE, InitExprs, FType, VK_LValue,
5390 if (GlobalBlockExpr) {
5391 assert (!GlobalConstructionExp &&
5392 "SynthBlockInitExpr - GlobalConstructionExp must be null");
5393 GlobalConstructionExp = NewRep;
5397 NewRep = UnaryOperator::Create(
5398 const_cast<ASTContext &
>(*Context), NewRep, UO_AddrOf,
5399 Context->getPointerType(NewRep->
getType()), VK_PRValue, OK_Ordinary,
5401 NewRep = NoTypeInfoCStyleCastExpr(Context, FType, CK_BitCast,
5407 BlockDeclRefs.clear();
5408 BlockByRefDecls.clear();
5409 BlockByRefDeclsPtrSet.clear();
5410 BlockByCopyDecls.clear();
5411 BlockByCopyDeclsPtrSet.clear();
5412 ImportedBlockDecls.clear();
5416bool RewriteModernObjC::IsDeclStmtInForeachHeader(
DeclStmt *DS) {
5418 dyn_cast<ObjCForCollectionStmt>(Stmts.back()))
5419 return CS->getElement() == DS;
5427Stmt *RewriteModernObjC::RewriteFunctionBodyOrGlobalInitializer(
Stmt *S) {
5428 if (isa<SwitchStmt>(S) || isa<WhileStmt>(S) ||
5429 isa<DoStmt>(S) || isa<ForStmt>(S))
5431 else if (isa<ObjCForCollectionStmt>(S)) {
5433 ObjCBcLabelNo.push_back(++BcLabelCount);
5440 return RewritePropertyOrImplicitSetter(PseudoOp);
5442 return RewritePropertyOrImplicitGetter(PseudoOp);
5444 }
else if (
ObjCIvarRefExpr *IvarRefExpr = dyn_cast<ObjCIvarRefExpr>(S)) {
5445 return RewriteObjCIvarRefExpr(IvarRefExpr);
5447 else if (isa<OpaqueValueExpr>(S))
5448 S = cast<OpaqueValueExpr>(S)->getSourceExpr();
5453 for (
Stmt *&childStmt : S->children())
5455 Stmt *newStmt = RewriteFunctionBodyOrGlobalInitializer(childStmt);
5457 childStmt = newStmt;
5461 if (
BlockExpr *BE = dyn_cast<BlockExpr>(S)) {
5464 InnerContexts.insert(BE->getBlockDecl());
5465 ImportedLocalExternalDecls.clear();
5466 GetInnerBlockDeclRefExprs(BE->getBody(),
5467 InnerBlockDeclRefs, InnerContexts);
5469 Stmt *SaveCurrentBody = CurrentBody;
5470 CurrentBody = BE->getBody();
5471 PropParentMap =
nullptr;
5477 bool saveDisableReplaceStmt = DisableReplaceStmt;
5478 DisableReplaceStmt =
false;
5479 RewriteFunctionBodyOrGlobalInitializer(BE->getBody());
5480 DisableReplaceStmt = saveDisableReplaceStmt;
5481 CurrentBody = SaveCurrentBody;
5482 PropParentMap =
nullptr;
5483 ImportedLocalExternalDecls.clear();
5485 std::string Str =
Rewrite.getRewrittenText(BE->getSourceRange());
5486 RewrittenBlockExprs[BE] = Str;
5488 Stmt *blockTranscribed = SynthBlockInitExpr(BE, InnerBlockDeclRefs);
5491 ReplaceStmt(S, blockTranscribed);
5492 return blockTranscribed;
5496 return RewriteAtEncode(AtEncode);
5499 return RewriteAtSelector(AtSelector);
5502 return RewriteObjCStringLiteral(AtString);
5505 return RewriteObjCBoolLiteralExpr(BoolLitExpr);
5508 return RewriteObjCBoxedExpr(BoxedExpr);
5511 return RewriteObjCArrayLiteralExpr(ArrayLitExpr);
5514 dyn_cast<ObjCDictionaryLiteral>(S))
5515 return RewriteObjCDictionaryLiteralExpr(DictionaryLitExpr);
5523 const char *startBuf =
SM->getCharacterData(startLoc);
5524 const char *endBuf =
SM->getCharacterData(endLoc);
5526 std::string messString;
5527 messString +=
"// ";
5528 messString.append(startBuf, endBuf-startBuf+1);
5537 return RewriteMessageExpr(MessExpr);
5541 dyn_cast<ObjCAutoreleasePoolStmt>(S)) {
5542 return RewriteObjCAutoreleasePoolStmt(StmtAutoRelease);
5546 return RewriteObjCTryStmt(StmtTry);
5549 return RewriteObjCSynchronizedStmt(StmtTry);
5552 return RewriteObjCThrowStmt(StmtThrow);
5555 return RewriteObjCProtocolExpr(ProtocolExp);
5558 dyn_cast<ObjCForCollectionStmt>(S))
5559 return RewriteObjCForCollectionStmt(StmtForCollection,
5562 dyn_cast<BreakStmt>(S))
5563 return RewriteBreakStmt(StmtBreakStmt);
5565 dyn_cast<ContinueStmt>(S))
5566 return RewriteContinueStmt(StmtContinueStmt);
5570 if (
DeclStmt *DS = dyn_cast<DeclStmt>(S)) {
5580 if (Stmts.empty() || !IsDeclStmtInForeachHeader(DS))
5581 RewriteObjCQualifiedInterfaceTypes(*DS->
decl_begin());
5587 if (
ValueDecl *ND = dyn_cast<ValueDecl>(SD)) {
5588 if (isTopLevelBlockPointerType(ND->
getType()))
5589 RewriteBlockPointerDecl(ND);
5591 CheckFunctionPointerDecl(ND->
getType(), ND);
5592 if (
VarDecl *VD = dyn_cast<VarDecl>(SD)) {
5593 if (VD->
hasAttr<BlocksAttr>()) {
5594 static unsigned uniqueByrefDeclCount = 0;
5595 assert(!BlockByRefDeclNo.count(ND) &&
5596 "RewriteFunctionBodyOrGlobalInitializer: Duplicate byref decl");
5597 BlockByRefDeclNo[ND] = uniqueByrefDeclCount++;
5598 RewriteByRefVar(VD, (DI == DS->
decl_begin()), ((DI+1) == DE));
5601 RewriteTypeOfDecl(VD);
5605 if (isTopLevelBlockPointerType(TD->getUnderlyingType()))
5606 RewriteBlockPointerDecl(TD);
5608 CheckFunctionPointerDecl(TD->getUnderlyingType(), TD);
5614 RewriteObjCQualifiedInterfaceTypes(CE);
5616 if (isa<SwitchStmt>(S) || isa<WhileStmt>(S) ||
5617 isa<DoStmt>(S) || isa<ForStmt>(S)) {
5618 assert(!Stmts.empty() &&
"Statement stack is empty");
5619 assert ((isa<SwitchStmt>(Stmts.back()) || isa<WhileStmt>(Stmts.back()) ||
5620 isa<DoStmt>(Stmts.back()) || isa<ForStmt>(Stmts.back()))
5621 &&
"Statement stack mismatch");
5625 if (
DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(S)) {
5627 if (VD->
hasAttr<BlocksAttr>())
5628 return RewriteBlockDeclRefExpr(DRE);
5629 if (HasLocalVariableExternalStorage(VD))
5630 return RewriteLocalVariableExternalStorage(DRE);
5633 if (
CallExpr *CE = dyn_cast<CallExpr>(S)) {
5635 Stmt *BlockCall = SynthesizeBlockCall(CE, CE->getCallee());
5636 ReplaceStmt(S, BlockCall);
5641 RewriteCastExpr(CE);
5644 RewriteImplicitCastObjCExpr(ICE);
5654 llvm::raw_string_ostream Buf(SStr);
5655 Replacement->printPretty(Buf);
5656 const std::string &Str = Buf.str();
5658 printf(
"CAST = %s\n", &Str[0]);
5668void RewriteModernObjC::RewriteRecordBody(
RecordDecl *RD) {
5669 for (
auto *FD : RD->
fields()) {
5670 if (isTopLevelBlockPointerType(FD->
getType()))
5671 RewriteBlockPointerDecl(FD);
5674 RewriteObjCQualifiedInterfaceTypes(FD);
5680void RewriteModernObjC::HandleDeclInMainFile(
Decl *
D) {
5681 switch (
D->getKind()) {
5682 case Decl::Function: {
5690 RewriteBlocksInFunctionProtoType(FD->
getType(), FD);
5697 CurFunctionDef = FD;
5700 cast_or_null<CompoundStmt>(RewriteFunctionBodyOrGlobalInitializer(Body));
5702 CurrentBody =
nullptr;
5703 if (PropParentMap) {
5704 delete PropParentMap;
5705 PropParentMap =
nullptr;
5709 InsertBlockLiteralsWithinFunction(FD);
5710 RewriteLineDirective(
D);
5711 CurFunctionDef =
nullptr;
5715 case Decl::ObjCMethod: {
5721 cast_or_null<CompoundStmt>(RewriteFunctionBodyOrGlobalInitializer(Body));
5723 CurrentBody =
nullptr;
5724 if (PropParentMap) {
5725 delete PropParentMap;
5726 PropParentMap =
nullptr;
5728 InsertBlockLiteralsWithinMethod(MD);
5729 RewriteLineDirective(
D);
5730 CurMethodDef =
nullptr;
5734 case Decl::ObjCImplementation: {
5736 ClassImplementation.push_back(CI);
5739 case Decl::ObjCCategoryImpl: {
5741 CategoryImplementation.push_back(CI);
5746 RewriteObjCQualifiedInterfaceTypes(VD);
5747 if (isTopLevelBlockPointerType(VD->
getType()))
5748 RewriteBlockPointerDecl(VD);
5750 CheckFunctionPointerDecl(VD->
getType(), VD);
5753 RewriteCastExpr(CE);
5759 RewriteRecordBody(RD);
5764 RewriteFunctionBodyOrGlobalInitializer(VD->
getInit());
5765 CurrentBody =
nullptr;
5766 if (PropParentMap) {
5767 delete PropParentMap;
5768 PropParentMap =
nullptr;
5771 GlobalVarDecl =
nullptr;
5775 RewriteCastExpr(CE);
5780 case Decl::TypeAlias:
5781 case Decl::Typedef: {
5783 if (isTopLevelBlockPointerType(TD->getUnderlyingType()))
5784 RewriteBlockPointerDecl(TD);
5786 CheckFunctionPointerDecl(TD->getUnderlyingType(), TD);
5788 RewriteObjCQualifiedInterfaceTypes(TD);
5792 case Decl::CXXRecord:
5793 case Decl::Record: {
5796 RewriteRecordBody(RD);
5808static void Write_ProtocolExprReferencedMetadata(
ASTContext *Context,
5810 std::string &Result) {
5812 if (Context->getLangOpts().MicrosoftExt)
5813 Result +=
"static ";
5814 Result +=
"struct _protocol_t *";
5815 Result +=
"_OBJC_PROTOCOL_REFERENCE_$_";
5822void RewriteModernObjC::HandleTranslationUnit(
ASTContext &C) {
5828 for (
unsigned i = 0, e = FunctionDefinitionsSeen.size(); i < e; i++) {
5833 HandleTopLevelSingleDecl(FDecl);
5839 RewriteObjCProtocolMetaData(ProtDecl, Preamble);
5840 Write_ProtocolExprReferencedMetadata(Context, ProtDecl, Preamble);
5843 InsertText(
SM->getLocForStartOfFile(MainFileID), Preamble,
false);
5845 if (ClassImplementation.size() || CategoryImplementation.size())
5846 RewriteImplementations();
5848 for (
unsigned i = 0, e = ObjCInterfacesSeen.size(); i < e; i++) {
5854 RewriteInterfaceDecl(CDecl);
5859 if (
const RewriteBuffer *RewriteBuf =
5860 Rewrite.getRewriteBufferFor(MainFileID)) {
5862 *OutFile << std::string(RewriteBuf->begin(), RewriteBuf->end());
5864 llvm::errs() <<
"No changes\n";
5867 if (ClassImplementation.size() || CategoryImplementation.size() ||
5868 ProtocolExprDecls.size()) {
5870 std::string ResultStr;
5871 RewriteMetaDataIntoBuffer(ResultStr);
5873 *OutFile << ResultStr;
5877 std::string ResultStr;
5878 WriteImageInfo(ResultStr);
5879 *OutFile << ResultStr;
5884void RewriteModernObjC::Initialize(
ASTContext &context) {
5885 InitializeCommon(context);
5895 Preamble +=
"struct objc_selector; struct objc_class;\n";
5896 Preamble +=
"struct __rw_objc_super { \n\tstruct objc_object *object; ";
5897 Preamble +=
"\n\tstruct objc_object *superClass; ";
5899 Preamble +=
"\n\t__rw_objc_super(struct objc_object *o, struct objc_object *s) ";
5900 Preamble +=
": object(o), superClass(s) {} ";
5903 if (LangOpts.MicrosoftExt) {
5906 Preamble +=
"\n#pragma section(\".objc_classlist$B\", long, read, write)\n";
5907 Preamble +=
"#pragma section(\".objc_catlist$B\", long, read, write)\n";
5908 Preamble +=
"#pragma section(\".objc_imageinfo$B\", long, read, write)\n";
5909 Preamble +=
"#pragma section(\".objc_nlclslist$B\", long, read, write)\n";
5910 Preamble +=
"#pragma section(\".objc_nlcatlist$B\", long, read, write)\n";
5912 Preamble +=
"#pragma section(\".cat_cls_meth$B\", long, read, write)\n";
5913 Preamble +=
"#pragma section(\".inst_meth$B\", long, read, write)\n";
5914 Preamble +=
"#pragma section(\".cls_meth$B\", long, read, write)\n";
5915 Preamble +=
"#pragma section(\".objc_ivar$B\", long, read, write)\n";
5919 Preamble +=
"#pragma section(\".objc_selrefs$B\", long, read, write)\n";
5920 Preamble +=
"#pragma section(\".objc_classrefs$B\", long, read, write)\n";
5921 Preamble +=
"#pragma section(\".objc_superrefs$B\", long, read, write)\n";
5924 Preamble +=
"#ifndef _REWRITER_typedef_Protocol\n";
5925 Preamble +=
"typedef struct objc_object Protocol;\n";
5926 Preamble +=
"#define _REWRITER_typedef_Protocol\n";
5928 if (LangOpts.MicrosoftExt) {
5929 Preamble +=
"#define __OBJC_RW_DLLIMPORT extern \"C\" __declspec(dllimport)\n";
5930 Preamble +=
"#define __OBJC_RW_STATICIMPORT extern \"C\"\n";
5933 Preamble +=
"#define __OBJC_RW_DLLIMPORT extern\n";
5935 Preamble +=
"__OBJC_RW_DLLIMPORT void objc_msgSend(void);\n";
5936 Preamble +=
"__OBJC_RW_DLLIMPORT void objc_msgSendSuper(void);\n";
5937 Preamble +=
"__OBJC_RW_DLLIMPORT void objc_msgSend_stret(void);\n";
5938 Preamble +=
"__OBJC_RW_DLLIMPORT void objc_msgSendSuper_stret(void);\n";
5939 Preamble +=
"__OBJC_RW_DLLIMPORT void objc_msgSend_fpret(void);\n";
5941 Preamble +=
"__OBJC_RW_DLLIMPORT struct objc_class *objc_getClass";
5943 Preamble +=
"__OBJC_RW_DLLIMPORT struct objc_class *class_getSuperclass";
5944 Preamble +=
"(struct objc_class *);\n";
5945 Preamble +=
"__OBJC_RW_DLLIMPORT struct objc_class *objc_getMetaClass";
5947 Preamble +=
"__OBJC_RW_DLLIMPORT void objc_exception_throw( struct objc_object *);\n";
5949 Preamble +=
"__OBJC_RW_DLLIMPORT int objc_sync_enter( struct objc_object *);\n";
5950 Preamble +=
"__OBJC_RW_DLLIMPORT int objc_sync_exit( struct objc_object *);\n";
5951 Preamble +=
"__OBJC_RW_DLLIMPORT Protocol *objc_getProtocol(const char *);\n";
5953 Preamble +=
"typedef unsigned long long _WIN_NSUInteger;\n";
5955 Preamble +=
"typedef unsigned int _WIN_NSUInteger;\n";
5957 Preamble +=
"#ifndef __FASTENUMERATIONSTATE\n";
5958 Preamble +=
"struct __objcFastEnumerationState {\n\t";
5959 Preamble +=
"unsigned long state;\n\t";
5960 Preamble +=
"void **itemsPtr;\n\t";
5961 Preamble +=
"unsigned long *mutationsPtr;\n\t";
5962 Preamble +=
"unsigned long extra[5];\n};\n";
5963 Preamble +=
"__OBJC_RW_DLLIMPORT void objc_enumerationMutation(struct objc_object *);\n";
5964 Preamble +=
"#define __FASTENUMERATIONSTATE\n";
5966 Preamble +=
"#ifndef __NSCONSTANTSTRINGIMPL\n";
5967 Preamble +=
"struct __NSConstantStringImpl {\n";
5972 Preamble +=
" long long length;\n";
5977 Preamble +=
"#ifdef CF_EXPORT_CONSTANT_STRING\n";
5978 Preamble +=
"extern \"C\" __declspec(dllexport) int __CFConstantStringClassReference[];\n";
5980 Preamble +=
"__OBJC_RW_DLLIMPORT int __CFConstantStringClassReference[];\n";
5982 Preamble +=
"#define __NSCONSTANTSTRINGIMPL\n";
5985 Preamble +=
"#ifndef BLOCK_IMPL\n";
5986 Preamble +=
"#define BLOCK_IMPL\n";
5987 Preamble +=
"struct __block_impl {\n";
5993 Preamble +=
"// Runtime copy/destroy helper functions (from Block_private.h)\n";
5994 Preamble +=
"#ifdef __OBJC_EXPORT_BLOCKS\n";
5995 Preamble +=
"extern \"C\" __declspec(dllexport) "
5996 "void _Block_object_assign(void *, const void *, const int);\n";
5997 Preamble +=
"extern \"C\" __declspec(dllexport) void _Block_object_dispose(const void *, const int);\n";
5998 Preamble +=
"extern \"C\" __declspec(dllexport) void *_NSConcreteGlobalBlock[32];\n";
5999 Preamble +=
"extern \"C\" __declspec(dllexport) void *_NSConcreteStackBlock[32];\n";
6001 Preamble +=
"__OBJC_RW_DLLIMPORT void _Block_object_assign(void *, const void *, const int);\n";
6002 Preamble +=
"__OBJC_RW_DLLIMPORT void _Block_object_dispose(const void *, const int);\n";
6003 Preamble +=
"__OBJC_RW_DLLIMPORT void *_NSConcreteGlobalBlock[32];\n";
6004 Preamble +=
"__OBJC_RW_DLLIMPORT void *_NSConcreteStackBlock[32];\n";
6007 if (LangOpts.MicrosoftExt) {
6008 Preamble +=
"#undef __OBJC_RW_DLLIMPORT\n";
6009 Preamble +=
"#undef __OBJC_RW_STATICIMPORT\n";
6010 Preamble +=
"#ifndef KEEP_ATTRIBUTES\n";
6011 Preamble +=
"#define __attribute__(X)\n";
6026 Preamble +=
"\n#include <stdarg.h>\n";
6027 Preamble +=
"struct __NSContainer_literal {\n";
6029 Preamble +=
" __NSContainer_literal (unsigned int count, ...) {\n";
6031 Preamble +=
"\tva_start(marker, count);\n";
6032 Preamble +=
"\tarr = new void *[count];\n";
6033 Preamble +=
"\tfor (unsigned i = 0; i < count; i++)\n";
6034 Preamble +=
"\t arr[i] = va_arg(marker, void *);\n";
6035 Preamble +=
"\tva_end( marker );\n";
6037 Preamble +=
" ~__NSContainer_literal() {\n";
6043 Preamble +=
"extern \"C\" __declspec(dllimport) void * objc_autoreleasePoolPush(void);\n";
6044 Preamble +=
"extern \"C\" __declspec(dllimport) void objc_autoreleasePoolPop(void *);\n\n";
6045 Preamble +=
"struct __AtAutoreleasePool {\n";
6046 Preamble +=
" __AtAutoreleasePool() {atautoreleasepoolobj = objc_autoreleasePoolPush();}\n";
6047 Preamble +=
" ~__AtAutoreleasePool() {objc_autoreleasePoolPop(atautoreleasepoolobj);}\n";
6048 Preamble +=
" void * atautoreleasepoolobj;\n";
6053 Preamble +=
"\n#define __OFFSETOFIVAR__(TYPE, MEMBER) ((long long) &((TYPE *)0)->MEMBER)\n";
6058void RewriteModernObjC::RewriteIvarOffsetComputation(
ObjCIvarDecl *ivar,
6059 std::string &Result) {
6060 Result +=
"__OFFSETOFIVAR__(struct ";
6062 if (LangOpts.MicrosoftExt)
6066 ObjCIvarBitfieldGroupDecl(ivar, Result);
6174static void WriteModernMetadataDeclarations(
ASTContext *Context, std::string &Result) {
6175 static bool meta_data_declared =
false;
6176 if (meta_data_declared)
6179 Result +=
"\nstruct _prop_t {\n";
6180 Result +=
"\tconst char *name;\n";
6181 Result +=
"\tconst char *attributes;\n";
6184 Result +=
"\nstruct _protocol_t;\n";
6186 Result +=
"\nstruct _objc_method {\n";
6187 Result +=
"\tstruct objc_selector * _cmd;\n";
6188 Result +=
"\tconst char *method_type;\n";
6189 Result +=
"\tvoid *_imp;\n";
6192 Result +=
"\nstruct _protocol_t {\n";
6193 Result +=
"\tvoid * isa; // NULL\n";
6194 Result +=
"\tconst char *protocol_name;\n";
6195 Result +=
"\tconst struct _protocol_list_t * protocol_list; // super protocols\n";
6196 Result +=
"\tconst struct method_list_t *instance_methods;\n";
6197 Result +=
"\tconst struct method_list_t *class_methods;\n";
6198 Result +=
"\tconst struct method_list_t *optionalInstanceMethods;\n";
6199 Result +=
"\tconst struct method_list_t *optionalClassMethods;\n";
6200 Result +=
"\tconst struct _prop_list_t * properties;\n";
6201 Result +=
"\tconst unsigned int size; // sizeof(struct _protocol_t)\n";
6202 Result +=
"\tconst unsigned int flags; // = 0\n";
6203 Result +=
"\tconst char ** extendedMethodTypes;\n";
6206 Result +=
"\nstruct _ivar_t {\n";
6207 Result +=
"\tunsigned long int *offset; // pointer to ivar offset location\n";
6208 Result +=
"\tconst char *name;\n";
6209 Result +=
"\tconst char *type;\n";
6210 Result +=
"\tunsigned int alignment;\n";
6211 Result +=
"\tunsigned int size;\n";
6214 Result +=
"\nstruct _class_ro_t {\n";
6215 Result +=
"\tunsigned int flags;\n";
6216 Result +=
"\tunsigned int instanceStart;\n";
6217 Result +=
"\tunsigned int instanceSize;\n";
6218 const llvm::Triple &Triple(Context->getTargetInfo().getTriple());
6219 if (Triple.getArch() == llvm::Triple::x86_64)
6220 Result +=
"\tunsigned int reserved;\n";
6221 Result +=
"\tconst unsigned char *ivarLayout;\n";
6222 Result +=
"\tconst char *name;\n";
6223 Result +=
"\tconst struct _method_list_t *baseMethods;\n";
6224 Result +=
"\tconst struct _objc_protocol_list *baseProtocols;\n";
6225 Result +=
"\tconst struct _ivar_list_t *ivars;\n";
6226 Result +=
"\tconst unsigned char *weakIvarLayout;\n";
6227 Result +=
"\tconst struct _prop_list_t *properties;\n";
6230 Result +=
"\nstruct _class_t {\n";
6231 Result +=
"\tstruct _class_t *isa;\n";
6232 Result +=
"\tstruct _class_t *superclass;\n";
6233 Result +=
"\tvoid *cache;\n";
6234 Result +=
"\tvoid *vtable;\n";
6235 Result +=
"\tstruct _class_ro_t *ro;\n";
6238 Result +=
"\nstruct _category_t {\n";
6239 Result +=
"\tconst char *name;\n";
6240 Result +=
"\tstruct _class_t *cls;\n";
6241 Result +=
"\tconst struct _method_list_t *instance_methods;\n";
6242 Result +=
"\tconst struct _method_list_t *class_methods;\n";
6243 Result +=
"\tconst struct _protocol_list_t *protocols;\n";
6244 Result +=
"\tconst struct _prop_list_t *properties;\n";
6247 Result +=
"extern \"C\" __declspec(dllimport) struct objc_cache _objc_empty_cache;\n";
6248 Result +=
"#pragma warning(disable:4273)\n";
6249 meta_data_declared =
true;
6252static void Write_protocol_list_t_TypeDecl(std::string &Result,
6253 long super_protocol_count) {
6254 Result +=
"struct /*_protocol_list_t*/"; Result +=
" {\n";
6255 Result +=
"\tlong protocol_count; // Note, this is 32/64 bit\n";
6256 Result +=
"\tstruct _protocol_t *super_protocols[";
6257 Result += utostr(super_protocol_count); Result +=
"];\n";
6261static void Write_method_list_t_TypeDecl(std::string &Result,
6262 unsigned int method_count) {
6263 Result +=
"struct /*_method_list_t*/"; Result +=
" {\n";
6264 Result +=
"\tunsigned int entsize; // sizeof(struct _objc_method)\n";
6265 Result +=
"\tunsigned int method_count;\n";
6266 Result +=
"\tstruct _objc_method method_list[";
6267 Result += utostr(method_count); Result +=
"];\n";
6271static void Write__prop_list_t_TypeDecl(std::string &Result,
6272 unsigned int property_count) {
6273 Result +=
"struct /*_prop_list_t*/"; Result +=
" {\n";
6274 Result +=
"\tunsigned int entsize; // sizeof(struct _prop_t)\n";
6275 Result +=
"\tunsigned int count_of_properties;\n";
6276 Result +=
"\tstruct _prop_t prop_list[";
6277 Result += utostr(property_count); Result +=
"];\n";
6281static void Write__ivar_list_t_TypeDecl(std::string &Result,
6282 unsigned int ivar_count) {
6283 Result +=
"struct /*_ivar_list_t*/"; Result +=
" {\n";
6284 Result +=
"\tunsigned int entsize; // sizeof(struct _prop_t)\n";
6285 Result +=
"\tunsigned int count;\n";
6286 Result +=
"\tstruct _ivar_t ivar_list[";
6287 Result += utostr(ivar_count); Result +=
"];\n";
6291static void Write_protocol_list_initializer(
ASTContext *Context, std::string &Result,
6294 StringRef ProtocolName) {
6295 if (SuperProtocols.size() > 0) {
6296 Result +=
"\nstatic ";
6297 Write_protocol_list_t_TypeDecl(Result, SuperProtocols.size());
6298 Result +=
" "; Result += VarName;
6299 Result += ProtocolName;
6300 Result +=
" __attribute__ ((used, section (\"__DATA,__objc_const\"))) = {\n";
6301 Result +=
"\t"; Result += utostr(SuperProtocols.size()); Result +=
",\n";
6302 for (
unsigned i = 0, e = SuperProtocols.size(); i < e; i++) {
6304 Result +=
"\t&"; Result +=
"_OBJC_PROTOCOL_";
6314static void Write_method_list_t_initializer(RewriteModernObjC &RewriteObj,
6318 StringRef TopLevelDeclName,
6320 if (Methods.size() > 0) {
6321 Result +=
"\nstatic ";
6322 Write_method_list_t_TypeDecl(Result, Methods.size());
6323 Result +=
" "; Result += VarName;
6324 Result += TopLevelDeclName;
6325 Result +=
" __attribute__ ((used, section (\"__DATA,__objc_const\"))) = {\n";
6326 Result +=
"\t"; Result +=
"sizeof(_objc_method)"; Result +=
",\n";
6327 Result +=
"\t"; Result += utostr(Methods.size()); Result +=
",\n";
6328 for (
unsigned i = 0, e = Methods.size(); i < e; i++) {
6331 Result +=
"\t{{(struct objc_selector *)\"";
6333 Result +=
"\t{(struct objc_selector *)\"";
6334 Result += (MD)->getSelector().getAsString(); Result +=
"\"";
6336 std::string MethodTypeString = Context->getObjCEncodingForMethodDecl(MD);
6337 Result +=
"\""; Result += MethodTypeString; Result +=
"\"";
6342 Result +=
"(void *)";
6343 Result += RewriteObj.MethodInternalNames[MD];
6354static void Write_prop_list_t_initializer(RewriteModernObjC &RewriteObj,
6357 const Decl *Container,
6359 StringRef ProtocolName) {
6360 if (Properties.size() > 0) {
6361 Result +=
"\nstatic ";
6362 Write__prop_list_t_TypeDecl(Result, Properties.size());
6363 Result +=
" "; Result += VarName;
6364 Result += ProtocolName;
6365 Result +=
" __attribute__ ((used, section (\"__DATA,__objc_const\"))) = {\n";
6366 Result +=
"\t"; Result +=
"sizeof(_prop_t)"; Result +=
",\n";
6367 Result +=
"\t"; Result += utostr(Properties.size()); Result +=
",\n";
6368 for (
unsigned i = 0, e = Properties.size(); i < e; i++) {
6374 Result += PropDecl->
getName(); Result +=
"\",";
6375 std::string PropertyTypeString =
6376 Context->getObjCEncodingForPropertyDecl(PropDecl, Container);
6377 std::string QuotePropertyTypeString;
6378 RewriteObj.QuoteDoublequotes(PropertyTypeString, QuotePropertyTypeString);
6379 Result +=
"\""; Result += QuotePropertyTypeString; Result +=
"\"";
6394 OBJC2_CLS_HIDDEN = 0x10,
6395 CLS_EXCEPTION = 0x20,
6398 CLS_HAS_IVAR_RELEASER = 0x40,
6400 CLS_COMPILED_BY_ARC = 0x80
6403static void Write__class_ro_t_initializer(
ASTContext *Context, std::string &Result,
6405 const std::string &InstanceStart,
6406 const std::string &InstanceSize,
6412 StringRef ClassName) {
6413 Result +=
"\nstatic struct _class_ro_t ";
6414 Result += VarName; Result += ClassName;
6415 Result +=
" __attribute__ ((used, section (\"__DATA,__objc_const\"))) = {\n";
6417 Result += llvm::utostr(flags); Result +=
", ";
6418 Result += InstanceStart; Result +=
", ";
6419 Result += InstanceSize; Result +=
", \n";
6421 const llvm::Triple &Triple(Context->getTargetInfo().getTriple());
6422 if (Triple.getArch() == llvm::Triple::x86_64)
6424 Result +=
"(unsigned int)0, \n\t";
6426 Result +=
"0, \n\t";
6427 Result +=
"\""; Result += ClassName; Result +=
"\",\n\t";
6428 bool metaclass = ((flags & CLS_META) != 0);
6429 if (baseMethods.size() > 0) {
6430 Result +=
"(const struct _method_list_t *)&";
6432 Result +=
"_OBJC_$_CLASS_METHODS_";
6434 Result +=
"_OBJC_$_INSTANCE_METHODS_";
6435 Result += ClassName;
6439 Result +=
"0, \n\t";
6441 if (!metaclass && baseProtocols.size() > 0) {
6442 Result +=
"(const struct _objc_protocol_list *)&";
6443 Result +=
"_OBJC_CLASS_PROTOCOLS_$_"; Result += ClassName;
6447 Result +=
"0, \n\t";
6449 if (!metaclass && ivars.size() > 0) {
6450 Result +=
"(const struct _ivar_list_t *)&";
6451 Result +=
"_OBJC_$_INSTANCE_VARIABLES_"; Result += ClassName;
6455 Result +=
"0, \n\t";
6458 Result +=
"0, \n\t";
6459 if (!metaclass && Properties.size() > 0) {
6460 Result +=
"(const struct _prop_list_t *)&";
6461 Result +=
"_OBJC_$_PROP_LIST_"; Result += ClassName;
6470static void Write_class_t(
ASTContext *Context, std::string &Result,
6484 if (metaclass && rootClass) {
6487 Result +=
"extern \"C\" ";
6489 Result +=
"__declspec(dllexport) ";
6491 Result +=
"__declspec(dllimport) ";
6493 Result +=
"struct _class_t OBJC_CLASS_$_";
6501 Result +=
"extern \"C\" ";
6503 Result +=
"__declspec(dllexport) ";
6505 Result +=
"__declspec(dllimport) ";
6507 Result +=
"struct _class_t ";
6512 if (metaclass && RootClass != SuperClass) {
6513 Result +=
"extern \"C\" ";
6515 Result +=
"__declspec(dllexport) ";
6517 Result +=
"__declspec(dllimport) ";
6519 Result +=
"struct _class_t ";
6526 Result +=
"\nextern \"C\" __declspec(dllexport) struct _class_t ";
6528 Result +=
" __attribute__ ((used, section (\"__DATA,__objc_data\"))) = {\n";
6532 Result +=
"0, // &"; Result += VarName;
6535 Result +=
"0, // &"; Result += VarName;
6540 Result +=
"0, // &"; Result += VarName;
6548 Result +=
"0, // &OBJC_METACLASS_$_";
6552 Result +=
"0, // &"; Result += VarName;
6559 Result +=
"0, // (void *)&_objc_empty_cache,\n\t";
6560 Result +=
"0, // unused, was (void *)&_objc_empty_vtable,\n\t";
6562 Result +=
"&_OBJC_METACLASS_RO_$_";
6564 Result +=
"&_OBJC_CLASS_RO_$_";
6566 Result +=
",\n};\n";
6576 Result +=
"static void OBJC_CLASS_SETUP_$_";
6578 Result +=
"(void ) {\n";
6580 Result +=
".isa = "; Result +=
"&OBJC_METACLASS_$_";
6584 Result +=
".superclass = ";
6586 Result +=
"&OBJC_CLASS_$_";
6588 Result +=
"&OBJC_METACLASS_$_";
6593 Result +=
".cache = "; Result +=
"&_objc_empty_cache"; Result +=
";\n";
6596 Result +=
".isa = "; Result +=
"&OBJC_METACLASS_$_";
6601 Result +=
".superclass = "; Result +=
"&OBJC_CLASS_$_";
6606 Result +=
".cache = "; Result +=
"&_objc_empty_cache"; Result +=
";\n";
6610static void Write_category_t(RewriteModernObjC &RewriteObj,
ASTContext *Context,
6611 std::string &Result,
6618 StringRef CatName = CatDecl->
getName();
6619 StringRef ClassName = ClassDecl->
getName();
6623 Result +=
"extern \"C\" ";
6625 Result +=
"__declspec(dllexport) ";
6627 Result +=
"__declspec(dllimport) ";
6629 Result +=
"struct _class_t ";
6630 Result +=
"OBJC_CLASS_$_"; Result += ClassName;
6633 Result +=
"\nstatic struct _category_t ";
6634 Result +=
"_OBJC_$_CATEGORY_";
6635 Result += ClassName; Result +=
"_$_"; Result += CatName;
6636 Result +=
" __attribute__ ((used, section (\"__DATA,__objc_const\"))) = \n";
6638 Result +=
"\t\""; Result += ClassName; Result +=
"\",\n";
6639 Result +=
"\t0, // &"; Result +=
"OBJC_CLASS_$_"; Result += ClassName;
6641 if (InstanceMethods.size() > 0) {
6642 Result +=
"\t(const struct _method_list_t *)&";
6643 Result +=
"_OBJC_$_CATEGORY_INSTANCE_METHODS_";
6644 Result += ClassName; Result +=
"_$_"; Result += CatName;
6650 if (ClassMethods.size() > 0) {
6651 Result +=
"\t(const struct _method_list_t *)&";
6652 Result +=
"_OBJC_$_CATEGORY_CLASS_METHODS_";
6653 Result += ClassName; Result +=
"_$_"; Result += CatName;
6659 if (RefedProtocols.size() > 0) {
6660 Result +=
"\t(const struct _protocol_list_t *)&";
6661 Result +=
"_OBJC_CATEGORY_PROTOCOLS_$_";
6662 Result += ClassName; Result +=
"_$_"; Result += CatName;
6668 if (ClassProperties.size() > 0) {
6669 Result +=
"\t(const struct _prop_list_t *)&"; Result +=
"_OBJC_$_PROP_LIST_";
6670 Result += ClassName; Result +=
"_$_"; Result += CatName;
6679 Result +=
"static void OBJC_CATEGORY_SETUP_$_";
6683 Result +=
"(void ) {\n";
6684 Result +=
"\t_OBJC_$_CATEGORY_";
6688 Result +=
".cls = "; Result +=
"&OBJC_CLASS_$_"; Result += ClassName;
6692static void Write__extendedMethodTypes_initializer(RewriteModernObjC &RewriteObj,
6696 StringRef ProtocolName) {
6697 if (Methods.size() == 0)
6700 Result +=
"\nstatic const char *";
6701 Result += VarName; Result += ProtocolName;
6702 Result +=
" [] __attribute__ ((used, section (\"__DATA,__objc_const\"))) = \n";
6704 for (
unsigned i = 0, e = Methods.size(); i < e; i++) {
6706 std::string MethodTypeString =
6707 Context->getObjCEncodingForMethodDecl(MD,
true);
6708 std::string QuoteMethodTypeString;
6709 RewriteObj.QuoteDoublequotes(MethodTypeString, QuoteMethodTypeString);
6710 Result +=
"\t\""; Result += QuoteMethodTypeString; Result +=
"\"";
6719static void Write_IvarOffsetVar(RewriteModernObjC &RewriteObj,
6721 std::string &Result,
6736 for (
unsigned i =0, e = Ivars.size(); i < e; i++) {
6738 if (Context->getLangOpts().MicrosoftExt)
6739 Result +=
"__declspec(allocate(\".objc_ivar$B\")) ";
6741 if (!Context->getLangOpts().MicrosoftExt ||
6744 Result +=
"extern \"C\" unsigned long int ";
6746 Result +=
"extern \"C\" __declspec(dllexport) unsigned long int ";
6747 if (Ivars[i]->isBitField())
6748 RewriteObj.ObjCIvarBitfieldGroupOffset(IvarDecl, Result);
6750 WriteInternalIvarName(CDecl, IvarDecl, Result);
6751 Result +=
" __attribute__ ((used, section (\"__DATA,__objc_ivar\")))";
6753 RewriteObj.RewriteIvarOffsetComputation(IvarDecl, Result);
6755 if (Ivars[i]->isBitField()) {
6757 SKIP_BITFIELDS(i , e, Ivars);
6762static void Write__ivar_list_t_initializer(RewriteModernObjC &RewriteObj,
6767 if (OriginalIvars.size() > 0) {
6768 Write_IvarOffsetVar(RewriteObj, Context, Result, OriginalIvars, CDecl);
6773 for (
unsigned i = 0, e = OriginalIvars.size(); i < e; i++) {
6774 if (OriginalIvars[i]->isBitField()) {
6775 Ivars.push_back(OriginalIvars[i]);
6777 SKIP_BITFIELDS(i , e, OriginalIvars);
6780 Ivars.push_back(OriginalIvars[i]);
6783 Result +=
"\nstatic ";
6784 Write__ivar_list_t_TypeDecl(Result, Ivars.size());
6785 Result +=
" "; Result += VarName;
6787 Result +=
" __attribute__ ((used, section (\"__DATA,__objc_const\"))) = {\n";
6788 Result +=
"\t"; Result +=
"sizeof(_ivar_t)"; Result +=
",\n";
6789 Result +=
"\t"; Result += utostr(Ivars.size()); Result +=
",\n";
6790 for (
unsigned i =0, e = Ivars.size(); i < e; i++) {
6796 Result +=
"(unsigned long int *)&";
6797 if (Ivars[i]->isBitField())
6798 RewriteObj.ObjCIvarBitfieldGroupOffset(IvarDecl, Result);
6800 WriteInternalIvarName(CDecl, IvarDecl, Result);
6804 if (Ivars[i]->isBitField())
6805 RewriteObj.ObjCIvarBitfieldGroupDecl(Ivars[i], Result);
6807 Result += IvarDecl->
getName();
6812 IVQT = RewriteObj.GetGroupRecordTypeForObjCIvarBitfield(IvarDecl);
6814 std::string IvarTypeString, QuoteIvarTypeString;
6815 Context->getObjCEncodingForType(IVQT, IvarTypeString,
6817 RewriteObj.QuoteDoublequotes(IvarTypeString, QuoteIvarTypeString);
6818 Result +=
"\""; Result += QuoteIvarTypeString; Result +=
"\", ";
6822 unsigned Align = Context->getTypeAlign(IVQT)/8;
6823 Align = llvm::Log2_32(Align);
6824 Result += llvm::utostr(Align); Result +=
", ";
6826 Result += llvm::utostr(
Size.getQuantity());
6837void RewriteModernObjC::RewriteObjCProtocolMetaData(
ObjCProtocolDecl *PDecl,
6838 std::string &Result) {
6843 WriteModernMetadataDeclarations(Context, Result);
6850 RewriteObjCProtocolMetaData(I, Result);
6853 std::vector<ObjCMethodDecl *> InstanceMethods, ClassMethods;
6854 std::vector<ObjCMethodDecl *> OptInstanceMethods, OptClassMethods;
6857 OptInstanceMethods.push_back(MD);
6859 InstanceMethods.push_back(MD);
6865 OptClassMethods.push_back(MD);
6867 ClassMethods.push_back(MD);
6870 std::vector<ObjCMethodDecl *> AllMethods;
6871 for (
unsigned i = 0, e = InstanceMethods.size(); i < e; i++)
6872 AllMethods.push_back(InstanceMethods[i]);
6873 for (
unsigned i = 0, e = ClassMethods.size(); i < e; i++)
6874 AllMethods.push_back(ClassMethods[i]);
6875 for (
unsigned i = 0, e = OptInstanceMethods.size(); i < e; i++)
6876 AllMethods.push_back(OptInstanceMethods[i]);
6877 for (
unsigned i = 0, e = OptClassMethods.size(); i < e; i++)
6878 AllMethods.push_back(OptClassMethods[i]);
6880 Write__extendedMethodTypes_initializer(*
this, Context, Result,
6882 "_OBJC_PROTOCOL_METHOD_TYPES_",
6886 Write_protocol_list_initializer(Context, Result, SuperProtocols,
6887 "_OBJC_PROTOCOL_REFS_",
6890 Write_method_list_t_initializer(*
this, Context, Result, InstanceMethods,
6891 "_OBJC_PROTOCOL_INSTANCE_METHODS_",
6894 Write_method_list_t_initializer(*
this, Context, Result, ClassMethods,
6895 "_OBJC_PROTOCOL_CLASS_METHODS_",
6898 Write_method_list_t_initializer(*
this, Context, Result, OptInstanceMethods,
6899 "_OBJC_PROTOCOL_OPT_INSTANCE_METHODS_",
6902 Write_method_list_t_initializer(*
this, Context, Result, OptClassMethods,
6903 "_OBJC_PROTOCOL_OPT_CLASS_METHODS_",
6909 Write_prop_list_t_initializer(*
this, Context, Result, ProtocolProperties,
6911 "_OBJC_PROTOCOL_PROPERTIES_",
6916 if (LangOpts.MicrosoftExt)
6917 Result +=
"static ";
6918 Result +=
"struct _protocol_t _OBJC_PROTOCOL_";
6920 Result +=
" __attribute__ ((used)) = {\n";
6922 Result +=
"\t\""; Result += PDecl->
getNameAsString(); Result +=
"\",\n";
6923 if (SuperProtocols.size() > 0) {
6924 Result +=
"\t(const struct _protocol_list_t *)&"; Result +=
"_OBJC_PROTOCOL_REFS_";
6929 if (InstanceMethods.size() > 0) {
6930 Result +=
"\t(const struct method_list_t *)&_OBJC_PROTOCOL_INSTANCE_METHODS_";
6936 if (ClassMethods.size() > 0) {
6937 Result +=
"\t(const struct method_list_t *)&_OBJC_PROTOCOL_CLASS_METHODS_";
6943 if (OptInstanceMethods.size() > 0) {
6944 Result +=
"\t(const struct method_list_t *)&_OBJC_PROTOCOL_OPT_INSTANCE_METHODS_";
6950 if (OptClassMethods.size() > 0) {
6951 Result +=
"\t(const struct method_list_t *)&_OBJC_PROTOCOL_OPT_CLASS_METHODS_";
6957 if (ProtocolProperties.size() > 0) {
6958 Result +=
"\t(const struct _prop_list_t *)&_OBJC_PROTOCOL_PROPERTIES_";
6964 Result +=
"\t"; Result +=
"sizeof(_protocol_t)"; Result +=
",\n";
6967 if (AllMethods.size() > 0) {
6968 Result +=
"\t(const char **)&"; Result +=
"_OBJC_PROTOCOL_METHOD_TYPES_";
6973 Result +=
"\t0\n};\n";
6975 if (LangOpts.MicrosoftExt)
6976 Result +=
"static ";
6977 Result +=
"struct _protocol_t *";
6978 Result +=
"_OBJC_LABEL_PROTOCOL_$_"; Result += PDecl->
getNameAsString();
6984 llvm_unreachable(
"protocol already synthesized");
6992 if (OID->
hasAttr<ObjCExceptionAttr>())
7000 std::string &Result) {
7006 "Legacy implicit interface rewriting not supported in moder abi");
7008 WriteModernMetadataDeclarations(Context, Result);
7014 if (!IVD->getDeclName())
7016 IVars.push_back(IVD);
7019 Write__ivar_list_t_initializer(*
this, Context, Result, IVars,
7020 "_OBJC_$_INSTANCE_VARIABLES_",
7029 if (Prop->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic)
7031 if (!Prop->getPropertyIvarDecl())
7037 if (mustSynthesizeSetterGetterMethod(IDecl, PD,
true ))
7038 InstanceMethods.push_back(Getter);
7042 if (mustSynthesizeSetterGetterMethod(IDecl, PD,
false ))
7043 InstanceMethods.push_back(Setter);
7046 Write_method_list_t_initializer(*
this, Context, Result, InstanceMethods,
7047 "_OBJC_$_INSTANCE_METHODS_",
7052 Write_method_list_t_initializer(*
this, Context, Result, ClassMethods,
7053 "_OBJC_$_CLASS_METHODS_",
7058 std::vector<ObjCProtocolDecl *> RefedProtocols;
7061 E = Protocols.
end();
7063 RefedProtocols.push_back(*I);
7066 RewriteObjCProtocolMetaData(*I, Result);
7069 Write_protocol_list_initializer(Context, Result,
7071 "_OBJC_CLASS_PROTOCOLS_$_",
7077 Write_prop_list_t_initializer(*
this, Context, Result, ClassProperties,
7079 "_OBJC_$_PROP_LIST_",
7084 std::string InstanceSize;
7085 std::string InstanceStart;
7089 flags |= OBJC2_CLS_HIDDEN;
7094 InstanceSize =
"sizeof(struct _class_t)";
7095 InstanceStart = InstanceSize;
7096 Write__class_ro_t_initializer(Context, Result, flags,
7097 InstanceStart, InstanceSize,
7102 "_OBJC_METACLASS_RO_$_",
7108 flags |= OBJC2_CLS_HIDDEN;
7111 flags |= CLS_EXCEPTION;
7117 InstanceSize.clear();
7118 InstanceStart.clear();
7119 if (!ObjCSynthesizedStructs.count(CDecl)) {
7121 InstanceStart =
"0";
7124 InstanceSize =
"sizeof(struct ";
7126 InstanceSize +=
"_IMPL)";
7130 RewriteIvarOffsetComputation(IVD, InstanceStart);
7133 InstanceStart = InstanceSize;
7135 Write__class_ro_t_initializer(Context, Result, flags,
7136 InstanceStart, InstanceSize,
7141 "_OBJC_CLASS_RO_$_",
7144 Write_class_t(Context, Result,
7145 "OBJC_METACLASS_$_",
7148 Write_class_t(Context, Result,
7152 if (ImplementationIsNonLazy(IDecl))
7153 DefinedNonLazyClasses.push_back(CDecl);
7156void RewriteModernObjC::RewriteClassSetupInitHook(std::string &Result) {
7157 int ClsDefCount = ClassImplementation.size();
7160 Result +=
"#pragma section(\".objc_inithooks$B\", long, read, write)\n";
7161 Result +=
"__declspec(allocate(\".objc_inithooks$B\")) ";
7162 Result +=
"static void *OBJC_CLASS_SETUP[] = {\n";
7163 for (
int i = 0; i < ClsDefCount; i++) {
7166 Result +=
"\t(void *)&OBJC_CLASS_SETUP_$_";
7167 Result += CDecl->
getName(); Result +=
",\n";
7172void RewriteModernObjC::RewriteMetaDataIntoBuffer(std::string &Result) {
7173 int ClsDefCount = ClassImplementation.size();
7174 int CatDefCount = CategoryImplementation.size();
7177 for (
int i = 0; i < ClsDefCount; i++)
7178 RewriteObjCClassMetaData(ClassImplementation[i], Result);
7180 RewriteClassSetupInitHook(Result);
7183 for (
int i = 0; i < CatDefCount; i++)
7184 RewriteObjCCategoryImplDecl(CategoryImplementation[i], Result);
7186 RewriteCategorySetupInitHook(Result);
7188 if (ClsDefCount > 0) {
7189 if (LangOpts.MicrosoftExt)
7190 Result +=
"__declspec(allocate(\".objc_classlist$B\")) ";
7191 Result +=
"static struct _class_t *L_OBJC_LABEL_CLASS_$ [";
7192 Result += llvm::utostr(ClsDefCount); Result +=
"]";
7194 " __attribute__((used, section (\"__DATA, __objc_classlist,"
7195 "regular,no_dead_strip\")))= {\n";
7196 for (
int i = 0; i < ClsDefCount; i++) {
7197 Result +=
"\t&OBJC_CLASS_$_";
7198 Result += ClassImplementation[i]->getNameAsString();
7203 if (!DefinedNonLazyClasses.empty()) {
7204 if (LangOpts.MicrosoftExt)
7205 Result +=
"__declspec(allocate(\".objc_nlclslist$B\")) \n";
7206 Result +=
"static struct _class_t *_OBJC_LABEL_NONLAZY_CLASS_$[] = {\n\t";
7207 for (
unsigned i = 0, e = DefinedNonLazyClasses.size(); i < e; i++) {
7208 Result +=
"\t&OBJC_CLASS_$_"; Result += DefinedNonLazyClasses[i]->getNameAsString();
7215 if (CatDefCount > 0) {
7216 if (LangOpts.MicrosoftExt)
7217 Result +=
"__declspec(allocate(\".objc_catlist$B\")) ";
7218 Result +=
"static struct _category_t *L_OBJC_LABEL_CATEGORY_$ [";
7219 Result += llvm::utostr(CatDefCount); Result +=
"]";
7221 " __attribute__((used, section (\"__DATA, __objc_catlist,"
7222 "regular,no_dead_strip\")))= {\n";
7223 for (
int i = 0; i < CatDefCount; i++) {
7224 Result +=
"\t&_OBJC_$_CATEGORY_";
7226 CategoryImplementation[i]->getClassInterface()->getNameAsString();
7228 Result += CategoryImplementation[i]->getNameAsString();
7234 if (!DefinedNonLazyCategories.empty()) {
7235 if (LangOpts.MicrosoftExt)
7236 Result +=
"__declspec(allocate(\".objc_nlcatlist$B\")) \n";
7237 Result +=
"static struct _category_t *_OBJC_LABEL_NONLAZY_CATEGORY_$[] = {\n\t";
7238 for (
unsigned i = 0, e = DefinedNonLazyCategories.size(); i < e; i++) {
7239 Result +=
"\t&_OBJC_$_CATEGORY_";
7241 DefinedNonLazyCategories[i]->getClassInterface()->getNameAsString();
7243 Result += DefinedNonLazyCategories[i]->getNameAsString();
7250void RewriteModernObjC::WriteImageInfo(std::string &Result) {
7251 if (LangOpts.MicrosoftExt)
7252 Result +=
"__declspec(allocate(\".objc_imageinfo$B\")) \n";
7254 Result +=
"static struct IMAGE_INFO { unsigned version; unsigned flag; } ";
7256 Result +=
"_OBJC_IMAGE_INFO = { 0, 2 };\n";
7262 std::string &Result) {
7263 WriteModernMetadataDeclarations(Context, Result);
7270 FullCategoryName +=
"_$_";
7279 if (Prop->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic)
7281 if (!Prop->getPropertyIvarDecl())
7287 InstanceMethods.push_back(Getter);
7291 InstanceMethods.push_back(Setter);
7294 Write_method_list_t_initializer(*
this, Context, Result, InstanceMethods,
7295 "_OBJC_$_CATEGORY_INSTANCE_METHODS_",
7296 FullCategoryName,
true);
7300 Write_method_list_t_initializer(*
this, Context, Result, ClassMethods,
7301 "_OBJC_$_CATEGORY_CLASS_METHODS_",
7302 FullCategoryName,
true);
7310 RewriteObjCProtocolMetaData(I, Result);
7312 Write_protocol_list_initializer(Context, Result,
7314 "_OBJC_CATEGORY_PROTOCOLS_$_",
7320 Write_prop_list_t_initializer(*
this, Context, Result, ClassProperties,
7322 "_OBJC_$_PROP_LIST_",
7325 Write_category_t(*
this, Context, Result,
7334 if (ImplementationIsNonLazy(IDecl))
7335 DefinedNonLazyCategories.push_back(CDecl);
7338void RewriteModernObjC::RewriteCategorySetupInitHook(std::string &Result) {
7339 int CatDefCount = CategoryImplementation.size();
7342 Result +=
"#pragma section(\".objc_inithooks$B\", long, read, write)\n";
7343 Result +=
"__declspec(allocate(\".objc_inithooks$B\")) ";
7344 Result +=
"static void *OBJC_CATEGORY_SETUP[] = {\n";
7345 for (
int i = 0; i < CatDefCount; i++) {
7349 Result +=
"\t(void *)&OBJC_CATEGORY_SETUP_$_";
7350 Result += ClassDecl->
getName();
7360template<
typename MethodIterator>
7361void RewriteModernObjC::RewriteObjCMethodsMetaData(MethodIterator MethodBegin,
7362 MethodIterator MethodEnd,
7363 bool IsInstanceMethod,
7365 StringRef ClassName,
7366 std::string &Result) {
7367 if (MethodBegin == MethodEnd)
return;
7369 if (!objc_impl_method) {
7376 Result +=
"\nstruct _objc_method {\n";
7377 Result +=
"\tSEL _cmd;\n";
7378 Result +=
"\tchar *method_types;\n";
7379 Result +=
"\tvoid *_imp;\n";
7382 objc_impl_method =
true;
7393 unsigned NumMethods = std::distance(MethodBegin, MethodEnd);
7395 if (LangOpts.MicrosoftExt) {
7396 if (IsInstanceMethod)
7397 Result +=
"__declspec(allocate(\".inst_meth$B\")) ";
7399 Result +=
"__declspec(allocate(\".cls_meth$B\")) ";
7401 Result +=
"static struct {\n";
7402 Result +=
"\tstruct _objc_method_list *next_method;\n";
7403 Result +=
"\tint method_count;\n";
7404 Result +=
"\tstruct _objc_method method_list[";
7405 Result += utostr(NumMethods);
7406 Result +=
"];\n} _OBJC_";
7409 Result +=
"_METHODS_";
7410 Result += ClassName;
7411 Result +=
" __attribute__ ((used, section (\"__OBJC, __";
7413 Result +=
"_meth\")))= ";
7414 Result +=
"{\n\t0, " + utostr(NumMethods) +
"\n";
7416 Result +=
"\t,{{(SEL)\"";
7417 Result += (*MethodBegin)->getSelector().getAsString().c_str();
7418 std::string MethodTypeString;
7419 Context->getObjCEncodingForMethodDecl(*MethodBegin, MethodTypeString);
7421 Result += MethodTypeString;
7422 Result +=
"\", (void *)";
7423 Result += MethodInternalNames[*MethodBegin];
7425 for (++MethodBegin; MethodBegin != MethodEnd; ++MethodBegin) {
7426 Result +=
"\t ,{(SEL)\"";
7427 Result += (*MethodBegin)->getSelector().getAsString().c_str();
7428 std::string MethodTypeString;
7429 Context->getObjCEncodingForMethodDecl(*MethodBegin, MethodTypeString);
7431 Result += MethodTypeString;
7432 Result +=
"\", (void *)";
7433 Result += MethodInternalNames[*MethodBegin];
7436 Result +=
"\t }\n};\n";
7445 DisableReplaceStmtScope S(*
this);
7446 BaseExpr = cast<Expr>(RewriteFunctionBodyOrGlobalInitializer(BaseExpr));
7452 Expr *Replacement = IV;
7457 assert(iFaceDecl &&
"RewriteObjCIvarRefExpr - iFaceDecl is null");
7462 assert(clsDeclared &&
"RewriteObjCIvarRefExpr(): Can't find class");
7465 std::string IvarOffsetName;
7466 if (
D->isBitField())
7467 ObjCIvarBitfieldGroupOffset(
D, IvarOffsetName);
7469 WriteInternalIvarName(clsDeclared,
D, IvarOffsetName);
7471 ReferencedIvars[clsDeclared].insert(
D);
7475 Context->getPointerType(Context->CharTy),
7480 Context->UnsignedLongTy,
nullptr,
7483 DeclRefExpr(*Context, NewVD,
false, Context->UnsignedLongTy,
7486 *Context, castExpr, DRE, BO_Add,
7487 Context->getPointerType(Context->CharTy), VK_PRValue, OK_Ordinary,
7494 if (
D->isBitField())
7495 IvarT = GetGroupRecordTypeForObjCIvarBitfield(
D);
7502 auto *CDecl = cast<ObjCContainerDecl>(
D->getDeclContext());
7506 std::string RecName = std::string(CDecl->
getName());
7511 QualType PtrStructIMPL = Context->getPointerType(Context->getTagDeclType(RD));
7512 unsigned UnsignedIntSize =
7513 static_cast<unsigned>(Context->getTypeSize(Context->UnsignedIntTy));
7514 Expr *
Zero = IntegerLiteral::Create(*Context,
7515 llvm::APInt(UnsignedIntSize, 0),
7517 Zero = NoTypeInfoCStyleCastExpr(Context, PtrStructIMPL, CK_BitCast, Zero);
7522 &Context->Idents.get(
D->getNameAsString()),
7527 *Context, PE,
true, FD, FD->
getType(), VK_LValue, OK_Ordinary);
7528 IvarT = Context->getDecltypeType(ME, ME->
getType());
7531 convertObjCTypeToCStyleType(IvarT);
7532 QualType castT = Context->getPointerType(IvarT);
7534 castExpr = NoTypeInfoCStyleCastExpr(Context,
7539 Expr *Exp = UnaryOperator::Create(
7540 const_cast<ASTContext &
>(*Context), castExpr, UO_Deref, IvarT,
7546 if (
D->isBitField()) {
7549 &Context->Idents.get(
D->getNameAsString()),
7550 D->getType(),
nullptr,
7554 MemberExpr::CreateImplicit(*Context, PE,
false, FD,
7555 FD->
getType(), VK_LValue, OK_Ordinary);
7563 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...
enum clang::sema::@1655::IndirectLocalPathEntry::EntryKind Kind
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...
ObjCCategoryDecl * FindCategoryDeclaration(const IdentifierInfo *CategoryId) const
FindCategoryDeclaration - Finds category declaration in the list of categories for this class and ret...
bool isThisDeclarationADefinition() const
Determine whether this particular declaration of this class is actually also a definition.
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 parenthesized 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...
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.
const FunctionProtoType * T
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 *.